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