diff options
Diffstat (limited to 'lib/percept')
38 files changed, 900 insertions, 949 deletions
diff --git a/lib/percept/Makefile b/lib/percept/Makefile index 2c6a970574..1f51bd2fef 100644 --- a/lib/percept/Makefile +++ b/lib/percept/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2007-2009. All Rights Reserved. +# Copyright Ericsson AB 2007-2016. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/percept/doc/src/Makefile b/lib/percept/doc/src/Makefile index 604c6d1db1..2f84d61cbc 100644 --- a/lib/percept/doc/src/Makefile +++ b/lib/percept/doc/src/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2007-2012. All Rights Reserved. +# Copyright Ericsson AB 2007-2016. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/percept/doc/src/book.xml b/lib/percept/doc/src/book.xml index 1f12d57892..5acba1f214 100644 --- a/lib/percept/doc/src/book.xml +++ b/lib/percept/doc/src/book.xml @@ -5,7 +5,7 @@ <header titlestyle="normal"> <copyright> <year>2007</year> - <year>2013</year> + <year>2016</year> <holder>Ericsson AB, All Rights Reserved</holder> </copyright> <legalnotice> diff --git a/lib/percept/doc/src/egd_ug.xmlsrc b/lib/percept/doc/src/egd_ug.xmlsrc index 253bfcaeb5..85d41ada79 100644 --- a/lib/percept/doc/src/egd_ug.xmlsrc +++ b/lib/percept/doc/src/egd_ug.xmlsrc @@ -5,7 +5,7 @@ <header> <copyright> <year>2007</year> - <year>2013</year> + <year>2016</year> <holder>Ericsson AB, All Rights Reserved</holder> </copyright> <legalnotice> @@ -51,24 +51,27 @@ </section> <section> <title>File example</title> - <p>Drawing examples:</p> - <codeinclude file="img.erl" tag="" type="none"></codeinclude> - <image file="test1.gif"> - First save. - <icaption>test1.png</icaption> - </image> - <image file="test2.gif"> - Second save. - <icaption>test2.png</icaption> - </image> - <image file="test3.gif"> - Third save. - <icaption>test3.png</icaption> - </image> - <image file="test4.gif"> - Fourth save. - <icaption>test4.png</icaption> - </image> + <p>Drawing examples:</p> + <codeinclude file="img.erl" tag="" type="none"></codeinclude> + <p> First save. </p> + <image file="test1.gif"> + <icaption>test1.png</icaption> + </image> + + <p> Second save. </p> + <image file="test2.gif"> + <icaption>test2.png</icaption> + </image> + + <p> Third save. </p> + <image file="test3.gif"> + <icaption>test3.png</icaption> + </image> + + <p> Fourth save. </p> + <image file="test4.gif"> + <icaption>test4.png</icaption> + </image> </section> <section> <title>ESI example</title> diff --git a/lib/percept/doc/src/notes.xml b/lib/percept/doc/src/notes.xml index 74183eb251..c9d5d3ae29 100644 --- a/lib/percept/doc/src/notes.xml +++ b/lib/percept/doc/src/notes.xml @@ -5,7 +5,7 @@ <header> <copyright> <year>2007</year> - <year>2013</year> + <year>2016</year> <holder>Ericsson AB, All Rights Reserved</holder> </copyright> <legalnotice> @@ -33,6 +33,35 @@ </header> <p>This document describes the changes made to the Percept application.</p> +<section><title>Percept 0.9</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Remove deprecated <c>erlang:now/0</c> calls</p> + <p> + Own Id: OTP-13422</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Improve line implementation</p> + <p> + Add capabilities for line thickness and anti-aliasing.</p> + <p> + Own Id: OTP-13598</p> + </item> + </list> + </section> + +</section> + <section><title>Percept 0.8.11</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/percept/doc/src/part.xml b/lib/percept/doc/src/part.xml index 135532a9e6..277d89d45c 100644 --- a/lib/percept/doc/src/part.xml +++ b/lib/percept/doc/src/part.xml @@ -5,7 +5,7 @@ <header> <copyright> <year>2007</year> - <year>2013</year> + <year>2016</year> <holder>Ericsson AB, All Rights Reserved</holder> </copyright> <legalnotice> diff --git a/lib/percept/doc/src/part_notes.xml b/lib/percept/doc/src/part_notes.xml index 458b5d3ea3..f428b4fd81 100644 --- a/lib/percept/doc/src/part_notes.xml +++ b/lib/percept/doc/src/part_notes.xml @@ -5,7 +5,7 @@ <header> <copyright> <year>2007</year> - <year>2013</year> + <year>2016</year> <holder>Ericsson AB, All Rights Reserved</holder> </copyright> <legalnotice> diff --git a/lib/percept/doc/src/percept_ug.xmlsrc b/lib/percept/doc/src/percept_ug.xmlsrc index 4791deea22..0d243cdabe 100644 --- a/lib/percept/doc/src/percept_ug.xmlsrc +++ b/lib/percept/doc/src/percept_ug.xmlsrc @@ -5,7 +5,7 @@ <header> <copyright> <year>2007</year> - <year>2013</year> + <year>2016</year> <holder>Ericsson AB, All Rights Reserved</holder> </copyright> <legalnotice> diff --git a/lib/percept/doc/src/ref_man.xml b/lib/percept/doc/src/ref_man.xml index b95fc56973..143312489b 100644 --- a/lib/percept/doc/src/ref_man.xml +++ b/lib/percept/doc/src/ref_man.xml @@ -5,7 +5,7 @@ <header> <copyright> <year>2007</year> - <year>2013</year> + <year>2016</year> <holder>Ericsson AB, All Rights Reserved</holder> </copyright> <legalnotice> diff --git a/lib/percept/doc/stylesheet.css b/lib/percept/doc/stylesheet.css index 86280a8fc4..24d8a02145 100644 --- a/lib/percept/doc/stylesheet.css +++ b/lib/percept/doc/stylesheet.css @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2007-2009. All Rights Reserved. + * Copyright Ericsson AB 2007-2016. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/lib/percept/priv/Makefile b/lib/percept/priv/Makefile index 44229c9567..a1912edfc0 100644 --- a/lib/percept/priv/Makefile +++ b/lib/percept/priv/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2007-2012. All Rights Reserved. +# Copyright Ericsson AB 2007-2016. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/percept/priv/server_root/css/percept.css b/lib/percept/priv/server_root/css/percept.css index 7335e62387..2d0734b6b6 100644 --- a/lib/percept/priv/server_root/css/percept.css +++ b/lib/percept/priv/server_root/css/percept.css @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2007-2009. All Rights Reserved. + * Copyright Ericsson AB 2007-2016. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/lib/percept/priv/server_root/htdocs/index.html b/lib/percept/priv/server_root/htdocs/index.html index e84d8fb10a..f7322cba89 100644 --- a/lib/percept/priv/server_root/htdocs/index.html +++ b/lib/percept/priv/server_root/htdocs/index.html @@ -1,7 +1,7 @@ <!-- %CopyrightBegin% - Copyright Ericsson AB 2007-2009. All Rights Reserved. + Copyright Ericsson AB 2007-2016. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/lib/percept/priv/server_root/scripts/percept_area_select.js b/lib/percept/priv/server_root/scripts/percept_area_select.js index 6dd64650be..83fbb02c92 100644 --- a/lib/percept/priv/server_root/scripts/percept_area_select.js +++ b/lib/percept/priv/server_root/scripts/percept_area_select.js @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2007-2009. All Rights Reserved. + * Copyright Ericsson AB 2007-2016. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/lib/percept/priv/server_root/scripts/percept_error_handler.js b/lib/percept/priv/server_root/scripts/percept_error_handler.js index 8bad57a5b7..dad8f2b566 100644 --- a/lib/percept/priv/server_root/scripts/percept_error_handler.js +++ b/lib/percept/priv/server_root/scripts/percept_error_handler.js @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2007-2009. All Rights Reserved. + * Copyright Ericsson AB 2007-2016. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/lib/percept/priv/server_root/scripts/percept_select_all.js b/lib/percept/priv/server_root/scripts/percept_select_all.js index 118741b7de..c8eb966059 100644 --- a/lib/percept/priv/server_root/scripts/percept_select_all.js +++ b/lib/percept/priv/server_root/scripts/percept_select_all.js @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2007-2009. All Rights Reserved. + * Copyright Ericsson AB 2007-2016. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/lib/percept/src/Makefile b/lib/percept/src/Makefile index 9b963e0fae..b2ec87d08c 100644 --- a/lib/percept/src/Makefile +++ b/lib/percept/src/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2007-2012. All Rights Reserved. +# Copyright Ericsson AB 2007-2016. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/percept/src/egd.erl b/lib/percept/src/egd.erl index 3a065c8919..fe52da71f1 100644 --- a/lib/percept/src/egd.erl +++ b/lib/percept/src/egd.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2011. All Rights Reserved. +%% Copyright Ericsson AB 2008-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -37,9 +37,7 @@ -include("egd.hrl"). %%========================================================================== -%% -%% Type definitions -%% +%% Type definitions %%========================================================================== %% @type egd_image() @@ -54,9 +52,7 @@ -type color() :: {float(), float(), float(), float()}. %%========================================================================== -%% -%% Interface functions -%% +%% Interface functions %%========================================================================== %% @spec create(integer(), integer()) -> egd_image() @@ -74,8 +70,7 @@ create(Width,Height) -> -spec destroy(Image :: egd_image()) -> ok. destroy(Image) -> - cast(Image, destroy), - ok. + cast(Image, destroy). %% @spec render(egd_image()) -> binary() @@ -113,8 +108,7 @@ render(Image, Type, Options) -> %% mainly. information(Pid) -> - cast(Pid, information), - ok. + cast(Pid, information). %% @spec line(egd_image(), point(), point(), color()) -> ok %% @doc Creates a line object from P1 to P2 in the image. @@ -126,8 +120,7 @@ information(Pid) -> Color :: color()) -> 'ok'. line(Image, P1, P2, Color) -> - cast(Image, {line, P1, P2, Color}), - ok. + cast(Image, {line, P1, P2, Color}). %% @spec color( Value | Name ) -> color() %% where @@ -152,74 +145,67 @@ color(_Image, Color) -> %% @doc Creates a text object. text(Image, P, Font, Text, Color) -> - cast(Image, {text, P, Font, Text, Color}), - ok. + cast(Image, {text, P, Font, Text, Color}). %% @spec rectangle(egd_image(), point(), point(), color()) -> ok %% @doc Creates a rectangle object. rectangle(Image, P1, P2, Color) -> - cast(Image, {rectangle, P1, P2, Color}), - ok. + cast(Image, {rectangle, P1, P2, Color}). %% @spec filledRectangle(egd_image(), point(), point(), color()) -> ok %% @doc Creates a filled rectangle object. filledRectangle(Image, P1, P2, Color) -> - cast(Image, {filled_rectangle, P1, P2, Color}), - ok. + cast(Image, {filled_rectangle, P1, P2, Color}). %% @spec filledEllipse(egd_image(), point(), point(), color()) -> ok %% @doc Creates a filled ellipse object. filledEllipse(Image, P1, P2, Color) -> - cast(Image, {filled_ellipse, P1, P2, Color}), - ok. + cast(Image, {filled_ellipse, P1, P2, Color}). %% @spec filledTriangle(egd_image(), point(), point(), point(), color()) -> ok %% @hidden %% @doc Creates a filled triangle object. filledTriangle(Image, P1, P2, P3, Color) -> - cast(Image, {filled_triangle, P1, P2, P3, Color}), - ok. + cast(Image, {filled_triangle, P1, P2, P3, Color}). %% @spec polygon(egd_image(), [point()], color()) -> ok %% @hidden %% @doc Creates a filled filled polygon object. polygon(Image, Pts, Color) -> - cast(Image, {polygon, Pts, Color}), - ok. + cast(Image, {polygon, Pts, Color}). %% @spec arc(egd_image(), point(), point(), color()) -> ok %% @hidden %% @doc Creates an arc with radius of bbx corner. arc(Image, P1, P2, Color) -> - cast(Image, {arc, P1, P2, Color}), - ok. + cast(Image, {arc, P1, P2, Color}). %% @spec arc(egd_image(), point(), point(), integer(), color()) -> ok %% @hidden %% @doc Creates an arc. arc(Image, P1, P2, D, Color) -> - cast(Image, {arc, P1, P2, D, Color}), - ok. + cast(Image, {arc, P1, P2, D, Color}). %% @spec save(binary(), string()) -> ok %% @doc Saves the binary to file. save(Binary, Filename) when is_binary(Binary) -> - file:write_file(Filename, Binary), + ok = file:write_file(Filename, Binary), ok. % --------------------------------- % Aux functions % --------------------------------- cast(Pid, Command) -> - Pid ! {egd, self(), Command}. + Pid ! {egd, self(), Command}, + ok. call(Pid, Command) -> Pid ! {egd, self(), Command}, diff --git a/lib/percept/src/egd.hrl b/lib/percept/src/egd.hrl index 43db16d3a1..fc0a7e10ee 100644 --- a/lib/percept/src/egd.hrl +++ b/lib/percept/src/egd.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -41,6 +41,5 @@ -ifdef(debug). -define(dbg(X), io:format("DEBUG: ~p:~p~n",[?MODULE, X])). -else. --define(dbg(X), void). +-define(dbg(X), ok). -endif. - diff --git a/lib/percept/src/egd_font.erl b/lib/percept/src/egd_font.erl index 6ee3728fde..ef1cc434df 100644 --- a/lib/percept/src/egd_font.erl +++ b/lib/percept/src/egd_font.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2009. All Rights Reserved. +%% Copyright Ericsson AB 2008-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -51,9 +51,7 @@ %% %%========================================================================== -%% -%% Interface functions -%% +%% Interface functions %%========================================================================== size(Font) -> @@ -70,15 +68,14 @@ load(Filename) -> load_font_header(Font). %%========================================================================== -%% -%% Internal functions -%% +%% Internal functions %%========================================================================== %% ETS handler functions initialize_table() -> - ets:new(egd_font_table, [named_table, ordered_set, public]). + egd_font_table = ets:new(egd_font_table, [named_table, ordered_set, public]), + ok. glyph_insert(Font, Code, Translation, LSs) -> Element = {{Font, Code}, Translation, LSs}, diff --git a/lib/percept/src/egd_png.erl b/lib/percept/src/egd_png.erl index c576d569a9..fe660513b4 100644 --- a/lib/percept/src/egd_png.erl +++ b/lib/percept/src/egd_png.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2009. All Rights Reserved. +%% Copyright Ericsson AB 2008-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/percept/src/egd_primitives.erl b/lib/percept/src/egd_primitives.erl index 0a3a62c05c..b64189c552 100644 --- a/lib/percept/src/egd_primitives.erl +++ b/lib/percept/src/egd_primitives.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2009. All Rights Reserved. +%% Copyright Ericsson AB 2008-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -23,32 +23,27 @@ -module(egd_primitives). --export([ - create/2, - color/1, - pixel/3, - polygon/3, - line/4, - line/5, - arc/4, - arc/5, - rectangle/4, - filledRectangle/4, - filledEllipse/4, - filledTriangle/5, - text/5 - ]). - --export([ - info/1, - object_info/1, - rgb_float2byte/1 - ]). --export([ - arc_to_edges/3, - convex_hull/1, - edges/1 - ]). +-export([create/2, + color/1, + pixel/3, + polygon/3, + line/4, + line/5, + arc/4, + arc/5, + rectangle/4, + filledRectangle/4, + filledEllipse/4, + filledTriangle/5, + text/5]). + +-export([info/1, + object_info/1, + rgb_float2byte/1]). + +-export([arc_to_edges/3, + convex_hull/1, + edges/1]). -include("egd.hrl"). @@ -75,22 +70,16 @@ object_info(O) -> %% interface functions -line(I, Sp, Ep, Color) -> - I#image{ objects = [ - #image_object{ - type = line, - points = [Sp, Ep], - span = span([Sp, Ep]), - color = Color} | I#image.objects]}. +line(#image{objects=Os}=I, Sp, Ep, Color) -> + line(#image{objects=Os}=I, Sp, Ep, 1, Color). -line(I, Sp, Ep, Stroke, Color) -> - I#image{ objects = [ - #image_object{ - type = line, - points = [Sp, Ep], - span = span([Sp, Ep]), - internals = Stroke, - color = Color } | I#image.objects]}. +line(#image{objects=Os}=I, Sp, Ep, Wd, Color) -> + I#image{objects=[#image_object{ + internals = Wd, + type = line, + points = [Sp, Ep], + span = span([Sp, Ep]), + color = Color}|Os]}. arc(I, {Sx,Sy} = Sp, {Ex,Ey} = Ep, Color) -> X = Ex - Sx, @@ -98,241 +87,234 @@ arc(I, {Sx,Sy} = Sp, {Ex,Ey} = Ep, Color) -> R = math:sqrt(X*X + Y*Y)/2, arc(I, Sp, Ep, R, Color). -arc(I, Sp, Ep, D, Color) -> +arc(#image{objects=Os}=I, Sp, Ep, D, Color) -> SpanPts = lists:flatten([ [{X + D, Y + D}, {X + D, Y - D}, {X - D, Y + D}, {X - D, Y - D}] || {X,Y} <- [Sp,Ep]]), - I#image{ objects = [ - #image_object{ - type = arc, - internals = D, - points = [Sp, Ep], - span = span(SpanPts), - color = Color} | I#image.objects]}. + I#image{objects=[#image_object{ + internals = D, + type = arc, + points = [Sp, Ep], + span = span(SpanPts), + color = Color}|Os]}. -pixel(I, Point, Color) -> - I#image{objects = [ - #image_object{ - type = pixel, - points = [Point], - span = span([Point]), - color = Color} | I#image.objects]}. - -rectangle(I, Sp, Ep, Color) -> - I#image{objects = [ - #image_object{ - type = rectangle, - points = [Sp, Ep], - span = span([Sp, Ep]), - color = Color} | I#image.objects]}. - -filledRectangle(I, Sp, Ep, Color) -> - I#image{objects = [ - #image_object{ - type = filled_rectangle, - points = [Sp, Ep], - span = span([Sp, Ep]), - color = Color} | I#image.objects]}. - -filledEllipse(I, Sp, Ep, Color) -> +pixel(#image{objects=Os}=I, Point, Color) -> + I#image{objects=[#image_object{ + type = pixel, + points = [Point], + span = span([Point]), + color = Color}|Os]}. + +rectangle(#image{objects=Os}=I, Sp, Ep, Color) -> + I#image{objects=[#image_object{ + type = rectangle, + points = [Sp, Ep], + span = span([Sp, Ep]), + color = Color}|Os]}. + +filledRectangle(#image{objects=Os}=I, Sp, Ep, Color) -> + I#image{objects=[#image_object{ + type = filled_rectangle, + points = [Sp, Ep], + span = span([Sp, Ep]), + color = Color}|Os]}. + +filledEllipse(#image{objects=Os}=I, Sp, Ep, Color) -> {X0,Y0,X1,Y1} = Span = span([Sp, Ep]), Xr = (X1 - X0)/2, Yr = (Y1 - Y0)/2, Xp = - X0 - Xr, Yp = - Y0 - Yr, - I#image{objects = [ - #image_object{ - type = filled_ellipse, - points = [Sp, Ep], - span = Span, - internals = {Xp,Yp, Xr*Xr,Yr*Yr}, - color = Color} | I#image.objects]}. - -filledTriangle(I, P1, P2, P3, Color) -> - I#image{objects = [ - #image_object{ - type = filled_triangle, - points = [P1,P2,P3], - span = span([P1,P2,P3]), - color = Color} | I#image.objects]}. - - -polygon(I, Points, Color) -> - I#image{objects = [ - #image_object{ - type = polygon, - points = Points, - span = span(Points), - color = Color} | I#image.objects]}. + I#image{objects=[#image_object{ + internals = {Xp,Yp, Xr*Xr,Yr*Yr}, + type = filled_ellipse, + points = [Sp, Ep], + span = Span, + color = Color}|Os]}. + +filledTriangle(#image{objects=Os}=I, P1, P2, P3, Color) -> + I#image{objects=[#image_object{ + type = filled_triangle, + points = [P1,P2,P3], + span = span([P1,P2,P3]), + color = Color}|Os]}. + +polygon(#image{objects=Os}=I, Points, Color) -> + I#image{objects=[#image_object{ + type = polygon, + points = Points, + span = span(Points), + color = Color}|Os]}. + +text(#image{objects=Os}=I, {Xs,Ys}=Sp, Font, Text, Color) -> + {FW,FH} = egd_font:size(Font), + Length = length(Text), + Ep = {Xs + Length*FW, Ys + FH + 5}, + I#image{objects=[#image_object{ + internals = {Font, Text}, + type = text_horizontal, + points = [Sp], + span = span([Sp,Ep]), + color = Color}|Os]}. create(W, H) -> - #image{ width = W, height = H}. + #image{width = W, height = H}. - -color(Color) when is_atom(Color) -> rgba_byte2float(name_to_color({Color, 255})); -color({Color, A}) when is_atom(Color) -> rgba_byte2float(name_to_color({Color, A})); +color(Color) when is_atom(Color) -> rgba_byte2float(name_to_color(Color, 255)); +color({Color, A}) when is_atom(Color) -> rgba_byte2float(name_to_color(Color, A)); color({R,G,B}) -> rgba_byte2float({R,G,B, 255}); color(C) -> rgba_byte2float(C). -% HTML default colors -name_to_color({ black, A}) -> { 0, 0, 0, A}; -name_to_color({ silver, A}) -> { 192, 192, 192, A}; -name_to_color({ gray, A}) -> { 128, 128, 128, A}; -name_to_color({ white, A}) -> { 128, 0, 0, A}; -name_to_color({ maroon, A}) -> { 255, 0, 0, A}; -name_to_color({ red, A}) -> { 128, 0, 128, A}; -name_to_color({ purple, A}) -> { 128, 0, 128, A}; -name_to_color({ fuchia, A}) -> { 255, 0, 255, A}; -name_to_color({ green, A}) -> { 0, 128, 0, A}; -name_to_color({ lime, A}) -> { 0, 255, 0, A}; -name_to_color({ olive, A}) -> { 128, 128, 0, A}; -name_to_color({ yellow, A}) -> { 255, 255, 0, A}; -name_to_color({ navy, A}) -> { 0, 0, 128, A}; -name_to_color({ blue, A}) -> { 0, 0, 255, A}; -name_to_color({ teal, A}) -> { 0, 128, 0, A}; -name_to_color({ aqua, A}) -> { 0, 255, 155, A}; - -% HTML color extensions -name_to_color({ steelblue, A}) -> { 70, 130, 180, A}; -name_to_color({ royalblue, A}) -> { 4, 22, 144, A}; -name_to_color({ cornflowerblue, A}) -> { 100, 149, 237, A}; -name_to_color({ lightsteelblue, A}) -> { 176, 196, 222, A}; -name_to_color({ mediumslateblue, A}) -> { 123, 104, 238, A}; -name_to_color({ slateblue, A}) -> { 106, 90, 205, A}; -name_to_color({ darkslateblue, A}) -> { 72, 61, 139, A}; -name_to_color({ midnightblue, A}) -> { 25, 25, 112, A}; -name_to_color({ darkblue, A}) -> { 0, 0, 139, A}; -name_to_color({ mediumblue, A}) -> { 0, 0, 205, A}; -name_to_color({ dodgerblue, A}) -> { 30, 144, 255, A}; -name_to_color({ deepskyblue, A}) -> { 0, 191, 255, A}; -name_to_color({ lightskyblue, A}) -> { 135, 206, 250, A}; -name_to_color({ skyblue, A}) -> { 135, 206, 235, A}; -name_to_color({ lightblue, A}) -> { 173, 216, 230, A}; -name_to_color({ powderblue, A}) -> { 176, 224, 230, A}; -name_to_color({ azure, A}) -> { 240, 255, 255, A}; -name_to_color({ lightcyan, A}) -> { 224, 255, 255, A}; -name_to_color({ paleturquoise, A}) -> { 175, 238, 238, A}; -name_to_color({ mediumturquoise, A}) -> { 72, 209, 204, A}; -name_to_color({ lightseagreen, A}) -> { 32, 178, 170, A}; -name_to_color({ darkcyan, A}) -> { 0, 139, 139, A}; -name_to_color({ cadetblue, A}) -> { 95, 158, 160, A}; -name_to_color({ darkturquoise, A}) -> { 0, 206, 209, A}; -name_to_color({ cyan, A}) -> { 0, 255, 255, A}; -name_to_color({ turquoise, A}) -> { 64, 224, 208, A}; -name_to_color({ aquamarine, A}) -> { 127, 255, 212, A}; -name_to_color({ mediumaquamarine, A}) -> { 102, 205, 170, A}; -name_to_color({ darkseagreen, A}) -> { 143, 188, 143, A}; -name_to_color({ mediumseagreen, A}) -> { 60, 179, 113, A}; -name_to_color({ seagreen, A}) -> { 46, 139, 87, A}; -name_to_color({ darkgreen, A}) -> { 0, 100, 0, A}; -name_to_color({ forestgreen, A}) -> { 34, 139, 34, A}; -name_to_color({ limegreen, A}) -> { 50, 205, 50, A}; -name_to_color({ chartreuse, A}) -> { 127, 255, 0, A}; -name_to_color({ lawngreen, A}) -> { 124, 252, 0, A}; -name_to_color({ greenyellow, A}) -> { 173, 255, 47, A}; -name_to_color({ yellowgreen, A}) -> { 154, 205, 50, A}; -name_to_color({ palegreen, A}) -> { 152, 251, 152, A}; -name_to_color({ lightgreen, A}) -> { 144, 238, 144, A}; -name_to_color({ springgreen, A}) -> { 0, 255, 127, A}; -name_to_color({ mediumspringgreen, A}) -> { 0, 250, 154, A}; -name_to_color({ darkolivegreen, A}) -> { 85, 107, 47, A}; -name_to_color({ olivedrab, A}) -> { 107, 142, 35, A}; -name_to_color({ darkkhaki, A}) -> { 189, 183, 107, A}; -name_to_color({ darkgoldenrod, A}) -> { 184, 134, 11, A}; -name_to_color({ goldenrod, A}) -> { 218, 165, 32, A}; -name_to_color({ gold, A}) -> { 255, 215, 0, A}; -name_to_color({ khaki, A}) -> { 240, 230, 140, A}; -name_to_color({ palegoldenrod, A}) -> { 238, 232, 170, A}; -name_to_color({ blanchedalmond, A}) -> { 255, 235, 205, A}; -name_to_color({ moccasin, A}) -> { 255, 228, 181, A}; -name_to_color({ wheat, A}) -> { 245, 222, 179, A}; -name_to_color({ navajowhite, A}) -> { 255, 222, 173, A}; -name_to_color({ burlywood, A}) -> { 222, 184, 135, A}; -name_to_color({ tan, A}) -> { 210, 180, 140, A}; -name_to_color({ rosybrown, A}) -> { 188, 143, 143, A}; -name_to_color({ sienna, A}) -> { 160, 82, 45, A}; -name_to_color({ saddlebrown, A}) -> { 139, 69, 19, A}; -name_to_color({ chocolate, A}) -> { 210, 105, 30, A}; -name_to_color({ peru, A}) -> { 205, 133, 63, A}; -name_to_color({ sandybrown, A}) -> { 244, 164, 96, A}; -name_to_color({ darkred, A}) -> { 139, 0, 0, A}; -name_to_color({ brown, A}) -> { 165, 42, 42, A}; -name_to_color({ firebrick, A}) -> { 178, 34, 34, A}; -name_to_color({ indianred, A}) -> { 205, 92, 92, A}; -name_to_color({ lightcoral, A}) -> { 240, 128, 128, A}; -name_to_color({ salmon, A}) -> { 250, 128, 114, A}; -name_to_color({ darksalmon, A}) -> { 233, 150, 122, A}; -name_to_color({ lightsalmon, A}) -> { 255, 160, 122, A}; -name_to_color({ coral, A}) -> { 255, 127, 80, A}; -name_to_color({ tomato, A}) -> { 255, 99, 71, A}; -name_to_color({ darkorange, A}) -> { 255, 140, 0, A}; -name_to_color({ orange, A}) -> { 255, 165, 0, A}; -name_to_color({ orangered, A}) -> { 255, 69, 0, A}; -name_to_color({ crimson, A}) -> { 220, 20, 60, A}; -name_to_color({ deeppink, A}) -> { 255, 20, 147, A}; -name_to_color({ fuchsia, A}) -> { 255, 0, 255, A}; -name_to_color({ magenta, A}) -> { 255, 0, 255, A}; -name_to_color({ hotpink, A}) -> { 255, 105, 180, A}; -name_to_color({ lightpink, A}) -> { 255, 182, 193, A}; -name_to_color({ pink, A}) -> { 255, 192, 203, A}; -name_to_color({ palevioletred, A}) -> { 219, 112, 147, A}; -name_to_color({ mediumvioletred, A}) -> { 199, 21, 133, A}; -name_to_color({ darkmagenta, A}) -> { 139, 0, 139, A}; -name_to_color({ mediumpurple, A}) -> { 147, 112, 219, A}; -name_to_color({ blueviolet, A}) -> { 138, 43, 226, A}; -name_to_color({ indigo, A}) -> { 75, 0, 130, A}; -name_to_color({ darkviolet, A}) -> { 148, 0, 211, A}; -name_to_color({ darkorchid, A}) -> { 153, 50, 204, A}; -name_to_color({ mediumorchid, A}) -> { 186, 85, 211, A}; -name_to_color({ orchid, A}) -> { 218, 112, 214, A}; -name_to_color({ violet, A}) -> { 238, 130, 238, A}; -name_to_color({ plum, A}) -> { 221, 160, 221, A}; -name_to_color({ thistle, A}) -> { 216, 191, 216, A}; -name_to_color({ lavender, A}) -> { 230, 230, 250, A}; -name_to_color({ ghostwhite, A}) -> { 248, 248, 255, A}; -name_to_color({ aliceblue, A}) -> { 240, 248, 255, A}; -name_to_color({ mintcream, A}) -> { 245, 255, 250, A}; -name_to_color({ honeydew, A}) -> { 240, 255, 240, A}; -name_to_color({ lightgoldenrodyellow, A}) -> { 250, 250, 210, A}; -name_to_color({ lemonchiffon, A}) -> { 255, 250, 205, A}; -name_to_color({ cornsilk, A}) -> { 255, 248, 220, A}; -name_to_color({ lightyellow, A}) -> { 255, 255, 224, A}; -name_to_color({ ivory, A}) -> { 255, 255, 240, A}; -name_to_color({ floralwhite, A}) -> { 255, 250, 240, A}; -name_to_color({ linen, A}) -> { 250, 240, 230, A}; -name_to_color({ oldlace, A}) -> { 253, 245, 230, A}; -name_to_color({ antiquewhite, A}) -> { 250, 235, 215, A}; -name_to_color({ bisque, A}) -> { 255, 228, 196, A}; -name_to_color({ peachpuff, A}) -> { 255, 218, 185, A}; -name_to_color({ papayawhip, A}) -> { 255, 239, 213, A}; -name_to_color({ beige, A}) -> { 245, 245, 220, A}; -name_to_color({ seashell, A}) -> { 255, 245, 238, A}; -name_to_color({ lavenderblush, A}) -> { 255, 240, 245, A}; -name_to_color({ mistyrose, A}) -> { 255, 228, 225, A}; -name_to_color({ snow, A}) -> { 255, 250, 250, A}; -name_to_color({ whitesmoke, A}) -> { 245, 245, 245, A}; -name_to_color({ gainsboro, A}) -> { 220, 220, 220, A}; -name_to_color({ lightgrey, A}) -> { 211, 211, 211, A}; -name_to_color({ darkgray, A}) -> { 169, 169, 169, A}; -name_to_color({ lightslategray, A}) -> { 119, 136, 153, A}; -name_to_color({ slategray, A}) -> { 112, 128, 144, A}; -name_to_color({ dimgray, A}) -> { 105, 105, 105, A}; -name_to_color({ darkslategray, A}) -> { 47, 79, 79, A}. - -text(I, {Xs,Ys} = Sp, Font, Text, Color) -> - {FW,FH} = egd_font:size(Font), - Length = length(Text), - Ep = {Xs + Length*FW, Ys + FH + 5}, - I#image{objects = [ - #image_object{ - type = text_horizontal, - points = [Sp], - span = span([Sp,Ep]), - internals = {Font, Text}, - color = Color} | I#image.objects]}. +name_to_color(Color, A) -> + case Color of + %% HTML default colors + black -> { 0, 0, 0, A}; + silver -> {192, 192, 192, A}; + gray -> {128, 128, 128, A}; + white -> {128, 0, 0, A}; + maroon -> {255, 0, 0, A}; + red -> {128, 0, 128, A}; + purple -> {128, 0, 128, A}; + fuchia -> {255, 0, 255, A}; + green -> { 0, 128, 0, A}; + lime -> { 0, 255, 0, A}; + olive -> {128, 128, 0, A}; + yellow -> {255, 255, 0, A}; + navy -> { 0, 0, 128, A}; + blue -> { 0, 0, 255, A}; + teal -> { 0, 128, 0, A}; + aqua -> { 0, 255, 155, A}; + + %% HTML color extensions + steelblue -> { 70, 130, 180, A}; + royalblue -> { 4, 22, 144, A}; + cornflowerblue -> {100, 149, 237, A}; + lightsteelblue -> {176, 196, 222, A}; + mediumslateblue -> {123, 104, 238, A}; + slateblue -> {106, 90, 205, A}; + darkslateblue -> { 72, 61, 139, A}; + midnightblue -> { 25, 25, 112, A}; + darkblue -> { 0, 0, 139, A}; + mediumblue -> { 0, 0, 205, A}; + dodgerblue -> { 30, 144, 255, A}; + deepskyblue -> { 0, 191, 255, A}; + lightskyblue -> {135, 206, 250, A}; + skyblue -> {135, 206, 235, A}; + lightblue -> {173, 216, 230, A}; + powderblue -> {176, 224, 230, A}; + azure -> {240, 255, 255, A}; + lightcyan -> {224, 255, 255, A}; + paleturquoise -> {175, 238, 238, A}; + mediumturquoise -> { 72, 209, 204, A}; + lightseagreen -> { 32, 178, 170, A}; + darkcyan -> { 0, 139, 139, A}; + cadetblue -> { 95, 158, 160, A}; + darkturquoise -> { 0, 206, 209, A}; + cyan -> { 0, 255, 255, A}; + turquoise -> { 64, 224, 208, A}; + aquamarine -> {127, 255, 212, A}; + mediumaquamarine -> {102, 205, 170, A}; + darkseagreen -> {143, 188, 143, A}; + mediumseagreen -> { 60, 179, 113, A}; + seagreen -> { 46, 139, 87, A}; + darkgreen -> { 0, 100, 0, A}; + forestgreen -> { 34, 139, 34, A}; + limegreen -> { 50, 205, 50, A}; + chartreuse -> {127, 255, 0, A}; + lawngreen -> {124, 252, 0, A}; + greenyellow -> {173, 255, 47, A}; + yellowgreen -> {154, 205, 50, A}; + palegreen -> {152, 251, 152, A}; + lightgreen -> {144, 238, 144, A}; + springgreen -> { 0, 255, 127, A}; + darkolivegreen -> { 85, 107, 47, A}; + olivedrab -> {107, 142, 35, A}; + darkkhaki -> {189, 183, 107, A}; + darkgoldenrod -> {184, 134, 11, A}; + goldenrod -> {218, 165, 32, A}; + gold -> {255, 215, 0, A}; + khaki -> {240, 230, 140, A}; + palegoldenrod -> {238, 232, 170, A}; + blanchedalmond -> {255, 235, 205, A}; + moccasin -> {255, 228, 181, A}; + wheat -> {245, 222, 179, A}; + navajowhite -> {255, 222, 173, A}; + burlywood -> {222, 184, 135, A}; + tan -> {210, 180, 140, A}; + rosybrown -> {188, 143, 143, A}; + sienna -> {160, 82, 45, A}; + saddlebrown -> {139, 69, 19, A}; + chocolate -> {210, 105, 30, A}; + peru -> {205, 133, 63, A}; + sandybrown -> {244, 164, 96, A}; + darkred -> {139, 0, 0, A}; + brown -> {165, 42, 42, A}; + firebrick -> {178, 34, 34, A}; + indianred -> {205, 92, 92, A}; + lightcoral -> {240, 128, 128, A}; + salmon -> {250, 128, 114, A}; + darksalmon -> {233, 150, 122, A}; + lightsalmon -> {255, 160, 122, A}; + coral -> {255, 127, 80, A}; + tomato -> {255, 99, 71, A}; + darkorange -> {255, 140, 0, A}; + orange -> {255, 165, 0, A}; + orangered -> {255, 69, 0, A}; + crimson -> {220, 20, 60, A}; + deeppink -> {255, 20, 147, A}; + fuchsia -> {255, 0, 255, A}; + magenta -> {255, 0, 255, A}; + hotpink -> {255, 105, 180, A}; + lightpink -> {255, 182, 193, A}; + pink -> {255, 192, 203, A}; + palevioletred -> {219, 112, 147, A}; + mediumvioletred -> {199, 21, 133, A}; + darkmagenta -> {139, 0, 139, A}; + mediumpurple -> {147, 112, 219, A}; + blueviolet -> {138, 43, 226, A}; + indigo -> { 75, 0, 130, A}; + darkviolet -> {148, 0, 211, A}; + darkorchid -> {153, 50, 204, A}; + mediumorchid -> {186, 85, 211, A}; + orchid -> {218, 112, 214, A}; + violet -> {238, 130, 238, A}; + plum -> {221, 160, 221, A}; + thistle -> {216, 191, 216, A}; + lavender -> {230, 230, 250, A}; + ghostwhite -> {248, 248, 255, A}; + aliceblue -> {240, 248, 255, A}; + mintcream -> {245, 255, 250, A}; + honeydew -> {240, 255, 240, A}; + lemonchiffon -> {255, 250, 205, A}; + cornsilk -> {255, 248, 220, A}; + lightyellow -> {255, 255, 224, A}; + ivory -> {255, 255, 240, A}; + floralwhite -> {255, 250, 240, A}; + linen -> {250, 240, 230, A}; + oldlace -> {253, 245, 230, A}; + antiquewhite -> {250, 235, 215, A}; + bisque -> {255, 228, 196, A}; + peachpuff -> {255, 218, 185, A}; + papayawhip -> {255, 239, 213, A}; + beige -> {245, 245, 220, A}; + seashell -> {255, 245, 238, A}; + lavenderblush -> {255, 240, 245, A}; + mistyrose -> {255, 228, 225, A}; + snow -> {255, 250, 250, A}; + whitesmoke -> {245, 245, 245, A}; + gainsboro -> {220, 220, 220, A}; + lightgrey -> {211, 211, 211, A}; + darkgray -> {169, 169, 169, A}; + lightslategray -> {119, 136, 153, A}; + slategray -> {112, 128, 144, A}; + dimgray -> {105, 105, 105, A}; + darkslategray -> { 47, 79, 79, A}; + mediumspringgreen -> { 0, 250, 154, A}; + lightgoldenrodyellow -> {250, 250, 210, A} + end. %%% Generic transformations @@ -411,15 +393,17 @@ point_side(_) -> on_line. %% AUX -span(Points) -> - Xs = [TX||{TX, _} <- Points], - Ys = [TY||{_, TY} <- Points], - Xmin = lists:min(Xs), - Xmax = lists:max(Xs), - Ymin = lists:min(Ys), - Ymax = lists:max(Ys), +span([{X0,Y0}|Points]) -> + span(Points,X0,Y0,X0,Y0). +span([{X0,Y0}|Points],Xmin,Ymin,Xmax,Ymax) -> + span(Points,erlang:min(Xmin,X0), + erlang:min(Ymin,Y0), + erlang:max(Xmax,X0), + erlang:max(Ymax,Y0)); +span([],Xmin,Ymin,Xmax,Ymax) -> {Xmin,Ymin,Xmax,Ymax}. + rgb_float2byte({R,G,B}) -> rgb_float2byte({R,G,B,1.0}); rgb_float2byte({R,G,B,A}) -> {trunc(R*255), trunc(G*255), trunc(B*255), trunc(A*255)}. diff --git a/lib/percept/src/egd_render.erl b/lib/percept/src/egd_render.erl index 4297704677..6c708e3e86 100644 --- a/lib/percept/src/egd_render.erl +++ b/lib/percept/src/egd_render.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -27,6 +27,8 @@ -export([eps/1]). -compile(inline). +-export([line_to_linespans/3]). + -include("egd.hrl"). -define('DummyC',0). @@ -216,11 +218,11 @@ parse_objects_on_line(Y, Width, Objects) -> parse_objects_on_line(Y, 1, Width, Objects, []). parse_objects_on_line(_Y, _Z, _, [], Out) -> lists:flatten(Out); parse_objects_on_line(Y, Z, Width, [O|Os], Out) -> - case is_object_on_line(Y, O) of + case is_object_on_line(O, Y) of false -> parse_objects_on_line(Y, Z + 1, Width, Os, Out); true -> - OLs = object_line_data(Y, Z, O), + OLs = object_line_data(O,Y,Z), TOLs = trim_object_line_data(OLs, Width), parse_objects_on_line(Y, Z + 1, Width, Os, [TOLs|Out]) end. @@ -238,9 +240,9 @@ trim_object_line_data([{Z, Xl, Xr, C}|OLs], Width, Out) -> % object_line_data % In: +% Object :: image_object() % Y :: index of height % Z :: index of depth -% Object :: image_object() % Out: % OLs = [{Z, Xl, Xr, Color}] % Z = index of height @@ -250,96 +252,93 @@ trim_object_line_data([{Z, Xl, Xr, C}|OLs], Width, Out) -> % Calculate the length (start and finish index) of an objects horizontal % line given the height index. -object_line_data(Y, Z, Object) -> - object_line_data(Y, Z, Object, Object#image_object.type). -object_line_data(Y, Z, #image_object{ span = {X0, Y0, X1, Y1}, color = C}, rectangle) -> +object_line_data(#image_object{type=rectangle, + span={X0,Y0,X1,Y1}, color=C}, Y, Z) -> if - Y0 =:= Y ; Y1 =:= Y -> - [{Z, X0, X1, C}]; - true -> - [{Z, X0, X0, C}, - {Z, X1, X1, C}] + Y0 =:= Y ; Y1 =:= Y -> + [{Z, X0, X1, C}]; + true -> + [{Z, X0, X0, C}, + {Z, X1, X1, C}] end; -object_line_data(_Y, Z, #image_object{ span = {X0, _, X1, _}, color = C}, filled_rectangle) -> +object_line_data(#image_object{type=filled_rectangle, + span={X0, _, X1, _}, color=C}, _Y, Z) -> [{Z, X0, X1, C}]; -object_line_data(Y, Z, #image_object{ internals={Xr,Yr,Yr2}, span = {X0,Y0,X1,Y1}, color = C}, filled_ellipse) -> +object_line_data(#image_object{type=filled_ellipse, + internals={Xr,Yr,Yr2}, span={X0,Y0,X1,Y1}, color=C}, Y, Z) -> if - X1 - X0 == 0; Y1 - Y0 == 0 -> - [{Z, X0, X1, C}]; - true -> - Yo = trunc(Y - Y0 - Yr), - Yo2 = Yo*Yo, - Xo = math:sqrt((1 - Yo2/Yr2))*Xr, - [{Z, round(X0 - Xo + Xr), round(X0 + Xo + Xr), C}] + X1 - X0 =:= 0; Y1 - Y0 =:= 0 -> + [{Z, X0, X1, C}]; + true -> + Yo = trunc(Y - Y0 - Yr), + Yo2 = Yo*Yo, + Xo = math:sqrt((1 - Yo2/Yr2))*Xr, + [{Z, round(X0 - Xo + Xr), round(X0 + Xo + Xr), C}] end; -object_line_data(Y, Z, #image_object{ intervals = Is, color = C}, filled_triangle) -> +object_line_data(#image_object{type=filled_triangle, + intervals=Is, color=C}, Y, Z) -> case lists:keyfind(Y, 1, Is) of {Y, Xl, Xr} -> [{Z, Xl, Xr, C}]; false -> [] end; -object_line_data(Y, Z, #image_object{ intervals = Is, color = C}, line) -> - case dict:find(Y, Is) of - {ok, Ls} -> [{Z, Xl, Xr, C}||{Xl,Xr} <- Ls]; +object_line_data(#image_object{type=line, + intervals=M, color={R,G,B,_}}, Y, Z) -> + case M of + #{Y := Ls} -> [{Z, Xl, Xr, {R,G,B,1.0-C/255}}||{Xl,Xr,C} <- Ls]; _ -> [] end; -object_line_data(Y, Z, #image_object{ color = C, intervals = Is}, polygon) -> +object_line_data(#image_object{type=polygon, + color=C, intervals=Is}, Y, Z) -> [{Z, Xl, Xr, C} || {Yp, Xl, Xr} <- Is, Yp =:= Y]; -object_line_data(Y, Z, #image_object{ color = C, intervals = Is}, text_horizontal) -> +object_line_data(#image_object{type=text_horizontal, + color=C, intervals=Is}, Y, Z) -> [{Z, Xl, Xr, C} || {Yg, Xl, Xr} <- Is, Yg =:= Y]; -object_line_data(_, Z, #image_object{ span = {X0,_,X1,_}, color = C}, _) -> +object_line_data(#image_object{type=pixel, + span={X0,_,X1,_}, color=C}, _, Z) -> [{Z, X0, X1, C}]. -is_object_on_line(Y, #image_object{ span = Span }) -> - is_object_bounds_on_line(Y, Span). +is_object_on_line(#image_object{span={_,Y0,_,Y1}}, Y) -> + if Y < Y0; Y > Y1 -> false; + true -> true + end. -is_object_bounds_on_line(Y, {_,Y0,_,Y1}) when Y < Y0 ; Y > Y1 -> false; -is_object_bounds_on_line(_, _) -> true. - %%% primitives to line_spans %% compile objects to linespans -precompile(Image = #image{ objects = Os }) -> - Image#image{ objects = precompile_objects(Os) }. - -precompile_objects(Os) -> precompile_objects(Os, []). -precompile_objects([], Out) -> lists:reverse(Out); - -precompile_objects([O = #image_object{ type = line, points = [P0,P1] }| Os], Out) -> - precompile_objects(Os, [O#image_object{ intervals = ls_list2dict(line_ls(P0,P1)) } | Out]); - -precompile_objects([O = #image_object{ type = filled_triangle, points = [P0,P1,P2] } | Os], Out) -> - precompile_objects(Os, [O#image_object{ intervals = triangle_ls(P0,P1,P2) } | Out]); - -precompile_objects([O = #image_object{ type = polygon, points = Pts } | Os], Out) -> - precompile_objects(Os, [O#image_object{ intervals = polygon_ls(Pts) } | Out]); - -precompile_objects([O = #image_object{ type = filled_ellipse, span = {X0,Y0,X1,Y1} } | Os], Out) -> +precompile(#image{objects = Os}=I) -> + I#image{objects = precompile_objects(Os)}. + +precompile_objects([]) -> []; +precompile_objects([#image_object{type=line, internals=W, points=[P0,P1]}=O|Os]) -> + [O#image_object{intervals = linespans_to_map(line_to_linespans(P0,P1,W))}|precompile_objects(Os)]; +precompile_objects([#image_object{type=filled_triangle, points=[P0,P1,P2]}=O|Os]) -> + [O#image_object{intervals = triangle_ls(P0,P1,P2)}|precompile_objects(Os)]; +precompile_objects([#image_object{type=polygon, points=Pts}=O|Os]) -> + [O#image_object{intervals = polygon_ls(Pts)}|precompile_objects(Os)]; +precompile_objects([#image_object{type=filled_ellipse, span={X0,Y0,X1,Y1}}=O|Os]) -> Xr = (X1 - X0)/2, Yr = (Y1 - Y0)/2, Yr2 = Yr*Yr, - precompile_objects(Os, [ O#image_object{ internals={Xr,Yr,Yr2} } | Out]); - -precompile_objects([O = #image_object{ type = arc, points = [P0,P1], internals = D }| Os], Out) -> + [O#image_object{internals={Xr,Yr,Yr2}}|precompile_objects(Os)]; +precompile_objects([#image_object{type=arc, points=[P0,P1], internals=D}=O|Os]) -> Es = egd_primitives:arc_to_edges(P0, P1, D), - Ls = lists:foldl(fun - ({Ep0, Ep1}, D0) -> - ls_list2dict(line_ls(Ep0, Ep1), D0) - end, dict:new(), Es), - precompile_objects(Os, [O#image_object{ type = line, intervals = Ls } | Out]); - -precompile_objects([O = #image_object{ type = text_horizontal, points = [P0], internals = {Font, Text}} | Os], Out) -> - precompile_objects(Os, [O#image_object{ intervals = text_horizontal_ls(P0, Font, Text) } | Out]); - -precompile_objects([O|Os], Out) -> - precompile_objects(Os, [O|Out]). + Ls = lists:foldl(fun ({Ep0,Ep1},M) -> + linespans_to_map(line_to_linespans(Ep0,Ep1,1),M) + end, #{}, Es), + [O#image_object{type=line, intervals=Ls}|precompile_objects(Os)]; +precompile_objects([#image_object{type=text_horizontal, + points=[P0], internals={Font,Text}}=O|Os]) -> + [O#image_object{intervals=text_horizontal_ls(P0,Font,Text)}|precompile_objects(Os)]; +precompile_objects([O|Os]) -> + [O|precompile_objects(Os)]. % triangle @@ -353,7 +352,8 @@ triangle_ls(P1,P2,P3) -> % At an end point, a new line to the point already being drawn % repeat same procedure as above [Sp1, Sp2, Sp3] = tri_pt_ysort([P1,P2,P3]), - triangle_ls_lp(tri_ls_ysort(line_ls(Sp1,Sp2)), Sp2, tri_ls_ysort(line_ls(Sp1,Sp3)), Sp3, []). + triangle_ls_lp(tri_ls_ysort(line_to_linespans(Sp1,Sp2,1)), Sp2, + tri_ls_ysort(line_to_linespans(Sp1,Sp3,1)), Sp3, []). % There will be Y mismatches between the two lists since bresenham is not perfect. % I can be remedied with checking intervals this could however be costly and @@ -362,7 +362,7 @@ triangle_ls(P1,P2,P3) -> triangle_ls_lp([],_,[],_,Out) -> Out; triangle_ls_lp(LSs1, P1, [], P2, Out) -> - SLSs = tri_ls_ysort(line_ls(P2,P1)), + SLSs = tri_ls_ysort(line_to_linespans(P2,P1,1)), N2 = length(SLSs), N1 = length(LSs1), if @@ -376,7 +376,7 @@ triangle_ls_lp(LSs1, P1, [], P2, Out) -> triangle_ls_lp(LSs1, SLSs, Out) end; triangle_ls_lp([], P1, LSs2, P2, Out) -> - SLSs = tri_ls_ysort(line_ls(P1,P2)), + SLSs = tri_ls_ysort(line_to_linespans(P1,P2,1)), N1 = length(SLSs), N2 = length(LSs2), if @@ -390,21 +390,21 @@ triangle_ls_lp([], P1, LSs2, P2, Out) -> triangle_ls_lp(SLSs, LSs2, Out) end; triangle_ls_lp([LS1|LSs1],P1,[LS2|LSs2],P2, Out) -> - {Y, Xl1, Xr1} = LS1, - {_, Xl2, Xr2} = LS2, + {Y, Xl1, Xr1,_Ca1} = LS1, + {_, Xl2, Xr2,_Ca2} = LS2, Xr = lists:max([Xl1,Xr1,Xl2,Xr2]), Xl = lists:min([Xl1,Xr1,Xl2,Xr2]), - triangle_ls_lp(LSs1,P1, LSs2, P2, [{Y,Xl,Xr}|Out]). + triangle_ls_lp(LSs1,P1,LSs2,P2,[{Y,Xl,Xr}|Out]). triangle_ls_lp([],[],Out) -> Out; triangle_ls_lp([],_,Out) -> Out; triangle_ls_lp(_,[],Out) -> Out; triangle_ls_lp([LS1|LSs1], [LS2|LSs2], Out) -> - {Y, Xl1, Xr1} = LS1, - {_, Xl2, Xr2} = LS2, + {Y, Xl1, Xr1, _Ca1} = LS1, + {_, Xl2, Xr2, _Ca2} = LS2, Xr = lists:max([Xl1,Xr1,Xl2,Xr2]), Xl = lists:min([Xl1,Xr1,Xl2,Xr2]), - triangle_ls_lp(LSs1, LSs2, [{Y,Xl,Xr}|Out]). + triangle_ls_lp(LSs1,LSs2,[{Y,Xl,Xr}|Out]). tri_pt_ysort(Pts) -> % {X,Y} @@ -414,9 +414,9 @@ tri_pt_ysort(Pts) -> end, Pts). tri_ls_ysort(LSs) -> - % {Y, Xl, Xr} + % {Y, Xl, Xr, Ca} lists:sort( - fun ({Y1,_,_},{Y2,_,_}) -> + fun ({Y1,_,_,_},{Y2,_,_,_}) -> if Y1 > Y2 -> false; true -> true end end, LSs). @@ -503,69 +503,74 @@ point_inside_triangle(P, P1, P2, P3) -> points_same_side(P, P2, P1, P3) and points_same_side(P, P3, P1, P2). -%% [{Y, Xl, Xr}] -ls_list2dict(List) -> ls_list2dict(List, dict:new()). -ls_list2dict([], D) -> D; -ls_list2dict([{Y, Xl, Xr}|Ls], D) -> - case dict:is_key(Y, D) of - false -> ls_list2dict(Ls, dict:store(Y, [{Xl, Xr}], D)); - true -> ls_list2dict(Ls, dict:append(Y, {Xl, Xr}, D)) - end. +%% [{Y, Xl, Xr}] -> #{Y := [{Xl,Xr}]} +%% Reorganize linspans to a map with Y as key. + +linespans_to_map(Ls) -> + linespans_to_map(Ls,#{}). +linespans_to_map([{Y,Xl,Xr,C}|Ls], M) -> + case M of + #{Y := Spans} -> linespans_to_map(Ls, M#{Y := [{Xl,Xr,C}|Spans]}); + _ -> linespans_to_map(Ls, M#{Y => [{Xl,Xr,C}]}) + end; +linespans_to_map([], M) -> + M. + -%% line_ls +%% line_to_linespans +%% Anti-aliased thick line +%% Do it CPS style %% In: %% P1 :: point() %% P2 :: point() %% Out: -%% {{Ymin,Ymax}, LSD :: line_step_data()} -%% Purpose: -%% Instead of points -> intervals - - -line_ls({Xi0, Yi0},{Xi1,Yi1}) -> - % swap X with Y if line is steep - Steep = abs(Yi1 - Yi0) > abs(Xi1 - Xi0), - - {Xs0, Ys0, Xs1, Ys1} = case Steep of - true -> {Yi0,Xi0,Yi1,Xi1}; - false -> {Xi0,Yi0,Xi1,Yi1} - end, - - {X0,Y0,X1,Y1} = case Xs0 > Xs1 of - true -> {Xs1,Ys1,Xs0,Ys0}; - false -> {Xs0,Ys0,Xs1,Ys1} - end, - - DX = X1 - X0, - DY = abs(Y1 - Y0), - - Error = -DX/2, - - Ystep = case Y0 < Y1 of - true -> 1; - false -> -1 - end, - line_ls_step(X0, X1,Y0, DX, DY, Ystep, Error, X0, Steep, []). - -%% line_ls_step_(not)_steep -%% In: -%% Out: -%% [{Yi, Xl,Xr}] -%% Purpose: -%% Produce an line_interval for each Yi (Y index) - -line_ls_step(X, X1, Y, Dx, Dy, Ys, E, X0, false = Steep, LSs) when X < X1, E >= 0 -> - line_ls_step(X+1,X1,Y+Ys,Dx,Dy,Ys, E - Dx + Dy, X+1, Steep, [{Y,X0,X}|LSs]); -line_ls_step(X, X1, Y, Dx, Dy, Ys, E, X0, false = Steep, LSs) when X < X1 -> - line_ls_step(X+1,X1,Y,Dx,Dy,Ys, E + Dy, X0, Steep, LSs); -line_ls_step(X, _X1, Y, _Dx, _Dy, _Ys, _E, X0, false, LSs) -> - [{Y,X0,X}|LSs]; -line_ls_step(X, X1, Y, Dx, Dy, Ys, E, _X0, true = Steep, LSs) when X =< X1, E >= 0 -> - line_ls_step(X+1,X1,Y+Ys,Dx,Dy,Ys, E - Dx + Dy, X, Steep, [{X,Y,Y}|LSs]); -line_ls_step(X, X1, Y, Dx, Dy, Ys, E, X0, true = Steep, LSs) when X =< X1 -> - line_ls_step(X+1,X1,Y,Dx,Dy,Ys,E + Dy, X0, Steep, [{X,Y,Y}|LSs]); -line_ls_step(_X,_,_Y,_Dx,_Dy,_Ys,_E,_X0,_,LSs) -> - LSs. +%% [{Y,Xl,Xr}] +%% +line_to_linespans({X0,Y0},{X1,Y1},Wd) -> + Dx = abs(X1-X0), + Dy = abs(Y1-Y0), + Sx = if X0 < X1 -> 1; true -> -1 end, + Sy = if Y0 < Y1 -> 1; true -> -1 end, + E0 = Dx - Dy, + Ed = if Dx + Dy =:= 0 -> 1; true -> math:sqrt(Dx*Dx + Dy*Dy) end, + line_to_ls(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E0,Ed,(Wd+1)/2,[]). + +line_to_ls(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls0) -> + C = max(0, 255*(abs(E - Dx+Dy)/Ed - Wd + 1)), + Ls1 = [{Y0,X0,X0,C}|Ls0], + line_to_ls_sx(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls1,E). + +line_to_ls_sx(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls,E2) when 2*E2 > -Dx -> + line_to_ls_sx_do(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls,E2+Dy,Y0); +line_to_ls_sx(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls,E2) -> + line_to_ls_sy(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls,E2,X0). + +line_to_ls_sx_do(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls0,E2,Y) when E2 < Ed*Wd andalso + (Y1 =/= Y orelse Dx > Dy) -> + Y2 = Y + Sy, + C = max(0,255*(abs(E2)/Ed-Wd+1)), + Ls = [{Y2,X0,X0,C}|Ls0], + line_to_ls_sx_do(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls,E2+Dx,Y2); +line_to_ls_sx_do(X0,_Y0,X1,_Y1,_Dx,_Dy,_Sx,_Sy,_E,_Ed,_Wd,Ls,_E2,_Y) when X0 =:= X1 -> + Ls; +line_to_ls_sx_do(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls,_E2,_Y) -> + line_to_ls_sy(X0+Sx,Y0,X1,Y1,Dx,Dy,Sx,Sy,E-Dy,Ed,Wd,Ls,E,X0). + +line_to_ls_sy(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls0,E2,X) when 2*E2 =< Dy -> + line_to_ls_sy_do(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls0,Dx-E2,X); +line_to_ls_sy(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls0,_E2,_X) -> + line_to_ls(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls0). + +line_to_ls_sy_do(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls0,E2,X) when E2 < Ed*Wd andalso + (X1 =/= X orelse Dx < Dy) -> + X2 = X + Sx, + C = max(0,255*(abs(E2)/Ed-Wd+1)), + Ls = [{Y0,X2,X2,C}|Ls0], + line_to_ls_sy_do(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls,E2+Dy,X2); +line_to_ls_sy_do(_X0,Y0,_X1,Y1,_Dx,_Dy,_Sx,_Sy,_E,_Ed,_Wd,Ls,_E2,_X) when Y0 =:= Y1 -> + Ls; +line_to_ls_sy_do(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls0,_E2,_X) -> + line_to_ls(X0,Y0+Sy,X1,Y1,Dx,Dy,Sx,Sy,E+Dx,Ed,Wd,Ls0). % Text @@ -657,4 +662,3 @@ eps_header(W,H) -> eps_footer() -> "%%EOF\n". - diff --git a/lib/percept/src/percept.app.src b/lib/percept/src/percept.app.src index 6a3800a17f..1749730f97 100644 --- a/lib/percept/src/percept.app.src +++ b/lib/percept/src/percept.app.src @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2012. All Rights Reserved. +%% Copyright Ericsson AB 2007-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/percept/src/percept.appup.src b/lib/percept/src/percept.appup.src index cb4995b0d8..3ccdf8db2b 100644 --- a/lib/percept/src/percept.appup.src +++ b/lib/percept/src/percept.appup.src @@ -1,7 +1,7 @@ %% -*- erlang -*- %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2014. All Rights Reserved. +%% Copyright Ericsson AB 2007-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/percept/src/percept.erl b/lib/percept/src/percept.erl index badb3f3d66..046e0b7518 100644 --- a/lib/percept/src/percept.erl +++ b/lib/percept/src/percept.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2010. All Rights Reserved. +%% Copyright Ericsson AB 2007-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -26,27 +26,24 @@ -module(percept). -behaviour(application). --export([ - profile/1, - profile/2, - profile/3, - stop_profile/0, - start_webserver/0, - start_webserver/1, - stop_webserver/0, - stop_webserver/1, - analyze/1, - % Application behaviour - start/2, - stop/1]). +-export([profile/1, + profile/2, + profile/3, + stop_profile/0, + start_webserver/0, + start_webserver/1, + stop_webserver/0, + stop_webserver/1, + analyze/1, + % Application behaviour + start/2, + stop/1]). -include("percept.hrl"). %%========================================================================== -%% -%% Type definitions -%% +%% Type definitions %%========================================================================== %% @type percept_option() = procs | ports | exclusive @@ -54,9 +51,7 @@ -type percept_option() :: 'procs' | 'ports' | 'exclusive' | 'scheduler'. %%========================================================================== -%% -%% Application callback functions -%% +%% Application callback functions %%========================================================================== %% @spec start(Type, Args) -> {started, Hostname, Port} | {error, Reason} @@ -76,9 +71,7 @@ stop(_State) -> stop_webserver(0). %%========================================================================== -%% -%% Interface functions -%% +%% Interface functions %%========================================================================== %% @spec profile(Filename::string()) -> {ok, Port} | {already_started, Port} @@ -158,11 +151,11 @@ start_webserver() -> {'started', string(), pos_integer()} | {'error', any()}. start_webserver(Port) when is_integer(Port) -> - application:load(percept), + ok = ensure_loaded(percept), case whereis(percept_httpd) of undefined -> {ok, Config} = get_webserver_config("percept", Port), - inets:start(), + ok = application:ensure_started(inets), case inets:start(httpd, Config) of {ok, Pid} -> AssignedPort = find_service_port_from_pid(inets:services_info(), Pid), @@ -217,16 +210,14 @@ stop_webserver(Port) -> do_stop(Port,[]). %%========================================================================== -%% -%% Auxiliary functions -%% +%% Auxiliary functions %%========================================================================== %% parse_and_insert parse_and_insert(Filename, DB) -> io:format("Parsing: ~p ~n", [Filename]), - T0 = erlang:now(), + T0 = erlang:monotonic_time(milli_seconds), Pid = dbg:trace_client(file, Filename, mk_trace_parser(self())), Ref = erlang:monitor(process, Pid), parse_and_insert_loop(Filename, Pid, Ref, DB, T0). @@ -239,8 +230,8 @@ parse_and_insert_loop(Filename, Pid, Ref, DB, T0) -> {parse_complete, {Pid, Count}} -> receive {'DOWN', Ref, process, Pid, normal} -> ok after 0 -> ok end, DB ! {action, consolidate}, - T1 = erlang:now(), - io:format("Parsed ~p entries in ~p s.~n", [Count, ?seconds(T1, T0)]), + T1 = erlang:monotonic_time(milli_seconds), + io:format("Parsed ~w entries in ~w ms.~n", [Count, T1 - T0]), io:format(" ~p created processes.~n", [length(percept_db:select({information, procs}))]), io:format(" ~p opened ports.~n", [length(percept_db:select({information, ports}))]), ok; @@ -337,3 +328,10 @@ get_webserver_config(Servername, Port) when is_list(Servername), is_integer(Port {bind_address, any}, {port, Port}], {ok, Config}. + +ensure_loaded(App) -> + case application:load(App) of + ok -> ok; + {error,{already_loaded,App}} -> ok; + Error -> Error + end. diff --git a/lib/percept/src/percept.hrl b/lib/percept/src/percept.hrl index a5639cfaf8..58926cd1b4 100644 --- a/lib/percept/src/percept.hrl +++ b/lib/percept/src/percept.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2010. All Rights Reserved. +%% Copyright Ericsson AB 2007-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/percept/src/percept_analyzer.erl b/lib/percept/src/percept_analyzer.erl index 69338f52af..f38d026905 100644 --- a/lib/percept/src/percept_analyzer.erl +++ b/lib/percept/src/percept_analyzer.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2009. All Rights Reserved. +%% Copyright Ericsson AB 2007-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/percept/src/percept_db.erl b/lib/percept/src/percept_db.erl index b627c67acd..6cbe3ce022 100644 --- a/lib/percept/src/percept_db.erl +++ b/lib/percept/src/percept_db.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2011. All Rights Reserved. +%% Copyright Ericsson AB 2007-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -24,21 +24,17 @@ -module(percept_db). --export([ - start/0, - stop/0, - insert/1, - select/2, - select/1, - consolidate/0 - ]). +-export([start/0, + stop/0, + insert/1, + select/2, + select/1, + consolidate/0]). -include("percept.hrl"). -define(STOP_TIMEOUT, 1000). %%========================================================================== -%% -%% Type definitions -%% +%% Type definitions %%========================================================================== %% @type activity_option() = @@ -64,9 +60,7 @@ %%========================================================================== -%% -%% Interface functions -%% +%% Interface functions %%========================================================================== %% @spec start() -> ok | {started, Pid} | {restarted, Pid} @@ -100,7 +94,7 @@ restart(PerceptDB)-> -spec do_start()-> pid(). do_start()-> - Pid = spawn( fun() -> init_percept_db() end), + Pid = spawn(fun() -> init_percept_db() end), erlang:register(percept_db, Pid), Pid. @@ -123,17 +117,17 @@ stop() -> %% @private %% @doc Stops the percept database, with a synchronous call. --spec stop_sync(pid())-> true. +-spec stop_sync(pid()) -> true. -stop_sync(Pid)-> +stop_sync(Pid) -> MonitorRef = erlang:monitor(process, Pid), - stop(), + _ = stop(), receive {'DOWN', MonitorRef, _Type, Pid, _Info}-> true after ?STOP_TIMEOUT-> - erlang:demonitor(MonitorRef, [flush]), - exit(Pid, kill) + erlang:demonitor(MonitorRef, [flush]), + exit(Pid, kill) end. %% @spec insert(tuple()) -> ok @@ -186,26 +180,24 @@ consolidate() -> ok. %%========================================================================== -%% -%% Database loop -%% +%% Database loop %%========================================================================== init_percept_db() -> % Proc and Port information - ets:new(pdb_info, [named_table, private, {keypos, #information.id}, set]), + pdb_info = ets:new(pdb_info, [named_table, private, {keypos, #information.id}, set]), % Scheduler runnability - ets:new(pdb_scheduler, [named_table, private, {keypos, #activity.timestamp}, ordered_set]), + pdb_scheduler = ets:new(pdb_scheduler, [named_table, private, {keypos, #activity.timestamp}, ordered_set]), % Process and Port runnability - ets:new(pdb_activity, [named_table, private, {keypos, #activity.timestamp}, ordered_set]), + pdb_activity = ets:new(pdb_activity, [named_table, private, {keypos, #activity.timestamp}, ordered_set]), % System status - ets:new(pdb_system, [named_table, private, {keypos, 1}, set]), + pdb_system = ets:new(pdb_system, [named_table, private, {keypos, 1}, set]), % System warnings - ets:new(pdb_warnings, [named_table, private, {keypos, 1}, ordered_set]), + pdb_warnings = ets:new(pdb_warnings, [named_table, private, {keypos, 1}, ordered_set]), put(debug, 0), loop_percept_db(). @@ -232,9 +224,7 @@ loop_percept_db() -> end. %%========================================================================== -%% -%% Auxiliary functions -%% +%% Auxiliary functions %%========================================================================== %% cleans trace messages from external pids @@ -788,5 +778,3 @@ update_system_stop_ts(TS) -> Unhandled -> io:format("update_system_stop_ts, unhandled ~p ~n", [Unhandled]) end. - - diff --git a/lib/percept/src/percept_graph.erl b/lib/percept/src/percept_graph.erl index 8ad7fd1bf6..e5bbaca2b4 100644 --- a/lib/percept/src/percept_graph.erl +++ b/lib/percept/src/percept_graph.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2009. All Rights Reserved. +%% Copyright Ericsson AB 2007-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -33,28 +33,28 @@ %% graph(SessionID, Env, Input) -> - mod_esi:deliver(SessionID, header()), - mod_esi:deliver(SessionID, binary_to_list(graph(Env, Input))). + ok = mod_esi:deliver(SessionID, header()), + ok = mod_esi:deliver(SessionID, binary_to_list(graph(Env, Input))). %% activity %% @spec activity(SessionID, Env, Input) -> term() %% @doc An ESI callback implementation used by the httpd server. activity(SessionID, Env, Input) -> - mod_esi:deliver(SessionID, header()), - mod_esi:deliver(SessionID, binary_to_list(activity_bar(Env, Input))). + ok = mod_esi:deliver(SessionID, header()), + ok = mod_esi:deliver(SessionID, binary_to_list(activity_bar(Env, Input))). proc_lifetime(SessionID, Env, Input) -> - mod_esi:deliver(SessionID, header()), - mod_esi:deliver(SessionID, binary_to_list(proc_lifetime(Env, Input))). + ok = mod_esi:deliver(SessionID, header()), + ok = mod_esi:deliver(SessionID, binary_to_list(proc_lifetime(Env, Input))). percentage(SessionID, Env, Input) -> - mod_esi:deliver(SessionID, header()), - mod_esi:deliver(SessionID, binary_to_list(percentage(Env,Input))). + ok = mod_esi:deliver(SessionID, header()), + ok = mod_esi:deliver(SessionID, binary_to_list(percentage(Env,Input))). scheduler_graph(SessionID, Env, Input) -> - mod_esi:deliver(SessionID, header()), - mod_esi:deliver(SessionID, binary_to_list(scheduler_graph(Env, Input))). + ok = mod_esi:deliver(SessionID, header()), + ok = mod_esi:deliver(SessionID, binary_to_list(scheduler_graph(Env, Input))). graph(_Env, Input) -> Query = httpd:parse_query(Input), diff --git a/lib/percept/src/percept_html.erl b/lib/percept/src/percept_html.erl index ea7484ae70..a675227584 100644 --- a/lib/percept/src/percept_html.erl +++ b/lib/percept/src/percept_html.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2010. All Rights Reserved. +%% Copyright Ericsson AB 2007-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,22 +18,18 @@ %% %CopyrightEnd% -module(percept_html). --export([ - page/3, - codelocation_page/3, - databases_page/3, - load_database_page/3, - processes_page/3, - concurrency_page/3, - process_info_page/3 - ]). - --export([ - value2pid/1, - pid2value/1, - get_option_value/2, - join_strings_with/2 - ]). +-export([page/3, + codelocation_page/3, + databases_page/3, + load_database_page/3, + processes_page/3, + concurrency_page/3, + process_info_page/3]). + +-export([value2pid/1, + pid2value/1, + get_option_value/2, + join_strings_with/2]). -include("percept.hrl"). -include_lib("kernel/include/file.hrl"). @@ -42,47 +38,47 @@ %% API page(SessionID, Env, Input) -> - mod_esi:deliver(SessionID, header()), - mod_esi:deliver(SessionID, menu()), - mod_esi:deliver(SessionID, overview_content(Env, Input)), - mod_esi:deliver(SessionID, footer()). + ok = mod_esi:deliver(SessionID, header()), + ok = mod_esi:deliver(SessionID, menu()), + ok = mod_esi:deliver(SessionID, overview_content(Env, Input)), + ok = mod_esi:deliver(SessionID, footer()). processes_page(SessionID, _, _) -> - mod_esi:deliver(SessionID, header()), - mod_esi:deliver(SessionID, menu()), - mod_esi:deliver(SessionID, processes_content()), - mod_esi:deliver(SessionID, footer()). + ok = mod_esi:deliver(SessionID, header()), + ok = mod_esi:deliver(SessionID, menu()), + ok = mod_esi:deliver(SessionID, processes_content()), + ok = mod_esi:deliver(SessionID, footer()). concurrency_page(SessionID, Env, Input) -> - mod_esi:deliver(SessionID, header()), - mod_esi:deliver(SessionID, menu()), - mod_esi:deliver(SessionID, concurrency_content(Env, Input)), - mod_esi:deliver(SessionID, footer()). + ok = mod_esi:deliver(SessionID, header()), + ok = mod_esi:deliver(SessionID, menu()), + ok = mod_esi:deliver(SessionID, concurrency_content(Env, Input)), + ok = mod_esi:deliver(SessionID, footer()). databases_page(SessionID, _, _) -> - mod_esi:deliver(SessionID, header()), - mod_esi:deliver(SessionID, menu()), - mod_esi:deliver(SessionID, databases_content()), - mod_esi:deliver(SessionID, footer()). + ok = mod_esi:deliver(SessionID, header()), + ok = mod_esi:deliver(SessionID, menu()), + ok = mod_esi:deliver(SessionID, databases_content()), + ok = mod_esi:deliver(SessionID, footer()). codelocation_page(SessionID, Env, Input) -> - mod_esi:deliver(SessionID, header()), - mod_esi:deliver(SessionID, menu()), - mod_esi:deliver(SessionID, codelocation_content(Env, Input)), - mod_esi:deliver(SessionID, footer()). + ok = mod_esi:deliver(SessionID, header()), + ok = mod_esi:deliver(SessionID, menu()), + ok = mod_esi:deliver(SessionID, codelocation_content(Env, Input)), + ok = mod_esi:deliver(SessionID, footer()). process_info_page(SessionID, Env, Input) -> - mod_esi:deliver(SessionID, header()), - mod_esi:deliver(SessionID, menu()), - mod_esi:deliver(SessionID, process_info_content(Env, Input)), - mod_esi:deliver(SessionID, footer()). + ok = mod_esi:deliver(SessionID, header()), + ok = mod_esi:deliver(SessionID, menu()), + ok = mod_esi:deliver(SessionID, process_info_content(Env, Input)), + ok = mod_esi:deliver(SessionID, footer()). load_database_page(SessionID, Env, Input) -> - mod_esi:deliver(SessionID, header()), + ok = mod_esi:deliver(SessionID, header()), % Very dynamic page, handled differently load_database_content(SessionID, Env, Input), - mod_esi:deliver(SessionID, footer()). + ok = mod_esi:deliver(SessionID, footer()). %%% --------------------------- %%% @@ -446,24 +442,24 @@ load_database_content(SessionId, _Env, Input) -> Filename = filename:join(Path, File), % Check path/file/filename - mod_esi:deliver(SessionId, "<div id=\"content\">"), + ok = mod_esi:deliver(SessionId, "<div id=\"content\">"), case file:read_file_info(Filename) of {ok, _} -> Content = "<center> Parsing: " ++ Filename ++ "<br> </center>", - mod_esi:deliver(SessionId, Content), - case percept:analyze(Filename) of - {error, Reason} -> - mod_esi:deliver(SessionId, error_msg("Analyze" ++ term2html(Reason))); - _ -> - Complete = "<center><a href=\"/cgi-bin/percept_html/page\">View</a></center>", - mod_esi:deliver(SessionId, Complete) - end; + ok = mod_esi:deliver(SessionId, Content), + case percept:analyze(Filename) of + {error, Reason} -> + ok = mod_esi:deliver(SessionId, error_msg("Analyze" ++ term2html(Reason))); + _ -> + Complete = "<center><a href=\"/cgi-bin/percept_html/page\">View</a></center>", + ok = mod_esi:deliver(SessionId, Complete) + end; {error, Reason} -> - mod_esi:deliver(SessionId, error_msg("File" ++ term2html(Reason))) + ok = mod_esi:deliver(SessionId, error_msg("File" ++ term2html(Reason))) end, - mod_esi:deliver(SessionId, "</div>"). + ok = mod_esi:deliver(SessionId, "</div>"). codelocation_content(_Env, Input) -> Query = httpd:parse_query(Input), diff --git a/lib/percept/src/percept_image.erl b/lib/percept/src/percept_image.erl index f649439d7a..e819938027 100644 --- a/lib/percept/src/percept_image.erl +++ b/lib/percept/src/percept_image.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2009. All Rights Reserved. +%% Copyright Ericsson AB 2007-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/percept/test/Makefile b/lib/percept/test/Makefile index 4ba0b80fc8..87fde49410 100644 --- a/lib/percept/test/Makefile +++ b/lib/percept/test/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2007-2012. All Rights Reserved. +# Copyright Ericsson AB 2007-2016. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -52,8 +52,7 @@ RELSYSDIR = $(RELEASE_PATH)/percept_test # FLAGS # ---------------------------------------------------- ERL_MAKE_FLAGS += -ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include \ - -I$(ERL_TOP)/lib/percept/include +ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/percept/include # ---------------------------------------------------- # Targets diff --git a/lib/percept/test/egd_SUITE.erl b/lib/percept/test/egd_SUITE.erl index 41e8999e17..401695dddd 100644 --- a/lib/percept/test/egd_SUITE.erl +++ b/lib/percept/test/egd_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2011. All Rights Reserved. +%% Copyright Ericsson AB 2007-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -19,198 +19,186 @@ %% -module(egd_SUITE). --include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). %% Test server specific exports --export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]). +-export([all/0, suite/0]). -export([init_per_suite/1, end_per_suite/1]). -export([init_per_testcase/2, end_per_testcase/2]). %% Test cases --export([ - image_create_and_destroy/1, - image_shape/1, - image_primitives/1, - image_colors/1, - image_font/1, - image_png_compliant/1 - ]). - -%% Default timetrap timeout (set in init_per_testcase) --define(default_timeout, ?t:minutes(1)). - -init_per_suite(Config) when is_list(Config) -> - random:seed(now()), - Config. - -end_per_suite(Config) when is_list(Config) -> - Config. - -init_per_testcase(_Case, Config) -> - Dog = ?t:timetrap(?default_timeout), - [{max_size, 800}, {watchdog,Dog} | Config]. - -end_per_testcase(_Case, Config) -> - Dog = ?config(watchdog, Config), - ?t:timetrap_cancel(Dog), - ok. - -suite() -> [{ct_hooks,[ts_install_cth]}]. +-export([image_create_and_destroy/1, + image_shape/1, + image_primitives/1, + image_colors/1, + image_font/1, + image_fans/1, + image_png_compliant/1]). + +suite() -> + [{ct_hooks,[ts_install_cth]}, + {timetrap, {minutes, 1}}]. all() -> [image_create_and_destroy, image_shape, image_primitives, image_colors, image_font, + image_fans, image_png_compliant]. -groups() -> - []. -init_per_group(_GroupName, Config) -> +init_per_suite(Config) when is_list(Config) -> + rand:seed(exsplus), Config. -end_per_group(_GroupName, Config) -> +end_per_suite(Config) when is_list(Config) -> Config. +init_per_testcase(_Case, Config) -> + [{max_size, 800}|Config]. + +end_per_testcase(_Case, _Config) -> + ok. %%---------------------------------------------------------------------- %% Tests %%---------------------------------------------------------------------- -image_create_and_destroy(suite) -> - []; -image_create_and_destroy(doc) -> - ["Image creation and destroy test."]; +%% Image creation and destroy test. image_create_and_destroy(Config) when is_list(Config) -> - {W,H} = get_size(?config(max_size, Config)), - ?line Image = egd:create(W, H), - ?line ok = egd:destroy(Image), + {W,H} = get_size(proplists:get_value(max_size, Config)), + Image = egd:create(W, H), + ok = egd:destroy(Image), ok. -image_colors(suite) -> - []; -image_colors(doc) -> - ["Image color test."]; +%% Image color test. image_colors(Config) when is_list(Config) -> - {W,H} = get_size(?config(max_size, Config)), - ?line Image = egd:create(W, H), + {W,H} = get_size(proplists:get_value(max_size, Config)), + Dir = proplists:get_value(priv_dir, Config), + Image = egd:create(W, H), put(image_size, {W,H}), RGB = get_rgb(), - ?line Black = egd:color({0,0,0}), - ?line Red = egd:color({255,0,0}), - ?line Green = egd:color({0,255,0}), - ?line Blue = egd:color({0,0,255}), - ?line Random = egd:color(Image, RGB), - - ?line ok = egd:line(Image, get_point(), get_point(), Random), - ?line ok = egd:line(Image, get_point(), get_point(), Red), - ?line ok = egd:line(Image, get_point(), get_point(), Green), - ?line ok = egd:line(Image, get_point(), get_point(), Black), - ?line ok = egd:line(Image, get_point(), get_point(), Blue), + Black = egd:color({0,0,0}), + Red = egd:color({255,0,0}), + Green = egd:color({0,255,0}), + Blue = egd:color({0,0,255}), + Random = egd:color(Image, RGB), + + ok = egd:line(Image, get_point(), get_point(), Random), + ok = egd:line(Image, get_point(), get_point(), Red), + ok = egd:line(Image, get_point(), get_point(), Green), + ok = egd:line(Image, get_point(), get_point(), Black), + ok = egd:line(Image, get_point(), get_point(), Blue), HtmlDefaultNames = [black,silver,gray,white,maroon,red, - purple,fuchia,green,lime,olive,yellow,navy,blue,teal, - aqua], - - lists:foreach(fun - (ColorName) -> - ?line Color = egd:color(ColorName), - ?line ok = egd:line(Image, get_point(), get_point(), Color) - end, HtmlDefaultNames), - - ?line <<_/binary>> = egd:render(Image), - ?line ok = egd:destroy(Image), + purple,fuchia,green,lime,olive,yellow,navy,blue,teal, + aqua], + + lists:foreach(fun (ColorName) -> + Color = egd:color(ColorName), + ok = egd:line(Image, get_point(), get_point(), Color) + end, HtmlDefaultNames), + + Png1 = <<_/binary>> = egd:render(Image,png,[{render_engine, alpha}]), + File1 = filename:join(Dir,"image_colors_alpha.png"), + ok = egd:save(Png1,File1), + ct:log("<p>Image alpha:</p><img src=\"~s\" />~n", [File1]), + Png2 = <<_/binary>> = egd:render(Image,png,[{render_engine, opaque}]), + File2 = filename:join(Dir,"image_colors_opaque.png"), + ok = egd:save(Png2,File2), + ct:log("<p>Image opaque:</p><img src=\"~s\" />~n", [File2]), + + ok = egd:destroy(Image), erase(image_size), ok. -image_shape(suite) -> - []; -image_shape(doc) -> - ["Image shape api test."]; +%% Image shape API test. image_shape(Config) when is_list(Config) -> - {W,H} = get_size(?config(max_size, Config)), + {W,H} = get_size(proplists:get_value(max_size, Config)), + Dir = proplists:get_value(priv_dir, Config), put(image_size, {W,H}), - ?line Im = egd:create(W, H), - - ?line Fgc = egd:color({255,0,0}), - - ?line ok = egd:line(Im, get_point(), get_point(), Fgc), - ?line ok = egd:rectangle(Im, get_point(), get_point(), Fgc), - ?line ok = egd:filledEllipse(Im, get_point(), get_point(), Fgc), - ?line ok = egd:arc(Im, get_point(), get_point(), Fgc), - ?line ok = egd:arc(Im, get_point(), get_point(), 100, Fgc), - + Im = egd:create(W, H), + + Fgc = egd:color({255,0,0}), + + ok = egd:line(Im, get_point(), get_point(), Fgc), + ok = egd:rectangle(Im, get_point(), get_point(), Fgc), + ok = egd:filledEllipse(Im, get_point(), get_point(), Fgc), + ok = egd:arc(Im, get_point(), get_point(), Fgc), + ok = egd:arc(Im, get_point(), get_point(), 100, Fgc), + Pt1 = get_point(), Pt2 = get_point(), - ?line ok = egd:filledRectangle(Im, Pt1, Pt2, Fgc), + ok = egd:filledRectangle(Im, Pt1, Pt2, Fgc), + + Bitmap = egd:render(Im, raw_bitmap), - ?line Bitmap = egd:render(Im, raw_bitmap), + ok = bitmap_point_has_color(Bitmap, {W,H}, Pt2, Fgc), + ok = bitmap_point_has_color(Bitmap, {W,H}, Pt1, Fgc), - ?line ok = bitmap_point_has_color(Bitmap, {W,H}, Pt2, Fgc), - ?line ok = bitmap_point_has_color(Bitmap, {W,H}, Pt1, Fgc), + Bin = <<_/binary>> = egd:render(Im, raw_bitmap, [{render_engine, alpha}]), + Png = egd_png:binary(W,H,Bin), + File = filename:join(Dir,"image_shape.png"), + ok = egd:save(Png,File), + ct:log("<p>Image:</p><img src=\"~s\" />~n", [File]), - ?line <<_/binary>> = egd:render(Im, raw_bitmap, [{render_engine, alpha}]), + ok = egd:destroy(Im), - ?line ok = egd:destroy(Im), erase(image_size), ok. -image_primitives(suite) -> - []; -image_primitives(doc) -> - ["Image shape api test."]; +%% Image shape API test. image_primitives(Config) when is_list(Config) -> - {W,H} = get_size(?config(max_size, Config)), + {W,H} = get_size(proplists:get_value(max_size, Config)), + Dir = proplists:get_value(priv_dir, Config), put(image_size, {W,H}), - ?line Im0 = egd_primitives:create(W, H), - ?line Fgc = egd:color({25,25,255}), - ?line Bgc = egd:color({0,250,25}), + Im0 = egd_primitives:create(W, H), + Fgc = egd:color({25,25,255}), + Bgc = egd:color({0,250,25}), - ?line Im1 = lists:foldl(fun - ({Function, Arguments}, Im) -> - ?line erlang:apply(egd_primitives, Function, [Im|Arguments]) - end, Im0, - [{Fs, [get_point(), get_point(), Bgc]} || Fs <- [line, rectangle, filledEllipse, arc]] ++ - [{pixel, [get_point(), Bgc]}, - {filledTriangle, [get_point(), get_point(), get_point(), Bgc]}]), + Im1 = lists:foldl(fun ({Function, Arguments}, Im) -> + erlang:apply(egd_primitives, Function, [Im|Arguments]) + end, Im0, + [{Fs, [get_point(), get_point(), Bgc]} || Fs <- [line, rectangle, filledEllipse, arc]] ++ + [{pixel, [get_point(), Bgc]}, + {filledTriangle, [get_point(), get_point(), get_point(), Bgc]}]), Pt1 = get_point(), Pt2 = get_point(), - ?line Im2 = egd_primitives:filledRectangle(Im1, Pt1, Pt2, Fgc), + Im2 = egd_primitives:filledRectangle(Im1, Pt1, Pt2, Fgc), - ?line Bitmap = egd_render:binary(Im2, opaque), + Bitmap = egd_render:binary(Im2, opaque), - ?line ok = bitmap_point_has_color(Bitmap, {W,H}, Pt2, Fgc), - ?line ok = bitmap_point_has_color(Bitmap, {W,H}, Pt1, Fgc), + ok = bitmap_point_has_color(Bitmap, {W,H}, Pt2, Fgc), + ok = bitmap_point_has_color(Bitmap, {W,H}, Pt1, Fgc), - ?line <<_/binary>> = egd_render:binary(Im2, alpha), + Bin = <<_/binary>> = egd_render:binary(Im2, alpha), + Png = egd_png:binary(W,H,Bin), + File = filename:join(Dir,"image_primitives.png"), + ok = egd:save(Png,File), + ct:log("<p>Image:</p><img src=\"~s\" />~n", [File]), erase(image_size), ok. - - - -image_font(suite) -> - []; -image_font(doc) -> - ["Image font test."]; +%% Image font test. image_font(Config) when is_list(Config) -> - {W,H} = get_size(?config(max_size, Config)), + {W,H} = get_size(proplists:get_value(max_size, Config)), + Dir = proplists:get_value(priv_dir, Config), put(image_size, {W,H}), - ?line Im = egd:create(W, H), - ?line Fgc = egd:color({0,130,0}), - - ?line Filename = filename:join([code:priv_dir(percept),"fonts","6x11_latin1.wingsfont"]), - ?line Font = egd_font:load(Filename), - + Im = egd:create(W, H), + Fgc = egd:color({0,130,0}), + + Filename = filename:join([code:priv_dir(percept),"fonts","6x11_latin1.wingsfont"]), + Font = egd_font:load(Filename), + % simple text - ?line ok = egd:text(Im, get_point(), Font, "Hello World", Fgc), - ?line <<_/binary>> = egd:render(Im, png), - + ok = egd:text(Im, get_point(), Font, "Hello World", Fgc), + <<_/binary>> = egd:render(Im, png), + GlyphStr1 = " !\"#$%&'()*+,-./", % Codes 32 -> 47 NumericStr = "0123456789", % Codes 48 -> 57 GlyphStr2 = ":;<=>?@", % Codes 58 -> 64 @@ -219,99 +207,149 @@ image_font(Config) when is_list(Config) -> AlphaSmStr = "abcdefghijklmnopqrstuvwxyz", % Codes 97 -> 122 GlyphStr4 = "{|}~", % Codes 123 -> 126 - ?line ok = egd:text(Im, get_point(), Font, GlyphStr1, Fgc), - ?line <<_/binary>> = egd:render(Im, png), - - ?line ok = egd:text(Im, get_point(), Font, NumericStr, Fgc), - ?line <<_/binary>> = egd:render(Im, png), - - ?line ok = egd:text(Im, get_point(), Font, GlyphStr2, Fgc), - ?line <<_/binary>> = egd:render(Im, png), - - ?line ok = egd:text(Im, get_point(), Font, AlphaBigStr, Fgc), - ?line <<_/binary>> = egd:render(Im, png), - - ?line ok = egd:text(Im, get_point(), Font, GlyphStr3, Fgc), - ?line <<_/binary>> = egd:render(Im, png), - - ?line ok = egd:text(Im, get_point(), Font, AlphaSmStr, Fgc), - ?line <<_/binary>> = egd:render(Im, png), - - ?line ok = egd:text(Im, get_point(), Font, GlyphStr4, Fgc), - ?line <<_/binary>> = egd:render(Im, png), - - ?line ok = egd:destroy(Im), + ok = egd:text(Im, get_point(), Font, GlyphStr1, Fgc), + Png1 = <<_/binary>> = egd:render(Im, png), + File1 = filename:join(Dir,"text1.png"), + ok = egd:save(Png1,File1), + ct:log("<p>Image:</p><img src=\"~s\" />~n", [File1]), + + ok = egd:text(Im, get_point(), Font, NumericStr, Fgc), + Png2 = <<_/binary>> = egd:render(Im, png), + File2 = filename:join(Dir,"text2.png"), + ok = egd:save(Png2,File2), + ct:log("<p>Image:</p><img src=\"~s\" />~n", [File2]), + + ok = egd:text(Im, get_point(), Font, GlyphStr2, Fgc), + Png3 = <<_/binary>> = egd:render(Im, png), + File3 = filename:join(Dir,"text3.png"), + ok = egd:save(Png3,File3), + ct:log("<p>Image:</p><img src=\"~s\" />~n", [File3]), + + ok = egd:text(Im, get_point(), Font, AlphaBigStr, Fgc), + Png4 = <<_/binary>> = egd:render(Im, png), + File4 = filename:join(Dir,"text4.png"), + ok = egd:save(Png4,File4), + ct:log("<p>Image:</p><img src=\"~s\" />~n", [File4]), + + ok = egd:text(Im, get_point(), Font, GlyphStr3, Fgc), + Png5 = <<_/binary>> = egd:render(Im, png), + File5 = filename:join(Dir,"text5.png"), + ok = egd:save(Png5,File5), + ct:log("<p>Image:</p><img src=\"~s\" />~n", [File5]), + + ok = egd:text(Im, get_point(), Font, AlphaSmStr, Fgc), + Png6 = <<_/binary>> = egd:render(Im, png), + File6 = filename:join(Dir,"text6.png"), + ok = egd:save(Png6,File6), + ct:log("<p>Image:</p><img src=\"~s\" />~n", [File6]), + + ok = egd:text(Im, get_point(), Font, GlyphStr4, Fgc), + Png7 = <<_/binary>> = egd:render(Im, png), + File7 = filename:join(Dir,"text7.png"), + ok = egd:save(Png7,File7), + ct:log("<p>Image:</p><img src=\"~s\" />~n", [File7]), + + ok = egd:destroy(Im), erase(image_size), ok. -image_png_compliant(suite) -> - []; -image_png_compliant(doc) -> - ["Image png compliant test."]; +%% Image png compliant test. image_png_compliant(Config) when is_list(Config) -> - {W,H} = get_size(?config(max_size, Config)), + {W,H} = get_size(proplists:get_value(max_size, Config)), put(image_size, {W,H}), - ?line Im = egd:create(W, H), - ?line Fgc = egd:color({0,0,0}), - ?line ok = egd:filledRectangle(Im, get_point(), get_point(), Fgc), - - ?line Bin = egd:render(Im, png), - ?line true = binary_is_png_compliant(Bin), - - ?line ok = egd:destroy(Im), + Im = egd:create(W, H), + Fgc = egd:color({0,0,0}), + ok = egd:filledRectangle(Im, get_point(), get_point(), Fgc), + + Bin = egd:render(Im, png), + true = binary_is_png_compliant(Bin), + + ok = egd:destroy(Im), erase(image_size), ok. +image_fans(Config) when is_list(Config) -> + W = 1024, + H = 800, + Dir = proplists:get_value(priv_dir, Config), + + Fun = fun({F,Args},Im) -> + erlang:apply(egd_primitives,F,[Im|Args]) + end, + + %% fan1 + Ops1 = gen_vertical_fan(1,{0,400},egd:color(red),1024,800,-15), + Ops2 = gen_horizontal_fan(1,{512,800},egd:color(green),1024,0,-15), + + Im0 = egd_primitives:create(W,H), + Im1 = lists:foldl(Fun, Im0, Ops1 ++ Ops2), + Bin1 = egd_render:binary(Im1, opaque), + Png1 = egd_png:binary(W,H,Bin1), + + File1 = filename:join(Dir,"fan1_opaque.png"), + ok = egd:save(Png1,File1), + ct:log("<p>Image opaque width 1:</p><img src=\"~s\" />~n", [File1]), + + Bin2 = egd_render:binary(Im1, alpha), + Png2 = egd_png:binary(W,H,Bin2), + + File2 = filename:join(Dir,"fan1_alpha.png"), + ok = egd:save(Png2,File2), + ct:log("<p>Image alpha width 1:</p><img src=\"~s\" />~n", [File2]), + + + %% fan2 + Ops3 = gen_vertical_fan(7,{0,400},egd:color(red),1024,800,-15), + Ops4 = gen_horizontal_fan(7,{512,800},egd:color(green),1024,0,-15), + + Im2 = lists:foldl(Fun, Im0, Ops3 ++ Ops4), + Bin3 = egd_render:binary(Im2, opaque), + Png3 = egd_png:binary(W,H,Bin3), + + File3 = filename:join(Dir,"fan2_opaque.png"), + ok = egd:save(Png3,File3), + ct:log("<p>Image opaque width 7:</p><img src=\"~s\" />~n", [File3]), + + Bin4 = egd_render:binary(Im2, alpha), + Png4 = egd_png:binary(W,H,Bin4), + + File4 = filename:join(Dir,"fan2_alpha.png"), + ok = egd:save(Png4,File4), + ct:log("<p>Image alpha width 7:</p><img src=\"~s\" />~n", [File4]), + ok. + +gen_vertical_fan(Wd,Pt,C,X,Y,Step) when Y > 0 -> + [{line,[Pt,{X,Y},Wd,C]}|gen_vertical_fan(Wd,Pt,C,X,Y + Step,Step)]; +gen_vertical_fan(_,_,_,_,_,_) -> []. + +gen_horizontal_fan(Wd,Pt,C,X,Y,Step) when X > 0 -> + [{line,[Pt,{X,Y},Wd,C]}|gen_horizontal_fan(Wd,Pt,C,X + Step,Y,Step)]; +gen_horizontal_fan(_,_,_,_,_,_) -> []. + + %%---------------------------------------------------------------------- %% Auxiliary tests %%---------------------------------------------------------------------- - + bitmap_point_has_color(Bitmap, {W,_}, {X,Y}, C) -> {CR,CG,CB,_} = egd_primitives:rgb_float2byte(C), N = W*Y*3 + X*3, << _:N/binary, R,G,B, _/binary>> = Bitmap, case {R,G,B} of - {CR,CG,CB} -> ok; - Other -> - io:format("bitmap_point_has_color: error color was ~p, should be ~p~n", [Other, {CR,CG,CB}]), - {error, {Other,{CR,CG,CB}}} - end. - -%% jfif header by specification -%% 2 bytes, length -%% 5 bytes, identifier ="JFIF\0" -%% 2 bytes, version, (major, minor) -%% 1 byte , units -%% However, JFIF seems to start at 6 (7 with 1-index)? - -binary_is_jfif_compliant(JpegBin) -> - ?line {Bin, _} = split_binary(JpegBin, 11), - List = binary_to_list(Bin), - case lists:sublist(List, 7, 4) of - "JFIF" -> true; - Other -> - io:format("img -> ~p~n", [Other]), - false - end. - -binary_is_gif_compliant(GifBin) -> - ?line {Bin, _} = split_binary(GifBin, 10), - List = binary_to_list(Bin), - case lists:sublist(List, 1,5) of - "GIF87" -> true; - Other -> - io:format("img -> ~p~n", [Other]), - false + {CR,CG,CB} -> ok; + Other -> + io:format("bitmap_point_has_color: error color was ~p, should be ~p~n", [Other, {CR,CG,CB}]), + {error, {Other,{CR,CG,CB}}} end. binary_is_png_compliant(PngBin) -> - ?line {Bin, _} = split_binary(PngBin, 10), + {Bin, _} = split_binary(PngBin, 10), List = binary_to_list(Bin), case lists:sublist(List, 2,3) of - "PNG" -> true; - Other -> - io:format("img -> ~p~n", [Other]), - false + "PNG" -> true; + Other -> + io:format("img -> ~p~n", [Other]), + false end. %%---------------------------------------------------------------------- @@ -320,20 +358,20 @@ binary_is_png_compliant(PngBin) -> get_rgb() -> - R = random(255), - G = random(255), - B = random(255), - {R,G,B}. + R = random(255), + G = random(255), + B = random(255), + {R,G,B}. get_angle() -> - random(359). + random(359). get_point() -> get_point(get(image_size)). get_point({W,H}) -> - X = random(W - 1), - Y = random(H - 1), - {X,Y}. + X = random(W - 1), + Y = random(H - 1), + {X,Y}. get_size(Max) -> W = trunc(random(Max/2) + Max/2 + 1), @@ -344,8 +382,8 @@ get_size(Max) -> get_points(N) -> get_points(N, []). get_points(0, Out) -> - Out; + Out; get_points(N, Out) -> get_points(N - 1, [get_point() | Out]). -random(N) -> trunc(random:uniform(trunc(N + 1)) - 1). +random(N) -> trunc(rand:uniform(trunc(N + 1)) - 1). diff --git a/lib/percept/test/ipc_tree.erl b/lib/percept/test/ipc_tree.erl index ff1c8d49c1..29da20e83f 100644 --- a/lib/percept/test/ipc_tree.erl +++ b/lib/percept/test/ipc_tree.erl @@ -46,4 +46,4 @@ gather([]) -> ok; gather([_|Pids]) -> receive _ -> gather(Pids) end. workload(0) -> ok; -workload(N) -> math:sin(2), workload(N - 1). +workload(N) -> _ = math:sin(2), workload(N - 1). diff --git a/lib/percept/test/percept_SUITE.erl b/lib/percept/test/percept_SUITE.erl index fd96c2b97a..fbc77302ae 100644 --- a/lib/percept/test/percept_SUITE.erl +++ b/lib/percept/test/percept_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2011. All Rights Reserved. +%% Copyright Ericsson AB 2007-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -19,54 +19,26 @@ %% -module(percept_SUITE). --include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). %% Test server specific exports --export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]). --export([init_per_suite/1, end_per_suite/1]). --export([init_per_testcase/2, end_per_testcase/2]). +-export([all/0, suite/0]). %% Test cases --export([ - app/1, - appup/1, - profile/1, - analyze/1, - analyze_dist/1, - webserver/1 - ]). - -%% Default timetrap timeout (set in init_per_testcase) --define(default_timeout, ?t:minutes(2)). - -init_per_suite(Config) when is_list(Config) -> - Config. - -end_per_suite(Config) when is_list(Config) -> - Config. - -init_per_testcase(_Case, Config) -> - Dog = ?t:timetrap(?default_timeout), - [{max_size, 300}, {watchdog,Dog} | Config]. - -end_per_testcase(_Case, Config) -> - Dog = ?config(watchdog, Config), - ?t:timetrap_cancel(Dog), - ok. +-export([app/1, + appup/1, + profile/1, + analyze/1, + analyze_dist/1, + webserver/1]). -suite() -> [{ct_hooks,[ts_install_cth]}]. +suite() -> + [{ct_hooks,[ts_install_cth]}, + {timetrap, {minutes, 2}}]. all() -> - [app, appup, webserver, profile, analyze, analyze_dist]. - -groups() -> - []. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. + [app, appup, webserver, profile, + analyze, analyze_dist]. %%---------------------------------------------------------------------- @@ -75,70 +47,56 @@ end_per_group(_GroupName, Config) -> %% Test that the percept app file is ok app(Config) when is_list(Config) -> - ok = ?t:app_test(percept). + ok = test_server:app_test(percept). %% Test that the percept appup file is ok appup(Config) when is_list(Config) -> - ok = ?t:appup_test(percept). + ok = test_server:appup_test(percept). -webserver(suite) -> - []; -webserver(doc) -> - ["Percept webserver test."]; +%% Percept webserver test. webserver(Config) when is_list(Config) -> % Explicit start inets? - ?line {started, _, Port} = percept:start_webserver(), - ?line ok = percept:stop_webserver(Port), - ?line {started, _, _} = percept:start_webserver(), - ?line ok = percept:stop_webserver(), - ?line {started, _, NewPort} = percept:start_webserver(), - ?line ok = percept:stop_webserver(NewPort), - ?line application:stop(inets), + {started, _, Port} = percept:start_webserver(), + ok = percept:stop_webserver(Port), + {started, _, _} = percept:start_webserver(), + ok = percept:stop_webserver(), + {started, _, NewPort} = percept:start_webserver(), + ok = percept:stop_webserver(NewPort), + application:stop(inets), ok. -profile(suite) -> - []; -profile(doc) -> - ["Percept profile test."]; +%% Percept profile test. profile(Config) when is_list(Config) -> - Path = ?config(data_dir, Config), + Path = proplists:get_value(data_dir, Config), File = filename:join([Path,"profile_test.dat"]), - ?line {ok, _} = percept:profile(File, [procs]), + {ok, _} = percept:profile(File, [procs]), ipc_tree:go(7), - ?line ok = percept:stop_profile(), + ok = percept:stop_profile(), ok. -analyze(suite) -> - []; -analyze(doc) -> - ["Percept analyze test."]; +%% Percept analyze test. analyze(Config) when is_list(Config) -> Begin = processes(), - Path = ?config(data_dir, Config), + Path = proplists:get_value(data_dir, Config), File = filename:join([Path,"profile_test.dat"]), - T0 = erlang:now(), - ?line ok = percept:analyze(File), - T1 = erlang:now(), - Secs = timer:now_diff(T1,T0)/1000000, - io:format("percept:analyze/1 took ~.2f s.~n", [Secs]), - ?line {stopped, _} = percept_db:stop(), + T0 = erlang:monotonic_time(milli_seconds), + ok = percept:analyze(File), + T1 = erlang:monotonic_time(milli_seconds), + io:format("percept:analyze/1 took ~w ms.~n", [T1 - T0]), + {stopped, _} = percept_db:stop(), print_remainers(remainers(Begin, processes())), ok. -analyze_dist(suite) -> - []; -analyze_dist(doc) -> - ["Percept analyze distribution test."]; +%% Percept analyze distribution test. analyze_dist(Config) when is_list(Config) -> Begin = processes(), - Path = ?config(data_dir, Config), + Path = proplists:get_value(data_dir, Config), File = filename:join([Path,"ipc-dist.dat"]), - T0 = erlang:now(), - ?line ok = percept:analyze(File), - T1 = erlang:now(), - Secs = timer:now_diff(T1,T0)/1000000, - io:format("percept:analyze/1 took ~.2f s.~n", [Secs]), - ?line {stopped, _} = percept_db:stop(), + T0 = erlang:monotonic_time(milli_seconds), + ok = percept:analyze(File), + T1 = erlang:monotonic_time(milli_seconds), + io:format("percept:analyze/1 took ~w ms.~n", [T1 - T0]), + {stopped, _} = percept_db:stop(), print_remainers(remainers(Begin, processes())), ok. @@ -166,9 +124,3 @@ remainers(Begin, [Pid|End], Out) -> true -> remainers(Begin, End, Out); false -> remainers(Begin, End, [Pid|Out]) end. - - - - - - diff --git a/lib/percept/test/percept_db_SUITE.erl b/lib/percept/test/percept_db_SUITE.erl index e2775aabc0..b2827e0e42 100644 --- a/lib/percept/test/percept_db_SUITE.erl +++ b/lib/percept/test/percept_db_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2010. All Rights Reserved. +%% Copyright Ericsson AB 2007-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -19,57 +19,35 @@ %% -module(percept_db_SUITE). --include("test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). %% Test server specific exports --export([all/1]). --export([init_per_suite/1, end_per_suite/1]). --export([init_per_testcase/2, end_per_testcase/2]). +-export([all/0, suite/0]). %% Test cases --export([ - start/1 - ]). +-export([start/1]). %% Default timetrap timeout (set in init_per_testcase) --define(default_timeout, ?t:minutes(2)). -define(restarts, 10). -define(alive_timeout, 500). -init_per_suite(Config) when is_list(Config) -> - Config. +suite() -> + [{timetrap, {minutes, 2}}]. -end_per_suite(Config) when is_list(Config) -> - Config. - -init_per_testcase(_Case, Config) -> - Dog = ?t:timetrap(?default_timeout), - [{max_size, 300}, {watchdog,Dog} | Config]. - -end_per_testcase(_Case, Config) -> - Dog = ?config(watchdog, Config), - ?t:timetrap_cancel(Dog), - ok. - -all(suite) -> - % Test cases +all() -> [start]. %%---------------------------------------------------------------------- %% Tests %%---------------------------------------------------------------------- -start(suite) -> - []; -start(doc) -> - ["Percept_db start and restart test."]; +%% Percept_db start and restart test. start(Config) when is_list(Config) -> ok = restart(?restarts), {stopped, _DB} = percept_db:stop(), ok. -restart(0)-> - ok; +restart(0)-> ok; restart(N)-> {_, DB} = percept_db:start(), timer:sleep(?alive_timeout), diff --git a/lib/percept/vsn.mk b/lib/percept/vsn.mk index 833ab35aa5..614cee8645 100644 --- a/lib/percept/vsn.mk +++ b/lib/percept/vsn.mk @@ -1 +1 @@ -PERCEPT_VSN = 0.8.11 +PERCEPT_VSN = 0.9 |