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 #define GX_SOURCE_CODE
21
22 #define REDVAL_332(_c) (USHORT)(((_c) >> 5) & 0x07)
23 #define GREENVAL_332(_c) (USHORT)(((_c) >> 2) & 0x07)
24 #define BLUEVAL_332(_c) (USHORT)((_c) & 0x03)
25
26 #define ASSEMBLECOLOR_332(_r, _g, _b) \
27 ((((_r) & 0x07) << 5) | \
28 (((_g) & 0x07) << 2) | \
29 ((_b) & 0x03))
30
31 /* Include necessary system files. */
32
33 #include "gx_api.h"
34 #include "gx_display.h"
35 #include "gx_context.h"
36 #include "gx_utility.h"
37 #include "gx_system.h"
38
39 /**************************************************************************/
40 /* */
41 /* FUNCTION RELEASE */
42 /* */
43 /* _gx_display_driver_332rgb_pixelmap_simple_alpha_rotate */
44 /* PORTABLE C */
45 /* 6.1.7 */
46 /* AUTHOR */
47 /* */
48 /* Kenneth Maxwell, Microsoft Corporation */
49 /* */
50 /* DESCRIPTION */
51 /* */
52 /* Internal helper function that rotates 332rgb format pixelmap with */
53 /* alpha in 90, 180 or 270 degree. */
54 /* */
55 /* INPUT */
56 /* */
57 /* context Drawing context */
58 /* xpos x-coord of top-left draw point*/
59 /* ypos y-coord of top-left draw point*/
60 /* pixelmap Pointer to GX_PIXELMAP struct */
61 /* angle The angle to rotate */
62 /* cx x-coord of rotate center */
63 /* cy y-coord of rotate center */
64 /* */
65 /* OUTPUT */
66 /* */
67 /* None */
68 /* */
69 /* CALLS */
70 /* */
71 /* [gx_display_driver_pixel_blend] Basic display driver pixel */
72 /* blend function */
73 /* */
74 /* CALLED BY */
75 /* */
76 /* _gx_display_driver_332rgb_pixelmap_rotate */
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 /* 06-02-2021 Kenneth Maxwell Modified comment(s), */
86 /* removed unused variable */
87 /* assignment, */
88 /* resulting in version 6.1.7 */
89 /* */
90 /**************************************************************************/
_gx_display_driver_332rgb_pixelmap_simple_alpha_rotate(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,INT angle,INT cx,INT cy)91 static VOID _gx_display_driver_332rgb_pixelmap_simple_alpha_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
92 INT angle, INT cx, INT cy)
93 {
94 GX_UBYTE *get;
95 GX_UBYTE *getalpha;
96 INT width;
97 INT height;
98 INT x;
99 INT y;
100 GX_RECTANGLE *clip;
101 INT newxpos;
102 INT newypos;
103 VOID (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR color, GX_UBYTE alpha);
104
105 clip = context -> gx_draw_context_clip;
106 blend_func = context -> gx_draw_context_display -> gx_display_driver_pixel_blend;
107
108 if (GX_NULL == blend_func)
109 {
110 return;
111 }
112
113 if (angle == 90)
114 {
115 width = pixelmap -> gx_pixelmap_height;
116 height = pixelmap -> gx_pixelmap_width;
117
118 newxpos = xpos + cx - (width - 1 - cy);
119 newypos = ypos + cy - cx;
120
121 for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
122 {
123 for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
124 {
125 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
126 getalpha = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
127 get += (width - 1 - x) * height;
128 get += y;
129 getalpha += (width - 1 - x) * height;
130 getalpha += y;
131 blend_func(context, x + newxpos, y + newypos, *get, *getalpha);
132 }
133 }
134 }
135 else if (angle == 180)
136 {
137
138 width = pixelmap -> gx_pixelmap_width;
139 height = pixelmap -> gx_pixelmap_height;
140
141 newxpos = xpos + cx - (width - 1 - cx);
142 newypos = ypos + cy - (height - 1 - cy);
143
144
145 for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
146 {
147 for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
148 {
149 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
150 getalpha = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
151 get += (height - 1 - y) * width;
152 get += width - 1 - x;
153 getalpha += (height - 1 - y) * width;
154 getalpha += width - 1 - x;
155
156 blend_func(context, x + newxpos, y + newypos, *get, *getalpha);
157 }
158 }
159 }
160 else
161 {
162 height = pixelmap -> gx_pixelmap_width;
163
164 newxpos = xpos + cx - cy;
165 newypos = ypos + cx - (height - 1 - cy);
166
167 for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
168 {
169 for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
170 {
171 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
172 getalpha = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
173 get += x * height;
174 get += height - 1 - y;
175 getalpha += x * height;
176 getalpha += height - 1 - y;
177
178 blend_func(context, x + newxpos, y + newypos, *get, *getalpha);
179 }
180 }
181 }
182 }
183
184 /**************************************************************************/
185 /* */
186 /* FUNCTION RELEASE */
187 /* */
188 /* _gx_display_driver_332rgb_pixelmap_alpha_rotate PORTABLE C */
189 /* 6.1.10 */
190 /* AUTHOR */
191 /* */
192 /* Kenneth Maxwell, Microsoft Corporation */
193 /* */
194 /* DESCRIPTION */
195 /* */
196 /* Internal helper function that rotates an 332rgb format pixelmap */
197 /* with alpha. */
198 /* */
199 /* INPUT */
200 /* */
201 /* context Drawing context */
202 /* xpos x-coord of top-left draw point*/
203 /* ypos y-coord of top-left draw point*/
204 /* pixelmap Pointer to GX_PIXELMAP struct */
205 /* angle The angle to rotate */
206 /* cx x-coord of rotate center */
207 /* cy y-coord of rotate center */
208 /* */
209 /* OUTPUT */
210 /* */
211 /* status Completion status */
212 /* */
213 /* CALLS */
214 /* */
215 /* _gx_utility_math_cos Compute the cosine value */
216 /* _gx_utility_math_sin Compute the sine value */
217 /* [gx_display_driver_pixel_blend] Basic display driver pixel */
218 /* blend function */
219 /* */
220 /* CALLED BY */
221 /* */
222 /* _gx_display_driver_8bpp_pixelmap_rotate */
223 /* */
224 /* RELEASE HISTORY */
225 /* */
226 /* DATE NAME DESCRIPTION */
227 /* */
228 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
229 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
230 /* resulting in version 6.1 */
231 /* 01-31-2022 Ting Zhu Modified comment(s), */
232 /* corrected logic, */
233 /* resulting in version 6.1.10 */
234 /* */
235 /**************************************************************************/
_gx_display_driver_332rgb_pixelmap_alpha_rotate(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,INT angle,INT cx,INT cy)236 static VOID _gx_display_driver_332rgb_pixelmap_alpha_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
237 INT angle, INT cx, INT cy)
238 {
239 GX_UBYTE *get;
240 GX_UBYTE *getalpha;
241 INT srcxres;
242 INT srcyres;
243 INT cosv;
244 INT sinv;
245 USHORT red;
246 USHORT green;
247 USHORT blue;
248 INT idxminx;
249 INT idxmaxx;
250 INT idxmaxy;
251 INT *mx;
252 INT *my;
253 INT xres;
254 INT yres;
255 INT x;
256 INT y;
257 INT xx;
258 INT yy;
259 USHORT a;
260 USHORT b;
261 USHORT c;
262 USHORT d;
263 USHORT alpha[4];
264 INT xdiff;
265 INT ydiff;
266 INT newxpos;
267 INT newypos;
268 GX_DISPLAY *display;
269 GX_RECTANGLE *clip;
270 VOID (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR color, GX_UBYTE alpha);
271
272 clip = context -> gx_draw_context_clip;
273 display = context -> gx_draw_context_display;
274 blend_func = display -> gx_display_driver_pixel_blend;
275 if (!blend_func)
276 {
277 return;
278 }
279
280 mx = _gx_system_scratchpad;
281 my = mx + 4;
282
283 mx[0] = mx[3] = -1;
284 mx[1] = mx[2] = 1;
285
286 my[0] = my[1] = 1;
287 my[2] = my[3] = -1;
288
289 idxminx = (angle / 90) & 0x3;
290 idxmaxx = (idxminx + 2) & 0x3;
291 idxmaxy = (idxminx + 1) & 0x3;
292
293 /* Calculate the source x and y center. */
294 srcxres = pixelmap -> gx_pixelmap_width >> 1;
295 srcyres = pixelmap -> gx_pixelmap_height >> 1;
296
297 cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
298 sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
299
300 xres = GX_FIXED_VAL_TO_INT(mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv);
301 yres = GX_FIXED_VAL_TO_INT(my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv);
302
303 /* Calculate the new rotation axis. */
304 xres = GX_FIXED_VAL_TO_INT((cx - srcxres) * cosv - (cy - srcyres) * sinv) + xres;
305 yres = GX_FIXED_VAL_TO_INT((cy - srcyres) * cosv + (cx - srcxres) * sinv) + yres;
306
307 newxpos = xpos + cx - xres;
308 newypos = ypos + cy - yres;
309
310 /* Loop through the source's pixels. */
311 for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
312 {
313 for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
314 {
315 xx = (x - xres) * cosv + (y - yres) * sinv;
316 yy = (y - yres) * cosv - (x - xres) * sinv;
317
318 xdiff = GX_FIXED_VAL_TO_INT(xx << 8) & 0xff;
319 ydiff = GX_FIXED_VAL_TO_INT(yy << 8) & 0xff;
320
321 xx = GX_FIXED_VAL_TO_INT(xx) + cx;
322 yy = GX_FIXED_VAL_TO_INT(yy) + cy;
323
324 if ((xx >= -1) && (xx < pixelmap -> gx_pixelmap_width) &&
325 (yy >= -1) && (yy < pixelmap -> gx_pixelmap_height))
326 {
327 if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_width - 1) && \
328 (yy >= 0) && (yy < pixelmap -> gx_pixelmap_height - 1))
329 {
330 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
331 get += yy * pixelmap -> gx_pixelmap_width;
332 get += xx;
333
334 getalpha = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
335 getalpha += yy * pixelmap -> gx_pixelmap_width;
336 getalpha += xx;
337
338 a = *get;
339 alpha[0] = *getalpha;
340
341 b = *(get + 1);
342 alpha[1] = *(getalpha + 1);
343
344 c = *(get + pixelmap -> gx_pixelmap_width);
345 alpha[2] = *(getalpha + pixelmap -> gx_pixelmap_width);
346
347 d = *(get + pixelmap -> gx_pixelmap_width + 1);
348 alpha[3] = *(getalpha + pixelmap -> gx_pixelmap_width + 1);
349 }
350 else
351 {
352 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
353 getalpha = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
354
355 a = 0;
356 b = 0;
357 c = 0;
358 d = 0;
359
360 if (xx == -1)
361 {
362 /* handle left edge. */
363 if (yy >= 0)
364 {
365 b = *(get + yy * pixelmap -> gx_pixelmap_width);
366 alpha[1] = *(getalpha + yy * pixelmap -> gx_pixelmap_width);
367 }
368
369 if (yy < pixelmap -> gx_pixelmap_height - 1)
370 {
371 d = *(get + (yy + 1) * pixelmap -> gx_pixelmap_width);
372 alpha[3] = *(getalpha + (yy + 1) * pixelmap -> gx_pixelmap_width);
373 }
374 }
375 else if (yy == -1)
376 {
377 /* handle top edge. */
378 c = *(get + xx);
379 alpha[2] = *(getalpha + xx);
380
381 if (xx < pixelmap -> gx_pixelmap_width - 1)
382 {
383 d = *(get + xx + 1);
384 alpha[3] = *(getalpha + xx + 1);
385 }
386 }
387 else if (xx == pixelmap -> gx_pixelmap_width - 1)
388 {
389 /* handle right edget. */
390 a = *(get + yy * pixelmap -> gx_pixelmap_width + xx);
391 alpha[0] = *(getalpha + yy * pixelmap -> gx_pixelmap_width + xx);
392
393 if (yy < pixelmap -> gx_pixelmap_height - 1)
394 {
395 c = *(get + (yy + 1) * pixelmap -> gx_pixelmap_width + xx);
396 alpha[2] = *(getalpha + (yy + 1) * pixelmap -> gx_pixelmap_width + xx);
397 }
398 }
399 else
400 {
401 /* handle bottom edge. */
402 a = *(get + yy * pixelmap -> gx_pixelmap_width + xx);
403 alpha[0] = *(getalpha + yy * pixelmap -> gx_pixelmap_width + xx);
404
405 b = *(get + yy * pixelmap -> gx_pixelmap_width + xx + 1);
406 alpha[1] = *(getalpha + yy * pixelmap -> gx_pixelmap_width + xx + 1);
407 }
408
409 if (!a)
410 {
411 alpha[0] = 0;
412 }
413
414 if (!b)
415 {
416 alpha[1] = 0;
417 }
418
419 if (!c)
420 {
421 alpha[2] = 0;
422 }
423
424 if (!d)
425 {
426 alpha[3] = 0;
427 }
428 }
429
430 red = (USHORT)((REDVAL_332(a) * alpha[0] * (256 - xdiff) * (256 - ydiff) +
431 REDVAL_332(b) * alpha[1] * xdiff * (256 - ydiff) +
432 REDVAL_332(c) * alpha[2] * ydiff * (256 - xdiff) +
433 REDVAL_332(d) * alpha[3] * xdiff * ydiff) >> 16);
434
435 green = (USHORT)((GREENVAL_332(a) * alpha[0] * (256 - xdiff) * (256 - ydiff) +
436 GREENVAL_332(b) * alpha[1] * xdiff * (256 - ydiff) +
437 GREENVAL_332(c) * alpha[2] * ydiff * (256 - xdiff) +
438 GREENVAL_332(d) * alpha[3] * xdiff * ydiff) >> 16);
439
440 blue = (USHORT)((BLUEVAL_332(a) * alpha[0] * (256 - xdiff) * (256 - ydiff) +
441 BLUEVAL_332(b) * alpha[1] * xdiff * (256 - ydiff) +
442 BLUEVAL_332(c) * alpha[2] * ydiff * (256 - xdiff) +
443 BLUEVAL_332(d) * alpha[3] * xdiff * ydiff) >> 16);
444
445 alpha[0] = (USHORT)((alpha[0] * (256 - xdiff) * (256 - ydiff) +
446 alpha[1] * xdiff * (256 - ydiff) +
447 alpha[2] * ydiff * (256 - xdiff) +
448 alpha[3] * xdiff * ydiff) >> 16);
449
450 if (alpha[0])
451 {
452 red /= alpha[0];
453 green /= alpha[0];
454 blue /= alpha[0];
455 }
456
457 red = red > 7 ? 7 : red;
458 green = green > 7 ? 7 : green;
459 blue = blue > 3 ? 3 : blue;
460 alpha[0] = alpha[0] > 255 ? 255 : alpha[0];
461
462 blend_func(context, x + newxpos, y + newypos, (GX_COLOR)ASSEMBLECOLOR_332(red, green, blue), (GX_UBYTE)alpha[0]);
463 }
464 }
465 }
466 }
467
468 /**************************************************************************/
469 /* */
470 /* FUNCTION RELEASE */
471 /* */
472 /* _gx_display_driver_332rgb_pixelmap_raw_rotate PORTABLE C */
473 /* 6.1.10 */
474 /* AUTHOR */
475 /* */
476 /* Kenneth Maxwell, Microsoft Corporation */
477 /* */
478 /* DESCRIPTION */
479 /* */
480 /* Internal helper function that rotates an 332rgb format pixelmap */
481 /* without compression, without alpha. */
482 /* */
483 /* INPUT */
484 /* */
485 /* context Drawing context */
486 /* xpos x-coord of top-left draw point*/
487 /* ypos y-coord of top-left draw point*/
488 /* pixelmap Pointer to GX_PIXELMAP struct */
489 /* angle The angle to rotate */
490 /* cx x-coord of rotate center */
491 /* cy y-coord of rotate center */
492 /* */
493 /* OUTPUT */
494 /* */
495 /* status Completion status */
496 /* */
497 /* CALLS */
498 /* */
499 /* _gx_utility_math_cos Compute the cosine value */
500 /* _gx_utility_math_sin Compute the sine value */
501 /* [gx_display_driver_pixel_blend] Basic display driver pixel */
502 /* blend function */
503 /* */
504 /* CALLED BY */
505 /* */
506 /* _gx_display_driver_332rgb_pixelmap_rotate */
507 /* */
508 /* RELEASE HISTORY */
509 /* */
510 /* DATE NAME DESCRIPTION */
511 /* */
512 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
513 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
514 /* resulting in version 6.1 */
515 /* 01-31-2022 Ting Zhu Modified comment(s), */
516 /* corrected logic, */
517 /* resulting in version 6.1.10 */
518 /* */
519 /**************************************************************************/
_gx_display_driver_332rgb_pixelmap_raw_rotate(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,INT angle,INT cx,INT cy)520 static VOID _gx_display_driver_332rgb_pixelmap_raw_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
521 INT angle, INT cx, INT cy)
522 {
523 GX_UBYTE *get;
524 INT srcxres;
525 INT srcyres;
526 INT cosv;
527 INT sinv;
528 USHORT red;
529 USHORT green;
530 USHORT blue;
531 INT idxminx;
532 INT idxmaxx;
533 INT idxmaxy;
534 INT *mx;
535 INT *my;
536 INT xres;
537 INT yres;
538 INT x;
539 INT y;
540 INT xx;
541 INT yy;
542 USHORT a;
543 USHORT b;
544 USHORT c;
545 USHORT d;
546 INT alpha;
547 INT xdiff;
548 INT ydiff;
549 INT newxpos;
550 INT newypos;
551 GX_DISPLAY *display;
552 GX_RECTANGLE *clip;
553 VOID (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR color, GX_UBYTE alpha);
554
555 clip = context -> gx_draw_context_clip;
556 display = context -> gx_draw_context_display;
557 blend_func = display -> gx_display_driver_pixel_blend;
558 if (!blend_func)
559 {
560 return;
561 }
562
563 mx = _gx_system_scratchpad;
564 my = mx + 4;
565
566 mx[0] = mx[3] = -1;
567 mx[1] = mx[2] = 1;
568
569 my[0] = my[1] = 1;
570 my[2] = my[3] = -1;
571
572 idxminx = (angle / 90) & 0x3;
573 idxmaxx = (idxminx + 2) & 0x3;
574 idxmaxy = (idxminx + 1) & 0x3;
575
576 /* Calculate the source x and y center. */
577 srcxres = pixelmap -> gx_pixelmap_width >> 1;
578 srcyres = pixelmap -> gx_pixelmap_height >> 1;
579
580 cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
581 sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
582
583 xres = GX_FIXED_VAL_TO_INT(mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv);
584 yres = GX_FIXED_VAL_TO_INT(my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv);
585
586 /* Calculate the new rotation axis. */
587 xres = GX_FIXED_VAL_TO_INT((cx - srcxres) * cosv - (cy - srcyres) * sinv) + xres;
588 yres = GX_FIXED_VAL_TO_INT((cy - srcyres) * cosv + (cx - srcxres) * sinv) + yres;
589
590 newxpos = xpos + cx - xres;
591 newypos = ypos + cy - yres;
592
593 /* Loop through the source's pixels. */
594 for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
595 {
596 for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
597 {
598 xx = (x - xres) * cosv + (y - yres) * sinv;
599 yy = (y - yres) * cosv - (x - xres) * sinv;
600
601 xdiff = GX_FIXED_VAL_TO_INT(xx << 8) & 0xff;
602 ydiff = GX_FIXED_VAL_TO_INT(yy << 8) & 0xff;
603
604 xx = GX_FIXED_VAL_TO_INT(xx) + cx;
605 yy = GX_FIXED_VAL_TO_INT(yy) + cy;
606
607 if ((xx >= -1) && (xx < pixelmap -> gx_pixelmap_width) &&
608 (yy >= -1) && (yy < pixelmap -> gx_pixelmap_height))
609 {
610 if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_width - 1) && \
611 (yy >= 0) && (yy < pixelmap -> gx_pixelmap_height - 1))
612 {
613 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
614 get += yy * pixelmap -> gx_pixelmap_width;
615 get += xx;
616
617 a = *get;
618 b = *(get + 1);
619 c = *(get + pixelmap -> gx_pixelmap_width);
620 d = *(get + pixelmap -> gx_pixelmap_width + 1);
621
622 alpha = 0xff;
623 }
624 else
625 {
626 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
627
628 a = 0;
629 b = 0;
630 c = 0;
631 d = 0;
632 alpha = 0;
633
634 if (xx == -1)
635 {
636 /* handle left edge. */
637 if (yy >= 0)
638 {
639 b = *(get + yy * pixelmap -> gx_pixelmap_width);
640 alpha += xdiff * (256 - ydiff);
641 }
642
643 if (yy < pixelmap -> gx_pixelmap_height - 1)
644 {
645 d = *(get + (yy + 1) * pixelmap -> gx_pixelmap_width);
646 alpha += xdiff * ydiff;
647 }
648 }
649 else if (yy == -1)
650 {
651 /* handle top edge. */
652 c = *(get + xx);
653 alpha += ydiff * (256 - xdiff);
654
655 if (xx < pixelmap -> gx_pixelmap_width - 1)
656 {
657 d = *(get + xx + 1);
658 alpha += xdiff * ydiff;
659 }
660 }
661 else if (xx == pixelmap -> gx_pixelmap_width - 1)
662 {
663 /* handle right edget. */
664 a = *(get + yy * pixelmap -> gx_pixelmap_width + xx);
665 alpha += (256 - xdiff) * (256 - ydiff);
666
667 if (yy < pixelmap -> gx_pixelmap_height - 1)
668 {
669 c = *(get + (yy + 1) * pixelmap -> gx_pixelmap_width + xx);
670 alpha += ydiff * (256 - xdiff);
671 }
672 }
673 else
674 {
675 /* handle bottom edge. */
676 a = *(get + yy * pixelmap -> gx_pixelmap_width + xx);
677 alpha += (256 - xdiff) * (256 - ydiff);
678
679 b = *(get + yy * pixelmap -> gx_pixelmap_width + xx + 1);
680 alpha += xdiff * (256 - ydiff);
681 }
682
683 alpha >>= 8;
684 }
685
686 red = (USHORT)((REDVAL_332(a) * (256 - xdiff) * (256 - ydiff) +
687 REDVAL_332(b) * xdiff * (256 - ydiff) +
688 REDVAL_332(c) * ydiff * (256 - xdiff) +
689 REDVAL_332(d) * xdiff * ydiff) >> 16);
690
691 green = (USHORT)((GREENVAL_332(a) * (256 - xdiff) * (256 - ydiff) +
692 GREENVAL_332(b) * xdiff * (256 - ydiff) +
693 GREENVAL_332(c) * ydiff * (256 - xdiff) +
694 GREENVAL_332(d) * xdiff * ydiff) >> 16);
695
696 blue = (USHORT)((BLUEVAL_332(a) * (256 - xdiff) * (256 - ydiff) +
697 BLUEVAL_332(b) * xdiff * (256 - ydiff) +
698 BLUEVAL_332(c) * ydiff * (256 - xdiff) +
699 BLUEVAL_332(d) * xdiff * ydiff) >> 16);
700
701 if (alpha && (alpha < 0xff))
702 {
703 red = (USHORT)((red << 8) / alpha);
704 green = (USHORT)((green << 8) / alpha);
705 blue = (USHORT)((blue << 8) / alpha);
706 }
707
708 red = red > 7 ? 7 : red;
709 green = green > 7 ? 7 : green;
710 blue = blue > 3 ? 3 : blue;
711 alpha = alpha > 255 ? 255 : alpha;
712
713 blend_func(context, x + newxpos, y + newypos, (GX_COLOR)ASSEMBLECOLOR_332(red, green, blue), (GX_UBYTE)alpha);
714 }
715 }
716 }
717 }
718
719 /**************************************************************************/
720 /* */
721 /* FUNCTION RELEASE */
722 /* */
723 /* _gx_display_driver_332rgb_pixelmap_rotate PORTABLE C */
724 /* 6.1 */
725 /* AUTHOR */
726 /* */
727 /* Kenneth Maxwell, Microsoft Corporation */
728 /* */
729 /* DESCRIPTION */
730 /* */
731 /* This service rotate a 332rgb format pixelmap to canvas memory. */
732 /* */
733 /* INPUT */
734 /* */
735 /* context Drawing context */
736 /* xpos x-coord of top-left draw point*/
737 /* ypos y-coord of top-left draw point*/
738 /* pixelmap Pointer to GX_PIXELMAP struct */
739 /* angle The angle to rotate */
740 /* rot_cx x-coord of rotating center. */
741 /* rot_cy y-coord of rotationg center. */
742 /* */
743 /* OUTPUT */
744 /* */
745 /* status Completion status */
746 /* */
747 /* CALLS */
748 /* */
749 /* _gx_display_driver_8bpp_pixelmap_rotate */
750 /* Rotate 8bpp format pixelmap */
751 /* _gx_display_driver_332rgb_pixelmap_simple_alpha_rotate */
752 /* Rotate 332rgb format pixelmap */
753 /* in simple case */
754 /* _gx_display_driver_332rgb_pixelmap_alpha_rotate */
755 /* Rotate 332rgb format pixelmap */
756 /* with alpha */
757 /* _gx_display_driver_332rgb_pixelmap_raw_rotate */
758 /* Rotate 332rgb format pixelmap */
759 /* without alpha */
760 /* */
761 /* CALLED BY */
762 /* */
763 /* Application Code */
764 /* GUIX Internal Code */
765 /* */
766 /* RELEASE HISTORY */
767 /* */
768 /* DATE NAME DESCRIPTION */
769 /* */
770 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
771 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
772 /* resulting in version 6.1 */
773 /* */
774 /**************************************************************************/
_gx_display_driver_332rgb_pixelmap_rotate(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,INT angle,INT rot_cx,INT rot_cy)775 VOID _gx_display_driver_332rgb_pixelmap_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
776 INT angle, INT rot_cx, INT rot_cy)
777 {
778 switch (pixelmap -> gx_pixelmap_format)
779 {
780 case GX_COLOR_FORMAT_8BIT_PACKED_PIXEL:
781 if (angle % 90 == 0)
782 {
783 /* Simple angle rotate: 90 degree, 180 degree and 270 degree. */
784 if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
785 {
786 /*Alpha, no compression.*/
787 _gx_display_driver_332rgb_pixelmap_simple_alpha_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
788 }
789 else
790 {
791 _gx_display_driver_8bpp_pixelmap_simple_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
792 }
793 }
794 else
795 {
796 if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
797 {
798 /*Not correct yet.*/
799 _gx_display_driver_332rgb_pixelmap_alpha_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
800 }
801 else
802 {
803 /* no compression or alpha */
804 _gx_display_driver_332rgb_pixelmap_raw_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
805 }
806 }
807 break;
808 }
809
810 return;
811 }
812
813