GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_generic_rotated_circle_fill.c Lines: 89 89 100.0 %
Date: 2026-03-06 19:21:09 Branches: 50 50 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
#include "gx_system.h"
30
#include "gx_utility.h"
31
32
#if defined(GX_ARC_DRAWING_SUPPORT)
33
34
/**************************************************************************/
35
/*                                                                        */
36
/*  FUNCTION                                               RELEASE        */
37
/*                                                                        */
38
/*    _gx_display_driver_generic_rotated_circle_fill      PORTABLE C      */
39
/*                                                           6.1.3        */
40
/*  AUTHOR                                                                */
41
/*                                                                        */
42
/*    Kenneth Maxwell, Microsoft Corporation                              */
43
/*                                                                        */
44
/*  DESCRIPTION                                                           */
45
/*                                                                        */
46
/*    Display driver fill circle.                                         */
47
/*                                                                        */
48
/*  INPUT                                                                 */
49
/*                                                                        */
50
/*    context                               Drawing context               */
51
/*    xcenter                               x-coord of center of circle   */
52
/*    ycenter                               y-coord of center of circle   */
53
/*    r                                     Radius of circle              */
54
/*                                                                        */
55
/*  OUTPUT                                                                */
56
/*                                                                        */
57
/*    None                                                                */
58
/*                                                                        */
59
/*  CALLS                                                                 */
60
/*                                                                        */
61
/*    [gx_display_driver_horizontal_line_draw]                            */
62
/*                                          Basic display driver          */
63
/*                                            horizontal line draw routine*/
64
/*    [gx_display_driver_horizontal_pixelmap_line_draw]                   */
65
/*                                          Basic display driver          */
66
/*                                            horizontal pixelmap line    */
67
/*                                            draw function               */
68
/*  CALLED BY                                                             */
69
/*                                                                        */
70
/*    GUIX Internal Code                                                  */
71
/*                                                                        */
72
/**************************************************************************/
73
113
VOID _gx_display_driver_generic_rotated_circle_fill(GX_DRAW_CONTEXT *context, INT xcenter, INT ycenter, UINT r)
74
{
75
GX_DISPLAY           *display;
76
GX_BRUSH             *brush;
77
GX_RECTANGLE         *clip;
78
INT                   ypos;
79
INT                   curx;
80
INT                   cury;
81
INT                   xmin;
82
INT                   xmax;
83
INT                   yi;
84
INT                   x1;
85
INT                   y1;
86
INT                   y2;
87
INT                   width;
88
INT                   loop;
89
INT                   skip_line;
90
113
GX_PIXELMAP          *pixelmap = GX_NULL;
91
GX_FILL_PIXELMAP_INFO info;
92
INT                  *pLineEnds;
93
INT                   Index;
94
113
GX_BYTE               sign[4][2] = {{1, 1}, {-1, 1}, {1, 1}, {-1, 1}};
95
INT                   error;
96
GX_COLOR              fill_color;
97
GX_BYTE               xsign;
98
99
113
    display = context -> gx_draw_context_display;
100
113
    clip = context -> gx_draw_context_clip;
101
113
    brush = &context -> gx_draw_context_brush;
102
103
113
    if (brush -> gx_brush_style & GX_BRUSH_PIXELMAP_FILL)
104
    {
105
66
        if (brush -> gx_brush_pixelmap == GX_NULL)
106
        {
107
            /* Nothing should be drawn if pixelmap isn't set with GX_BRUSH_PIXELMAP_FILL style. */
108
2
            return;
109
        }
110
111
65
        pixelmap = brush -> gx_brush_pixelmap;
112
65
        if (pixelmap -> gx_pixelmap_format != display -> gx_display_color_format)
113
        {
114
            /* Display driver only support its native format pixelmap.*/
115
            /* Nothing should be drawn if pixelmap format isn't support. */
116
1
            return;
117
        }
118
119
64
        memset(&info, 0, sizeof(GX_FILL_PIXELMAP_INFO));
120
121
        /* If filling pixelmap, set fill pixelmap info. */
122
64
        info.pixelmap = pixelmap;
123
64
        info.current_pixel_ptr = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
124
64
        if (pixelmap -> gx_pixelmap_aux_data_size)
125
        {
126
24
            info.current_aux_ptr = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
127
        }
128
    }
129
130
111
    xmin = xcenter - (INT)r;
131
111
    xmax = xcenter + (INT)r;
132
133
    /* Calculate minimum y line. */
134
111
    if (clip -> gx_rectangle_left > xmin)
135
    {
136
2
        xmin = clip -> gx_rectangle_left;
137
    }
138
139
    /* Calculat maximum y line. */
140
111
    if (clip -> gx_rectangle_right < xmax)
141
    {
142
4
        xmax = clip -> gx_rectangle_right;
143
    }
144
145
111
    width = xmax - xmin + 1;
146
111
    pLineEnds = _gx_system_scratchpad;
147
148
    /* default the point array to being off the screen on both sides: */
149
35722
    for (loop = 0; loop < width * 2; loop += 2)
150
    {
151
35611
        pLineEnds[loop] = 2000;
152
35611
        pLineEnds[loop + 1] = 0;
153
    }
154
155
111
    curx = 0;
156
111
    cury = (INT)r;
157
111
    error = 0;
158
159
    /* For shapes pixelmap-fill driver function, it must fill shapes line by line from up to bottom.
160
       So this contains two steps here: first, calculate the boudary point of circle; Second, draw pixelmap line by line. */
161
12907
    while (curx <= cury)
162
    {
163
63980
        for (loop = 0; loop < 4; loop++)
164
        {
165
            /* Upper half part. */
166
51184
            if (loop < 2)
167
            {
168
25592
                x1 = curx * sign[loop][0];
169
25592
                y1 = (cury - 1) * sign[loop][1];
170
            }
171
            /* lower half part. */
172
            else
173
            {
174
25592
                x1 = (cury - 1) * sign[loop][0];
175
25592
                y1 = curx * sign[loop][1];
176
            }
177
178
51184
            y2 = -y1;
179
51184
            y1 += ycenter;
180
51184
            y2 += ycenter;
181
51184
            x1 += xcenter;
182
183

51184
            if ((x1 >= xmin) && (x1 <= xmax))
184
            {
185
50272
                if (y1 > y2)
186
                {
187
50054
                    GX_SWAP_VALS(y1, y2);
188
                }
189
190
50272
                if (y1 < clip -> gx_rectangle_top)
191
                {
192
730
                    y1 = clip -> gx_rectangle_top;
193
                }
194
195
50272
                if (y2 > clip -> gx_rectangle_bottom)
196
                {
197
792
                    y2 = clip -> gx_rectangle_bottom;
198
                }
199
200
50272
                Index = (x1 - xmin) << 1;
201
50272
                pLineEnds[Index] = y1;
202
50272
                pLineEnds[Index + 1] = y2;
203
            }
204
        }
205
206
12796
        curx++;
207
12796
        yi = (INT)(r * r) - curx * curx;
208
12796
        error = (cury << 8) - (INT)(_gx_utility_math_sqrt((UINT)(yi << 10)) << 3);
209
210
18073
        while (error >= 255)
211
        {
212
5277
            error -= 255;
213
5277
            cury--;
214
        }
215
    }
216
217
111
    if (pixelmap)
218
    {
219
64
        if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
220
        {
221
36
            skip_line = (xmax - (xcenter - (INT)r) + 1) % pixelmap -> gx_pixelmap_width;
222
223
36
            if (skip_line)
224
            {
225
35
                skip_line = pixelmap -> gx_pixelmap_width - skip_line;
226
            }
227
228
36
            x1 = xmax;
229
36
            xsign = -1;
230
36
            Index = (width - 1) * 2;
231
        }
232
        else
233
        {
234
28
            skip_line = (xmin - clip -> gx_rectangle_left);
235
236
28
            x1 = xmin;
237
28
            xsign = 1;
238
28
            Index = 0;
239
        }
240
241
64
        if (skip_line)
242
        {
243
244
63
            info.draw = GX_FALSE;
245
2681
            while (skip_line--)
246
            {
247
2618
                display -> gx_display_driver_horizontal_pixelmap_line_draw(context, 0, 0, 0, &info);
248
            }
249
        }
250
251
64
        info.draw = GX_TRUE;
252
64
        ypos = ycenter - (INT)r;
253
254
20598
        for (curx = xmin; curx <= xmax; curx++)
255
        {
256
20534
            if (pLineEnds[Index] <= pLineEnds[Index + 1])
257
            {
258
20409
                info.x_offset = pLineEnds[Index] - ypos;
259
20409
                display -> gx_display_driver_horizontal_pixelmap_line_draw(context, pLineEnds[Index], pLineEnds[Index + 1], x1, &info);
260
            }
261
262
20534
            x1 += xsign;
263
20534
            Index += xsign;
264
20534
            Index += xsign;
265
        }
266
    }
267
    else
268
    {
269
47
        Index = 0;
270
47
        fill_color = brush -> gx_brush_fill_color;
271
272
15124
        for (curx = xmin; curx <= xmax; curx++)
273
        {
274
15077
            if (pLineEnds[Index] <= pLineEnds[Index + 1])
275
            {
276
14986
                display -> gx_display_driver_vertical_line_draw(context, pLineEnds[Index], pLineEnds[Index + 1], curx, 1, fill_color);
277
            }
278
15077
            Index += 2;
279
        }
280
    }
281
}
282
#endif
283