GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_generic_aliased_ellipse_draw.c Lines: 65 65 100.0 %
Date: 2026-03-06 19:21:09 Branches: 30 30 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_utility.h"
29
#include "gx_display.h"
30
31
/**************************************************************************/
32
/*                                                                        */
33
/*  FUNCTION                                               RELEASE        */
34
/*                                                                        */
35
/*    _gx_display_driver_generic_aliased_ellipse_draw     PORTABLE C      */
36
/*                                                           6.1          */
37
/*  AUTHOR                                                                */
38
/*                                                                        */
39
/*    Kenneth Maxwell, Microsoft Corporation                              */
40
/*                                                                        */
41
/*  DESCRIPTION                                                           */
42
/*                                                                        */
43
/*    Display driver to draw anti-alised ellipse.                         */
44
/*                                                                        */
45
/*  INPUT                                                                 */
46
/*                                                                        */
47
/*    context                               Drawing context               */
48
/*    xcenter                               x-coord of center of ellipse  */
49
/*    ycenter                               y-coord of center of ellipse  */
50
/*    a                                     Length of the Semi-major Axis */
51
/*    b                                     Length of the Semi-minor Axis */
52
/*                                                                        */
53
/*  OUTPUT                                                                */
54
/*                                                                        */
55
/*    None                                                                */
56
/*                                                                        */
57
/*  CALLS                                                                 */
58
/*                                                                        */
59
/*    _gx_utility_rectangle_overlap_detect  Detect two rectangles being   */
60
/*                                            overlap to each other       */
61
/*    _gx_utility_math_sqrt                 Compute the square root value */
62
/*    [gx_display_driver_pixel_blend]       Basic display driver pixel    */
63
/*                                            blend function              */
64
/*                                                                        */
65
/*  CALLED BY                                                             */
66
/*                                                                        */
67
/*    GUIX Internal Code                                                  */
68
/*                                                                        */
69
/**************************************************************************/
70
395
VOID _gx_display_driver_generic_aliased_ellipse_draw(GX_DRAW_CONTEXT *context, INT xcenter, INT ycenter, INT a, INT b)
71
{
72
/* The ellipse draw function is implemented from midpoint ellipse algorithm. */
73
74
GX_DISPLAY   *display;
75
GX_RECTANGLE *clip;
76
GX_BRUSH     *brush;
77
INT           x;
78
INT           y;
79
GX_POINT      point;
80
395
INT           sign[4][2] = {{1, 1}, {-1, 1}, {1, -1}, {-1, -1}};
81
INT           index;
82
INT           aa;
83
INT           bb;
84
INT           realval;
85
INT           error;
86
GX_UBYTE      alpha1;
87
GX_UBYTE      alpha2;
88
89
VOID          (*blend_func)(GX_DRAW_CONTEXT *context,
90
                            INT x, INT y, GX_COLOR color, GX_UBYTE alpha);
91
92
#if defined(GX_BRUSH_ALPHA_SUPPORT)
93
GX_UBYTE brush_alpha;
94
95
395
    brush_alpha = context -> gx_draw_context_brush.gx_brush_alpha;
96
97
395
    if (brush_alpha == 0)
98
    {
99
        /* Nothing to draw here. */
100
128
        return;
101
    }
102
#endif
103
104
268
    display = context -> gx_draw_context_display;
105
268
    clip = context -> gx_draw_context_clip;
106
268
    brush = &context -> gx_draw_context_brush;
107
108
268
    blend_func = display -> gx_display_driver_pixel_blend;
109
110
268
    if (blend_func == GX_NULL)
111
    {
112
1
        return;
113
    }
114
115
267
    aa = a * a;
116
267
    bb = b * b;
117
267
    x = 0;
118
267
    y = b;
119
267
    error = 0;
120
121
    /* Region I of the first quarter of the ellipse.  */
122
16661
    while (2 * bb * (x + 1) < aa * (2 * y - 1))
123
    {
124
16411
        alpha1 = (GX_UBYTE)(255 - error);
125
16411
        alpha2 = (GX_UBYTE)error;
126
#if defined(GX_BRUSH_ALPHA_SUPPORT)
127
16411
        alpha1 = (GX_UBYTE)(alpha1 * brush_alpha / 255);
128
16411
        alpha2 = (GX_UBYTE)(alpha2 * brush_alpha / 255);
129
#endif
130
        /* calculate error of next pixel. */
131
16411
        realval = bb - bb * (x + 1) * (x + 1) / aa;
132
16411
        error = (y << 8) - (INT)(_gx_utility_math_sqrt((UINT)(realval << 10)) << 3);
133
134
16411
        if (error >= 510)
135
        {
136
            /* The slope in point(x + 1, y) is greater than -1,
137
               make point(x, y) the delimit pixel, break here. */
138
17
            realval = bb - bb * x * x / aa;
139
17
            error = (y << 8) - (INT)(_gx_utility_math_sqrt((UINT)(realval << 10)) << 3);
140
17
            break;
141
        }
142
143
81970
        for (index = 0; index < 4; index++)
144
        {
145
65576
            point.gx_point_x = (GX_VALUE)(x * sign[index][0] + xcenter);
146
65576
            point.gx_point_y = (GX_VALUE)(y * sign[index][1] + ycenter);
147
148
65576
            if (_gx_utility_rectangle_point_detect(clip, point))
149
            {
150
64504
                blend_func(context, point.gx_point_x, point.gx_point_y, brush -> gx_brush_line_color, alpha1);
151
            }
152
153
65576
            point.gx_point_y = (GX_VALUE)((y - 1) * sign[index][1] + ycenter);
154
155
65576
            if (_gx_utility_rectangle_point_detect(clip, point))
156
            {
157
64504
                blend_func(context, point.gx_point_x, point.gx_point_y, brush -> gx_brush_line_color, alpha2);
158
            }
159
        }
160
161
16394
        if (error >= 255)
162
        {
163
2742
            error -= 255;
164
2742
            y--;
165
        }
166
167
16394
        x++;
168
    }
169
170
267
    alpha1 = (GX_UBYTE)(255 - error);
171
#if defined(GX_BRUSH_ALPHA_SUPPORT)
172
267
    alpha1 = (GX_UBYTE)(alpha1 * brush_alpha / 255);
173
#endif
174
175
    /* Draw delimit pixel where delta x equals to delta y.  */
176
1335
    for (index = 0; index < 4; index++)
177
    {
178
1068
        point.gx_point_x = (GX_VALUE)(x * sign[index][0] + xcenter);
179
1068
        point.gx_point_y = (GX_VALUE)(y * sign[index][1] + ycenter);
180
181
1068
        if (_gx_utility_rectangle_point_detect(clip, point))
182
        {
183
1016
            blend_func(context, point.gx_point_x, point.gx_point_y, brush -> gx_brush_line_color, alpha1);
184
        }
185
    }
186
187
    /* Region II of the first quarter of the ellipse.  */
188
17925
    while (y > 0)
189
    {
190
17658
        y--;
191
192
17658
        realval = aa - aa * y * y / bb;
193
17658
        error = (INT)(_gx_utility_math_sqrt((UINT)(realval << 10)) << 3) - (x << 8);
194
195
20528
        while (error >= 255)
196
        {
197
2870
            error -= 255;
198
2870
            x++;
199
        }
200
17658
        alpha1 = (GX_UBYTE)(255 - error);
201
17658
        alpha2 = (GX_UBYTE)error;
202
#if defined(GX_BRUSH_ALPHA_SUPPORT)
203
17658
        alpha1 = (GX_UBYTE)(alpha1 * brush_alpha / 255);
204
17658
        alpha2 = (GX_UBYTE)(alpha2 * brush_alpha / 255);
205
#endif
206
207
88290
        for (index = 0; index < 4; index++)
208
        {
209
70632
            point.gx_point_x = (GX_VALUE)(x * sign[index][0] + xcenter);
210
70632
            point.gx_point_y = (GX_VALUE)(y * sign[index][1] + ycenter);
211
212
213
70632
            if (_gx_utility_rectangle_point_detect(clip, point))
214
            {
215
63100
                blend_func(context, point.gx_point_x, point.gx_point_y, brush -> gx_brush_line_color, alpha1);
216
            }
217
218
70632
            point.gx_point_x = (GX_VALUE)((x + 1) * sign[index][0] + xcenter);
219
220
70632
            if (_gx_utility_rectangle_point_detect(clip, point))
221
            {
222
62984
                blend_func(context, point.gx_point_x, point.gx_point_y, brush -> gx_brush_line_color, alpha2);
223
            }
224
        }
225
    }
226
}
227