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