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 /* Include necessary system files. */
23
24 #include "gx_api.h"
25 #include "gx_display.h"
26 #include "gx_context.h"
27 #include "gx_utility.h"
28 #include "gx_system.h"
29
30 /**************************************************************************/
31 /* */
32 /* FUNCTION RELEASE */
33 /* */
34 /* _gx_display_driver_4bpp_pixelmap_raw_rotate PORTABLE C */
35 /* 6.1.10 */
36 /* AUTHOR */
37 /* */
38 /* Kenneth Maxwell, Microsoft Corporation */
39 /* */
40 /* DESCRIPTION */
41 /* */
42 /* Internal helper function that rotate an uncompressed pixelmap */
43 /* without transparent. */
44 /* */
45 /* INPUT */
46 /* */
47 /* context Drawing context */
48 /* xpos x-coord of top-left draw point*/
49 /* ypos y-coord of top-left draw point*/
50 /* pixelmap Pointer to GX_PIXELMAP struct */
51 /* angle The angle to rotate */
52 /* rot_cx x-coord of rotate center */
53 /* rot_cy y-coord of rotate center */
54 /* */
55 /* OUTPUT */
56 /* */
57 /* status Completion status */
58 /* */
59 /* CALLS */
60 /* */
61 /* _gx_utility_math_cos Compute the cosine value */
62 /* _gx_utility_math_sin Compute the sine value */
63 /* */
64 /* CALLED BY */
65 /* */
66 /* _gx_display_driver_4bpp_pixelmap_rotate */
67 /* */
68 /* RELEASE HISTORY */
69 /* */
70 /* DATE NAME DESCRIPTION */
71 /* */
72 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
73 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
74 /* resulting in version 6.1 */
75 /* 01-31-2022 Ting Zhu Modified comment(s), */
76 /* corrected logic, */
77 /* resulting in version 6.1.10 */
78 /* */
79 /**************************************************************************/
_gx_display_driver_4bpp_pixelmap_raw_rotate(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,INT angle,INT cx,INT cy)80 static VOID _gx_display_driver_4bpp_pixelmap_raw_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
81 INT angle, INT cx, INT cy)
82 {
83 GX_UBYTE *putrow;
84 GX_UBYTE *put;
85 GX_UBYTE *get;
86 INT srcxres;
87 INT srcyres;
88 INT cosv;
89 INT sinv;
90 INT idxminx;
91 INT idxmaxx;
92 INT idxmaxy;
93 INT mx[] = {-1, 1, 1, -1};
94 INT my[] = {1, 1, -1, -1};
95 INT xres;
96 INT yres;
97 INT x;
98 INT y;
99 INT xx;
100 INT yy;
101 GX_RECTANGLE *clip;
102 INT newxpos;
103 INT newypos;
104 GX_UBYTE putmask;
105 INT putstride;
106 INT getstride;
107 GX_UBYTE color;
108
109 clip = context -> gx_draw_context_clip;
110
111 /* Set transparent color. */
112 idxminx = (angle / 90) & 0x3;
113 idxmaxx = (idxminx + 2) & 0x3;
114 idxmaxy = (idxminx + 1) & 0x3;
115
116 /* Calculate the source x and y center. */
117 srcxres = pixelmap -> gx_pixelmap_width >> 1;
118 srcyres = pixelmap -> gx_pixelmap_height >> 1;
119
120 cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
121 sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
122
123 xres = GX_FIXED_VAL_TO_INT((mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv));
124 yres = GX_FIXED_VAL_TO_INT((my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv));
125
126 getstride = (pixelmap -> gx_pixelmap_width + 1) >> 1;
127 putstride = (context -> gx_draw_context_pitch + 1) >> 1;
128 putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
129 putrow += clip -> gx_rectangle_top * putstride;
130 putrow += clip -> gx_rectangle_left >> 1;
131
132 /* Calculate the new rotation axis. */
133 xres = GX_FIXED_VAL_TO_INT((cx - srcxres) * cosv - (cy - srcyres) * sinv) + xres;
134 yres = GX_FIXED_VAL_TO_INT((cy - srcyres) * cosv + (cx - srcxres) * sinv) + yres;
135
136 newxpos = xpos + cx - xres;
137 newypos = ypos + cy - yres;
138
139 /* For every pixel in destination bitmap, find its position in source bitmap,
140 and set the pixel with the value in source bitmap. */
141 for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
142 {
143 if (clip -> gx_rectangle_left & 1)
144 {
145 putmask = 0x0f;
146 }
147 else
148 {
149 putmask = 0xf0;
150 }
151 put = putrow;
152
153 for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
154 {
155 xx = GX_FIXED_VAL_TO_INT((x - xres) * cosv + (y - yres) * sinv) + cx;
156 yy = GX_FIXED_VAL_TO_INT((y - yres) * cosv - (x - xres) * sinv) + cy;
157
158 if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_width) &&
159 (yy >= 0) && (yy < pixelmap -> gx_pixelmap_height))
160 {
161 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
162 get += yy * getstride;
163 get += xx >> 1;
164
165 if (xx & 1)
166 {
167 color = *get & 0x0f;
168 }
169 else
170 {
171 color = (*get & 0xf0) >> 4;
172 }
173 color |= (GX_UBYTE)(color << 4);
174
175 *put &= (GX_UBYTE)(~putmask);
176 *put |= color & putmask;
177 }
178
179 putmask >>= 4;
180 if (putmask == 0)
181 {
182 put++;
183 putmask = 0xf0;
184 }
185 }
186 putrow += putstride;
187 }
188 }
189
190 /**************************************************************************/
191 /* */
192 /* FUNCTION RELEASE */
193 /* */
194 /* _gx_display_driver_4bpp_pixelmap_transparent_rotate PORTABLE C */
195 /* 6.1.10 */
196 /* AUTHOR */
197 /* */
198 /* Kenneth Maxwell, Microsoft Corporation */
199 /* */
200 /* DESCRIPTION */
201 /* */
202 /* Internal helper function that rotate an uncompressed pixelmap */
203 /* with transparent info. */
204 /* */
205 /* INPUT */
206 /* */
207 /* context Drawing context */
208 /* xpos x-coord of top-left draw point*/
209 /* ypos y-coord of top-left draw point*/
210 /* pixelmap Pointer to GX_PIXELMAP struct */
211 /* angle The angle to rotate */
212 /* rot_cx x-coord of rotate center */
213 /* rot_cy y-coord of rotate center */
214 /* */
215 /* OUTPUT */
216 /* */
217 /* status Completion status */
218 /* */
219 /* CALLS */
220 /* */
221 /* _gx_utility_math_cos Compute the cosine value */
222 /* _gx_utility_math_sin Compute the sine value */
223 /* */
224 /* CALLED BY */
225 /* */
226 /* _gx_display_driver_4bpp_pixelmap_rotate */
227 /* */
228 /* RELEASE HISTORY */
229 /* */
230 /* DATE NAME DESCRIPTION */
231 /* */
232 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
233 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
234 /* resulting in version 6.1 */
235 /* 01-31-2022 Ting Zhu Modified comment(s), */
236 /* corrected logic, */
237 /* resulting in version 6.1.10 */
238 /* */
239 /**************************************************************************/
_gx_display_driver_4bpp_pixelmap_transparent_rotate(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,INT angle,INT cx,INT cy)240 static VOID _gx_display_driver_4bpp_pixelmap_transparent_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
241 INT angle, INT cx, INT cy)
242 {
243 GX_UBYTE *putrow;
244 GX_UBYTE *put;
245 GX_UBYTE *get;
246 GX_UBYTE *getaux;
247 GX_UBYTE putmask;
248 GX_UBYTE transmask;
249 GX_UBYTE pixel;
250 INT putstride;
251 INT getauxstride;
252 INT getstride;
253 INT srcxres;
254 INT srcyres;
255 INT cosv;
256 INT sinv;
257 INT idxminx;
258 INT idxmaxx;
259 INT idxmaxy;
260 INT mx[] = {-1, 1, 1, -1};
261 INT my[] = {1, 1, -1, -1};
262 INT xres;
263 INT yres;
264 INT x;
265 INT y;
266 INT xx;
267 INT yy;
268 GX_RECTANGLE *clip;
269 INT newxpos;
270 INT newypos;
271
272 clip = context -> gx_draw_context_clip;
273 putstride = (context -> gx_draw_context_pitch + 1) >> 1;
274 getstride = (pixelmap -> gx_pixelmap_width + 1) >> 1;
275 getauxstride = (pixelmap -> gx_pixelmap_width + 7) >> 3;
276
277 /* Set transparent color. */
278 idxminx = (angle / 90) & 0x3;
279 idxmaxx = (idxminx + 2) & 0x3;
280 idxmaxy = (idxminx + 1) & 0x3;
281
282 /* Calculate the source x and y center. */
283 srcxres = pixelmap -> gx_pixelmap_width >> 1;
284 srcyres = pixelmap -> gx_pixelmap_height >> 1;
285
286 cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
287 sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
288
289 xres = GX_FIXED_VAL_TO_INT((mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv));
290 yres = GX_FIXED_VAL_TO_INT((my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv));
291
292 putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
293 putrow += clip -> gx_rectangle_top * putstride;
294 putrow += clip -> gx_rectangle_left >> 1;
295
296 /* Calculate the new rotation axis. */
297 x = (cx - srcxres) * cosv - (cy - srcyres) * sinv;
298 y = (cy - srcyres) * cosv + (cx - srcxres) * sinv;
299
300 xres = GX_FIXED_VAL_TO_INT(x) + xres;
301 yres = GX_FIXED_VAL_TO_INT(y) + yres;
302
303 newxpos = xpos + cx - xres;
304 newypos = ypos + cy - yres;
305
306 /* For every pixel in destination bitmap, find its position in source bitmap,
307 and set the pixel with the value in source bitmap. */
308 for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
309 {
310 put = putrow;
311 if (clip -> gx_rectangle_left & 1)
312 {
313 putmask = 0x0f;
314 }
315 else
316 {
317 putmask = 0xf0;
318 }
319
320 for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
321 {
322 xx = GX_FIXED_VAL_TO_INT((x - xres) * cosv + (y - yres) * sinv) + cx;
323 yy = GX_FIXED_VAL_TO_INT((y - yres) * cosv - (x - xres) * sinv) + cy;
324
325 if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_width) &&
326 (yy >= 0) && (yy < pixelmap -> gx_pixelmap_height))
327 {
328 getaux = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
329 getaux += yy * getauxstride;
330 getaux += xx >> 3;
331
332 transmask = (GX_UBYTE)(0x80 >> (xx & 0x07));
333 if (!(transmask & (*getaux)))
334 {
335 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
336 get += yy * getstride;
337 get += xx >> 1;
338
339 if (xx & 1)
340 {
341 pixel = *get & 0x0f;
342 }
343 else
344 {
345 pixel = *get >> 4;
346 }
347 pixel |= (GX_UBYTE)(pixel << 4);
348
349 *put &= (GX_UBYTE)(~putmask);
350 *put |= pixel & putmask;
351 }
352 }
353
354 putmask >>= 4;
355 if (putmask == 0)
356 {
357 put++;
358 putmask = 0xf0;
359 }
360 }
361 putrow += putstride;
362 }
363 }
364
365 /**************************************************************************/
366 /* */
367 /* FUNCTION RELEASE */
368 /* */
369 /* _gx_display_driver_4bpp_pixelmap_simple_rotate PORTABLE C */
370 /* 6.1.7 */
371 /* AUTHOR */
372 /* */
373 /* Kenneth Maxwell, Microsoft Corporation */
374 /* */
375 /* DESCRIPTION */
376 /* */
377 /* Internal help function that hangles 90, 180 and 270 degree pixelmap */
378 /* rotation. */
379 /* */
380 /* INPUT */
381 /* */
382 /* context Drawing context */
383 /* xpos x-coord of top-left draw point*/
384 /* ypos y-coord of top-left draw point*/
385 /* pixelmap Pointer to GX_PIXELMAP struct */
386 /* angle The angle to rotate */
387 /* rot_cx x-coord of rotate center */
388 /* rot_cy y-coord of rotate center */
389 /* */
390 /* OUTPUT */
391 /* */
392 /* status Completion status */
393 /* */
394 /* CALLS */
395 /* */
396 /* None */
397 /* */
398 /* CALLED BY */
399 /* */
400 /* _gx_display_driver_4bpp_pixelmap_rotate */
401 /* */
402 /* RELEASE HISTORY */
403 /* */
404 /* DATE NAME DESCRIPTION */
405 /* */
406 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
407 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
408 /* resulting in version 6.1 */
409 /* 06-02-2021 Kenneth Maxwell Modified comment(s), */
410 /* removed unused variable */
411 /* assignment, */
412 /* resulting in version 6.1.7 */
413 /* */
414 /**************************************************************************/
_gx_display_driver_4bpp_pixelmap_simple_rotate(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,INT angle,INT cx,INT cy)415 static VOID _gx_display_driver_4bpp_pixelmap_simple_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
416 INT angle, INT cx, INT cy)
417 {
418 GX_UBYTE *putrow;
419 GX_UBYTE *put;
420 GX_UBYTE putmask;
421 GX_UBYTE *get;
422 INT putstride;
423 INT width;
424 INT height;
425 INT x;
426 INT y;
427 GX_RECTANGLE *clip;
428 INT newxpos;
429 INT newypos;
430 GX_UBYTE color;
431
432 clip = context -> gx_draw_context_clip;
433 putstride = (context -> gx_draw_context_pitch + 1) >> 1;
434
435 putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
436 putrow += clip -> gx_rectangle_top * putstride;
437 putrow += clip -> gx_rectangle_left >> 1;
438
439 if (angle == 90)
440 {
441 width = pixelmap -> gx_pixelmap_height;
442 height = (pixelmap -> gx_pixelmap_width + 1) >> 1;
443
444 newxpos = xpos + cx - (width - 1 - cy);
445 newypos = ypos + cy - cx;
446
447 for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
448 {
449 if (clip -> gx_rectangle_left & 1)
450 {
451 putmask = 0x0f;
452 }
453 else
454 {
455 putmask = 0xf0;
456 }
457
458 put = putrow;
459
460 for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
461 {
462 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
463 get += (width - 1 - x) * height;
464 get += y >> 1;
465
466 if (y & 1)
467 {
468 color = *get & 0x0f;
469 }
470 else
471 {
472 color = (*get & 0xf0) >> 4;
473 }
474 color |= (GX_UBYTE)(color << 4);
475
476 *put &= (GX_UBYTE)(~putmask);
477 *put |= color & putmask;
478
479 putmask >>= 4;
480 if (putmask == 0)
481 {
482 putmask = 0xf0;
483 put++;
484 }
485 }
486
487 putrow += putstride;
488 }
489 }
490 else if (angle == 180)
491 {
492
493 width = pixelmap -> gx_pixelmap_width;
494 height = pixelmap -> gx_pixelmap_height;
495
496 newxpos = xpos + cx - (width - 1 - cx);
497 newypos = ypos + cy - (height - 1 - cy);
498
499 for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
500 {
501 if (clip -> gx_rectangle_left & 1)
502 {
503 putmask = 0x0f;
504 }
505 else
506 {
507 putmask = 0xf0;
508 }
509 put = putrow;
510
511 for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
512 {
513 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
514 get += (height - 1 - y) * ((width + 1) >> 1);
515 get += (width - 1 - x) >> 1;
516
517 if ((pixelmap -> gx_pixelmap_width - 1 - x) & 1)
518 {
519 color = *get & 0x0f;
520 }
521 else
522 {
523 color = (*get & 0xf0) >> 4;
524 }
525 color |= (GX_UBYTE)(color << 4);
526 *put &= (GX_UBYTE)(~putmask);
527 *put |= color & putmask;
528
529 putmask >>= 4;
530 if (putmask == 0)
531 {
532 putmask = 0xf0;
533 put++;
534 }
535 }
536 putrow += putstride;
537 }
538 }
539 else
540 {
541 height = pixelmap -> gx_pixelmap_width;
542
543 newxpos = xpos + cx - cy;
544 newypos = ypos + cx - (height - 1 - cy);
545
546 for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
547 {
548 if (clip -> gx_rectangle_left & 1)
549 {
550 putmask = 0x0f;
551 }
552 else
553 {
554 putmask = 0xf0;
555 }
556 put = putrow;
557
558 for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
559 {
560 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
561 get += x * ((height + 1) >> 1);
562 get += (height - 1 - y) >> 1;
563
564 if ((height - 1 - y) & 1)
565 {
566 color = *get & 0x0f;
567 }
568 else
569 {
570 color = (*get & 0xf0) >> 4;
571 }
572 color |= (GX_UBYTE)(color << 4);
573
574 *put &= (GX_UBYTE)(~putmask);
575 *put |= color & putmask;
576
577 putmask >>= 4;
578 if (putmask == 0)
579 {
580 putmask = 0xf0;
581 put++;
582 }
583 }
584
585 putrow += putstride;
586 }
587 }
588 }
589 /**************************************************************************/
590 /* */
591 /* FUNCTION RELEASE */
592 /* */
593 /* _gx_display_driver_4bpp_pixelmap_simple_transparent_rotate */
594 /* PORTABLE C */
595 /* 6.1.7 */
596 /* AUTHOR */
597 /* */
598 /* Kenneth Maxwell, Microsoft Corporation */
599 /* */
600 /* DESCRIPTION */
601 /* */
602 /* Internal help function that hangles 90, 180 and 270 degree pixelmap */
603 /* rotation. */
604 /* */
605 /* INPUT */
606 /* */
607 /* context Drawing context */
608 /* xpos x-coord of top-left draw point*/
609 /* ypos y-coord of top-left draw point*/
610 /* pixelmap Pointer to GX_PIXELMAP struct */
611 /* angle The angle to rotate */
612 /* rot_cx x-coord of rotate center */
613 /* rot_cy y-coord of rotate center */
614 /* */
615 /* OUTPUT */
616 /* */
617 /* status Completion status */
618 /* */
619 /* CALLS */
620 /* */
621 /* None */
622 /* */
623 /* CALLED BY */
624 /* */
625 /* _gx_display_driver_4bpp_pixelmap_rotate */
626 /* */
627 /* RELEASE HISTORY */
628 /* */
629 /* DATE NAME DESCRIPTION */
630 /* */
631 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
632 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
633 /* resulting in version 6.1 */
634 /* 06-02-2021 Kenneth Maxwell Modified comment(s), */
635 /* removed unused variable */
636 /* assignment, */
637 /* resulting in version 6.1.7 */
638 /* */
639 /**************************************************************************/
_gx_display_driver_4bpp_pixelmap_simple_transparent_rotate(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,INT angle,INT cx,INT cy)640 static VOID _gx_display_driver_4bpp_pixelmap_simple_transparent_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
641 INT angle, INT cx, INT cy)
642 {
643 GX_UBYTE *get;
644 GX_UBYTE *gettransmask;
645 INT width;
646 INT height;
647 INT x;
648 INT y;
649 GX_RECTANGLE *clip;
650 INT newxpos;
651 INT newypos;
652 GX_UBYTE *put;
653 GX_UBYTE *putrow;
654 INT putstride;
655 GX_UBYTE putmask;
656 INT getstride;
657 INT getauxstride;
658 GX_UBYTE transmask;
659 GX_UBYTE pixel;
660
661 if (pixelmap -> gx_pixelmap_aux_data == GX_NULL)
662 {
663 /* 4bpp transparent pixelmap must have aux data to store the transparent mask info. */
664 return;
665 }
666
667 clip = context -> gx_draw_context_clip;
668 /* 4bpp pixelmap is stored as half byte. And it's transparent info is stored in aux data by one bit */
669 getstride = (pixelmap -> gx_pixelmap_width + 1) >> 1;
670 getauxstride = (pixelmap -> gx_pixelmap_width + 7) >> 3;
671 putstride = (context -> gx_draw_context_pitch + 1) >> 1;
672 putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
673 putrow += clip -> gx_rectangle_top * putstride;
674 putrow += clip -> gx_rectangle_left >> 1;
675
676 clip = context -> gx_draw_context_clip;
677
678 if (angle == 90)
679 {
680 width = pixelmap -> gx_pixelmap_height;
681
682 newxpos = xpos + cx - (width - 1 - cy);
683 newypos = ypos + cy - cx;
684
685 for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
686 {
687 put = putrow;
688 if (clip -> gx_rectangle_left & 1)
689 {
690 putmask = 0x0f;
691 }
692 else
693 {
694 putmask = 0xf0;
695 }
696
697 for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
698 {
699 gettransmask = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
700 gettransmask += (width - 1 - x) * getauxstride;
701 gettransmask += y >> 3;
702
703 transmask = (GX_UBYTE)(0x80 >> (y & 0x07));
704
705 /* if not transparent, draw pixel. else skip. */
706 if (!(transmask & (*gettransmask)))
707 {
708 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
709 get += (width - 1 - x) * getstride;
710 get += y >> 1;
711
712 if (y & 1)
713 {
714 pixel = *get & 0x0f;
715 }
716 else
717 {
718 pixel = *get >> 4;
719 }
720 pixel |= (GX_UBYTE)(pixel << 4);
721
722 *put &= (GX_UBYTE)(~putmask);
723 *put |= pixel & putmask;
724 }
725
726 putmask >>= 4;
727 if (putmask == 0)
728 {
729 putmask = 0xf0;
730 put++;
731 }
732 }
733 putrow += putstride;
734 }
735 }
736 else if (angle == 180)
737 {
738 width = pixelmap -> gx_pixelmap_width;
739 height = pixelmap -> gx_pixelmap_height;
740
741 newxpos = xpos + cx - (width - 1 - cx);
742 newypos = ypos + cy - (height - 1 - cy);
743
744 for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
745 {
746 put = putrow;
747 if (clip -> gx_rectangle_left & 1)
748 {
749 putmask = 0x0f;
750 }
751 else
752 {
753 putmask = 0xf0;
754 }
755 for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
756 {
757 gettransmask = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
758 gettransmask += (height - 1 - y) * getauxstride;
759 gettransmask += (width - 1 - x) >> 3;
760
761 /* Calculate and go ot the transmask bit.*/
762 transmask = (GX_UBYTE)(0x80 >> ((width - 1 - x) & 0x07));
763 /* if not transparent, draw pixel. else skip. */
764 if (!(transmask & (*gettransmask)))
765 {
766 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
767 get += (height - 1 - y) * getstride;
768 get += (width - 1 - x) >> 1;
769
770 if ((width - 1 - x) & 1)
771 {
772 pixel = *get & 0x0f;
773 }
774 else
775 {
776 pixel = *get >> 4;
777 }
778 pixel |= (GX_UBYTE)(pixel << 4);
779
780 *put &= (GX_UBYTE)(~putmask);
781 *put |= pixel & putmask;
782 }
783
784 putmask >>= 4;
785 if (putmask == 0)
786 {
787 putmask = 0xf0;
788 put++;
789 }
790 }
791 putrow += putstride;
792 }
793 }
794 else
795 {
796 height = pixelmap -> gx_pixelmap_width;
797
798 newxpos = xpos + cx - cy;
799 newypos = ypos + cx - (height - 1 - cy);
800
801 for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
802 {
803 put = putrow;
804 if (clip -> gx_rectangle_left & 1)
805 {
806 putmask = 0x0f;
807 }
808 else
809 {
810 putmask = 0xf0;
811 }
812
813 for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
814 {
815 gettransmask = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
816 gettransmask += x * getauxstride;
817 gettransmask += (height - 1 - y) >> 3;
818
819 transmask = (GX_UBYTE)(0x80 >> ((height - 1 - y) & 0x07));
820 /* if not transparent, draw pixel. else skip. */
821 if (!(transmask & (*gettransmask)))
822 {
823 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
824 get += x * getstride;
825 get += (height - 1 - y) >> 1;
826
827 if ((height - 1 - y) & 1)
828 {
829 pixel = *get & 0x0f;
830 }
831 else
832 {
833 pixel = *get >> 4;
834 }
835 pixel |= (GX_UBYTE)(pixel << 4);
836
837 *put &= (GX_UBYTE)(~putmask);
838 *put |= pixel & putmask;
839 }
840
841 putmask >>= 4;
842 if (putmask == 0)
843 {
844 putmask = 0xf0;
845 put++;
846 }
847 }
848 putrow += putstride;
849 }
850 }
851 }
852
853 /**************************************************************************/
854 /* */
855 /* FUNCTION RELEASE */
856 /* */
857 /* _gx_display_driver_4bpp_pixelmap_rotate PORTABLE C */
858 /* 6.1 */
859 /* AUTHOR */
860 /* */
861 /* Kenneth Maxwell, Microsoft Corporation */
862 /* */
863 /* DESCRIPTION */
864 /* */
865 /* This service rotate a pixelmap directly to canvas memory. */
866 /* */
867 /* INPUT */
868 /* */
869 /* context Drawing context */
870 /* xpos x-coord of top-left draw point*/
871 /* ypos y-coord of top-left draw point*/
872 /* pixelmap Pointer to GX_PIXELMAP struct */
873 /* angle The angle to rotate */
874 /* rot_cx x-coord of rotating center. */
875 /* rot_cy y-coord of rotationg center. */
876 /* */
877 /* OUTPUT */
878 /* */
879 /* status Completion status */
880 /* */
881 /* CALLS */
882 /* */
883 /* _gx_display_driver_4bpp_pixelmap_simple_transparent_rotate */
884 /* Real pixelmap rotate routine */
885 /* _gx_display_driver_4bpp_pixelmap_simple_rotate */
886 /* Real pixelmap rotate routine */
887 /* _gx_display_driver_4bpp_pixelmap_transparent_rotate */
888 /* Real pixelmap rotate routine */
889 /* _gx_display_driver_4bpp_pixelmap_raw_rotate */
890 /* Real pixelmap rotate routine */
891 /* */
892 /* CALLED BY */
893 /* */
894 /* Application Code */
895 /* GUIX Internal Code */
896 /* */
897 /* RELEASE HISTORY */
898 /* */
899 /* DATE NAME DESCRIPTION */
900 /* */
901 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
902 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
903 /* resulting in version 6.1 */
904 /* */
905 /**************************************************************************/
_gx_display_driver_4bpp_pixelmap_rotate(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,INT angle,INT rot_cx,INT rot_cy)906 VOID _gx_display_driver_4bpp_pixelmap_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
907 INT angle, INT rot_cx, INT rot_cy)
908 {
909 if (angle % 90 == 0)
910 {
911 /* Simple angle rotate: 90 degree, 180 degree and 270 degree. */
912 if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_TRANSPARENT)
913 {
914 _gx_display_driver_4bpp_pixelmap_simple_transparent_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
915 }
916 else
917 {
918 _gx_display_driver_4bpp_pixelmap_simple_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
919 }
920 }
921 else
922 {
923 if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_TRANSPARENT)
924 {
925 /* no compression or alpha */
926 _gx_display_driver_4bpp_pixelmap_transparent_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
927 }
928 else
929 {
930 /* no compression or alpha */
931 _gx_display_driver_4bpp_pixelmap_raw_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
932 }
933 }
934
935 return;
936 }
937
938