GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_generic_arc_draw.c Lines: 60 60 100.0 %
Date: 2026-03-06 19:21:09 Branches: 50 50 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_system.h"
29
#include "gx_utility.h"
30
#include "gx_display.h"
31
32
/**************************************************************************/
33
/*                                                                        */
34
/*  FUNCTION                                               RELEASE        */
35
/*                                                                        */
36
/*    _gx_display_driver_generic_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 arc.                                  */
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_pixel_blend]       Basic display driver pixel    */
60
/*                                            blend function              */
61
/*    _gx_display_driver_arc_clipping_get                                 */
62
/*                                          Get the clipping rectangles   */
63
/*                                            of the circle arc           */
64
/*    _gx_utility_rectangle_point_detect    Detect whether a pixel is     */
65
/*                                            inside rectangle            */
66
/*    [gx_display_driver_pixel_write]       Basic display driver pixel    */
67
/*                                            write function              */
68
/*                                                                        */
69
/*  CALLED BY                                                             */
70
/*                                                                        */
71
/*    GUIX Internal Code                                                  */
72
/*                                                                        */
73
/**************************************************************************/
74
#if defined(GX_ARC_DRAWING_SUPPORT)
75
478
VOID _gx_display_driver_generic_arc_draw(GX_DRAW_CONTEXT *context, INT xcenter, INT ycenter, UINT r, INT start_angle, INT end_angle)
76
{
77
/* The arc draw function is implemented by clipping a circle.
78
   Calculate the arc clipping first, turn on the pixel on circle when the pixel
79
   is inside the arc clipping area.                                             */
80
81
GX_RECTANGLE clip[4];
82
INT          x, y;
83
INT          d;
84
GX_POINT     point;
85
478
INT          sign[4][2] = {{1, 1}, {-1, 1}, {1, -1}, {-1, -1}};
86
INT          index;
87
478
GX_DISPLAY  *display = context -> gx_draw_context_display;
88
478
GX_BRUSH    *brush = &context -> gx_draw_context_brush;
89
90
#if defined(GX_BRUSH_ALPHA_SUPPORT)
91
478
GX_UBYTE     brush_alpha = brush -> gx_brush_alpha;
92
93
478
    if (display -> gx_display_driver_pixel_blend == GX_NULL)
94
    {
95
        /* Pixel blend function is null means alpha isn't supported in this driver.
96
        So set alpha value to 0xff to make it draw the original color in case GX_BRUSH_ALPHA_SUPPORT is defined. */
97
413
        brush_alpha = 0xff;
98
    }
99
    else
100
    {
101
65
        if (brush_alpha == 0)
102
        /* Nothing to draw here. */
103
8
        return;
104
    }
105
#endif
106
107
    /* Get the clipping rectangles of the circle arc. */
108
470
    _gx_display_driver_arc_clipping_get(xcenter, ycenter, r, start_angle, end_angle, &clip[0], &clip[1], &clip[2], &clip[3]);
109
110
470
    _gx_utility_rectangle_overlap_detect(context -> gx_draw_context_clip, &clip[0], &clip[0]);
111
470
    _gx_utility_rectangle_overlap_detect(context -> gx_draw_context_clip, &clip[1], &clip[1]);
112
470
    _gx_utility_rectangle_overlap_detect(context -> gx_draw_context_clip, &clip[2], &clip[2]);
113
470
    _gx_utility_rectangle_overlap_detect(context -> gx_draw_context_clip, &clip[3], &clip[3]);
114
115
470
    x = 0;
116
470
    y = (INT)r;
117
470
    d = (INT)(5 - 4 * r);
118
119
#if defined (GX_BRUSH_ALPHA_SUPPORT)
120
470
    if (brush_alpha != 0xff)
121
    {
122
3178
        while (x <= y)
123
        {
124
15780
            for (index = 0; index < 4; index++)
125
            {
126
12624
                point.gx_point_x = (GX_VALUE)(x * sign[index][0] + xcenter);
127
12624
                point.gx_point_y = (GX_VALUE)(y * sign[index][1] + ycenter);
128
129

25011
                if ((_gx_utility_rectangle_point_detect(&clip[0], point)) ||
130
24546
                    (_gx_utility_rectangle_point_detect(&clip[1], point)) ||
131
24185
                    (_gx_utility_rectangle_point_detect(&clip[2], point)) ||
132
12026
                    (_gx_utility_rectangle_point_detect(&clip[3], point)))
133
                {
134
697
                    display -> gx_display_driver_pixel_blend(context, point.gx_point_x, point.gx_point_y, brush -> gx_brush_line_color, brush_alpha);
135
                }
136
137
12624
                point.gx_point_x = (GX_VALUE)(y * sign[index][0] + xcenter);
138
12624
                point.gx_point_y = (GX_VALUE)(x * sign[index][1] + ycenter);
139
140

24975
                if ((_gx_utility_rectangle_point_detect(&clip[0], point)) ||
141
24506
                    (_gx_utility_rectangle_point_detect(&clip[1], point)) ||
142
24215
                    (_gx_utility_rectangle_point_detect(&clip[2], point)) ||
143
12060
                    (_gx_utility_rectangle_point_detect(&clip[3], point)))
144
                {
145
601
                    display -> gx_display_driver_pixel_blend(context, point.gx_point_x, point.gx_point_y, brush -> gx_brush_line_color, brush_alpha);
146
                }
147
            }
148
149
3156
            if (d < 0)
150
            {
151
1834
                d += 8 * x + 12;
152
            }
153
            else
154
            {
155
1322
                d += 8 * (x - y) + 20;
156
1322
                y--;
157
            }
158
3156
            x++;
159
        }
160
    }
161
    else
162
    {
163
#endif
164
37356
        while (x <= y)
165
        {
166
184540
            for (index = 0; index < 4; index++)
167
            {
168
147632
                point.gx_point_x = (GX_VALUE)(x * sign[index][0] + xcenter);
169
147632
                point.gx_point_y = (GX_VALUE)(y * sign[index][1] + ycenter);
170
171

280308
                if ((_gx_utility_rectangle_point_detect(&clip[0], point)) ||
172
253685
                    (_gx_utility_rectangle_point_detect(&clip[1], point)) ||
173
241019
                    (_gx_utility_rectangle_point_detect(&clip[2], point)) ||
174
120010
                    (_gx_utility_rectangle_point_detect(&clip[3], point)))
175
                {
176
27830
                    display -> gx_display_driver_pixel_write(context, point.gx_point_x, point.gx_point_y, brush -> gx_brush_line_color);
177
                }
178
179
147632
                point.gx_point_x = (GX_VALUE)(y * sign[index][0] + xcenter);
180
147632
                point.gx_point_y = (GX_VALUE)(x * sign[index][1] + ycenter);
181
182

284036
                if ((_gx_utility_rectangle_point_detect(&clip[0], point)) ||
183
265257
                    (_gx_utility_rectangle_point_detect(&clip[1], point)) ||
184
256943
                    (_gx_utility_rectangle_point_detect(&clip[2], point)) ||
185
128090
                    (_gx_utility_rectangle_point_detect(&clip[3], point)))
186
                {
187
19795
                    display -> gx_display_driver_pixel_write(context, point.gx_point_x, point.gx_point_y, brush -> gx_brush_line_color);
188
                }
189
            }
190
191
36908
            if (d < 0)
192
            {
193
21334
                d += 8 * x + 12;
194
            }
195
            else
196
            {
197
15574
                d += 8 * (x - y) + 20;
198
15574
                y--;
199
            }
200
36908
            x++;
201
        }
202
#if defined (GX_BRUSH_ALPHA_SUPPORT)
203
    }
204
#endif
205
}
206
#endif
207