GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_generic_circle_fill.c Lines: 88 88 100.0 %
Date: 2024-12-05 08:52:37 Branches: 56 56 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
#include "gx_system.h"
29
#include "gx_utility.h"
30
31
#if defined(GX_ARC_DRAWING_SUPPORT)
32
33
/**************************************************************************/
34
/*                                                                        */
35
/*  FUNCTION                                               RELEASE        */
36
/*                                                                        */
37
/*    _gx_display_driver_generic_circle_fill              PORTABLE C      */
38
/*                                                           6.1          */
39
/*  AUTHOR                                                                */
40
/*                                                                        */
41
/*    Kenneth Maxwell, Microsoft Corporation                              */
42
/*                                                                        */
43
/*  DESCRIPTION                                                           */
44
/*                                                                        */
45
/*    Display driver fill circle.                                         */
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
/*                                          Basic display driver          */
62
/*                                            horizontal line draw routine*/
63
/*    [gx_display_driver_horizontal_pixelmap_line_draw]                   */
64
/*                                          Basic display driver          */
65
/*                                            horizontal pixelmap line    */
66
/*                                            draw function               */
67
/*  CALLED BY                                                             */
68
/*                                                                        */
69
/*    GUIX Internal Code                                                  */
70
/*                                                                        */
71
/*  RELEASE HISTORY                                                       */
72
/*                                                                        */
73
/*    DATE              NAME                      DESCRIPTION             */
74
/*                                                                        */
75
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
76
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
77
/*                                            resulting in version 6.1    */
78
/*                                                                        */
79
/**************************************************************************/
80
2649
VOID _gx_display_driver_generic_circle_fill(GX_DRAW_CONTEXT *context, INT xcenter, INT ycenter, UINT r)
81
{
82
GX_DISPLAY           *display;
83
GX_BRUSH             *brush;
84
GX_RECTANGLE         *clip;
85
INT                   xpos;
86
INT                   curx;
87
INT                   cury;
88
INT                   ymin;
89
INT                   ymax;
90
INT                   yi;
91
INT                   x1;
92
INT                   x2;
93
INT                   y1;
94
INT                   height;
95
INT                   loop;
96
GX_VALUE              format;
97
INT                   skip_line;
98
2649
GX_PIXELMAP          *pixelmap = GX_NULL;
99
GX_FILL_PIXELMAP_INFO info;
100
INT                  *pLineEnds;
101
INT                   Index;
102
2649
INT                   sign[4][2] = {{1, 1}, {1, -1}, {1, 1}, {1, -1}};
103
INT                   error;
104
GX_COLOR              fill_color;
105
106
2649
    display = context -> gx_draw_context_display;
107
2649
    clip = context -> gx_draw_context_clip;
108
2649
    brush = &context -> gx_draw_context_brush;
109
110
2649
    if (brush -> gx_brush_style & GX_BRUSH_PIXELMAP_FILL)
111
    {
112
2054
        pixelmap = brush -> gx_brush_pixelmap;
113
2054
        if (pixelmap == GX_NULL)
114
        {
115
            /* Nothing should be drawn if pixelmap isn't set with GX_BRUSH_PIXELMAP_FILL style. */
116
5
            return;
117
        }
118
2053
        if (pixelmap -> gx_pixelmap_height <= 0 ||
119
2052
            pixelmap -> gx_pixelmap_width <= 0)
120
        {
121
2
            return;
122
        }
123
2051
        format = display -> gx_display_color_format;
124
2051
        memset(&info, 0, sizeof(GX_FILL_PIXELMAP_INFO));
125
126
        /*Check the pixelmap format is supported in this driver or not.*/
127
2051
        if (format >= GX_COLOR_FORMAT_24XRGB)
128
        {
129
            /*32ARGB FORMAT use 24xrgb driver for now. So this is a special case.*/
130
1192
            if (pixelmap -> gx_pixelmap_format < GX_COLOR_FORMAT_24XRGB)
131
            {
132
                /* Display driver only support its native format pixelmap.*/
133
                /* Nothing should be drawn if pixelmap format isn't support. */
134
1
                return;
135
            }
136
        }
137
        else
138
        {
139
859
            if (pixelmap -> gx_pixelmap_format != format)
140
            {
141
                /* Display driver only support its native format pixelmap.*/
142
                /* Nothing should be drawn if pixelmap format isn't support. */
143
1
                return;
144
            }
145
        }
146
147
2049
        if (format == GX_COLOR_FORMAT_4BIT_GRAY)
148
        {
149
2
            info.mask = 0xf0;
150
        }
151
152
        /* If filling pixelmap, set fill pixelmap info. */
153
2049
        info.pixelmap = pixelmap;
154
2049
        info.current_pixel_ptr = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
155
2049
        if (pixelmap -> gx_pixelmap_aux_data_size)
156
        {
157
783
            info.current_aux_ptr = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
158
        }
159
    }
160
161
2644
    xpos = xcenter - (INT)r;
162
2644
    ymin = ycenter - (INT)r;
163
2644
    ymax = ycenter + (INT)r;
164
165
    /* Calculate minimum y line. */
166
2644
    if (clip -> gx_rectangle_top > ymin)
167
    {
168
455
        skip_line = clip -> gx_rectangle_top - ymin;
169
455
        ymin = clip -> gx_rectangle_top;
170
    }
171
    else
172
    {
173
2189
        skip_line = 0;
174
    }
175
176
    /* Calculat maximum y line. */
177
2644
    if (clip -> gx_rectangle_bottom < ymax)
178
    {
179
1050
        ymax = clip -> gx_rectangle_bottom;
180
    }
181
182
2644
    height = ymax - ymin + 1;
183
2644
    pLineEnds = _gx_system_scratchpad;
184
185
    /* default the point array to being off the screen on both sides: */
186
580545
    for (loop = 0; loop < height * 2; loop += 2)
187
    {
188
577901
        pLineEnds[loop] = 2000;
189
577901
        pLineEnds[loop + 1] = 0;
190
    }
191
192
2644
    curx = 0;
193
2644
    cury = (INT)r;
194
2644
    error = 0;
195
196
    /* For shapes pixelmap-fill driver function, it must fill shapes line by line from up to bottom.
197
       So this contains two steps here: first, calculate the boudary point of circle; Second, draw pixelmap line by line. */
198
216705
    while (curx <= cury)
199
    {
200
1070305
        for (loop = 0; loop < 4; loop++)
201
        {
202
            /* Upper half part. */
203
856244
            if (loop < 2)
204
            {
205
428122
                x1 = curx * sign[loop][0];
206
428122
                y1 = (cury - 1) * sign[loop][1];
207
            }
208
            /* lower half part. */
209
            else
210
            {
211
428122
                x1 = (cury - 1) * sign[loop][0];
212
428122
                y1 = curx * sign[loop][1];
213
            }
214
215
856244
            x2 = -x1;
216
856244
            x1 += xcenter;
217
856244
            x2 += xcenter;
218
856244
            y1 += ycenter;
219
220

856244
            if ((y1 >= ymin) && (y1 <= ymax))
221
            {
222
756469
                if (x1 > x2)
223
                {
224
751416
                    GX_SWAP_VALS(x1, x2);
225
                }
226
227
756469
                if (x1 < clip -> gx_rectangle_left)
228
                {
229
168320
                    x1 = clip -> gx_rectangle_left;
230
                }
231
232
756469
                if (x2 > clip -> gx_rectangle_right)
233
                {
234
163184
                    x2 = clip -> gx_rectangle_right;
235
                }
236
237
756469
                Index = (y1 - ymin) << 1;
238
756469
                pLineEnds[Index] = x1;
239
756469
                pLineEnds[Index + 1] = x2;
240
            }
241
        }
242
243
214061
        curx++;
244
214061
        yi = (INT)(r * r) - curx * curx;
245
214061
        error = (cury << 8) - (INT)(_gx_utility_math_sqrt((UINT)(yi << 10)) << 3);
246
247
303569
        while (error >= 255)
248
        {
249
89508
            error -= 255;
250
89508
            cury--;
251
        }
252
    }
253
254
2644
    Index = 0;
255
256
2644
    if (pixelmap)
257
    {
258
2049
        skip_line = (skip_line % info.pixelmap -> gx_pixelmap_height);
259
2049
        if (skip_line)
260
        {
261
344
            info.draw = GX_FALSE;
262
2224
            while (skip_line--)
263
            {
264
1880
                display -> gx_display_driver_horizontal_pixelmap_line_draw(context, 0, 0, 0, &info);
265
            }
266
        }
267
268
2049
        info.draw = GX_TRUE;
269
270
442101
        for (cury = ymin; cury <= ymax; cury++)
271
        {
272
440052
            if (pLineEnds[Index] <= pLineEnds[Index + 1])
273
            {
274
437105
                info.x_offset = pLineEnds[Index] - xpos;
275
437105
                display -> gx_display_driver_horizontal_pixelmap_line_draw(context, pLineEnds[Index], pLineEnds[Index + 1], cury, &info);
276
            }
277
440052
            Index += 2;
278
        }
279
    }
280
    else
281
    {
282
595
        fill_color = brush -> gx_brush_fill_color;
283
284
138444
        for (cury = ymin; cury <= ymax; cury++)
285
        {
286
137849
            if (pLineEnds[Index] <= pLineEnds[Index + 1])
287
            {
288
137015
                display -> gx_display_driver_horizontal_line_draw(context, pLineEnds[Index], pLineEnds[Index + 1], cury, 1, fill_color);
289
            }
290
137849
            Index += 2;
291
        }
292
    }
293
}
294
#endif
295