GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_generic_filled_circle_draw.c Lines: 68 68 100.0 %
Date: 2026-03-06 19:21:09 Branches: 44 44 100.0 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 * Copyright (c) 2026-present Eclipse ThreadX contributors
4
 *
5
 * This program and the accompanying materials are made available under the
6
 * terms of the MIT License which is available at
7
 * https://opensource.org/licenses/MIT.
8
 *
9
 * SPDX-License-Identifier: MIT
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
/**************************************************************************/
67
7336
VOID _gx_display_driver_generic_filled_circle_draw(GX_DRAW_CONTEXT *context, GX_FIXED_VAL xcenter, GX_FIXED_VAL ycenter, GX_FIXED_VAL r)
68
{
69
/* The circle draw function is implemented from midpoint circle algorithm. */
70
71
GX_DISPLAY   *display;
72
GX_RECTANGLE *clip;
73
GX_BRUSH     *brush;
74
INT           x;
75
INT           y;
76
7336
GX_BYTE       ysign[2] = {1, -1};
77
INT           index;
78
INT           yi;
79
GX_VALUE      xstart;
80
GX_VALUE      xend;
81
GX_FIXED_VAL  xfraction;
82
GX_FIXED_VAL  yfraction;
83
INT           decision;
84
INT           half_shift;
85
86
7336
    display = context -> gx_draw_context_display;
87
7336
    clip = context -> gx_draw_context_clip;
88
7336
    brush = &context -> gx_draw_context_brush;
89
90
7336
    xfraction = (xcenter & GX_FIXED_VAL_FRACTION_MASK);
91
7336
    yfraction = (ycenter & GX_FIXED_VAL_FRACTION_MASK);
92
93
7336
    r -= GX_FIXED_VAL_HALF;
94
95
7336
    if (xfraction)
96
    {
97
929
        x = GX_FIXED_VAL_ONE - xfraction;
98
    }
99
    else
100
    {
101
6407
        x = 0;
102
    }
103
7336
    y = GX_FIXED_VAL_RND_UP(r + yfraction);
104
7336
    y = GX_FIXED_VAL_MAKE(y) - yfraction;
105
106
7336
    half_shift = GX_FIXED_VAL_SHIFT >> 1;
107
108

7336
    if ((x == 0) && (y == r))
109
    {
110
4895
        decision = 256 - r;
111
    }
112
    else
113
    {
114
2441
        decision = (x >> half_shift) * (x >> half_shift);
115
2441
        decision += ((y - GX_FIXED_VAL_HALF) >> half_shift) * ((y - GX_FIXED_VAL_HALF) >> half_shift);
116
2441
        decision -= ((r >> half_shift) * (r >> half_shift));
117
    }
118
119
    while (1)
120
    {
121
34476
        if (decision < 0)
122
        {
123
17948
            decision += 2 * x + GX_FIXED_VAL_ONE;
124
        }
125
        else
126
        {
127
16528
            decision += 2 * (x - y) + GX_FIXED_VAL_MAKE(3);
128
16528
            y -= GX_FIXED_VAL_ONE;
129
        }
130
131
34476
        if (x > y)
132
        {
133
7336
            break;
134
        }
135
136
81420
        for (index = 0; index < 2; index++)
137
        {
138
54280
            xstart = (GX_VALUE)GX_FIXED_VAL_TO_INT(xcenter - x);
139
54280
            xend = (GX_VALUE)GX_FIXED_VAL_TO_INT(xcenter + x);
140
54280
            yi = (GX_VALUE)GX_FIXED_VAL_TO_INT(ycenter + y * ysign[index]);
141
142
54280
            if (xstart < clip -> gx_rectangle_left)
143
            {
144
1068
                xstart = clip -> gx_rectangle_left;
145
            }
146
147
54280
            if (xend > clip -> gx_rectangle_right)
148
            {
149
4488
                xend = clip -> gx_rectangle_right;
150
            }
151
152
54280
            if (xstart <= xend &&
153
49968
                yi >= clip -> gx_rectangle_top &&
154
49572
                yi <= clip -> gx_rectangle_bottom)
155
            {
156
48236
                display -> gx_display_driver_horizontal_line_draw(context, xstart, xend, yi, 1, brush -> gx_brush_line_color);
157
            }
158
        }
159
160
27140
        x += GX_FIXED_VAL_ONE;
161
    }
162
163
7336
    x = GX_FIXED_VAL_RND_UP(r + xfraction);
164
7336
    x = GX_FIXED_VAL_MAKE(x) - xfraction;
165
166
7336
    if (yfraction)
167
    {
168
1123
        y = yfraction;
169
    }
170
    else
171
    {
172
6213
        y = 0;
173
    }
174
175

7336
    if ((y == 0) && (x == r))
176
    {
177
4711
        decision = 256 - r;
178
    }
179
    else
180
    {
181
2625
        decision = (((x - GX_FIXED_VAL_HALF) >> half_shift) * ((x - GX_FIXED_VAL_HALF) >> half_shift));
182
2625
        decision += ((y >> half_shift) * (y >> half_shift));
183
2625
        decision -=  ((r >> half_shift) * (r >> half_shift));
184
    }
185
186
    while (1)
187
    {
188
30733
        if (decision < 0)
189
        {
190
17764
            decision += 2 * y + GX_FIXED_VAL_ONE;
191
        }
192
        else
193
        {
194
12969
            decision += 2 * (y - x) + GX_FIXED_VAL_MAKE(3);
195
12969
            x -= GX_FIXED_VAL_ONE;
196
        }
197
198
30733
        if (x <= y)
199
        {
200
7336
            break;
201
        }
202
203
70191
        for (index = 0; index < 2; index++)
204
        {
205
46794
            xstart = (GX_VALUE)GX_FIXED_VAL_TO_INT(xcenter - x);
206
46794
            xend  = (GX_VALUE)GX_FIXED_VAL_TO_INT(xcenter + x);
207
46794
            yi = (GX_VALUE)GX_FIXED_VAL_TO_INT(ycenter + y * ysign[index]);
208
209
46794
            if (xstart < clip -> gx_rectangle_left)
210
            {
211
1132
                xstart = clip -> gx_rectangle_left;
212
            }
213
214
46794
            if (xend > clip -> gx_rectangle_right)
215
            {
216
4032
                xend = clip -> gx_rectangle_right;
217
            }
218
219
46794
            if (xstart <= xend &&
220
43902
                yi >= clip -> gx_rectangle_top &&
221
43602
                yi <= clip -> gx_rectangle_bottom)
222
            {
223
42738
                display -> gx_display_driver_horizontal_line_draw(context, xstart, xend, yi, 1, brush -> gx_brush_line_color);
224
            }
225
        }
226
227
23397
        y += GX_FIXED_VAL_ONE;
228
    }
229
7336
}
230