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_arc_clipping_get                 PORTABLE C      */
36 /*                                                           6.1          */
37 /*  AUTHOR                                                                */
38 /*                                                                        */
39 /*    Kenneth Maxwell, Microsoft Corporation                              */
40 /*                                                                        */
41 /*  DESCRIPTION                                                           */
42 /*                                                                        */
43 /*    This function returns the clipping area of a circle arc.            */
44 /*                                                                        */
45 /*  INPUT                                                                 */
46 /*                                                                        */
47 /*    xcenter                               x-coord of center of circle   */
48 /*    ycenter                               y-coord of center of circle   */
49 /*    r                                     Radius of circle              */
50 /*    start_angle                           Start angle for clipping      */
51 /*    end_argle                             End angle for clipping        */
52 /*    clip_1                                Clip result                   */
53 /*    cllp_2                                Clip result                   */
54 /*    clip_3                                Clip result                   */
55 /*    clip_4                                Clip result                   */
56 /*                                                                        */
57 /*  OUTPUT                                                                */
58 /*                                                                        */
59 /*    None                                                                */
60 /*                                                                        */
61 /*  CALLS                                                                 */
62 /*                                                                        */
63 /*    _gx_utility_circle_point_get          Get point coord on a circle   */
64 /*                                                                        */
65 /*  CALLED BY                                                             */
66 /*                                                                        */
67 /*    GUIX Internal Code                                                  */
68 /*                                                                        */
69 /*  RELEASE HISTORY                                                       */
70 /*                                                                        */
71 /*    DATE              NAME                      DESCRIPTION             */
72 /*                                                                        */
73 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
74 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
75 /*                                            resulting in version 6.1    */
76 /*                                                                        */
77 /**************************************************************************/
78 #if defined(GX_ARC_DRAWING_SUPPORT)
_gx_display_driver_arc_clipping_get(INT xcenter,INT ycenter,UINT r,INT start_angle,INT end_angle,GX_RECTANGLE * clip_1,GX_RECTANGLE * clip_2,GX_RECTANGLE * clip_3,GX_RECTANGLE * clip_4)79 VOID _gx_display_driver_arc_clipping_get(INT xcenter, INT ycenter, UINT r, INT start_angle, INT end_angle,
80                                          GX_RECTANGLE *clip_1, GX_RECTANGLE *clip_2, GX_RECTANGLE *clip_3, GX_RECTANGLE *clip_4)
81 {
82 
83 GX_POINT start_point;
84 GX_POINT end_point;
85 GX_VALUE ori_r = (GX_VALUE)r;
86 GX_VALUE neg_r = (GX_VALUE)(-ori_r);
87 
88     memset(clip_1, 0, sizeof(GX_RECTANGLE));
89     memset(clip_2, 0, sizeof(GX_RECTANGLE));
90     memset(clip_3, 0, sizeof(GX_RECTANGLE));
91     memset(clip_4, 0, sizeof(GX_RECTANGLE));
92 
93     /* Get two endpoint of the arc. */
94     _gx_utility_circle_point_get(0, 0, r, start_angle, &start_point);
95     _gx_utility_circle_point_get(0, 0, r, end_angle, &end_point);
96 
97     /* Calculate clipping. */
98     if (start_angle < 90)
99     {
100         if (end_angle <= 90)
101         {
102             clip_1 -> gx_rectangle_left = end_point.gx_point_x;
103             clip_1 -> gx_rectangle_top = end_point.gx_point_y;
104             clip_1 -> gx_rectangle_right = start_point.gx_point_x;
105             clip_1 -> gx_rectangle_bottom = start_point.gx_point_y;
106         }
107         else
108         {
109             clip_1 -> gx_rectangle_left = 0;
110             clip_1 -> gx_rectangle_top = neg_r;
111             clip_1 -> gx_rectangle_right = start_point.gx_point_x;
112             clip_1 -> gx_rectangle_bottom = start_point.gx_point_y;
113 
114             if (end_angle <= 180)
115             {
116                 clip_2 -> gx_rectangle_left = end_point.gx_point_x;
117                 clip_2 -> gx_rectangle_top = neg_r;
118                 clip_2 -> gx_rectangle_right = 0;
119                 clip_2 -> gx_rectangle_bottom = end_point.gx_point_y;
120             }
121             else
122             {
123                 clip_2 -> gx_rectangle_left = neg_r;
124                 clip_2 -> gx_rectangle_top = neg_r;
125                 clip_2 -> gx_rectangle_right = 0;
126                 clip_2 -> gx_rectangle_bottom = 0;
127 
128                 if (end_angle <= 270)
129                 {
130                     clip_3 -> gx_rectangle_left = neg_r;
131                     clip_3 -> gx_rectangle_top = 0;
132                     clip_3 -> gx_rectangle_right = end_point.gx_point_x;
133                     clip_3 -> gx_rectangle_bottom = end_point.gx_point_y;
134                 }
135                 else
136                 {
137                     clip_2 -> gx_rectangle_bottom = ori_r;
138 
139                     if (end_angle <= 360)
140                     {
141                         clip_3 -> gx_rectangle_left = 0;
142                         clip_3 -> gx_rectangle_top = end_point.gx_point_y;
143                         clip_3 -> gx_rectangle_right = end_point.gx_point_x;
144                         clip_3 -> gx_rectangle_bottom = ori_r;
145                     }
146                     else
147                     {
148                         clip_3 -> gx_rectangle_left = 0;
149                         clip_3 -> gx_rectangle_top = 0;
150                         clip_3 -> gx_rectangle_right = ori_r;
151                         clip_3 -> gx_rectangle_bottom = ori_r;
152 
153                         clip_4 -> gx_rectangle_left = end_point.gx_point_x;
154                         clip_4 -> gx_rectangle_top = end_point.gx_point_y;
155                         clip_4 -> gx_rectangle_right = ori_r;
156                         clip_4 -> gx_rectangle_bottom = 0;
157                     }
158                 }
159             }
160         }
161     }
162     else if (start_angle < 180)
163     {
164         if (end_angle <= 180)
165         {
166             clip_1 -> gx_rectangle_left = end_point.gx_point_x;
167             clip_1 -> gx_rectangle_top = start_point.gx_point_y;
168             clip_1 -> gx_rectangle_right = start_point.gx_point_x;
169             clip_1 -> gx_rectangle_bottom = end_point.gx_point_y;
170         }
171         else
172         {
173             clip_1 -> gx_rectangle_left = neg_r;
174             clip_1 -> gx_rectangle_top = start_point.gx_point_y;
175             clip_1 -> gx_rectangle_right = start_point.gx_point_x;
176             clip_1 -> gx_rectangle_bottom = 0;
177 
178             if (end_angle <= 270)
179             {
180                 clip_2 -> gx_rectangle_left = neg_r;
181                 clip_2 -> gx_rectangle_top = 0;
182                 clip_2 -> gx_rectangle_right = end_point.gx_point_x;
183                 clip_2 -> gx_rectangle_bottom = end_point.gx_point_y;
184             }
185             else
186             {
187                 clip_2 -> gx_rectangle_left = neg_r;
188                 clip_2 -> gx_rectangle_top = 0;
189                 clip_2 -> gx_rectangle_right = 0;
190                 clip_2 -> gx_rectangle_bottom = ori_r;
191 
192                 if (end_angle <= 360)
193                 {
194                     clip_3 -> gx_rectangle_left = 0;
195                     clip_3 -> gx_rectangle_top = end_point.gx_point_y;
196                     clip_3 -> gx_rectangle_right = end_point.gx_point_x;
197                     clip_3 -> gx_rectangle_bottom = ori_r;
198                 }
199                 else
200                 {
201                     clip_2 -> gx_rectangle_right = ori_r;
202 
203                     if (end_angle <= 450)
204                     {
205                         clip_3 -> gx_rectangle_left = end_point.gx_point_x;
206                         clip_3 -> gx_rectangle_top = end_point.gx_point_y;
207                         clip_3 -> gx_rectangle_right = ori_r;
208                         clip_3 -> gx_rectangle_bottom = 0;
209                     }
210                     else
211                     {
212                         clip_3 -> gx_rectangle_left = 0;
213                         clip_3 -> gx_rectangle_top = neg_r;
214                         clip_3 -> gx_rectangle_right = ori_r;
215                         clip_3 -> gx_rectangle_bottom = 0;
216 
217                         clip_4 -> gx_rectangle_left = end_point.gx_point_x;
218                         clip_4 -> gx_rectangle_top = neg_r;
219                         clip_4 -> gx_rectangle_right = 0;
220                         clip_4 -> gx_rectangle_bottom = end_point.gx_point_y;
221                     }
222                 }
223             }
224         }
225     }
226     else if (start_angle < 270)
227     {
228         if (end_angle <= 270)
229         {
230             clip_1 -> gx_rectangle_left = start_point.gx_point_x;
231             clip_1 -> gx_rectangle_top = start_point.gx_point_y;
232             clip_1 -> gx_rectangle_right = end_point.gx_point_x;
233             clip_1 -> gx_rectangle_bottom = end_point.gx_point_y;
234         }
235         else
236         {
237             clip_1 -> gx_rectangle_left = start_point.gx_point_x;
238             clip_1 -> gx_rectangle_top = start_point.gx_point_y;
239             clip_1 -> gx_rectangle_right = 0;
240             clip_1 -> gx_rectangle_bottom = ori_r;
241 
242             if (end_angle <= 360)
243             {
244                 clip_2 -> gx_rectangle_left = 0;
245                 clip_2 -> gx_rectangle_top = end_point.gx_point_y;
246                 clip_2 -> gx_rectangle_right = end_point.gx_point_x;
247                 clip_2 -> gx_rectangle_bottom = ori_r;
248             }
249             else
250             {
251                 clip_2 -> gx_rectangle_left = 0;
252                 clip_2 -> gx_rectangle_top = 0;
253                 clip_2 -> gx_rectangle_right = ori_r;
254                 clip_2 -> gx_rectangle_bottom = ori_r;
255 
256                 if (end_angle <= 450)
257                 {
258                     clip_3 -> gx_rectangle_left = end_point.gx_point_x;
259                     clip_3 -> gx_rectangle_top = end_point.gx_point_y;
260                     clip_3 -> gx_rectangle_right = ori_r;
261                     clip_3 -> gx_rectangle_bottom = ori_r;
262                 }
263                 else
264                 {
265                     clip_2 -> gx_rectangle_top = neg_r;
266 
267                     if (end_angle <= 540)
268                     {
269                         clip_3 -> gx_rectangle_left = end_point.gx_point_x;
270                         clip_3 -> gx_rectangle_top = neg_r;
271                         clip_3 -> gx_rectangle_right = 0;
272                         clip_3 -> gx_rectangle_bottom = end_point.gx_point_y;
273                     }
274                     else
275                     {
276                         clip_3 -> gx_rectangle_left = neg_r;
277                         clip_3 -> gx_rectangle_top = neg_r;
278                         clip_3 -> gx_rectangle_right = 0;
279                         clip_3 -> gx_rectangle_bottom = 0;
280 
281                         clip_4 -> gx_rectangle_left = neg_r;
282                         clip_4 -> gx_rectangle_top = 0;
283                         clip_4 -> gx_rectangle_right = end_point.gx_point_x;
284                         clip_4 -> gx_rectangle_bottom = end_point.gx_point_y;
285                     }
286                 }
287             }
288         }
289     }
290     else
291     {
292         if (end_angle <= 360)
293         {
294             clip_1 -> gx_rectangle_left = start_point.gx_point_x;
295             clip_1 -> gx_rectangle_top = end_point.gx_point_y;
296             clip_1 -> gx_rectangle_right = end_point.gx_point_x;
297             clip_1 -> gx_rectangle_bottom = start_point.gx_point_y;
298         }
299         else
300         {
301             clip_1 -> gx_rectangle_left = start_point.gx_point_x;
302             clip_1 -> gx_rectangle_top = 0;
303             clip_1 -> gx_rectangle_right = ori_r;
304             clip_1 -> gx_rectangle_bottom = start_point.gx_point_y;
305 
306             if (end_angle <= 450)
307             {
308                 clip_2 -> gx_rectangle_left = end_point.gx_point_x;
309                 clip_2 -> gx_rectangle_top = end_point.gx_point_y;
310                 clip_2 -> gx_rectangle_right = ori_r;
311                 clip_2 -> gx_rectangle_bottom = 0;
312             }
313             else
314             {
315                 clip_2 -> gx_rectangle_left = 0;
316                 clip_2 -> gx_rectangle_top = neg_r;
317                 clip_2 -> gx_rectangle_right = ori_r;
318                 clip_2 -> gx_rectangle_bottom = 0;
319 
320                 if (end_angle <= 540)
321                 {
322                     clip_3 -> gx_rectangle_left = end_point.gx_point_x;
323                     clip_3 -> gx_rectangle_top = neg_r;
324                     clip_3 -> gx_rectangle_right = 0;
325                     clip_3 -> gx_rectangle_bottom = end_point.gx_point_y;
326                 }
327                 else
328                 {
329                     clip_2 -> gx_rectangle_left = neg_r;
330 
331                     if (end_angle <= 630)
332                     {
333                         clip_3 -> gx_rectangle_left = neg_r;
334                         clip_3 -> gx_rectangle_top = 0;
335                         clip_3 -> gx_rectangle_right = end_point.gx_point_x;
336                         clip_3 -> gx_rectangle_bottom = end_point.gx_point_y;
337                     }
338                     else
339                     {
340                         clip_3 -> gx_rectangle_left = neg_r;
341                         clip_3 -> gx_rectangle_top = 0;
342                         clip_3 -> gx_rectangle_right = 0;
343                         clip_3 -> gx_rectangle_bottom = ori_r;
344 
345                         clip_4 -> gx_rectangle_left = 0;
346                         clip_4 -> gx_rectangle_top = end_point.gx_point_y;
347                         clip_4 -> gx_rectangle_right = end_point.gx_point_x;
348                         clip_4 -> gx_rectangle_bottom = ori_r;
349                     }
350                 }
351             }
352         }
353     }
354 
355     clip_1 -> gx_rectangle_left = (GX_VALUE)(clip_1 -> gx_rectangle_left + (GX_VALUE)xcenter);
356     clip_1 -> gx_rectangle_top = (GX_VALUE)(clip_1 -> gx_rectangle_top + (GX_VALUE)ycenter);
357     clip_1 -> gx_rectangle_right = (GX_VALUE)(clip_1 -> gx_rectangle_right + (GX_VALUE)xcenter);
358     clip_1 -> gx_rectangle_bottom = (GX_VALUE)(clip_1 -> gx_rectangle_bottom + (GX_VALUE)ycenter);
359 
360     clip_2 -> gx_rectangle_left = (GX_VALUE)(clip_2 -> gx_rectangle_left + (GX_VALUE)xcenter);
361     clip_2 -> gx_rectangle_top = (GX_VALUE)(clip_2 -> gx_rectangle_top + (GX_VALUE)ycenter);
362     clip_2 -> gx_rectangle_right = (GX_VALUE)(clip_2 -> gx_rectangle_right + (GX_VALUE)xcenter);
363     clip_2 -> gx_rectangle_bottom = (GX_VALUE)(clip_2 -> gx_rectangle_bottom + (GX_VALUE)ycenter);
364 
365     clip_3 -> gx_rectangle_left = (GX_VALUE)(clip_3 -> gx_rectangle_left + (GX_VALUE)xcenter);
366     clip_3 -> gx_rectangle_top = (GX_VALUE)(clip_3 -> gx_rectangle_top + (GX_VALUE)ycenter);
367     clip_3 -> gx_rectangle_right = (GX_VALUE)(clip_3 -> gx_rectangle_right + (GX_VALUE)xcenter);
368     clip_3 -> gx_rectangle_bottom = (GX_VALUE)(clip_3 -> gx_rectangle_bottom + (GX_VALUE)ycenter);
369 
370     clip_4 -> gx_rectangle_left = (GX_VALUE)(clip_4 -> gx_rectangle_left + (GX_VALUE)xcenter);
371     clip_4 -> gx_rectangle_top = (GX_VALUE)(clip_4 -> gx_rectangle_top + (GX_VALUE)ycenter);
372     clip_4 -> gx_rectangle_right = (GX_VALUE)(clip_4 -> gx_rectangle_right + (GX_VALUE)xcenter);
373     clip_4 -> gx_rectangle_bottom = (GX_VALUE)(clip_4 -> gx_rectangle_bottom + (GX_VALUE)ycenter);
374 }
375 #endif
376 
377