GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_generic_aliased_circle_draw.c Lines: 47 47 100.0 %
Date: 2024-12-05 08:52:37 Branches: 22 22 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
/**************************************************************************/
32
/*                                                                        */
33
/*  FUNCTION                                               RELEASE        */
34
/*                                                                        */
35
/*    _gx_display_driver_generic_aliased_circle_draw      PORTABLE C      */
36
/*                                                           6.1          */
37
/*  AUTHOR                                                                */
38
/*                                                                        */
39
/*    Kenneth Maxwell, Microsoft Corporation                              */
40
/*                                                                        */
41
/*  DESCRIPTION                                                           */
42
/*                                                                        */
43
/*    Display driver to draw anti-aliased circle.                         */
44
/*                                                                        */
45
/*  INPUT                                                                 */
46
/*                                                                        */
47
/*    context                               Drawing context               */
48
/*    xcenter                               x-coord of center of circle   */
49
/*    ycenter                               y-coord of center of circle   */
50
/*    r                                     Radius of circle              */
51
/*                                                                        */
52
/*  OUTPUT                                                                */
53
/*                                                                        */
54
/*    None                                                                */
55
/*                                                                        */
56
/*  CALLS                                                                 */
57
/*                                                                        */
58
/*    _gx_utility_rectangle_overlap_detect  Detect two rectangles being   */
59
/*                                            overlap to each other       */
60
/*    [gx_display_driver_pixel_blend]       Basic display driver pixel    */
61
/*                                            blend 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
#if defined(GX_ARC_DRAWING_SUPPORT)
77
78
306
VOID _gx_display_driver_generic_aliased_circle_draw(GX_DRAW_CONTEXT *context, INT xcenter, INT ycenter, UINT r)
79
{
80
/* The circle draw function is implemented from midpoint circle algorithm. */
81
82
GX_DISPLAY   *display;
83
GX_RECTANGLE *clip;
84
GX_BRUSH     *brush;
85
INT           x;
86
INT           y;
87
GX_POINT      point;
88
306
INT           sign[4][2] = {{1, 1}, {-1, 1}, {1, -1}, {-1, -1}};
89
INT           index;
90
INT           error;
91
INT           yi;
92
GX_UBYTE      alpha1;
93
GX_UBYTE      alpha2;
94
VOID          (*blend_func)(GX_DRAW_CONTEXT *context,
95
                            INT x, INT y, GX_COLOR color, GX_UBYTE alpha);
96
97
#if defined(GX_BRUSH_ALPHA_SUPPORT)
98
GX_UBYTE brush_alpha;
99
100
306
    brush_alpha = context -> gx_draw_context_brush.gx_brush_alpha;
101
102
306
    if (brush_alpha == 0)
103
    {
104
        /* Nothing to draw here. */
105
85
        return;
106
    }
107
#endif
108
109
222
    display = context -> gx_draw_context_display;
110
222
    clip = context -> gx_draw_context_clip;
111
222
    brush = &context -> gx_draw_context_brush;
112
113
222
    blend_func = display -> gx_display_driver_pixel_blend;
114
115
222
    if (blend_func == GX_NULL)
116
    {
117
1
        return;
118
    }
119
120
221
    x = 0;
121
221
    y = (INT)r;
122
221
    error = 0;
123
124
21140
    while (x < y)
125
    {
126
20919
        alpha1 = (GX_UBYTE)(255 - error);
127
20919
        alpha2 = (GX_UBYTE)error;
128
#if defined(GX_BRUSH_ALPHA_SUPPORT)
129
20919
        alpha1 = (GX_UBYTE)(alpha1 * brush_alpha / 255);
130
20919
        alpha2 = (GX_UBYTE)(alpha2 * brush_alpha / 255);
131
#endif
132
133
104595
        for (index = 0; index < 4; index++)
134
        {
135
83676
            point.gx_point_x = (GX_VALUE)(x * sign[index][0] + xcenter);
136
83676
            point.gx_point_y = (GX_VALUE)(y * sign[index][1] + ycenter);
137
138
83676
            if (_gx_utility_rectangle_point_detect(clip, point))
139
            {
140
61872
                blend_func(context, point.gx_point_x, point.gx_point_y, brush -> gx_brush_line_color, alpha1);
141
            }
142
143
83676
            point.gx_point_y = (GX_VALUE)((y - 1) * sign[index][1] + ycenter);
144
145
83676
            if (_gx_utility_rectangle_point_detect(clip, point))
146
            {
147
62946
                blend_func(context, point.gx_point_x, point.gx_point_y, brush -> gx_brush_line_color, alpha2);
148
            }
149
150
83676
            point.gx_point_x = (GX_VALUE)(y * sign[index][0] + xcenter);
151
83676
            point.gx_point_y = (GX_VALUE)(x * sign[index][1] + ycenter);
152
153
83676
            if (_gx_utility_rectangle_point_detect(clip, point))
154
            {
155
45058
                blend_func(context, point.gx_point_x, point.gx_point_y, brush -> gx_brush_line_color, alpha1);
156
            }
157
158
83676
            point.gx_point_x = (GX_VALUE)((y - 1) * sign[index][0] + xcenter);
159
160
83676
            if (_gx_utility_rectangle_point_detect(clip, point))
161
            {
162
45908
                blend_func(context, point.gx_point_x, point.gx_point_y, brush -> gx_brush_line_color, alpha2);
163
            }
164
        }
165
166
20919
        x++;
167
168
20919
        yi = (INT)(r * r) - x * x;
169
20919
        error = (y << 8) - (INT)(_gx_utility_math_sqrt((UINT)(yi << 10)) << 3);
170
171
29591
        while (error >= 255)
172
        {
173
8672
            error -= 255;
174
8672
            y--;
175
        }
176
    }
177
178
221
    alpha1 = (GX_UBYTE)(255 - error);
179
#if defined(GX_BRUSH_ALPHA_SUPPORT)
180
221
    alpha1 = (GX_UBYTE)(alpha1 * brush_alpha / 255);
181
#endif
182
183
1105
    for (index = 0; index < 4; index++)
184
    {
185
884
        point.gx_point_x = (GX_VALUE)(x * sign[index][0] + xcenter);
186
884
        point.gx_point_y = (GX_VALUE)(y * sign[index][1] + ycenter);
187
188
884
        if (_gx_utility_rectangle_point_detect(clip, point))
189
        {
190
870
            blend_func(context, point.gx_point_x, point.gx_point_y, brush -> gx_brush_line_color, alpha1);
191
        }
192
    }
193
}
194
195
#endif
196