GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_generic_filled_circle_draw.c Lines: 68 68 100.0 %
Date: 2024-12-05 08:52:37 Branches: 44 44 100.0 %

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_display.h"
28
29
30
/**************************************************************************/
31
/*                                                                        */
32
/*  FUNCTION                                               RELEASE        */
33
/*                                                                        */
34
/*    _gx_display_driver_generic_filled_circle_draw       PORTABLE C      */
35
/*                                                           6.1          */
36
/*  AUTHOR                                                                */
37
/*                                                                        */
38
/*    Kenneth Maxwell, Microsoft Corporation                              */
39
/*                                                                        */
40
/*  DESCRIPTION                                                           */
41
/*                                                                        */
42
/*    Display driver to draw filled circals.                              */
43
/*                                                                        */
44
/*  INPUT                                                                 */
45
/*                                                                        */
46
/*    context                               Drawing context               */
47
/*    xcenter                               x-coord of center of circle   */
48
/*    ycenter                               y-coord of center of circle   */
49
/*    r                                     Radius of circle              */
50
/*                                                                        */
51
/*  OUTPUT                                                                */
52
/*                                                                        */
53
/*    None                                                                */
54
/*                                                                        */
55
/*  CALLS                                                                 */
56
/*                                                                        */
57
/*    [gx_display_driver_horizontal_line_draw]                            */
58
/*                                          Driver-level horizontal line  */
59
/*                                            draw function               */
60
/*                                                                        */
61
/*  CALLED BY                                                             */
62
/*                                                                        */
63
/*    _gx_display_driver_generic_simple_wide_line_draw                    */
64
/*                                                                        */
65
/*  RELEASE HISTORY                                                       */
66
/*                                                                        */
67
/*    DATE              NAME                      DESCRIPTION             */
68
/*                                                                        */
69
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
70
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
71
/*                                            resulting in version 6.1    */
72
/*                                                                        */
73
/**************************************************************************/
74
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)
75
{
76
/* The circle draw function is implemented from midpoint circle algorithm. */
77
78
GX_DISPLAY   *display;
79
GX_RECTANGLE *clip;
80
GX_BRUSH     *brush;
81
INT           x;
82
INT           y;
83
7336
GX_BYTE       ysign[2] = {1, -1};
84
INT           index;
85
INT           yi;
86
GX_VALUE      xstart;
87
GX_VALUE      xend;
88
GX_FIXED_VAL  xfraction;
89
GX_FIXED_VAL  yfraction;
90
INT           decision;
91
INT           half_shift;
92
93
7336
    display = context -> gx_draw_context_display;
94
7336
    clip = context -> gx_draw_context_clip;
95
7336
    brush = &context -> gx_draw_context_brush;
96
97
7336
    xfraction = (xcenter & GX_FIXED_VAL_FRACTION_MASK);
98
7336
    yfraction = (ycenter & GX_FIXED_VAL_FRACTION_MASK);
99
100
7336
    r -= GX_FIXED_VAL_HALF;
101
102
7336
    if (xfraction)
103
    {
104
929
        x = GX_FIXED_VAL_ONE - xfraction;
105
    }
106
    else
107
    {
108
6407
        x = 0;
109
    }
110
7336
    y = GX_FIXED_VAL_RND_UP(r + yfraction);
111
7336
    y = GX_FIXED_VAL_MAKE(y) - yfraction;
112
113
7336
    half_shift = GX_FIXED_VAL_SHIFT >> 1;
114
115

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

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