GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/*************************************************************************** |
||
2 |
* Copyright (c) 2024 Microsoft Corporation |
||
3 |
* |
||
4 |
* This program and the accompanying materials are made available under the |
||
5 |
* terms of the MIT License which is available at |
||
6 |
* https://opensource.org/licenses/MIT. |
||
7 |
* |
||
8 |
* SPDX-License-Identifier: MIT |
||
9 |
**************************************************************************/ |
||
10 |
|||
11 |
|||
12 |
/**************************************************************************/ |
||
13 |
/**************************************************************************/ |
||
14 |
/** */ |
||
15 |
/** GUIX Component */ |
||
16 |
/** */ |
||
17 |
/** Display Management (Display) */ |
||
18 |
/** */ |
||
19 |
/**************************************************************************/ |
||
20 |
|||
21 |
#define GX_SOURCE_CODE |
||
22 |
|||
23 |
|||
24 |
/* Include necessary system files. */ |
||
25 |
|||
26 |
#include "gx_api.h" |
||
27 |
#include "gx_system.h" |
||
28 |
#include "gx_utility.h" |
||
29 |
#include "gx_display.h" |
||
30 |
#include "gx_canvas.h" |
||
31 |
|||
32 |
#if defined(GX_ARC_DRAWING_SUPPORT) |
||
33 |
|||
34 |
/**************************************************************************/ |
||
35 |
/* */ |
||
36 |
/* FUNCTION RELEASE */ |
||
37 |
/* */ |
||
38 |
/* _gx_display_driver_generic_simple_aliased_wide_arc_draw */ |
||
39 |
/* PORTABLE C */ |
||
40 |
/* 6.1 */ |
||
41 |
/* AUTHOR */ |
||
42 |
/* */ |
||
43 |
/* Kenneth Maxwell, Microsoft Corporation */ |
||
44 |
/* */ |
||
45 |
/* DESCRIPTION */ |
||
46 |
/* */ |
||
47 |
/* Innner help function that draw an aliased wide arc between [90, 180]*/ |
||
48 |
/* or [270, 540]. */ |
||
49 |
/* */ |
||
50 |
/* INPUT */ |
||
51 |
/* */ |
||
52 |
/* context Drawing context */ |
||
53 |
/* xcenter curx-coord of center of circle*/ |
||
54 |
/* ycenter cury-coord of center of circle*/ |
||
55 |
/* r Radius of circle */ |
||
56 |
/* */ |
||
57 |
/* OUTPUT */ |
||
58 |
/* */ |
||
59 |
/* None */ |
||
60 |
/* */ |
||
61 |
/* CALLS */ |
||
62 |
/* */ |
||
63 |
/* [gx_display_driver_pixel_blend] Basic display driver pixel */ |
||
64 |
/* blend function */ |
||
65 |
/* _gx_display_driver_arc_clipping_get Get an arc clipping. */ |
||
66 |
/* _gx_utility_rectangle_point_detect Detect whether a pixel is */ |
||
67 |
/* inside rectangle */ |
||
68 |
/* _gx_utility_circle_point_get Get point coord on a circle */ |
||
69 |
/* [gx_display_driver_horizontal_line_draw] */ |
||
70 |
/* Basic display driver */ |
||
71 |
/* horizontal line draw routine*/ |
||
72 |
/* */ |
||
73 |
/* CALLED BY */ |
||
74 |
/* */ |
||
75 |
/* _gx_display_driver_generic_aliased_wide_arc_draw */ |
||
76 |
/* */ |
||
77 |
/* RELEASE HISTORY */ |
||
78 |
/* */ |
||
79 |
/* DATE NAME DESCRIPTION */ |
||
80 |
/* */ |
||
81 |
/* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */ |
||
82 |
/* 09-30-2020 Kenneth Maxwell Modified comment(s), */ |
||
83 |
/* resulting in version 6.1 */ |
||
84 |
/* */ |
||
85 |
/**************************************************************************/ |
||
86 |
10243 |
static VOID _gx_display_driver_generic_simple_aliased_wide_arc_draw(GX_DRAW_CONTEXT *context, INT xcenter, INT ycenter, UINT r, INT start_angle, INT end_angle) |
|
87 |
{ |
||
88 |
/* The function draw a wide arc between 90 and 270 or beween 270 and 450.*/ |
||
89 |
GX_DISPLAY *display; |
||
90 |
GX_BRUSH *brush; |
||
91 |
GX_RECTANGLE *clip; |
||
92 |
GX_RECTANGLE arc_clip[4]; |
||
93 |
GX_POINT point; |
||
94 |
GX_POINT inner_start; |
||
95 |
GX_POINT inner_end; |
||
96 |
GX_POINT outer_start; |
||
97 |
GX_POINT outer_end; |
||
98 |
10243 |
INT sign[4][2] = {{1, 1}, {-1, 1}, {1, -1}, {-1, -1}}; |
|
99 |
INT *pLineEnds; |
||
100 |
INT ymin; |
||
101 |
INT ymax; |
||
102 |
INT xstart; |
||
103 |
INT xend; |
||
104 |
INT ystart; |
||
105 |
INT yend; |
||
106 |
INT curx; |
||
107 |
INT cury; |
||
108 |
INT nextx; |
||
109 |
INT nexty; |
||
110 |
INT dx; |
||
111 |
INT dy; |
||
112 |
INT Index; |
||
113 |
INT Index1; |
||
114 |
INT loop; |
||
115 |
INT height; |
||
116 |
INT xsign; |
||
117 |
INT ysign; |
||
118 |
INT error; |
||
119 |
INT decision; |
||
120 |
INT brush_width; |
||
121 |
GX_UBYTE alpha1; |
||
122 |
GX_UBYTE alpha2; |
||
123 |
VOID (*blend_func)(GX_DRAW_CONTEXT *, INT, INT, GX_COLOR, GX_UBYTE); |
||
124 |
10243 |
GX_BOOL right = GX_TRUE; |
|
125 |
INT test; |
||
126 |
INT cur_shift; |
||
127 |
INT next_shift; |
||
128 |
|||
129 |
✓✓✓✓ |
10243 |
if ((start_angle >= 90) && |
130 |
✓✓ | 7087 |
(start_angle <= 270) && |
131 |
(end_angle <= 270)) |
||
132 |
{ |
||
133 |
3738 |
right = GX_FALSE; |
|
134 |
} |
||
135 |
|||
136 |
10243 |
display = context -> gx_draw_context_display; |
|
137 |
10243 |
brush = &context -> gx_draw_context_brush; |
|
138 |
10243 |
brush_width = brush -> gx_brush_width; |
|
139 |
10243 |
blend_func = display -> gx_display_driver_pixel_blend; |
|
140 |
|||
141 |
✓✓ | 10243 |
if (blend_func == GX_NULL) |
142 |
{ |
||
143 |
50 |
return; |
|
144 |
} |
||
145 |
|||
146 |
10241 |
clip = context -> gx_draw_context_clip; |
|
147 |
10241 |
pLineEnds = _gx_system_scratchpad; |
|
148 |
|||
149 |
✓✓ | 10241 |
if (r <= (UINT)((brush_width - 1) >> 1)) |
150 |
{ |
||
151 |
48 |
return; |
|
152 |
} |
||
153 |
|||
154 |
/* Calculate the ridius of the inner circle. */ |
||
155 |
10193 |
r = (UINT)(r - (UINT)((brush_width - 1) >> 1)); |
|
156 |
|||
157 |
/* Get end points. */ |
||
158 |
10193 |
_gx_utility_circle_point_get(xcenter, ycenter, r, start_angle, &inner_start); |
|
159 |
10193 |
_gx_utility_circle_point_get(xcenter, ycenter, r, end_angle, &inner_end); |
|
160 |
10193 |
_gx_utility_circle_point_get(xcenter, ycenter, (UINT)(r + (UINT)brush_width - 1), start_angle, &outer_start); |
|
161 |
10193 |
_gx_utility_circle_point_get(xcenter, ycenter, (UINT)(r + (UINT)brush_width - 1), end_angle, &outer_end); |
|
162 |
|||
163 |
10193 |
ymin = ycenter - (INT)r - brush_width + 1; |
|
164 |
10193 |
ymax = ycenter + (INT)r + brush_width - 1; |
|
165 |
|||
166 |
✓✓✓✓ ✓✓ |
10193 |
if (((start_angle < 90) && (end_angle < 90)) || |
167 |
✓✓ | 6634 |
((start_angle > 90) && (end_angle < 450))) |
168 |
{ |
||
169 |
✓✓ | 3971 |
if (outer_start.gx_point_y < outer_end.gx_point_y) |
170 |
{ |
||
171 |
3016 |
ymin = outer_start.gx_point_y; |
|
172 |
} |
||
173 |
else |
||
174 |
{ |
||
175 |
955 |
ymin = outer_end.gx_point_y; |
|
176 |
} |
||
177 |
|||
178 |
✓✓ | 3971 |
if (inner_start.gx_point_y < ymin) |
179 |
{ |
||
180 |
387 |
ymin = inner_start.gx_point_y; |
|
181 |
} |
||
182 |
|||
183 |
✓✓ | 3971 |
if (inner_end.gx_point_y < ymin) |
184 |
{ |
||
185 |
401 |
ymin = inner_end.gx_point_y; |
|
186 |
} |
||
187 |
} |
||
188 |
|||
189 |
✓✓ | 10193 |
if (clip -> gx_rectangle_top > ymin) |
190 |
{ |
||
191 |
37 |
ymin = clip -> gx_rectangle_top; |
|
192 |
} |
||
193 |
|||
194 |
/* Calculate maximum y line. */ |
||
195 |
✓✓✓✓ ✓✓ |
10193 |
if (((start_angle < 270) && (end_angle < 270)) || (start_angle > 270)) |
196 |
{ |
||
197 |
✓✓ | 4094 |
if (outer_start.gx_point_y > outer_end.gx_point_y) |
198 |
{ |
||
199 |
3156 |
ymax = outer_start.gx_point_y; |
|
200 |
} |
||
201 |
else |
||
202 |
{ |
||
203 |
938 |
ymax = outer_end.gx_point_y; |
|
204 |
} |
||
205 |
|||
206 |
✓✓ | 4094 |
if (inner_start.gx_point_y > ymax) |
207 |
{ |
||
208 |
2737 |
ymax = inner_start.gx_point_y; |
|
209 |
} |
||
210 |
|||
211 |
✓✓ | 4094 |
if (inner_end.gx_point_y > ymax) |
212 |
{ |
||
213 |
350 |
ymax = inner_end.gx_point_y; |
|
214 |
} |
||
215 |
} |
||
216 |
|||
217 |
✓✓ | 10193 |
if (clip -> gx_rectangle_bottom < ymax) |
218 |
{ |
||
219 |
33 |
ymax = clip -> gx_rectangle_bottom; |
|
220 |
} |
||
221 |
|||
222 |
10193 |
height = ymax - ymin + 1; |
|
223 |
|||
224 |
/* default the point array to being off the screen on both sides: */ |
||
225 |
|||
226 |
✓✓ | 597993 |
for (loop = 0; loop < height * 2; loop += 2) |
227 |
{ |
||
228 |
587800 |
pLineEnds[loop] = 2000; |
|
229 |
587800 |
pLineEnds[loop + 1] = 0; |
|
230 |
} |
||
231 |
|||
232 |
/* Get point array of inner arc and outer arc. */ |
||
233 |
✓✓ | 30579 |
for (Index1 = 0; Index1 < 2; Index1++) |
234 |
{ |
||
235 |
✓✓ | 20386 |
if (Index1 == 1) |
236 |
{ |
||
237 |
10193 |
r += (UINT)(brush_width - 1); |
|
238 |
} |
||
239 |
|||
240 |
20386 |
_gx_display_driver_arc_clipping_get(xcenter, ycenter, r, start_angle, end_angle, |
|
241 |
&arc_clip[0], &arc_clip[1], &arc_clip[2], &arc_clip[3]); |
||
242 |
|||
243 |
20386 |
curx = 0; |
|
244 |
20386 |
cury = (INT)r; |
|
245 |
20386 |
error = 0; |
|
246 |
|||
247 |
✓✓ | 795945 |
while (curx < cury) |
248 |
{ |
||
249 |
775559 |
alpha1 = (GX_UBYTE)(255 - error); |
|
250 |
775559 |
alpha2 = (GX_UBYTE)error; |
|
251 |
|||
252 |
✓✓ | 3877795 |
for (loop = 0; loop < 4; loop++) |
253 |
{ |
||
254 |
3102236 |
point.gx_point_x = (GX_VALUE)(curx * sign[loop][0] + xcenter); |
|
255 |
3102236 |
point.gx_point_y = (GX_VALUE)(cury * sign[loop][1] + ycenter); |
|
256 |
|||
257 |
✓✓✓✓ |
5589351 |
if ((_gx_utility_rectangle_point_detect(&arc_clip[0], point) || |
258 |
✓✓ | 3311234 |
_gx_utility_rectangle_point_detect(&arc_clip[1], point)) && |
259 |
824119 |
_gx_utility_rectangle_point_detect(clip, point)) |
|
260 |
{ |
||
261 |
/* Draw point(curx, cury). */ |
||
262 |
776167 |
blend_func(context, point.gx_point_x, point.gx_point_y, brush -> gx_brush_line_color, alpha1); |
|
263 |
} |
||
264 |
|||
265 |
3102236 |
point.gx_point_y = (GX_VALUE)((cury - 1) * sign[loop][1] + ycenter); |
|
266 |
|||
267 |
✓✓✓✓ |
5589705 |
if ((_gx_utility_rectangle_point_detect(&arc_clip[0], point) || |
268 |
✓✓ | 3311728 |
_gx_utility_rectangle_point_detect(&arc_clip[1], point)) && |
269 |
824259 |
_gx_utility_rectangle_point_detect(clip, point)) |
|
270 |
{ |
||
271 |
776393 |
blend_func(context, point.gx_point_x, point.gx_point_y, brush -> gx_brush_line_color, (GX_UBYTE)alpha2); |
|
272 |
} |
||
273 |
|||
274 |
3102236 |
point.gx_point_x = (GX_VALUE)(cury * sign[loop][0] + xcenter); |
|
275 |
3102236 |
point.gx_point_y = (GX_VALUE)(curx * sign[loop][1] + ycenter); |
|
276 |
|||
277 |
✓✓✓✓ |
5694312 |
if ((_gx_utility_rectangle_point_detect(&arc_clip[0], point) || |
278 |
✓✓ | 3370133 |
_gx_utility_rectangle_point_detect(&arc_clip[1], point)) && |
279 |
778057 |
_gx_utility_rectangle_point_detect(clip, point)) |
|
280 |
{ |
||
281 |
/* Draw point(cury, curx). */ |
||
282 |
738823 |
blend_func(context, point.gx_point_x, point.gx_point_y, brush -> gx_brush_line_color, alpha1); |
|
283 |
} |
||
284 |
|||
285 |
✓✓✓✓ |
3102236 |
if ((point.gx_point_y >= ymin) && (point.gx_point_y <= ymax)) |
286 |
{ |
||
287 |
✓✓✓✓ |
2572185 |
if (_gx_utility_rectangle_point_detect(&arc_clip[0], point) || |
288 |
1038259 |
_gx_utility_rectangle_point_detect(&arc_clip[1], point)) |
|
289 |
{ |
||
290 |
756529 |
Index = (point.gx_point_y - ymin) << 1; |
|
291 |
|||
292 |
✓✓ | 756529 |
if (right) |
293 |
{ |
||
294 |
✓✓ | 448249 |
if (Index1 == 0) |
295 |
{ |
||
296 |
202110 |
pLineEnds[Index] = cury * sign[loop][0] + xcenter; |
|
297 |
} |
||
298 |
else |
||
299 |
{ |
||
300 |
246139 |
pLineEnds[Index + 1] = (cury - 1) * sign[loop][0] + xcenter; |
|
301 |
} |
||
302 |
} |
||
303 |
else |
||
304 |
{ |
||
305 |
✓✓ | 308280 |
if (Index1 == 0) |
306 |
{ |
||
307 |
145613 |
pLineEnds[Index + 1] = cury * sign[loop][0] + xcenter; |
|
308 |
} |
||
309 |
else |
||
310 |
{ |
||
311 |
162667 |
pLineEnds[Index] = (cury - 1) * sign[loop][0] + xcenter; |
|
312 |
} |
||
313 |
} |
||
314 |
} |
||
315 |
} |
||
316 |
|||
317 |
3102236 |
point.gx_point_x = (GX_VALUE)((cury - 1) * sign[loop][0] + xcenter); |
|
318 |
|||
319 |
✓✓✓✓ |
5693448 |
if ((_gx_utility_rectangle_point_detect(&arc_clip[0], point) || |
320 |
✓✓ | 3369757 |
_gx_utility_rectangle_point_detect(&arc_clip[1], point)) && |
321 |
778545 |
_gx_utility_rectangle_point_detect(clip, point)) |
|
322 |
{ |
||
323 |
/* Draw point(cury - 1, curx). */ |
||
324 |
739376 |
blend_func(context, point.gx_point_x, point.gx_point_y, brush -> gx_brush_line_color, (GX_UBYTE)alpha2); |
|
325 |
} |
||
326 |
|||
327 |
✓✓✓✓ |
3102236 |
if ((point.gx_point_y >= ymin) && (point.gx_point_y <= ymax)) |
328 |
{ |
||
329 |
✓✓✓✓ |
2571318 |
if (_gx_utility_rectangle_point_detect(&arc_clip[0], point) || |
330 |
1037392 |
_gx_utility_rectangle_point_detect(&arc_clip[1], point)) |
|
331 |
{ |
||
332 |
757020 |
Index = (point.gx_point_y - ymin) << 1; |
|
333 |
|||
334 |
✓✓ | 757020 |
if (right) |
335 |
{ |
||
336 |
✓✓ | 448475 |
if (Index1 == 0) |
337 |
{ |
||
338 |
202218 |
pLineEnds[Index] = cury * sign[loop][0] + xcenter; |
|
339 |
} |
||
340 |
else |
||
341 |
{ |
||
342 |
246257 |
pLineEnds[Index + 1] = (cury - 1) * sign[loop][0] + xcenter; |
|
343 |
} |
||
344 |
} |
||
345 |
else |
||
346 |
{ |
||
347 |
✓✓ | 308545 |
if (Index1 == 0) |
348 |
{ |
||
349 |
145617 |
pLineEnds[Index + 1] = cury * sign[loop][0] + xcenter; |
|
350 |
} |
||
351 |
else |
||
352 |
{ |
||
353 |
162928 |
pLineEnds[Index] = (cury - 1) * sign[loop][0] + xcenter; |
|
354 |
} |
||
355 |
} |
||
356 |
} |
||
357 |
} |
||
358 |
} |
||
359 |
|||
360 |
/* Calculate the distance between mathmatical point to drawing poing, |
||
361 |
which is used to blending pixel. */ |
||
362 |
775559 |
curx++; |
|
363 |
775559 |
nexty = (INT)(r * r) - curx * curx; |
|
364 |
775559 |
error = (cury << 8) - (INT)(_gx_utility_math_sqrt((UINT)(nexty << 10)) << 3); |
|
365 |
|||
366 |
✓✓ | 1092893 |
while (error >= 255) |
367 |
{ |
||
368 |
317334 |
error -= 255; |
|
369 |
317334 |
cury--; |
|
370 |
|||
371 |
✓✓ | 1586670 |
for (loop = 0; loop < 4; loop++) |
372 |
{ |
||
373 |
1269336 |
point.gx_point_x = (GX_VALUE)(curx * sign[loop][0] + xcenter); |
|
374 |
1269336 |
point.gx_point_y = (GX_VALUE)(cury * sign[loop][1] + ycenter); |
|
375 |
|||
376 |
✓✓✓✓ |
1269336 |
if ((point.gx_point_y >= ymin) && (point.gx_point_y <= ymax)) |
377 |
{ |
||
378 |
✓✓✓✓ |
1053822 |
if (_gx_utility_rectangle_point_detect(&arc_clip[0], point) || |
379 |
413398 |
_gx_utility_rectangle_point_detect(&arc_clip[1], point)) |
|
380 |
{ |
||
381 |
309718 |
Index = (point.gx_point_y - ymin) << 1; |
|
382 |
|||
383 |
✓✓ | 309718 |
if (right) |
384 |
{ |
||
385 |
✓✓ | 194124 |
if (Index1 == 0) |
386 |
{ |
||
387 |
86035 |
pLineEnds[Index] = curx * sign[loop][0] + xcenter; |
|
388 |
} |
||
389 |
else |
||
390 |
{ |
||
391 |
108089 |
pLineEnds[Index + 1] = (curx - 1) * sign[loop][0] + xcenter; |
|
392 |
} |
||
393 |
} |
||
394 |
else |
||
395 |
{ |
||
396 |
✓✓ | 115594 |
if (Index1 == 0) |
397 |
{ |
||
398 |
53521 |
pLineEnds[Index + 1] = curx * sign[loop][0] + xcenter; |
|
399 |
} |
||
400 |
else |
||
401 |
{ |
||
402 |
62073 |
pLineEnds[Index] = (curx - 1) * sign[loop][0] + xcenter; |
|
403 |
} |
||
404 |
} |
||
405 |
} |
||
406 |
} |
||
407 |
} |
||
408 |
} |
||
409 |
} |
||
410 |
|||
411 |
20386 |
alpha1 = (GX_UBYTE)(255 - error); |
|
412 |
|||
413 |
✓✓ | 101930 |
for (loop = 0; loop < 4; loop++) |
414 |
{ |
||
415 |
|||
416 |
81544 |
point.gx_point_x = (GX_VALUE)(curx * sign[loop][0] + xcenter); |
|
417 |
81544 |
point.gx_point_y = (GX_VALUE)(cury * sign[loop][1] + ycenter); |
|
418 |
|||
419 |
✓✓✓✓ |
145241 |
if ((_gx_utility_rectangle_point_detect(&arc_clip[0], point) || |
420 |
✓✓ | 88453 |
_gx_utility_rectangle_point_detect(&arc_clip[1], point)) && |
421 |
24756 |
_gx_utility_rectangle_point_detect(clip, point)) |
|
422 |
{ |
||
423 |
24676 |
blend_func(context, point.gx_point_x, point.gx_point_y, brush -> gx_brush_line_color, alpha1); |
|
424 |
} |
||
425 |
} |
||
426 |
} |
||
427 |
|||
428 |
/* Fill in the point array by using Breshenhams line for |
||
429 |
2 lines of the arc end. |
||
430 |
*/ |
||
431 |
|||
432 |
✓✓ | 30579 |
for (loop = 0; loop < 2; loop++) |
433 |
{ |
||
434 |
✓✓ | 20386 |
if (loop == 0) |
435 |
{ |
||
436 |
10193 |
xstart = inner_start.gx_point_x; |
|
437 |
10193 |
ystart = inner_start.gx_point_y; |
|
438 |
10193 |
xend = outer_start.gx_point_x; |
|
439 |
10193 |
yend = outer_start.gx_point_y; |
|
440 |
} |
||
441 |
else |
||
442 |
{ |
||
443 |
10193 |
xstart = inner_end.gx_point_x; |
|
444 |
10193 |
ystart = inner_end.gx_point_y; |
|
445 |
10193 |
xend = outer_end.gx_point_x; |
|
446 |
10193 |
yend = outer_end.gx_point_y; |
|
447 |
} |
||
448 |
|||
449 |
20386 |
dx = GX_ABS(xend - xstart); |
|
450 |
20386 |
dy = GX_ABS(yend - ystart); |
|
451 |
|||
452 |
/* Horizontal Line. */ |
||
453 |
✓✓ | 20386 |
if (ystart == yend) |
454 |
{ |
||
455 |
2814 |
continue; |
|
456 |
} |
||
457 |
|||
458 |
/* Vertical Line. */ |
||
459 |
✓✓ | 17572 |
if (xstart == xend) |
460 |
{ |
||
461 |
✓✓ | 12755 |
if (ystart > yend) |
462 |
{ |
||
463 |
6470 |
GX_SWAP_VALS(xstart, xend); |
|
464 |
6470 |
GX_SWAP_VALS(ystart, yend); |
|
465 |
} |
||
466 |
|||
467 |
✓✓ | 114596 |
for (cury = ystart; cury <= yend; cury++) |
468 |
{ |
||
469 |
✓✓✓✓ |
101841 |
if ((cury >= ymin) && (cury <= ymax)) |
470 |
{ |
||
471 |
101354 |
Index = (cury - ymin) << 1; |
|
472 |
✓✓ | 101354 |
if (xstart <= pLineEnds[Index]) |
473 |
{ |
||
474 |
78741 |
pLineEnds[Index] = xstart; |
|
475 |
} |
||
476 |
|||
477 |
✓✓ | 101354 |
if (xstart > pLineEnds[Index + 1]) |
478 |
{ |
||
479 |
36922 |
pLineEnds[Index + 1] = xstart; |
|
480 |
} |
||
481 |
} |
||
482 |
} |
||
483 |
12755 |
continue; |
|
484 |
} |
||
485 |
|||
486 |
/* Simple Line. */ |
||
487 |
✓✓✓✓ ✓✓ |
4817 |
if (((dx >= dy && (xstart > xend)) || |
488 |
✓✓ | 1162 |
((dy > dx) && ystart > yend))) |
489 |
{ |
||
490 |
1620 |
GX_SWAP_VALS(xend, xstart); |
|
491 |
1620 |
GX_SWAP_VALS(yend, ystart); |
|
492 |
} |
||
493 |
|||
494 |
4817 |
xsign = (xend - xstart) / dx; |
|
495 |
4817 |
ysign = (yend - ystart) / dy; |
|
496 |
|||
497 |
4817 |
cur_shift = 0; |
|
498 |
4817 |
next_shift = 0; |
|
499 |
|||
500 |
✓✓ | 4817 |
if (dx >= dy) |
501 |
{ |
||
502 |
✓✓✓✓ ✓✓ |
3655 |
if ((right && loop == 1) || |
503 |
✓✓ | 918 |
(!right && loop == 0)) |
504 |
{ |
||
505 |
✓✓ | 726 |
if (ysign > 0) |
506 |
{ |
||
507 |
362 |
cur_shift = 1; |
|
508 |
} |
||
509 |
else |
||
510 |
{ |
||
511 |
364 |
next_shift = 1; |
|
512 |
} |
||
513 |
} |
||
514 |
else |
||
515 |
{ |
||
516 |
✓✓ | 2929 |
if (ysign > 0) |
517 |
{ |
||
518 |
312 |
next_shift = -1; |
|
519 |
} |
||
520 |
else |
||
521 |
{ |
||
522 |
2617 |
cur_shift = -1; |
|
523 |
} |
||
524 |
} |
||
525 |
|||
526 |
3655 |
for (curx = xstart, cury = ystart, nextx = xend, nexty = yend, |
|
527 |
✓✓ | 20724 |
decision = 0; curx <= nextx; curx++, nextx--, |
528 |
17069 |
decision += dy) |
|
529 |
{ |
||
530 |
✓✓ | 17069 |
if (decision >= dx) |
531 |
{ |
||
532 |
2661 |
decision -= dx; |
|
533 |
2661 |
cury += ysign; |
|
534 |
2661 |
nexty -= ysign; |
|
535 |
} |
||
536 |
|||
537 |
17069 |
test = cury + cur_shift; |
|
538 |
|||
539 |
✓✓✓✓ |
17069 |
if ((test >= ymin) && (test <= ymax)) |
540 |
{ |
||
541 |
17053 |
Index = (test - ymin) << 1; |
|
542 |
|||
543 |
✓✓ | 17053 |
if (curx < pLineEnds[Index]) |
544 |
{ |
||
545 |
1614 |
pLineEnds[Index] = curx; |
|
546 |
} |
||
547 |
|||
548 |
✓✓ | 17053 |
if (curx > pLineEnds[Index + 1]) |
549 |
{ |
||
550 |
3878 |
pLineEnds[Index + 1] = curx; |
|
551 |
} |
||
552 |
} |
||
553 |
|||
554 |
17069 |
test = nexty + next_shift; |
|
555 |
|||
556 |
✓✓✓✓ |
17069 |
if ((test >= ymin) && (test <= ymax)) |
557 |
{ |
||
558 |
17053 |
Index1 = (test - ymin) << 1; |
|
559 |
|||
560 |
✓✓ | 17053 |
if (nextx < pLineEnds[Index1]) |
561 |
{ |
||
562 |
2827 |
pLineEnds[Index1] = nextx; |
|
563 |
} |
||
564 |
|||
565 |
✓✓ | 17053 |
if (nextx > pLineEnds[Index1 + 1]) |
566 |
{ |
||
567 |
4105 |
pLineEnds[Index1 + 1] = nextx; |
|
568 |
} |
||
569 |
} |
||
570 |
} |
||
571 |
} |
||
572 |
else |
||
573 |
{ |
||
574 |
✓✓✓✓ ✓✓ |
1162 |
if ((right && loop == 1) || |
575 |
✓✓ | 394 |
(!right && loop == 0)) |
576 |
{ |
||
577 |
608 |
next_shift = -xsign; |
|
578 |
} |
||
579 |
else |
||
580 |
{ |
||
581 |
554 |
cur_shift = xsign; |
|
582 |
} |
||
583 |
|||
584 |
1162 |
for (curx = xstart, cury = ystart, nextx = xend, nexty = yend, |
|
585 |
✓✓ | 7861 |
decision = 0; cury <= nexty; cury++, nexty--, |
586 |
6699 |
decision += dx) |
|
587 |
{ |
||
588 |
✓✓ | 6699 |
if (decision >= dy) |
589 |
{ |
||
590 |
1689 |
decision -= dy; |
|
591 |
1689 |
curx += xsign; |
|
592 |
1689 |
nextx -= xsign; |
|
593 |
} |
||
594 |
|||
595 |
✓✓✓✓ |
6699 |
if ((cury >= ymin) && (cury <= ymax)) |
596 |
{ |
||
597 |
|||
598 |
6678 |
Index = (cury - ymin) << 1; |
|
599 |
6678 |
test = curx + cur_shift; |
|
600 |
|||
601 |
✓✓ | 6678 |
if (test < pLineEnds[Index]) |
602 |
{ |
||
603 |
3589 |
pLineEnds[Index] = test; |
|
604 |
} |
||
605 |
|||
606 |
✓✓ | 6678 |
if (test > pLineEnds[Index + 1]) |
607 |
{ |
||
608 |
3873 |
pLineEnds[Index + 1] = test; |
|
609 |
} |
||
610 |
} |
||
611 |
|||
612 |
✓✓✓✓ |
6699 |
if ((nexty >= ymin) && (nexty <= ymax)) |
613 |
{ |
||
614 |
6678 |
Index1 = (nexty - ymin) << 1; |
|
615 |
6678 |
test = nextx + next_shift; |
|
616 |
|||
617 |
✓✓ | 6678 |
if (test < pLineEnds[Index1]) |
618 |
{ |
||
619 |
2894 |
pLineEnds[Index1] = test; |
|
620 |
} |
||
621 |
|||
622 |
✓✓ | 6678 |
if (test > pLineEnds[Index1 + 1]) |
623 |
{ |
||
624 |
3667 |
pLineEnds[Index1 + 1] = test; |
|
625 |
} |
||
626 |
} |
||
627 |
} |
||
628 |
} |
||
629 |
} |
||
630 |
|||
631 |
/* Filling the outline area with horizontal line. */ |
||
632 |
|||
633 |
10193 |
Index = 0; |
|
634 |
✓✓ | 597993 |
for (cury = ymin; cury <= ymax; cury++) |
635 |
{ |
||
636 |
✓✓ | 587800 |
if (pLineEnds[Index] <= pLineEnds[Index + 1]) |
637 |
{ |
||
638 |
✓✓ | 582428 |
if (pLineEnds[Index] < clip -> gx_rectangle_left) |
639 |
{ |
||
640 |
4855 |
pLineEnds[Index] = clip -> gx_rectangle_left; |
|
641 |
} |
||
642 |
|||
643 |
✓✓ | 582428 |
if (pLineEnds[Index + 1] > clip -> gx_rectangle_right) |
644 |
{ |
||
645 |
2980 |
pLineEnds[Index + 1] = clip -> gx_rectangle_right; |
|
646 |
} |
||
647 |
|||
648 |
582428 |
display -> gx_display_driver_horizontal_line_draw(context, pLineEnds[Index], pLineEnds[Index + 1], cury, 1, |
|
649 |
brush -> gx_brush_line_color); |
||
650 |
} |
||
651 |
587800 |
Index += 2; |
|
652 |
} |
||
653 |
} |
||
654 |
|||
655 |
/**************************************************************************/ |
||
656 |
/* */ |
||
657 |
/* FUNCTION RELEASE */ |
||
658 |
/* */ |
||
659 |
/* _gx_display_driver_generic_aliased_wide_arc_draw PORTABLE C */ |
||
660 |
/* 6.1 */ |
||
661 |
/* AUTHOR */ |
||
662 |
/* */ |
||
663 |
/* Kenneth Maxwell, Microsoft Corporation */ |
||
664 |
/* */ |
||
665 |
/* DESCRIPTION */ |
||
666 |
/* */ |
||
667 |
/* Display driver function to draw wide anti-aliased circular arc. */ |
||
668 |
/* */ |
||
669 |
/* INPUT */ |
||
670 |
/* */ |
||
671 |
/* context Drawing context */ |
||
672 |
/* xcenter curx-coord of center of circle */ |
||
673 |
/* ycenter cury-coord of center of circle */ |
||
674 |
/* r Radius of circle */ |
||
675 |
/* */ |
||
676 |
/* OUTPUT */ |
||
677 |
/* */ |
||
678 |
/* None */ |
||
679 |
/* */ |
||
680 |
/* CALLS */ |
||
681 |
/* */ |
||
682 |
/* [gx_display_driver_generic_simple_wide_arc_draw] */ |
||
683 |
/* Real display driver wide arc */ |
||
684 |
/* draw function */ |
||
685 |
/* _gx_utility_circle_point_get Get point coord on a circle */ |
||
686 |
/* _gx_canvas_circle_draw Draw circle into a canvas */ |
||
687 |
/* [gx_display_driver_anti_aliased_line_draw] */ |
||
688 |
/* Basic driver-level aliased */ |
||
689 |
/* line draw function */ |
||
690 |
/* */ |
||
691 |
/* CALLED BY */ |
||
692 |
/* */ |
||
693 |
/* GUIX Internal Code */ |
||
694 |
/* */ |
||
695 |
/* RELEASE HISTORY */ |
||
696 |
/* */ |
||
697 |
/* DATE NAME DESCRIPTION */ |
||
698 |
/* */ |
||
699 |
/* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */ |
||
700 |
/* 09-30-2020 Kenneth Maxwell Modified comment(s), */ |
||
701 |
/* resulting in version 6.1 */ |
||
702 |
/* */ |
||
703 |
/**************************************************************************/ |
||
704 |
6794 |
VOID _gx_display_driver_generic_aliased_wide_arc_draw(GX_DRAW_CONTEXT *context, INT xcenter, INT ycenter, UINT r, INT start_angle, INT end_angle) |
|
705 |
{ |
||
706 |
GX_BRUSH *brush; |
||
707 |
INT brush_width; |
||
708 |
GX_POINT startp; |
||
709 |
GX_POINT endp; |
||
710 |
GX_DISPLAY *display; |
||
711 |
GX_COLOR old_fill; |
||
712 |
UINT old_style; |
||
713 |
|||
714 |
#if defined(GX_BRUSH_ALPHA_SUPPORT) |
||
715 |
GX_UBYTE old_alpha; |
||
716 |
|||
717 |
6794 |
old_alpha = context -> gx_draw_context_brush.gx_brush_alpha; |
|
718 |
6794 |
context -> gx_draw_context_brush.gx_brush_alpha = GX_ALPHA_VALUE_OPAQUE; |
|
719 |
#endif |
||
720 |
|||
721 |
6794 |
brush = &context -> gx_draw_context_brush; |
|
722 |
6794 |
brush_width = brush -> gx_brush_width; |
|
723 |
6794 |
display = context -> gx_draw_context_display; |
|
724 |
|||
725 |
✓✓ | 6794 |
if (start_angle < 90) |
726 |
{ |
||
727 |
✓✓ | 2838 |
if (end_angle <= 90) |
728 |
{ |
||
729 |
2305 |
_gx_display_driver_generic_simple_aliased_wide_arc_draw(context, xcenter, ycenter, r, start_angle, end_angle); |
|
730 |
} |
||
731 |
✓✓ | 533 |
else if (end_angle <= 270) |
732 |
{ |
||
733 |
399 |
_gx_display_driver_generic_simple_aliased_wide_arc_draw(context, xcenter, ycenter, r, start_angle, 90); |
|
734 |
399 |
_gx_display_driver_generic_simple_aliased_wide_arc_draw(context, xcenter, ycenter, r, 90, end_angle); |
|
735 |
} |
||
736 |
else |
||
737 |
{ |
||
738 |
134 |
_gx_display_driver_generic_simple_aliased_wide_arc_draw(context, xcenter, ycenter, r, start_angle, 90); |
|
739 |
134 |
_gx_display_driver_generic_simple_aliased_wide_arc_draw(context, xcenter, ycenter, r, 90, 270); |
|
740 |
134 |
_gx_display_driver_generic_simple_aliased_wide_arc_draw(context, xcenter, ycenter, r, 270, end_angle); |
|
741 |
} |
||
742 |
} |
||
743 |
✓✓ | 3956 |
else if (start_angle < 270) |
744 |
{ |
||
745 |
✓✓ | 3067 |
if (end_angle <= 270) |
746 |
{ |
||
747 |
453 |
_gx_display_driver_generic_simple_aliased_wide_arc_draw(context, xcenter, ycenter, r, start_angle, end_angle); |
|
748 |
} |
||
749 |
✓✓ | 2614 |
else if (end_angle <= 450) |
750 |
{ |
||
751 |
2533 |
_gx_display_driver_generic_simple_aliased_wide_arc_draw(context, xcenter, ycenter, r, start_angle, 270); |
|
752 |
2533 |
_gx_display_driver_generic_simple_aliased_wide_arc_draw(context, xcenter, ycenter, r, 270, end_angle); |
|
753 |
} |
||
754 |
else |
||
755 |
{ |
||
756 |
81 |
_gx_display_driver_generic_simple_aliased_wide_arc_draw(context, xcenter, ycenter, r, start_angle, 270); |
|
757 |
81 |
_gx_display_driver_generic_simple_aliased_wide_arc_draw(context, xcenter, ycenter, r, 270, 450); |
|
758 |
81 |
_gx_display_driver_generic_simple_aliased_wide_arc_draw(context, xcenter, ycenter, r, 90, end_angle - 360); |
|
759 |
} |
||
760 |
} |
||
761 |
else |
||
762 |
{ |
||
763 |
✓✓ | 889 |
if (end_angle <= 450) |
764 |
{ |
||
765 |
832 |
_gx_display_driver_generic_simple_aliased_wide_arc_draw(context, xcenter, ycenter, r, start_angle, end_angle); |
|
766 |
} |
||
767 |
✓✓ | 57 |
else if (end_angle <= 630) |
768 |
{ |
||
769 |
27 |
_gx_display_driver_generic_simple_aliased_wide_arc_draw(context, xcenter, ycenter, r, start_angle, 450); |
|
770 |
27 |
_gx_display_driver_generic_simple_aliased_wide_arc_draw(context, xcenter, ycenter, r, 90, end_angle - 360); |
|
771 |
} |
||
772 |
else |
||
773 |
{ |
||
774 |
30 |
_gx_display_driver_generic_simple_aliased_wide_arc_draw(context, xcenter, ycenter, r, start_angle, 450); |
|
775 |
30 |
_gx_display_driver_generic_simple_aliased_wide_arc_draw(context, xcenter, ycenter, r, 90, 270); |
|
776 |
30 |
_gx_display_driver_generic_simple_aliased_wide_arc_draw(context, xcenter, ycenter, r, 270, end_angle - 360); |
|
777 |
} |
||
778 |
} |
||
779 |
|||
780 |
6794 |
old_fill = brush -> gx_brush_fill_color; |
|
781 |
6794 |
old_style = brush -> gx_brush_style; |
|
782 |
|||
783 |
6794 |
brush -> gx_brush_width = 1; |
|
784 |
6794 |
brush -> gx_brush_fill_color = brush -> gx_brush_line_color; |
|
785 |
6794 |
brush -> gx_brush_style |= GX_BRUSH_SOLID_FILL; |
|
786 |
|||
787 |
6794 |
r = (UINT)(r - (UINT)((brush_width - 1) >> 1)); |
|
788 |
6794 |
_gx_utility_circle_point_get(xcenter, ycenter, r, start_angle, &startp); |
|
789 |
6794 |
_gx_utility_circle_point_get(xcenter, ycenter, r + (UINT)brush_width - 1, start_angle, &endp); |
|
790 |
|||
791 |
✓✓ | 6794 |
if (brush -> gx_brush_style & GX_BRUSH_ROUND) |
792 |
{ |
||
793 |
6379 |
brush -> gx_brush_style &= (ULONG)(~GX_BRUSH_PIXELMAP_FILL); |
|
794 |
|||
795 |
6379 |
_gx_display_driver_generic_aliased_filled_circle_draw(context, |
|
796 |
6379 |
GX_FIXED_VAL_MAKE(startp.gx_point_x + endp.gx_point_x) >> 1, |
|
797 |
6379 |
GX_FIXED_VAL_MAKE(startp.gx_point_y + endp.gx_point_y) >> 1, |
|
798 |
6379 |
GX_FIXED_VAL_MAKE(brush_width) >> 1); |
|
799 |
} |
||
800 |
else |
||
801 |
{ |
||
802 |
415 |
display -> gx_display_driver_anti_aliased_line_draw(context, |
|
803 |
415 |
startp.gx_point_x, |
|
804 |
415 |
startp.gx_point_y, |
|
805 |
415 |
endp.gx_point_x, |
|
806 |
415 |
endp.gx_point_y); |
|
807 |
} |
||
808 |
|||
809 |
6794 |
_gx_utility_circle_point_get(xcenter, ycenter, r, end_angle, &startp); |
|
810 |
6794 |
_gx_utility_circle_point_get(xcenter, ycenter, r + (UINT)brush_width - 1, end_angle, &endp); |
|
811 |
|||
812 |
✓✓ | 6794 |
if (brush -> gx_brush_style & GX_BRUSH_ROUND) |
813 |
{ |
||
814 |
6379 |
brush -> gx_brush_style &= (ULONG)(~GX_BRUSH_PIXELMAP_FILL); |
|
815 |
|||
816 |
6379 |
_gx_display_driver_generic_aliased_filled_circle_draw(context, |
|
817 |
6379 |
GX_FIXED_VAL_MAKE(startp.gx_point_x + endp.gx_point_x) >> 1, |
|
818 |
6379 |
GX_FIXED_VAL_MAKE(startp.gx_point_y + endp.gx_point_y) >> 1, |
|
819 |
6379 |
GX_FIXED_VAL_MAKE(brush_width) >> 1); |
|
820 |
} |
||
821 |
else |
||
822 |
{ |
||
823 |
415 |
display -> gx_display_driver_anti_aliased_line_draw(context, |
|
824 |
415 |
startp.gx_point_x, |
|
825 |
415 |
startp.gx_point_y, |
|
826 |
415 |
endp.gx_point_x, |
|
827 |
415 |
endp.gx_point_y); |
|
828 |
} |
||
829 |
|||
830 |
6794 |
brush -> gx_brush_width = (GX_VALUE)brush_width; |
|
831 |
6794 |
brush -> gx_brush_fill_color = old_fill; |
|
832 |
6794 |
brush -> gx_brush_style = old_style; |
|
833 |
|||
834 |
#if defined(GX_BRUSH_ALPHA_SUPPORT) |
||
835 |
6794 |
context -> gx_draw_context_brush.gx_brush_alpha = old_alpha; |
|
836 |
#endif |
||
837 |
6794 |
} |
|
838 |
#endif |
||
839 |
Generated by: GCOVR (Version 4.1) |