GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_canvas_pie_draw.c Lines: 56 56 100.0 %
Date: 2026-03-06 19:21:09 Branches: 40 40 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
#include "gx_canvas.h"
32
33
/**************************************************************************/
34
/*                                                                        */
35
/*  FUNCTION                                               RELEASE        */
36
/*                                                                        */
37
/*    _gx_canvas_pie_draw                                 PORTABLE C      */
38
/*                                                           6.1          */
39
/*  AUTHOR                                                                */
40
/*                                                                        */
41
/*    Kenneth Maxwell, Microsoft Corporation                              */
42
/*                                                                        */
43
/*  DESCRIPTION                                                           */
44
/*                                                                        */
45
/*    This draws a pie into the currrent context.                         */
46
/*                                                                        */
47
/*  INPUT                                                                 */
48
/*                                                                        */
49
/*    xcenter                               x-coord of center of circle   */
50
/*                                            arc                         */
51
/*    ycenter                               y-coord of center of circle   */
52
/*                                            arc                         */
53
/*    r                                     Radius of circle arc          */
54
/*    start_angle                           The start angle of circle arc */
55
/*    end_angle                             The end angle of circle arc   */
56
/*                                                                        */
57
/*  OUTPUT                                                                */
58
/*                                                                        */
59
/*    None                                                                */
60
/*                                                                        */
61
/*  CALLS                                                                 */
62
/*                                                                        */
63
/*    _gx_utility_rectangle_define          Define a rectangle            */
64
/*    _gx_utility_rectangle_overlap_detect  Detect rectangle overlap      */
65
/*    [gx_display_driver_pie_fill]          Display driver basic          */
66
/*                                            pie drawing routine         */
67
/*    [gx_display_driver_arc_draw]          Display driver basic          */
68
/*                                            arc drawing routine         */
69
/*    _gx_display_driver_anti_aliased_arc_draw                            */
70
/*                                          Display driver basic aliased  */
71
/*                                            arc drawing routine         */
72
/*    _gx_utility_circle_point_get          Get point position on a circle*/
73
/*    _gx_canvas_line_draw                  Draw a line                   */
74
/*                                                                        */
75
/*  CALLED BY                                                             */
76
/*                                                                        */
77
/*    Application code                                                    */
78
/*                                                                        */
79
/**************************************************************************/
80
#if defined(GX_ARC_DRAWING_SUPPORT)
81
2703
UINT _gx_canvas_pie_draw(INT xcenter, INT ycenter, UINT r, INT start_angle, INT end_angle)
82
{
83
/* A pie is a fraction of a circle delimited by two lines that span from the center of the
84
   circle to the one side each. */
85
86
GX_DRAW_CONTEXT *context;
87
GX_DISPLAY      *display;
88
GX_RECTANGLE     bound;
89
GX_RECTANGLE     clip_rect;
90
GX_VIEW         *view;
91
GX_BRUSH        *brush;
92
GX_POINT         point;
93
INT              brush_width;
94
VOID             (*outline_function)(GX_DRAW_CONTEXT *context, INT xcenter, INT ycenter, UINT r, INT start_angle, INT end_angle);
95
96
#if defined(GX_BRUSH_ALPHA_SUPPORT)
97
GX_UBYTE brush_alpha;
98
#endif
99
100
2867
    while (start_angle < 0)
101
    {
102
164
        start_angle += 360;
103
    }
104
105
2751
    while (end_angle < 0)
106
    {
107
48
        end_angle += 360;
108
    }
109
110
2703
    if (start_angle >= 360)
111
    {
112
408
        start_angle %= 360;
113
    }
114
115
2703
    if (end_angle >= 360)
116
    {
117
600
        end_angle %= 360;
118
    }
119
120
2703
    if (end_angle <= start_angle)
121
    {
122
620
        end_angle += 360;
123
    }
124
    /* pick up the current drawing context */
125
2703
    context = _gx_system_current_draw_context;
126
127
2703
    brush = &context -> gx_draw_context_brush;
128
129
2703
    brush_width = ((INT)(brush -> gx_brush_width + 1)) >> 1;
130
131
    /* Define pie bounding rectangle. */
132
2703
    _gx_utility_rectangle_define(&bound, (GX_VALUE)(xcenter - (INT)r - brush_width), (GX_VALUE)(ycenter - (INT)r - brush_width),
133
2703
                                 (GX_VALUE)(xcenter + (INT)r + brush_width), (GX_VALUE)(ycenter + (INT)r + brush_width));
134
135
2703
    brush_width = brush -> gx_brush_width;
136
137
138
    /* clip the pie bounding box to the dirty rectangle */
139
2703
    if (!_gx_utility_rectangle_overlap_detect(&bound, &context -> gx_draw_context_dirty, &bound))
140
    {
141
        /* nothing to draw, return */
142
4
        return GX_SUCCESS;
143
    }
144
145
    /* pick up current display driver */
146
2699
    display = context -> gx_draw_context_display;
147
148
    /* Determine outline function to utilize.*/
149
2699
    outline_function = GX_NULL;
150
151
    /* Determine which outline function to use.*/
152
2699
    if (brush_width == 1)
153
    {
154
        /* if anti-alias is requested and this is supported by display, use it */
155
677
        if ((brush -> gx_brush_style & GX_BRUSH_ALIAS) &&
156
496
            display -> gx_display_driver_anti_aliased_arc_draw != GX_NULL)
157
        {
158
368
            outline_function = display -> gx_display_driver_anti_aliased_arc_draw;
159
        }
160
        else
161
        {
162
            /* otherwise use non-aliased outline */
163
309
            outline_function = display -> gx_display_driver_arc_draw;
164
        }
165
    }
166
    else
167
    {
168
2022
        if (brush_width > 1)
169
        {
170
            /* if anti-alias is requested and this is supported by display, use it */
171
1604
            if ((brush -> gx_brush_style & GX_BRUSH_ALIAS) &&
172
1288
                display -> gx_display_driver_anti_aliased_wide_arc_draw)
173
            {
174
1024
                outline_function = display -> gx_display_driver_anti_aliased_wide_arc_draw;
175
            }
176
            else
177
            {
178
                /* otherwise use non-aliased outline */
179
580
                outline_function = display -> gx_display_driver_wide_arc_draw;
180
            }
181
        }
182
    }
183
184
    /* test to determine if the bounding rectangle overlaps the region we are allowed to draw
185
       into. For each view that overlaps the bounding rectangle, do some drawing.
186
     */
187
2699
    view = context -> gx_draw_context_view_head;
188
189
5410
    while (view)
190
    {
191
2711
        if (!_gx_utility_rectangle_overlap_detect(&view -> gx_view_rectangle, &bound, &clip_rect))
192
        {
193
16
            view = view -> gx_view_next;
194
16
            continue;
195
        }
196
197
        /* we have a view into which we can draw the arc, do it */
198
2695
        context -> gx_draw_context_clip = &clip_rect;
199
200
2695
        if (brush_width)
201
        {
202
2277
            brush_width -= 1;
203
2277
            brush_width >>= 1;
204
        }
205
206
2695
        if ((brush -> gx_brush_style & (GX_BRUSH_SOLID_FILL | GX_BRUSH_PIXELMAP_FILL)) &&
207
2351
            (r > (UINT)brush_width))
208
        {
209
2159
            display -> gx_display_driver_pie_fill(context, xcenter, ycenter, r - (UINT)brush_width, start_angle, end_angle);
210
        }
211
212
#if defined(GX_BRUSH_ALPHA_SUPPORT)
213
2695
        brush_alpha = context -> gx_draw_context_brush.gx_brush_alpha;
214
2695
        if (brush -> gx_brush_width > 1)
215
        {
216
1600
            context -> gx_draw_context_brush.gx_brush_alpha = GX_ALPHA_VALUE_OPAQUE;
217
        }
218
#endif
219
2695
        if (outline_function)
220
        {
221
2277
            outline_function(context, xcenter, ycenter, r, start_angle, end_angle);
222
        }
223
224
2695
        if (r > (UINT)brush_width)
225
        {
226
2439
            _gx_utility_circle_point_get(xcenter, ycenter, r - (UINT)brush_width, start_angle, &point);
227
228
            /* Draw delimiting line. */
229
2439
            _gx_canvas_line_draw((GX_VALUE)xcenter, (GX_VALUE)ycenter, point.gx_point_x, point.gx_point_y);
230
231
2439
            _gx_utility_circle_point_get(xcenter, ycenter, r - (UINT)brush_width, end_angle, &point);
232
233
            /* Draw delimiting line. */
234
2439
            _gx_canvas_line_draw((GX_VALUE)xcenter, (GX_VALUE)ycenter, point.gx_point_x, point.gx_point_y);
235
        }
236
237
#if defined(GX_BRUSH_ALPHA_SUPPORT)
238
2695
        context -> gx_draw_context_brush.gx_brush_alpha = brush_alpha;
239
#endif
240
2695
        view = view -> gx_view_next;
241
    }
242
243
    /* Return successful completion.  */
244
2699
    return(GX_SUCCESS);
245
}
246
247
#endif
248