aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/percept/src/egd.erl8
-rw-r--r--lib/percept/src/egd_font.erl7
-rw-r--r--[-rwxr-xr-x]lib/percept/src/egd_png.erl0
-rw-r--r--lib/percept/src/egd_primitives.erl138
-rw-r--r--lib/percept/src/egd_render.erl166
-rw-r--r--lib/percept/test/egd_SUITE.erl43
6 files changed, 114 insertions, 248 deletions
diff --git a/lib/percept/src/egd.erl b/lib/percept/src/egd.erl
index 4becfef19b..7972fde597 100644
--- a/lib/percept/src/egd.erl
+++ b/lib/percept/src/egd.erl
@@ -128,13 +128,13 @@ line(Image, P1, P2, Color) ->
%% @spec color( Value | Name ) -> color()
%% where
-%% Value = {byte(), byte(), byte()} | {byte(), byte(), byte(), byte()}
-%% Name = black | silver | gray | white | maroon | red | purple | fuchia | green | lime | olive | yellow | navy | blue | teal | aqua
+%% Value = {byte(), byte(), byte()} | {byte(), byte(), byte(), byte()}
+%% Name = black | silver | gray | white | maroon | red | purple | fuchia | green | lime | olive | yellow | navy | blue | teal | aqua
%% @doc Creates a color reference.
-spec(color/1 :: (
- Value :: {byte(), byte(), byte()} | {byte(), byte(), byte(), byte()} | atom()) ->
- color()).
+ Value :: {byte(), byte(), byte()} | {byte(), byte(), byte(), byte()} | atom()) ->
+ color()).
color(Color) ->
egd_primitives:color(Color).
diff --git a/lib/percept/src/egd_font.erl b/lib/percept/src/egd_font.erl
index 2b2a89a0a9..5f0d56dd90 100644
--- a/lib/percept/src/egd_font.erl
+++ b/lib/percept/src/egd_font.erl
@@ -131,18 +131,18 @@ parse_glyph({Code,W,H,X0,Y0,Xm,Offset}, Bitmasks) ->
render_glyph(W, H, X0, Y0, Xm, Bitmask) ->
render_glyph(W,{0,H},X0,Y0,Xm,Bitmask, []).
render_glyph(_W, {H,H}, _X0, _Y0, _Xm, _Bitmask, Out) -> Out;
-render_glyph(W, {Hi,H}, X0, Y0,Xm, Bitmask, LSs) ->
+render_glyph(W, {Hi,H}, X0, Y0,Xm, Bitmask , LSs) ->
N = ((W+7) div 8),
O = N*Hi,
<<_:O/binary, Submask/binary>> = Bitmask,
- LS = render_glyph_horizontal(
+ LS = render_glyph_horizontal(
Submask, % line glyph bitmask
{down, W - 1}, % loop state
W - 1, % Width
[]), % Linespans
render_glyph(W,{Hi+1,H},X0,Y0,Xm, Bitmask, [LS|LSs]).
-render_glyph_horizontal(Value, {Pr, Px}, 0, Spans) ->
+render_glyph_horizontal(Value, {Pr, Px}, 0, Spans) ->
Cr = bit_spin(Value, 0),
case {Pr,Cr} of
{up , up } -> % closure of interval since its last
@@ -173,4 +173,3 @@ bit_spin(Value, Cx) ->
1 -> up;
0 -> down
end.
-
diff --git a/lib/percept/src/egd_png.erl b/lib/percept/src/egd_png.erl
index 3a0aaeef31..3a0aaeef31 100755..100644
--- a/lib/percept/src/egd_png.erl
+++ b/lib/percept/src/egd_png.erl
diff --git a/lib/percept/src/egd_primitives.erl b/lib/percept/src/egd_primitives.erl
index 245e0d48e2..77c600279f 100644
--- a/lib/percept/src/egd_primitives.erl
+++ b/lib/percept/src/egd_primitives.erl
@@ -28,6 +28,7 @@
pixel/3,
polygon/3,
line/4,
+ line/5,
arc/4,
arc/5,
rectangle/4,
@@ -50,7 +51,6 @@
-include("egd.hrl").
-
%% API info
info(I) ->
W = I#image.width, H = I#image.height,
@@ -75,13 +75,22 @@ object_info(O) ->
%% interface functions
line(I, Sp, Ep, Color) ->
- I#image{objects = [
+ I#image{ objects = [
#image_object{
type = line,
points = [Sp, Ep],
span = span([Sp, Ep]),
color = Color} | I#image.objects]}.
+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]}.
+
arc(I, {Sx,Sy} = Sp, {Ex,Ey} = Ep, Color) ->
X = Ex - Sx,
Y = Ey - Sy,
@@ -162,8 +171,6 @@ create(W, H) ->
#image{ width = W, height = H}.
-%color({crayon, Color}) -> rgba_byte2float(name_to_color({crayon, Color, 255}));
-%color({crayon, Color, A}) -> rgba_byte2float(name_to_color({crayon, 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});
@@ -314,129 +321,6 @@ 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}.
-%% Crayons
-%name_to_color({crayon, mahogany, A}) -> { 205, 74, 74, A};
-%name_to_color({crayon, 'fuzzy wuzzy brown', A}) -> { 204, 102, 102, A};
-%name_to_color({crayon, chestnut, A}) -> { 188, 93, 88, A};
-%name_to_color({crayon, 'red orange', A}) -> { 255, 83, 73, A};
-%name_to_color({crayon, 'sunset orange', A}) -> { 253, 94, 83, A};
-%name_to_color({crayon, bittersweet, A}) -> { 253, 124, 110, A};
-%name_to_color({crayon, melon, A}) -> { 253, 188, 180, A};
-%name_to_color({crayon, 'outrageous orange', A}) -> { 255, 110, 74, A};
-%name_to_color({crayon, 'vivid tangerine', A}) -> { 255, 160, 137, A};
-%name_to_color({crayon, 'burnt sienna', A}) -> { 234, 126, 93, A};
-%name_to_color({crayon, brown, A}) -> { 180, 103, 77, A};
-%name_to_color({crayon, sepia, A}) -> { 165, 105, 79, A};
-%name_to_color({crayon, orange, A}) -> { 255, 117, 56, A};
-%name_to_color({crayon, 'burnt orange', A}) -> { 255, 127, 73, A};
-%name_to_color({crayon, copper, A}) -> { 221, 148, 117, A};
-%name_to_color({crayon, 'mango tango', A}) -> { 255, 130, 67, A};
-%name_to_color({crayon, 'atomic tangerine', A}) -> { 255, 164, 116, A};
-%name_to_color({crayon, beaver, A}) -> { 159, 129, 112, A};
-%name_to_color({crayon, 'antique brass', A}) -> { 205, 149, 117, A};
-%name_to_color({crayon, 'desert sand', A}) -> { 239, 205, 184, A};
-%name_to_color({crayon, 'raw sienna', A}) -> { 214, 138, 89, A};
-%name_to_color({crayon, tumbleweed, A}) -> { 222, 170, 136, A};
-%name_to_color({crayon, tan, A}) -> { 250, 167, 108, A};
-%name_to_color({crayon, peach, A}) -> { 255, 207, 171, A};
-%name_to_color({crayon, 'macaroni and cheese', A}) -> { 255, 189, 136, A};
-%name_to_color({crayon, apricot, A}) -> { 253, 217, 181, A};
-%name_to_color({crayon, 'neon carrot', A}) -> { 255, 163, 67, A};
-%name_to_color({crayon, almond, A}) -> { 239, 219, 197, A};
-%name_to_color({crayon, 'yellow orange', A}) -> { 255, 182, 83, A};
-%name_to_color({crayon, gold, A}) -> { 231, 198, 151, A};
-%name_to_color({crayon, shadow, A}) -> { 138, 121, 93, A};
-%name_to_color({crayon, 'banana mania', A}) -> { 250, 231, 181, A};
-%name_to_color({crayon, sunglow, A}) -> { 255, 207, 72, A};
-%name_to_color({crayon, goldenrod, A}) -> { 252, 217, 117, A};
-%name_to_color({crayon, dandelion, A}) -> { 253, 219, 109, A};
-%name_to_color({crayon, yellow, A}) -> { 252, 232, 131, A};
-%name_to_color({crayon, 'green yellow', A}) -> { 240, 232, 145, A};
-%name_to_color({crayon, 'spring green', A}) -> { 236, 234, 190, A};
-%name_to_color({crayon, 'olive green', A}) -> { 186, 184, 108, A};
-%name_to_color({crayon, 'laser lemon', A}) -> { 253, 252, 116, A};
-%name_to_color({crayon, 'unmellow yellow', A}) -> { 253, 252, 116, A};
-%name_to_color({crayon, canary, A}) -> { 255, 255, 153, A};
-%name_to_color({crayon, 'yellow green', A}) -> { 197, 227, 132, A};
-%name_to_color({crayon, 'inch worm', A}) -> { 178, 236, 93, A};
-%name_to_color({crayon, asparagus, A}) -> { 135, 169, 107, A};
-%name_to_color({crayon, 'granny smith apple', A}) -> { 168, 228, 160, A};
-%name_to_color({crayon, 'electric lime', A}) -> { 29, 249, 20, A};
-%name_to_color({crayon, 'screamin green', A}) -> { 118, 255, 122, A};
-%name_to_color({crayon, fern, A}) -> { 113, 188, 120, A};
-%name_to_color({crayon, 'forest green', A}) -> { 109, 174, 129, A};
-%name_to_color({crayon, 'sea green', A}) -> { 159, 226, 191, A};
-%name_to_color({crayon, green, A}) -> { 28, 172, 120, A};
-%name_to_color({crayon, 'mountain meadow', A}) -> { 48, 186, 143, A};
-%name_to_color({crayon, shamrock, A}) -> { 69, 206, 162, A};
-%name_to_color({crayon, 'jungle green', A}) -> { 59, 176, 143, A};
-%name_to_color({crayon, 'caribbean green', A}) -> { 28, 211, 162, A};
-%name_to_color({crayon, 'tropical rain forest', A}) -> { 23, 128, 109, A};
-%name_to_color({crayon, 'pine green', A}) -> { 21, 128, 120, A};
-%name_to_color({crayon, 'robin egg blue', A}) -> { 31, 206, 203, A};
-%name_to_color({crayon, aquamarine, A}) -> { 120, 219, 226, A};
-%name_to_color({crayon, 'turquoise blue', A}) -> { 119, 221, 231, A};
-%name_to_color({crayon, 'sky blue', A}) -> { 128, 218, 235, A};
-%name_to_color({crayon, 'outer space', A}) -> { 65, 74, 76, A};
-%name_to_color({crayon, 'blue green', A}) -> { 25, 158, 189, A};
-%name_to_color({crayon, 'pacific blue', A}) -> { 28, 169, 201, A};
-%name_to_color({crayon, cerulean, A}) -> { 29, 172, 214, A};
-%name_to_color({crayon, cornflower, A}) -> { 154, 206, 235, A};
-%name_to_color({crayon, 'midnight blue', A}) -> { 26, 72, 118, A};
-%name_to_color({crayon, 'navy blue', A}) -> { 25, 116, 210, A};
-%name_to_color({crayon, denim, A}) -> { 43, 108, 196, A};
-%name_to_color({crayon, blue, A}) -> { 31, 117, 254, A};
-%name_to_color({crayon, periwinkle, A}) -> { 197, 208, 230, A};
-%name_to_color({crayon, 'cadet blue', A}) -> { 176, 183, 198, A};
-%name_to_color({crayon, indigo, A}) -> { 93, 118, 203, A};
-%name_to_color({crayon, 'wild blue yonder', A}) -> { 162, 173, 208, A};
-%name_to_color({crayon, manatee, A}) -> { 151, 154, 170, A};
-%name_to_color({crayon, 'blue bell', A}) -> { 173, 173, 214, A};
-%name_to_color({crayon, 'blue violet', A}) -> { 115, 102, 189, A};
-%name_to_color({crayon, 'purple heart', A}) -> { 116, 66, 200, A};
-%name_to_color({crayon, 'royal purple', A}) -> { 120, 81, 169, A};
-%name_to_color({crayon, 'purple mountains majesty', A}) -> { 157, 129, 186, A};
-%name_to_color({crayon, violet, A}) -> { 146, 110, 174, A};
-%name_to_color({crayon, wisteria, A}) -> { 205, 164, 222, A};
-%name_to_color({crayon, 'vivid violet', A}) -> { 143, 80, 157, A};
-%name_to_color({crayon, fuchsia, A}) -> { 195, 100, 197, A};
-%name_to_color({crayon, 'shocking pink', A}) -> { 251, 126, 253, A};
-%name_to_color({crayon, 'pink flamingo', A}) -> { 252, 116, 253, A};
-%name_to_color({crayon, plum, A}) -> { 142, 69, 133, A};
-%name_to_color({crayon, 'hot magenta', A}) -> { 255, 29, 206, A};
-%name_to_color({crayon, 'purple pizzazz', A}) -> { 255, 29, 206, A};
-%name_to_color({crayon, 'razzle dazzle rose', A}) -> { 255, 72, 208, A};
-%name_to_color({crayon, orchid, A}) -> { 230, 168, 215, A};
-%name_to_color({crayon, 'red violet', A}) -> { 192, 68, 143, A};
-%name_to_color({crayon, eggplant, A}) -> { 110, 81, 96, A};
-%name_to_color({crayon, cerise, A}) -> { 221, 68, 146, A};
-%name_to_color({crayon, 'wild strawberry', A}) -> { 255, 67, 164, A};
-%name_to_color({crayon, magenta, A}) -> { 246, 100, 175, A};
-%name_to_color({crayon, lavender, A}) -> { 252, 180, 213, A};
-%name_to_color({crayon, 'cotton candy', A}) -> { 255, 188, 217, A};
-%name_to_color({crayon, 'violet red', A}) -> { 247, 83, 148, A};
-%name_to_color({crayon, 'carnation pink', A}) -> { 255, 170, 204, A};
-%name_to_color({crayon, razzmatazz, A}) -> { 227, 37, 107, A};
-%name_to_color({crayon, 'piggy pink', A}) -> { 253, 215, 228, A};
-%name_to_color({crayon, 'jazzberry jam', A}) -> { 202, 55, 103, A};
-%name_to_color({crayon, blush, A}) -> { 222, 93, 131, A};
-%name_to_color({crayon, 'tickle me pink', A}) -> { 252, 137, 172, A};
-%name_to_color({crayon, 'pink sherbet', A}) -> { 247, 128, 161, A};
-%name_to_color({crayon, maroon, A}) -> { 200, 56, 90, A};
-%name_to_color({crayon, red, A}) -> { 238, 32, 77, A};
-%name_to_color({crayon, 'radical red', A}) -> { 255, 73, 108, A};
-%name_to_color({crayon, mauvelous, A}) -> { 239, 152, 170, A};
-%name_to_color({crayon, 'wild watermelon', A}) -> { 252, 108, 133, A};
-%name_to_color({crayon, scarlet, A}) -> { 252, 40, 71, A};
-%name_to_color({crayon, salmon, A}) -> { 255, 155, 170, A};
-%name_to_color({crayon, 'brick red', A}) -> { 203, 65, 84, A};
-%name_to_color({crayon, white, A}) -> { 237, 237, 237, A};
-%name_to_color({crayon, timberwolf, A}) -> { 219, 215, 210, A};
-%name_to_color({crayon, silver, A}) -> { 205, 197, 194, A};
-%name_to_color({crayon, gray, A}) -> { 149, 145, 140, A};
-%name_to_color({crayon, black, A}) -> { 35, 35, 35, A}.
-
-
text(I, {Xs,Ys} = Sp, Font, Text, Color) ->
{FW,FH} = egd_font:size(Font),
Length = length(Text),
diff --git a/lib/percept/src/egd_render.erl b/lib/percept/src/egd_render.erl
index f5e32c2a0f..cea9d2d926 100644
--- a/lib/percept/src/egd_render.erl
+++ b/lib/percept/src/egd_render.erl
@@ -35,7 +35,7 @@ binary(Image, Type) ->
parallel_binary(precompile(Image),Type).
parallel_binary(Image = #image{ height = Height },Type) ->
- case lists:min([erlang:system_info(schedulers), Height]) of
+ case erlang:min(erlang:system_info(schedulers), Height) of
1 ->
% if the height or the number of schedulers is 1
% do the scanlines in this process.
@@ -120,27 +120,15 @@ receive_binaries(H, Bins) when H > 0 ->
scanline(Y, Os, {_,_,Width,_}=LSB, Type) ->
- OLSs = parse_objects_on_line(Y-1, Width, Os),
- URLSs = resulting_line_spans([LSB|OLSs],Type),
-
- % FIXME: Can we keep the list sorted instead of sorting it?
- % sort descending
- RLSs = lists:reverse(URLSs),
-
- resulting_scanline(RLSs,Width).
-
-resulting_scanline(RLSs, Width) -> resulting_scanline(RLSs, Width, []).
-resulting_scanline([], _, Scanlines) -> Scanlines;
-resulting_scanline([{_,Xl, Xr, C} | RLSs], Width, Scanlines) ->
- {R,G,B,_} = rgb_float2byte(C),
- Scanline = lists:duplicate(trunc(Xr - Xl + 1), <<R:8,G:8,B:8>>),
- resulting_scanline(RLSs, Width, [Scanline|Scanlines]).
+ OLSs = parse_objects_on_line(Y-1, Width, Os),
+ RLSs = resulting_line_spans([LSB|OLSs],Type),
+ [ lists:duplicate(Xr - Xl + 1, <<(trunc(R*255)):8,(trunc(G*255)):8,(trunc(B*255)):8>>) || {_,Xl, Xr, {R,G,B,_}} <- RLSs ].
resulting_line_spans(LSs,Type) ->
%% Build a list of "transitions" from left to right.
Trans = line_spans_to_trans(LSs),
%% Convert list of "transitions" to linespans.
- trans_to_line_spans(Trans,Type).
+ trans_to_line_spans(Trans,Type).
line_spans_to_trans(LSs) ->
line_spans_to_trans(LSs,[],0).
@@ -194,19 +182,14 @@ color([{_,C}|_],opaque) -> C;
color(Layers,alpha) -> color1({0,0,0,0},Layers).
color1(Color,[]) -> Color;
-color1(Color,[{_,C}|Layers]) -> color1(blend(Color,C),Layers).
-
-blend(C1,C2) -> alpha_blend(C1,C2).
+color1(Color,[{_,C}|Layers]) -> color1(alpha_blend(Color,C),Layers).
modify_layers(Layers,[]) -> Layers;
-modify_layers(Layers,[{{_,Z,Op},C}|Trans]) ->
- modify_layers(case Op of
- start ->
- add_layer(Layers,Z,C);
- stop ->
- remove_layer(Layers,Z,C)
- end,
- Trans).
+modify_layers(Layers,[{{_,Z,start},C}|Trans]) ->
+ modify_layers(add_layer(Layers, Z, C), Trans);
+modify_layers(Layers,[{{_,Z,stop },C}|Trans]) ->
+ modify_layers(remove_layer(Layers, Z, C), Trans).
+
add_layer([{Z1,_}=H|Layers],Z,C) when Z1 > Z ->
[H|add_layer(Layers,Z,C)];
@@ -216,7 +199,7 @@ add_layer(Layers,Z,C) ->
remove_layer(Layers,Z,C) ->
Layers -- [{Z,C}].
-alpha_blend({R1,G1,B1,A1}, {R2,G2,B2,A2}) ->
+alpha_blend({R1,G1,B1,A1}, {R2,G2,B2,A2}) when is_float(A1), is_float(A2)->
Beta = A2*(1.0 - A1),
A = A1 + Beta,
R = R1*A1 + R2*Beta,
@@ -232,7 +215,7 @@ parse_objects_on_line(Y, Z, Width, [O|Os], Out) ->
false ->
parse_objects_on_line(Y, Z + 1, Width, Os, Out);
true ->
- OLs = object_line_data(Y, Z, O),
+ OLs = object_line_data(Y, Z, O),
TOLs = trim_object_line_data(OLs, Width),
parse_objects_on_line(Y, Z + 1, Width, Os, [TOLs|Out])
end.
@@ -240,15 +223,13 @@ parse_objects_on_line(Y, Z, Width, [O|Os], Out) ->
trim_object_line_data(OLs, Width) ->
trim_object_line_data(OLs, Width, []).
trim_object_line_data([], _, Out) -> Out;
+
+trim_object_line_data([{_, Xl, _, _}|OLs], Width, Out) when Xl > Width ->
+ trim_object_line_data(OLs, Width, Out);
+trim_object_line_data([{_, _, Xr, _}|OLs], Width, Out) when Xr < 0 ->
+ trim_object_line_data(OLs, Width, Out);
trim_object_line_data([{Z, Xl, Xr, C}|OLs], Width, Out) ->
- if
- Xl > Width ->
- trim_object_line_data(OLs, Width, Out);
- Xr < 0 ->
- trim_object_line_data(OLs, Width, Out);
- true ->
- trim_object_line_data(OLs, Width, [{Z, lists:max([0,Xl]), lists:min([Xr,Width]), C}|Out])
- end.
+ trim_object_line_data(OLs, Width, [{Z, erlang:max(0,Xl), erlang:min(Xr,Width), C}|Out]).
% object_line_data
% In:
@@ -264,7 +245,8 @@ 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, 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) ->
if
Y0 =:= Y ; Y1 =:= Y ->
@@ -277,70 +259,43 @@ object_line_data(Y, Z, #image_object{ span = {X0, Y0, X1, Y1}, color = C}, recta
object_line_data(_Y, Z, #image_object{ span = {X0, _, X1, _}, color = C}, filled_rectangle) ->
[{Z, X0, X1, C}];
-object_line_data(Y, Z, #image_object{ span = {X0,Y0,X1,Y1}, color = C}, filled_ellipse) ->
+object_line_data(Y, Z, #image_object{ internals={Xr,Yr,Yr2}, span = {X0,Y0,X1,Y1}, color = C}, filled_ellipse) ->
if
- X1 - X0 == 0 -> % if the width is exactly one pixel
- [{Z, X1, X0, C}];
- X1 - X0 < 0 -> throw(bad_ellipse_width);
- Y1 - Y0 == 0 -> % Height exactly one pixel, get width
+ X1 - X0 == 0; Y1 - Y0 == 0 ->
[{Z, X0, X1, C}];
true ->
- Xr = (X1 - X0)/2,
- Yr = (Y1 - Y0)/2,
- Yo = trunc(Y - Y0 - Yr),
+ Yo = trunc(Y - Y0 - Yr),
Yo2 = Yo*Yo,
- Yr2 = Yr*Yr,
- Xo = math:sqrt((1 - Yo2/Yr2))*Xr,
+ 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) ->
- case lists:keysearch(Y, 1, Is) of
- {value, {Y, Xl, Xr}} -> [{Z, Xl, Xr, C}];
+ 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, {Xl, Xr}} -> [{Z, Xl, Xr, C}];
{ok, Ls} -> [{Z, Xl, Xr, C}||{Xl,Xr} <- Ls];
_ -> []
end;
-object_line_data(Y, Z, O, polygon) ->
- Is = lists:filter(
- fun({Yp,_,_}) ->
- if Yp == Y -> true; true -> false end
- end, O#image_object.intervals),
- [ {Z, Xl, Xr, O#image_object.color} || {_, Xl, Xr} <- Is];
-
-object_line_data(Y, Z, #image_object{ color = C, intervals = Is }, text_horizontal) ->
- % FIXME: optimize!
- lists:foldl(
- fun ({Yg,Xl,Xr}, Out) ->
- if
- Yg == Y ->
- [{Z, Xl, Xr, C}|Out];
- true ->
- Out
- end
- end, [], Is);
+object_line_data(Y, Z, #image_object{ color = C, intervals = Is}, polygon) ->
+ [{Z, Xl, Xr, C} || {Yp, Xl, Xr} <- Is, Yp =:= Y];
+
+object_line_data(Y, Z, #image_object{ color = C, intervals = Is}, text_horizontal) ->
+ [{Z, Xl, Xr, C} || {Yg, Xl, Xr} <- Is, Yg =:= Y];
+
object_line_data(_, Z, #image_object{ span = {X0,_,X1,_}, color = C}, _) ->
- % faked
[{Z, X0, X1, C}].
-is_object_on_line(Y, Object) ->
- is_object_bounds_on_line(Y, Object#image_object.span).
+is_object_on_line(Y, #image_object{ span = Span }) ->
+ is_object_bounds_on_line(Y, Span).
-is_object_bounds_on_line(Y, {_,Y0,_,Y1}) ->
- if
- Y < Y0 -> false;
- Y > Y1 -> false;
- true -> true
- end.
-
-rgb_float2byte({R,G,B,A}) ->
- {trunc(R*255), trunc(G*255), trunc(B*255), trunc(A*255)}.
+is_object_bounds_on_line(Y, {_,Y0,_,Y1}) when Y < Y0 ; Y > Y1 -> false;
+is_object_bounds_on_line(_, _) -> true.
%%% primitives to line_spans
@@ -360,6 +315,12 @@ precompile_objects([O = #image_object{ type = filled_triangle, points = [P0,P1,P
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) ->
+ 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) ->
Es = egd_primitives:arc_to_edges(P0, P1, D),
@@ -579,13 +540,7 @@ line_ls({Xi0, Yi0},{Xi1,Yi1}) ->
true -> 1;
false -> -1
end,
- case Steep of
- false ->
- line_ls_step_not_steep({X0, X1},Y0, DX, DY, Ystep, Error, X0, []);
- true ->
- line_ls_step_steep({X0, X1},Y0, DX, DY, Ystep, Error, X0, [])
- end.
-
+ line_ls_step(X0, X1,Y0, DX, DY, Ystep, Error, X0, Steep, []).
%% line_ls_step_(not)_steep
%% In:
@@ -594,27 +549,17 @@ line_ls({Xi0, Yi0},{Xi1,Yi1}) ->
%% Purpose:
%% Produce an line_interval for each Yi (Y index)
-% Iterating the X-axis
-
-line_ls_step_not_steep({X,X1},Y,Dx,Dy,Ys,E, X0, LSs) when X < X1 ->
- case E >= 0 of
- true ->
- line_ls_step_not_steep({X+1,X1},Y+Ys,Dx,Dy,Ys, E - Dx + Dy, X+1,[{Y,X0,X}|LSs]);
- false ->
- line_ls_step_not_steep({X+1,X1},Y,Dx,Dy,Ys, E + Dy, X0, LSs)
- end;
-line_ls_step_not_steep({X,_},Y,_Dx,_Dy,_Ystep,_E,X0,LSs) ->
- [{Y,X0,X}|LSs].
-
-% Iterating the Y-axis
-line_ls_step_steep({X,X1},Y,Dx,Dy,Ystep,E, X0, LSs) when X =< X1 ->
- case E >= 0 of
- true ->
- line_ls_step_steep({X + 1,X1},Y+Ystep,Dx,Dy,Ystep,E - Dx + Dy,X,[{X,Y,Y}|LSs]);
- false ->
- line_ls_step_steep({X + 1,X1},Y,Dx,Dy,Ystep,E + Dy,X0, [{X,Y,Y}|LSs])
- end;
-line_ls_step_steep({_X,_},_Y,_Dx,_Dy,_Ystep,_E,_X0,LSs) ->
+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.
% Text
@@ -707,3 +652,4 @@ eps_header(W,H) ->
eps_footer() ->
"%%EOF\n".
+
diff --git a/lib/percept/test/egd_SUITE.erl b/lib/percept/test/egd_SUITE.erl
index 603ad628d3..a2595400dd 100644
--- a/lib/percept/test/egd_SUITE.erl
+++ b/lib/percept/test/egd_SUITE.erl
@@ -29,6 +29,7 @@
-export([
image_create_and_destroy/1,
image_shape/1,
+ image_primitives/1,
image_colors/1,
image_font/1,
image_png_compliant/1
@@ -38,8 +39,7 @@
-define(default_timeout, ?t:minutes(1)).
init_per_suite(Config) when is_list(Config) ->
- {A1,A2,A3} = now(),
- random:seed(A1, A2, A3),
+ random:seed(now()),
Config.
end_per_suite(Config) when is_list(Config) ->
@@ -59,6 +59,7 @@ all(suite) ->
[
image_create_and_destroy,
image_shape,
+ image_primitives,
image_colors,
image_font,
image_png_compliant
@@ -145,7 +146,43 @@ image_shape(Config) when is_list(Config) ->
?line ok = egd:destroy(Im),
erase(image_size),
ok.
-
+
+image_primitives(suite) ->
+ [];
+image_primitives(doc) ->
+ ["Image shape api test."];
+image_primitives(Config) when is_list(Config) ->
+ {W,H} = get_size(?config(max_size, 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}),
+
+ ?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]}]),
+
+ Pt1 = get_point(),
+ Pt2 = get_point(),
+
+ ?line Im2 = egd_primitives:filledRectangle(Im1, Pt1, Pt2, Fgc),
+
+ ?line 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),
+
+ erase(image_size),
+ ok.
+
+
+
+
image_font(suite) ->
[];
image_font(doc) ->