GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_generic_wide_circle_draw.c Lines: 73 73 100.0 %
Date: 2026-03-06 19:21:09 Branches: 56 56 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_system.h"
29
#include "gx_utility.h"
30
#include "gx_display.h"
31
32
#if defined(GX_ARC_DRAWING_SUPPORT)
33
/**************************************************************************/
34
/*                                                                        */
35
/*  FUNCTION                                               RELEASE        */
36
/*                                                                        */
37
/*    _gx_display_driver_generic_wide_circle_draw         PORTABLE C      */
38
/*                                                           6.1          */
39
/*  AUTHOR                                                                */
40
/*                                                                        */
41
/*    Kenneth Maxwell, Microsoft Corporation                              */
42
/*                                                                        */
43
/*  DESCRIPTION                                                           */
44
/*                                                                        */
45
/*    Display driver to draw circle with specified outline width.         */
46
/*                                                                        */
47
/*  INPUT                                                                 */
48
/*                                                                        */
49
/*    context                               Drawing context               */
50
/*    xcenter                               x-coord of center of circle   */
51
/*    ycenter                               y-coord of center of circle   */
52
/*    r                                     Radius of circle              */
53
/*                                                                        */
54
/*  OUTPUT                                                                */
55
/*                                                                        */
56
/*    None                                                                */
57
/*                                                                        */
58
/*  CALLS                                                                 */
59
/*                                                                        */
60
/*    [gx_display_driver_horizontal_line_draw]                            */
61
/*                                          The display driver horizontal */
62
/*                                            line drawing function       */
63
/*                                                                        */
64
/*  CALLED BY                                                             */
65
/*                                                                        */
66
/*    GUIX Internal Code                                                  */
67
/*                                                                        */
68
/**************************************************************************/
69
1402
VOID _gx_display_driver_generic_wide_circle_draw(GX_DRAW_CONTEXT *context, INT xcenter, INT ycenter, UINT r)
70
{
71
/* The circle draw function is implemented from midpoint circle algorithm. */
72
73
GX_DISPLAY   *display;
74
GX_RECTANGLE *clip;
75
GX_BRUSH     *brush;
76
INT           brush_width;
77
INT           x;
78
INT           x2;
79
INT           y;
80
INT           y2;
81
INT           d;
82
1402
INT           sign[2] = {1, -1};
83
INT           index;
84
INT          *pLineEnds;
85
INT           ymin;
86
INT           ymax;
87
INT           height;
88
INT           loop;
89
INT           pos;
90
91
#if defined(GX_BRUSH_ALPHA_SUPPORT)
92
GX_UBYTE old_alpha;
93
1402
    old_alpha = context -> gx_draw_context_brush.gx_brush_alpha;
94
1402
    context -> gx_draw_context_brush.gx_brush_alpha = GX_ALPHA_VALUE_OPAQUE;
95
#endif
96
1402
    display = context -> gx_draw_context_display;
97
1402
    clip = context -> gx_draw_context_clip;
98
1402
    brush = &context -> gx_draw_context_brush;
99
1402
    brush_width = brush -> gx_brush_width;
100
101
1402
    if (r <= (UINT)((brush_width - 1) >> 1))
102
    {
103
178
        return;
104
    }
105
106
1224
    ymin = ycenter - (INT)r - (brush_width >> 1);
107
1224
    ymax = ycenter + (INT)r + (brush_width >> 1);
108
109
1224
    if (ymin < clip -> gx_rectangle_top)
110
    {
111
164
        ymin = clip -> gx_rectangle_top;
112
    }
113
114
1224
    if (ymax > clip -> gx_rectangle_bottom)
115
    {
116
244
        ymax = clip -> gx_rectangle_bottom;
117
    }
118
119
1224
    height = ymax - ymin + 1;
120
1224
    pLineEnds = _gx_system_scratchpad;
121
122
255582
    for (y = 0; y <= height * 2; y += 2)
123
    {
124
254358
        pLineEnds[y] = 2000;
125
254358
        pLineEnds[y + 1] = 0;
126
    }
127
128
1224
    y2 = ycenter - (INT)r - (brush_width >> 1);
129
16067
    for (y = y2; y < y2 + brush_width; y++)
130
    {
131

14843
        if ((y >= ymin) && (y <= ymax))
132
        {
133
13661
            pLineEnds[(y - ymin) << 1] = 0;
134
        }
135
    }
136
137
1224
    y2 = ycenter + (INT)r - (INT)((brush_width - 1) >> 1);
138
16067
    for (y = y2; y < y2 + brush_width; y++)
139
    {
140

14843
        if ((y >= ymin) && (y <= ymax))
141
        {
142
12344
            pLineEnds[(y - ymin) << 1] = 0;
143
        }
144
    }
145
146
3672
    for (loop = 0; loop < 2; loop++)
147
    {
148
2448
        if (loop == 0)
149
        {
150
            /* inner circle. */
151
1224
            r = (UINT)(r - (UINT)((brush_width - 1) >> 1));
152
        }
153
        else
154
        {
155
            /* outer circle. */
156
1224
            r += (UINT)(brush_width - 1);
157
        }
158
159
2448
        x = 0;
160
2448
        y = (INT)r;
161
2448
        d = 5 - (INT)(4 * r);
162
163
        /* Record points in the fourth quarter of the inner circle.  */
164
178985
        while (x <= y)
165
        {
166
529611
            for (index = 0; index < 2; index++)
167
            {
168
353074
                x2 = y;
169
353074
                y2 = x * sign[index] + ycenter;
170
171

353074
                if ((y2 >= ymin) && (y2 <= ymax))
172
                {
173
351430
                    pos = (y2 - ymin) << 1;
174
175
351430
                    if (x2 < pLineEnds[pos])
176
                    {
177
164793
                        pLineEnds[pos] = x2;
178
                    }
179
180
351430
                    if (x2 > pLineEnds[pos + 1])
181
                    {
182
348986
                        pLineEnds[pos + 1] = x2;
183
                    }
184
                }
185
186
353074
                x2 = x;
187
353074
                y2 = y * sign[index] + ycenter;
188
189

353074
                if ((y2 >= ymin) && (y2 <= ymax))
190
                {
191
305082
                    pos = (y2 - ymin) << 1;
192
193
305082
                    if (x2 < pLineEnds[pos])
194
                    {
195
62336
                        pLineEnds[pos] = x2;
196
                    }
197
198
305082
                    if (x2 > pLineEnds[pos + 1])
199
                    {
200
297526
                        pLineEnds[pos + 1] = x2;
201
                    }
202
                }
203
            }
204
205
176537
            if (d < 0)
206
            {
207
102076
                d += 8 * x + 12;
208
            }
209
            else
210
            {
211
74461
                d += 8 * (x - y) + 20;
212
74461
                y--;
213
            }
214
176537
            x++;
215
        }
216
    }
217
218
    /* Filling outlines with horizontal line. */
219
1224
    index = 0;
220
254358
    for (y = ymin; y <= ymax; y++)
221
    {
222
759402
        for (loop = 0; loop < 2; loop++)
223
        {
224
506268
            x = pLineEnds[index] * sign[loop] + xcenter;
225
506268
            x2 = pLineEnds[index + 1] * sign[loop] + xcenter;
226
227
506268
            if (loop)
228
            {
229
253134
                GX_SWAP_VALS(x, x2);
230
            }
231
232
506268
            if (x < clip -> gx_rectangle_left)
233
            {
234
42583
                x = clip -> gx_rectangle_left;
235
            }
236
237
506268
            if (x2 > clip -> gx_rectangle_right)
238
            {
239
41035
                x2 = clip -> gx_rectangle_right;
240
            }
241
242
506268
            display -> gx_display_driver_horizontal_line_draw(context, x, x2, y, 1,
243
                                                              brush -> gx_brush_line_color);
244
        }
245
246
253134
        index += 2;
247
    }
248
#if defined(GX_BRUSH_ALPHA_SUPPORT)
249
1224
    context -> gx_draw_context_brush.gx_brush_alpha = old_alpha;
250
#endif
251
}
252
#endif
253