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

14843
        if ((y >= ymin) && (y <= ymax))
139
        {
140
13661
            pLineEnds[(y - ymin) << 1] = 0;
141
        }
142
    }
143
144
1224
    y2 = ycenter + (INT)r - (INT)((brush_width - 1) >> 1);
145
16067
    for (y = y2; y < y2 + brush_width; y++)
146
    {
147

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

353074
                if ((y2 >= ymin) && (y2 <= ymax))
179
                {
180
351430
                    pos = (y2 - ymin) << 1;
181
182
351430
                    if (x2 < pLineEnds[pos])
183
                    {
184
164793
                        pLineEnds[pos] = x2;
185
                    }
186
187
351430
                    if (x2 > pLineEnds[pos + 1])
188
                    {
189
348986
                        pLineEnds[pos + 1] = x2;
190
                    }
191
                }
192
193
353074
                x2 = x;
194
353074
                y2 = y * sign[index] + ycenter;
195
196

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