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
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _gx_display_driver_generic_circle_draw PORTABLE C */
37 /* 6.1 */
38 /* AUTHOR */
39 /* */
40 /* Kenneth Maxwell, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* Display driver to draw circle. */
45 /* */
46 /* INPUT */
47 /* */
48 /* context Drawing context */
49 /* xcenter x-coord of center of circle */
50 /* ycenter y-coord of center of circle */
51 /* r Radius of circle */
52 /* */
53 /* OUTPUT */
54 /* */
55 /* None */
56 /* */
57 /* CALLS */
58 /* */
59 /* [gx_display_driver_pixel_blend] Basic display driver pixel */
60 /* blend function */
61 /* _gx_utility_rectangle_point_detect Detect whether a pixel is */
62 /* inside rectangle */
63 /* [gx_display_driver_pixel_write] Basic display driver pixel */
64 /* write function */
65 /* */
66 /* CALLED BY */
67 /* */
68 /* GUIX Internal Code */
69 /* */
70 /* RELEASE HISTORY */
71 /* */
72 /* DATE NAME DESCRIPTION */
73 /* */
74 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
75 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
76 /* resulting in version 6.1 */
77 /* */
78 /**************************************************************************/
79 #if defined(GX_ARC_DRAWING_SUPPORT)
80
_gx_display_driver_generic_circle_draw(GX_DRAW_CONTEXT * context,INT xcenter,INT ycenter,UINT r)81 VOID _gx_display_driver_generic_circle_draw(GX_DRAW_CONTEXT *context, INT xcenter, INT ycenter, UINT r)
82 {
83 /* The circle draw function is implemented from midpoint circle algorithm. */
84 INT x;
85 INT y;
86 INT d;
87 GX_POINT point;
88 INT sign[4][2] = { {1, 1}, {-1, 1}, {1, -1}, {-1, -1} };
89 INT index;
90
91 GX_RECTANGLE *clip = context -> gx_draw_context_clip;
92 GX_DISPLAY *display = context -> gx_draw_context_display;
93 GX_BRUSH *brush = &context -> gx_draw_context_brush;
94
95 #if defined(GX_BRUSH_ALPHA_SUPPORT)
96 GX_UBYTE brush_alpha = brush -> gx_brush_alpha;
97
98 if (display -> gx_display_driver_pixel_blend == GX_NULL)
99 {
100 /* Pixel blend function is null means alpha isn't supported in this driver.
101 So set alpha value to 0xff to make it draw the original color in case GX_BRUSH_ALPHA_SUPPORT is defined. */
102 brush_alpha = 0xff;
103 }
104 else
105 {
106 if (brush_alpha == 0)
107 {
108 /* Nothing to draw here. */
109 return;
110 }
111 }
112 #endif
113
114 x = 0;
115 y = (INT)r;
116 d = 5 - (INT)(4 * r);
117 #if defined (GX_BRUSH_ALPHA_SUPPORT)
118 if (brush_alpha != 0xff)
119 {
120 while (x <= y)
121 {
122 for (index = 0; index < 4; index++)
123 {
124 point.gx_point_x = (GX_VALUE)(x * sign[index][0] + xcenter);
125 point.gx_point_y = (GX_VALUE)(y * sign[index][1] + ycenter);
126
127 if (_gx_utility_rectangle_point_detect(clip, point))
128 {
129 display -> gx_display_driver_pixel_blend(context, point.gx_point_x, point.gx_point_y, brush -> gx_brush_line_color, brush_alpha);
130 }
131
132 point.gx_point_x = (GX_VALUE)(y * sign[index][0] + xcenter);
133 point.gx_point_y = (GX_VALUE)(x * sign[index][1] + ycenter);
134
135 if (_gx_utility_rectangle_point_detect(clip, point))
136 {
137 display -> gx_display_driver_pixel_blend(context, point.gx_point_x, point.gx_point_y, brush -> gx_brush_line_color, brush_alpha);
138 }
139 }
140
141 if (d < 0)
142 {
143 d += 8 * x + 12;
144 }
145 else
146 {
147 d += 8 * (x - y) + 20;
148 y--;
149 }
150 x++;
151 }
152 }
153 else
154 {
155 #endif
156 while (x <= y)
157 {
158 for (index = 0; index < 4; index++)
159 {
160 point.gx_point_x = (GX_VALUE)(x * sign[index][0] + xcenter);
161 point.gx_point_y = (GX_VALUE)(y * sign[index][1] + ycenter);
162
163 if (_gx_utility_rectangle_point_detect(clip, point))
164 {
165 display -> gx_display_driver_pixel_write(context, point.gx_point_x, point.gx_point_y, brush -> gx_brush_line_color);
166 }
167
168 point.gx_point_x = (GX_VALUE)(y * sign[index][0] + xcenter);
169 point.gx_point_y = (GX_VALUE)(x * sign[index][1] + ycenter);
170
171 if (_gx_utility_rectangle_point_detect(clip, point))
172 {
173 display -> gx_display_driver_pixel_write(context, point.gx_point_x, point.gx_point_y, brush -> gx_brush_line_color);
174 }
175 }
176
177 if (d < 0)
178 {
179 d += 8 * x + 12;
180 }
181 else
182 {
183 d += 8 * (x - y) + 20;
184 y--;
185 }
186 x++;
187 }
188 #if defined (GX_BRUSH_ALPHA_SUPPORT)
189 }
190 #endif
191 }
192
193 #endif
194
195