GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_generic_arc_draw.c Lines: 60 60 100.0 %
Date: 2024-12-05 08:52:37 Branches: 50 50 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_circle_draw              PORTABLE C      */
36
/*                                                           6.1          */
37
/*  AUTHOR                                                                */
38
/*                                                                        */
39
/*    Kenneth Maxwell, Microsoft Corporation                              */
40
/*                                                                        */
41
/*  DESCRIPTION                                                           */
42
/*                                                                        */
43
/*    Display driver to draw circle arc.                                  */
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_display_driver_pixel_blend]       Basic display driver pixel    */
59
/*                                            blend function              */
60
/*    _gx_display_driver_arc_clipping_get                                 */
61
/*                                          Get the clipping rectangles   */
62
/*                                            of the circle arc           */
63
/*    _gx_utility_rectangle_point_detect    Detect whether a pixel is     */
64
/*                                            inside rectangle            */
65
/*    [gx_display_driver_pixel_write]       Basic display driver pixel    */
66
/*                                            write function              */
67
/*                                                                        */
68
/*  CALLED BY                                                             */
69
/*                                                                        */
70
/*    GUIX Internal Code                                                  */
71
/*                                                                        */
72
/*  RELEASE HISTORY                                                       */
73
/*                                                                        */
74
/*    DATE              NAME                      DESCRIPTION             */
75
/*                                                                        */
76
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
77
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
78
/*                                            resulting in version 6.1    */
79
/*                                                                        */
80
/**************************************************************************/
81
#if defined(GX_ARC_DRAWING_SUPPORT)
82
478
VOID _gx_display_driver_generic_arc_draw(GX_DRAW_CONTEXT *context, INT xcenter, INT ycenter, UINT r, INT start_angle, INT end_angle)
83
{
84
/* The arc draw function is implemented by clipping a circle.
85
   Calculate the arc clipping first, turn on the pixel on circle when the pixel
86
   is inside the arc clipping area.                                             */
87
88
GX_RECTANGLE clip[4];
89
INT          x, y;
90
INT          d;
91
GX_POINT     point;
92
478
INT          sign[4][2] = {{1, 1}, {-1, 1}, {1, -1}, {-1, -1}};
93
INT          index;
94
478
GX_DISPLAY  *display = context -> gx_draw_context_display;
95
478
GX_BRUSH    *brush = &context -> gx_draw_context_brush;
96
97
#if defined(GX_BRUSH_ALPHA_SUPPORT)
98
478
GX_UBYTE     brush_alpha = brush -> gx_brush_alpha;
99
100
478
    if (display -> gx_display_driver_pixel_blend == GX_NULL)
101
    {
102
        /* Pixel blend function is null means alpha isn't supported in this driver.
103
        So set alpha value to 0xff to make it draw the original color in case GX_BRUSH_ALPHA_SUPPORT is defined. */
104
413
        brush_alpha = 0xff;
105
    }
106
    else
107
    {
108
65
        if (brush_alpha == 0)
109
        /* Nothing to draw here. */
110
8
        return;
111
    }
112
#endif
113
114
    /* Get the clipping rectangles of the circle arc. */
115
470
    _gx_display_driver_arc_clipping_get(xcenter, ycenter, r, start_angle, end_angle, &clip[0], &clip[1], &clip[2], &clip[3]);
116
117
470
    _gx_utility_rectangle_overlap_detect(context -> gx_draw_context_clip, &clip[0], &clip[0]);
118
470
    _gx_utility_rectangle_overlap_detect(context -> gx_draw_context_clip, &clip[1], &clip[1]);
119
470
    _gx_utility_rectangle_overlap_detect(context -> gx_draw_context_clip, &clip[2], &clip[2]);
120
470
    _gx_utility_rectangle_overlap_detect(context -> gx_draw_context_clip, &clip[3], &clip[3]);
121
122
470
    x = 0;
123
470
    y = (INT)r;
124
470
    d = (INT)(5 - 4 * r);
125
126
#if defined (GX_BRUSH_ALPHA_SUPPORT)
127
470
    if (brush_alpha != 0xff)
128
    {
129
3178
        while (x <= y)
130
        {
131
15780
            for (index = 0; index < 4; index++)
132
            {
133
12624
                point.gx_point_x = (GX_VALUE)(x * sign[index][0] + xcenter);
134
12624
                point.gx_point_y = (GX_VALUE)(y * sign[index][1] + ycenter);
135
136

25011
                if ((_gx_utility_rectangle_point_detect(&clip[0], point)) ||
137
24546
                    (_gx_utility_rectangle_point_detect(&clip[1], point)) ||
138
24185
                    (_gx_utility_rectangle_point_detect(&clip[2], point)) ||
139
12026
                    (_gx_utility_rectangle_point_detect(&clip[3], point)))
140
                {
141
697
                    display -> gx_display_driver_pixel_blend(context, point.gx_point_x, point.gx_point_y, brush -> gx_brush_line_color, brush_alpha);
142
                }
143
144
12624
                point.gx_point_x = (GX_VALUE)(y * sign[index][0] + xcenter);
145
12624
                point.gx_point_y = (GX_VALUE)(x * sign[index][1] + ycenter);
146
147

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

280308
                if ((_gx_utility_rectangle_point_detect(&clip[0], point)) ||
179
253685
                    (_gx_utility_rectangle_point_detect(&clip[1], point)) ||
180
241019
                    (_gx_utility_rectangle_point_detect(&clip[2], point)) ||
181
120010
                    (_gx_utility_rectangle_point_detect(&clip[3], point)))
182
                {
183
27830
                    display -> gx_display_driver_pixel_write(context, point.gx_point_x, point.gx_point_y, brush -> gx_brush_line_color);
184
                }
185
186
147632
                point.gx_point_x = (GX_VALUE)(y * sign[index][0] + xcenter);
187
147632
                point.gx_point_y = (GX_VALUE)(x * sign[index][1] + ycenter);
188
189

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