GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_generic_rotated_circle_fill.c Lines: 89 89 100.0 %
Date: 2024-12-05 08:52:37 Branches: 50 50 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_rotated_circle_fill      PORTABLE C      */
38
/*                                                           6.1.3        */
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
/*  12-31-2020     Kenneth Maxwell          Initial Version 6.1.3         */
76
/*                                                                        */
77
/**************************************************************************/
78
113
VOID _gx_display_driver_generic_rotated_circle_fill(GX_DRAW_CONTEXT *context, INT xcenter, INT ycenter, UINT r)
79
{
80
GX_DISPLAY           *display;
81
GX_BRUSH             *brush;
82
GX_RECTANGLE         *clip;
83
INT                   ypos;
84
INT                   curx;
85
INT                   cury;
86
INT                   xmin;
87
INT                   xmax;
88
INT                   yi;
89
INT                   x1;
90
INT                   y1;
91
INT                   y2;
92
INT                   width;
93
INT                   loop;
94
INT                   skip_line;
95
113
GX_PIXELMAP          *pixelmap = GX_NULL;
96
GX_FILL_PIXELMAP_INFO info;
97
INT                  *pLineEnds;
98
INT                   Index;
99
113
GX_BYTE               sign[4][2] = {{1, 1}, {-1, 1}, {1, 1}, {-1, 1}};
100
INT                   error;
101
GX_COLOR              fill_color;
102
GX_BYTE               xsign;
103
104
113
    display = context -> gx_draw_context_display;
105
113
    clip = context -> gx_draw_context_clip;
106
113
    brush = &context -> gx_draw_context_brush;
107
108
113
    if (brush -> gx_brush_style & GX_BRUSH_PIXELMAP_FILL)
109
    {
110
66
        if (brush -> gx_brush_pixelmap == GX_NULL)
111
        {
112
            /* Nothing should be drawn if pixelmap isn't set with GX_BRUSH_PIXELMAP_FILL style. */
113
2
            return;
114
        }
115
116
65
        pixelmap = brush -> gx_brush_pixelmap;
117
65
        if (pixelmap -> gx_pixelmap_format != display -> gx_display_color_format)
118
        {
119
            /* Display driver only support its native format pixelmap.*/
120
            /* Nothing should be drawn if pixelmap format isn't support. */
121
1
            return;
122
        }
123
124
64
        memset(&info, 0, sizeof(GX_FILL_PIXELMAP_INFO));
125
126
        /* If filling pixelmap, set fill pixelmap info. */
127
64
        info.pixelmap = pixelmap;
128
64
        info.current_pixel_ptr = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
129
64
        if (pixelmap -> gx_pixelmap_aux_data_size)
130
        {
131
24
            info.current_aux_ptr = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
132
        }
133
    }
134
135
111
    xmin = xcenter - (INT)r;
136
111
    xmax = xcenter + (INT)r;
137
138
    /* Calculate minimum y line. */
139
111
    if (clip -> gx_rectangle_left > xmin)
140
    {
141
2
        xmin = clip -> gx_rectangle_left;
142
    }
143
144
    /* Calculat maximum y line. */
145
111
    if (clip -> gx_rectangle_right < xmax)
146
    {
147
4
        xmax = clip -> gx_rectangle_right;
148
    }
149
150
111
    width = xmax - xmin + 1;
151
111
    pLineEnds = _gx_system_scratchpad;
152
153
    /* default the point array to being off the screen on both sides: */
154
35722
    for (loop = 0; loop < width * 2; loop += 2)
155
    {
156
35611
        pLineEnds[loop] = 2000;
157
35611
        pLineEnds[loop + 1] = 0;
158
    }
159
160
111
    curx = 0;
161
111
    cury = (INT)r;
162
111
    error = 0;
163
164
    /* For shapes pixelmap-fill driver function, it must fill shapes line by line from up to bottom.
165
       So this contains two steps here: first, calculate the boudary point of circle; Second, draw pixelmap line by line. */
166
12907
    while (curx <= cury)
167
    {
168
63980
        for (loop = 0; loop < 4; loop++)
169
        {
170
            /* Upper half part. */
171
51184
            if (loop < 2)
172
            {
173
25592
                x1 = curx * sign[loop][0];
174
25592
                y1 = (cury - 1) * sign[loop][1];
175
            }
176
            /* lower half part. */
177
            else
178
            {
179
25592
                x1 = (cury - 1) * sign[loop][0];
180
25592
                y1 = curx * sign[loop][1];
181
            }
182
183
51184
            y2 = -y1;
184
51184
            y1 += ycenter;
185
51184
            y2 += ycenter;
186
51184
            x1 += xcenter;
187
188

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