1 /**************************************************************************/
2 /*                                                                        */
3 /*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4 /*                                                                        */
5 /*       This software is licensed under the Microsoft Software License   */
6 /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7 /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8 /*       and in the root directory of this software.                      */
9 /*                                                                        */
10 /**************************************************************************/
11 
12 
13 /**************************************************************************/
14 /**************************************************************************/
15 /**                                                                       */
16 /** GUIX Component                                                        */
17 /**                                                                       */
18 /**   Display Management (Display)                                        */
19 /**                                                                       */
20 /**************************************************************************/
21 
22 #define GX_SOURCE_CODE
23 
24 
25 /* Include necessary system files.  */
26 
27 #include "gx_api.h"
28 #include "gx_display.h"
29 
30 
31 /**************************************************************************/
32 /*                                                                        */
33 /*  FUNCTION                                               RELEASE        */
34 /*                                                                        */
35 /*    _gx_display_driver_generic_filled_circle_draw       PORTABLE C      */
36 /*                                                           6.1          */
37 /*  AUTHOR                                                                */
38 /*                                                                        */
39 /*    Kenneth Maxwell, Microsoft Corporation                              */
40 /*                                                                        */
41 /*  DESCRIPTION                                                           */
42 /*                                                                        */
43 /*    Display driver to draw filled circals.                              */
44 /*                                                                        */
45 /*  INPUT                                                                 */
46 /*                                                                        */
47 /*    context                               Drawing context               */
48 /*    xcenter                               x-coord of center of circle   */
49 /*    ycenter                               y-coord of center of circle   */
50 /*    r                                     Radius of circle              */
51 /*                                                                        */
52 /*  OUTPUT                                                                */
53 /*                                                                        */
54 /*    None                                                                */
55 /*                                                                        */
56 /*  CALLS                                                                 */
57 /*                                                                        */
58 /*    [gx_display_driver_horizontal_line_draw]                            */
59 /*                                          Driver-level horizontal line  */
60 /*                                            draw function               */
61 /*                                                                        */
62 /*  CALLED BY                                                             */
63 /*                                                                        */
64 /*    _gx_display_driver_generic_simple_wide_line_draw                    */
65 /*                                                                        */
66 /*  RELEASE HISTORY                                                       */
67 /*                                                                        */
68 /*    DATE              NAME                      DESCRIPTION             */
69 /*                                                                        */
70 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
71 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
72 /*                                            resulting in version 6.1    */
73 /*                                                                        */
74 /**************************************************************************/
_gx_display_driver_generic_filled_circle_draw(GX_DRAW_CONTEXT * context,GX_FIXED_VAL xcenter,GX_FIXED_VAL ycenter,GX_FIXED_VAL r)75 VOID _gx_display_driver_generic_filled_circle_draw(GX_DRAW_CONTEXT *context, GX_FIXED_VAL xcenter, GX_FIXED_VAL ycenter, GX_FIXED_VAL r)
76 {
77 /* The circle draw function is implemented from midpoint circle algorithm. */
78 
79 GX_DISPLAY   *display;
80 GX_RECTANGLE *clip;
81 GX_BRUSH     *brush;
82 INT           x;
83 INT           y;
84 GX_BYTE       ysign[2] = {1, -1};
85 INT           index;
86 INT           yi;
87 GX_VALUE      xstart;
88 GX_VALUE      xend;
89 GX_FIXED_VAL  xfraction;
90 GX_FIXED_VAL  yfraction;
91 INT           decision;
92 INT           half_shift;
93 
94     display = context -> gx_draw_context_display;
95     clip = context -> gx_draw_context_clip;
96     brush = &context -> gx_draw_context_brush;
97 
98     xfraction = (xcenter & GX_FIXED_VAL_FRACTION_MASK);
99     yfraction = (ycenter & GX_FIXED_VAL_FRACTION_MASK);
100 
101     r -= GX_FIXED_VAL_HALF;
102 
103     if (xfraction)
104     {
105         x = GX_FIXED_VAL_ONE - xfraction;
106     }
107     else
108     {
109         x = 0;
110     }
111     y = GX_FIXED_VAL_RND_UP(r + yfraction);
112     y = GX_FIXED_VAL_MAKE(y) - yfraction;
113 
114     half_shift = GX_FIXED_VAL_SHIFT >> 1;
115 
116     if ((x == 0) && (y == r))
117     {
118         decision = 256 - r;
119     }
120     else
121     {
122         decision = (x >> half_shift) * (x >> half_shift);
123         decision += ((y - GX_FIXED_VAL_HALF) >> half_shift) * ((y - GX_FIXED_VAL_HALF) >> half_shift);
124         decision -= ((r >> half_shift) * (r >> half_shift));
125     }
126 
127     while (1)
128     {
129         if (decision < 0)
130         {
131             decision += 2 * x + GX_FIXED_VAL_ONE;
132         }
133         else
134         {
135             decision += 2 * (x - y) + GX_FIXED_VAL_MAKE(3);
136             y -= GX_FIXED_VAL_ONE;
137         }
138 
139         if (x > y)
140         {
141             break;
142         }
143 
144         for (index = 0; index < 2; index++)
145         {
146             xstart = (GX_VALUE)GX_FIXED_VAL_TO_INT(xcenter - x);
147             xend = (GX_VALUE)GX_FIXED_VAL_TO_INT(xcenter + x);
148             yi = (GX_VALUE)GX_FIXED_VAL_TO_INT(ycenter + y * ysign[index]);
149 
150             if (xstart < clip -> gx_rectangle_left)
151             {
152                 xstart = clip -> gx_rectangle_left;
153             }
154 
155             if (xend > clip -> gx_rectangle_right)
156             {
157                 xend = clip -> gx_rectangle_right;
158             }
159 
160             if (xstart <= xend &&
161                 yi >= clip -> gx_rectangle_top &&
162                 yi <= clip -> gx_rectangle_bottom)
163             {
164                 display -> gx_display_driver_horizontal_line_draw(context, xstart, xend, yi, 1, brush -> gx_brush_line_color);
165             }
166         }
167 
168         x += GX_FIXED_VAL_ONE;
169     }
170 
171     x = GX_FIXED_VAL_RND_UP(r + xfraction);
172     x = GX_FIXED_VAL_MAKE(x) - xfraction;
173 
174     if (yfraction)
175     {
176         y = yfraction;
177     }
178     else
179     {
180         y = 0;
181     }
182 
183     if ((y == 0) && (x == r))
184     {
185         decision = 256 - r;
186     }
187     else
188     {
189         decision = (((x - GX_FIXED_VAL_HALF) >> half_shift) * ((x - GX_FIXED_VAL_HALF) >> half_shift));
190         decision += ((y >> half_shift) * (y >> half_shift));
191         decision -=  ((r >> half_shift) * (r >> half_shift));
192     }
193 
194     while (1)
195     {
196         if (decision < 0)
197         {
198             decision += 2 * y + GX_FIXED_VAL_ONE;
199         }
200         else
201         {
202             decision += 2 * (y - x) + GX_FIXED_VAL_MAKE(3);
203             x -= GX_FIXED_VAL_ONE;
204         }
205 
206         if (x <= y)
207         {
208             break;
209         }
210 
211         for (index = 0; index < 2; index++)
212         {
213             xstart = (GX_VALUE)GX_FIXED_VAL_TO_INT(xcenter - x);
214             xend  = (GX_VALUE)GX_FIXED_VAL_TO_INT(xcenter + x);
215             yi = (GX_VALUE)GX_FIXED_VAL_TO_INT(ycenter + y * ysign[index]);
216 
217             if (xstart < clip -> gx_rectangle_left)
218             {
219                 xstart = clip -> gx_rectangle_left;
220             }
221 
222             if (xend > clip -> gx_rectangle_right)
223             {
224                 xend = clip -> gx_rectangle_right;
225             }
226 
227             if (xstart <= xend &&
228                 yi >= clip -> gx_rectangle_top &&
229                 yi <= clip -> gx_rectangle_bottom)
230             {
231                 display -> gx_display_driver_horizontal_line_draw(context, xstart, xend, yi, 1, brush -> gx_brush_line_color);
232             }
233         }
234 
235         y += GX_FIXED_VAL_ONE;
236     }
237 }
238 
239