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_1bpp_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 rotates an uncompressed pixelmap */
43 /* without transparency. */
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 /* cx x-coord of rotate center */
53 /* 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_1bpp_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_1bpp_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_1bpp_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 GX_UBYTE getmask;
106 INT putstride;
107 INT getstride;
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((int)(mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv));
124 yres = GX_FIXED_VAL_TO_INT((int)(my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv));
125
126 getstride = (pixelmap -> gx_pixelmap_width + 7) >> 3;
127 putstride = (context -> gx_draw_context_pitch + 7) >> 3;
128 putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
129 putrow += clip -> gx_rectangle_top * putstride;
130 putrow += clip -> gx_rectangle_left >> 3;
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 put = putrow;
144 putmask = (GX_UBYTE)(0x80 >> (clip -> gx_rectangle_left & 0x07));
145
146 for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
147 {
148 xx = (x - xres) * cosv + (y - yres) * sinv;
149 yy = (y - yres) * cosv - (x - xres) * sinv;
150
151 xx = GX_FIXED_VAL_TO_INT(xx) + cx;
152 yy = GX_FIXED_VAL_TO_INT(yy) + cy;
153
154 if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_width) &&
155 (yy >= 0) && (yy < pixelmap -> gx_pixelmap_height))
156 {
157 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
158 get += yy * getstride;
159 get += xx >> 3;
160 getmask = (GX_UBYTE)(0x80 >> (xx & 0x07));
161
162 if ((*get) & getmask)
163 {
164 *put |= putmask;
165 }
166 else
167 {
168 *put = (GX_UBYTE)(*put & (~putmask));
169 }
170 }
171
172 putmask >>= 1;
173 if (putmask == 0)
174 {
175 put++;
176 putmask = 0x80;
177 }
178 }
179 putrow += putstride;
180 }
181 }
182
183 /**************************************************************************/
184 /* */
185 /* FUNCTION RELEASE */
186 /* */
187 /* _gx_display_driver_1bpp_pixelmap_transparent_rotate PORTABLE C */
188 /* 6.1.10 */
189 /* AUTHOR */
190 /* */
191 /* Kenneth Maxwell, Microsoft Corporation */
192 /* */
193 /* DESCRIPTION */
194 /* */
195 /* Internal helper function that rotate an uncompressed pixelmap */
196 /* with transparent info. */
197 /* */
198 /* INPUT */
199 /* */
200 /* context Drawing context */
201 /* xpos x-coord of top-left draw point*/
202 /* ypos y-coord of top-left draw point*/
203 /* pixelmap Pointer to GX_PIXELMAP struct */
204 /* angle The angle to rotate */
205 /* rot_cx x-coord of rotate center */
206 /* rot_cy y-coord of rotate center */
207 /* */
208 /* OUTPUT */
209 /* */
210 /* status Completion status */
211 /* */
212 /* CALLS */
213 /* */
214 /* _gx_utility_math_cos Compute the cosine value */
215 /* _gx_utility_math_sin Compute the sine value */
216 /* */
217 /* CALLED BY */
218 /* */
219 /* _gx_display_driver_1bpp_pixelmap_rotate */
220 /* */
221 /* RELEASE HISTORY */
222 /* */
223 /* DATE NAME DESCRIPTION */
224 /* */
225 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
226 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
227 /* resulting in version 6.1 */
228 /* 01-31-2022 Ting Zhu Modified comment(s), */
229 /* corrected logic, */
230 /* resulting in version 6.1.10 */
231 /* */
232 /**************************************************************************/
_gx_display_driver_1bpp_pixelmap_transparent_rotate(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,INT angle,INT cx,INT cy)233 static VOID _gx_display_driver_1bpp_pixelmap_transparent_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
234 INT angle, INT cx, INT cy)
235 {
236 GX_UBYTE *putrow;
237 GX_UBYTE *put;
238 GX_UBYTE *get;
239 GX_UBYTE putmask;
240 GX_UBYTE transmask;
241 GX_UBYTE getmask;
242 INT putstride;
243 INT getstride;
244 INT srcxres;
245 INT srcyres;
246 INT cosv;
247 INT sinv;
248 INT idxminx;
249 INT idxmaxx;
250 INT idxmaxy;
251 INT mx[] = {-1, 1, 1, -1};
252 INT my[] = {1, 1, -1, -1};
253 INT xres;
254 INT yres;
255 INT x;
256 INT y;
257 INT xx;
258 INT yy;
259 GX_RECTANGLE *clip;
260 INT newxpos;
261 INT newypos;
262
263 clip = context -> gx_draw_context_clip;
264 putstride = (context -> gx_draw_context_pitch + 7) >> 3;
265 getstride = (pixelmap -> gx_pixelmap_width + 3) >> 2;
266
267 /* Set transparent color. */
268 idxminx = (angle / 90) & 0x3;
269 idxmaxx = (idxminx + 2) & 0x3;
270 idxmaxy = (idxminx + 1) & 0x3;
271
272 /* Calculate the source x and y center. */
273 srcxres = pixelmap -> gx_pixelmap_width >> 1;
274 srcyres = pixelmap -> gx_pixelmap_height >> 1;
275
276 cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
277 sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
278
279 xres = GX_FIXED_VAL_TO_INT((mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv));
280 yres = GX_FIXED_VAL_TO_INT((my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv));
281
282 putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
283 putrow += clip -> gx_rectangle_top * putstride;
284 putrow += clip -> gx_rectangle_left >> 3;
285
286 /* Calculate the new rotation axis. */
287 xres = GX_FIXED_VAL_TO_INT((cx - srcxres) * cosv - (cy - srcyres) * sinv) + xres;
288 yres = GX_FIXED_VAL_TO_INT((cy - srcyres) * cosv + (cx - srcxres) * sinv) + yres;
289
290 newxpos = xpos + cx - xres;
291 newypos = ypos + cy - yres;
292
293 /* For every pixel in destination bitmap, find its position in source bitmap,
294 and set the pixel with the value in source bitmap. */
295 for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
296 {
297 put = putrow;
298 putmask = (GX_UBYTE)(0x80 >> (clip -> gx_rectangle_left & 0x07));
299
300 for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
301 {
302 xx = GX_FIXED_VAL_TO_INT((x - xres) * cosv + (y - yres) * sinv) + cx;
303 yy = GX_FIXED_VAL_TO_INT((y - yres) * cosv - (x - xres) * sinv) + cy;
304
305 if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_width) &&
306 (yy >= 0) && (yy < pixelmap -> gx_pixelmap_height))
307 {
308 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
309 get += yy * getstride;
310 get += xx >> 2;
311
312 transmask = (GX_UBYTE)(0x40 >> ((xx & 0x03) << 1));
313 if (transmask & (*get))
314 {
315 getmask = (GX_UBYTE)(transmask << 1);
316 if ((*get) & getmask)
317 {
318 *put |= putmask;
319 }
320 else
321 {
322 *put = (GX_UBYTE)(*put & (~putmask));
323 }
324 }
325 }
326
327 putmask >>= 1;
328 if (putmask == 0)
329 {
330 put++;
331 putmask = 0x80;
332 }
333 }
334 putrow += putstride;
335 }
336 }
337
338 /**************************************************************************/
339 /* */
340 /* FUNCTION RELEASE */
341 /* */
342 /* _gx_display_driver_1bpp_pixelmap_simple_rotate PORTABLE C */
343 /* 6.1.7 */
344 /* AUTHOR */
345 /* */
346 /* Kenneth Maxwell, Microsoft Corporation */
347 /* */
348 /* DESCRIPTION */
349 /* */
350 /* Internal help function that hangles 90, 180 and 270 degree pixelmap */
351 /* rotation. */
352 /* */
353 /* INPUT */
354 /* */
355 /* context Drawing context */
356 /* xpos x-coord of top-left draw point*/
357 /* ypos y-coord of top-left draw point*/
358 /* pixelmap Pointer to GX_PIXELMAP struct */
359 /* angle The angle to rotate */
360 /* rot_cx x-coord of rotate center */
361 /* rot_cy y-coord of rotate center */
362 /* */
363 /* OUTPUT */
364 /* */
365 /* status Completion status */
366 /* */
367 /* CALLS */
368 /* */
369 /* None */
370 /* */
371 /* CALLED BY */
372 /* */
373 /* _gx_display_driver_1bpp_pixelmap_rotate */
374 /* */
375 /* RELEASE HISTORY */
376 /* */
377 /* DATE NAME DESCRIPTION */
378 /* */
379 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
380 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
381 /* resulting in version 6.1 */
382 /* 06-02-2021 Kenneth Maxwell Modified comment(s), */
383 /* removed unused variable */
384 /* assignment, */
385 /* resulting in version 6.1.7 */
386 /* */
387 /**************************************************************************/
_gx_display_driver_1bpp_pixelmap_simple_rotate(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,INT angle,INT cx,INT cy)388 static VOID _gx_display_driver_1bpp_pixelmap_simple_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
389 INT angle, INT cx, INT cy)
390 {
391 GX_UBYTE *putrow;
392 GX_UBYTE *put;
393 GX_UBYTE putmask;
394 GX_UBYTE *get;
395 GX_UBYTE getmask;
396 INT putstride;
397 INT width;
398 INT height;
399 INT x;
400 INT y;
401 GX_RECTANGLE *clip;
402 INT newxpos;
403 INT newypos;
404
405 clip = context -> gx_draw_context_clip;
406 putstride = (context -> gx_draw_context_pitch + 7) >> 3;
407
408 putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
409 putrow += clip -> gx_rectangle_top * putstride;
410 putrow += clip -> gx_rectangle_left >> 3;
411
412 if (angle == 90)
413 {
414 width = pixelmap -> gx_pixelmap_height;
415 height = (pixelmap -> gx_pixelmap_width + 7) >> 3;
416
417 newxpos = xpos + cx - (width - 1 - cy);
418 newypos = ypos + cy - cx;
419
420 for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
421 {
422 put = putrow;
423 putmask = (GX_UBYTE)(0x80 >> (clip -> gx_rectangle_left & 0x07));
424
425 for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
426 {
427 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
428 get += (width - 1 - x) * height;
429 get += y >> 3;
430
431 getmask = (GX_UBYTE)(0x80 >> (y & 0x07));
432
433 if ((*get) & getmask)
434 {
435 *put |= putmask;
436 }
437 else
438 {
439 *put = (GX_UBYTE)(*put & (~putmask));
440 }
441
442 putmask >>= 1;
443 if (putmask == 0)
444 {
445 putmask = 0x80;
446 put++;
447 }
448 }
449 putrow += putstride;
450 }
451 }
452 else if (angle == 180)
453 {
454 width = pixelmap -> gx_pixelmap_width;
455 height = pixelmap -> gx_pixelmap_height;
456
457 newxpos = xpos + cx - (width - 1 - cx);
458 newypos = ypos + cy - (height - 1 - cy);
459
460 for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
461 {
462 putmask = (GX_UBYTE)(0x80 >> (clip -> gx_rectangle_left & 0x07));
463 put = putrow;
464
465 for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
466 {
467 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
468 get += (height - 1 - y) * ((width + 7) >> 3);
469 get += (width - 1 - x) >> 3;
470
471 getmask = (GX_UBYTE)(0x80 >> ((width - 1 - x) & 0x07));
472
473 if ((*get) & getmask)
474 {
475 *put |= putmask;
476 }
477 else
478 {
479 *put = (GX_UBYTE)(*put & (~putmask));
480 }
481
482 putmask >>= 1;
483 if (putmask == 0)
484 {
485 putmask = 0x80;
486 put++;
487 }
488 }
489 putrow += putstride;
490 }
491 }
492 else
493 {
494 height = pixelmap -> gx_pixelmap_width;
495
496 newxpos = xpos + cx - cy;
497 newypos = ypos + cx - (height - 1 - cy);
498
499 for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
500 {
501 putmask = (GX_UBYTE)(0x80 >> (clip -> gx_rectangle_left & 0x07));
502 put = putrow;
503
504 for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
505 {
506 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
507 get += x * ((height + 7) >> 3);
508 get += (height - 1 - y) >> 3;
509
510 getmask = (GX_UBYTE)(0x80 >> ((height - 1 - y) & 0x07));
511
512 if ((*get) & getmask)
513 {
514 *put |= putmask;
515 }
516 else
517 {
518 *put = (GX_UBYTE)(*put & (~putmask));
519 }
520
521 putmask >>= 1;
522 if (putmask == 0)
523 {
524 putmask = 0x80;
525 put++;
526 }
527 }
528
529 putrow += putstride;
530 }
531 }
532 }
533 /**************************************************************************/
534 /* */
535 /* FUNCTION RELEASE */
536 /* */
537 /* _gx_display_driver_1bpp_pixelmap_simple_transparent_rotate */
538 /* PORTABLE C */
539 /* 6.1.7 */
540 /* AUTHOR */
541 /* */
542 /* Kenneth Maxwell, Microsoft Corporation */
543 /* */
544 /* DESCRIPTION */
545 /* */
546 /* Internal help function that hangles 90, 180 and 270 degree pixelmap */
547 /* rotation. */
548 /* */
549 /* INPUT */
550 /* */
551 /* context Drawing context */
552 /* xpos x-coord of top-left draw point*/
553 /* ypos y-coord of top-left draw point*/
554 /* pixelmap Pointer to GX_PIXELMAP struct */
555 /* angle The angle to rotate */
556 /* rot_cx x-coord of rotate center */
557 /* rot_cy y-coord of rotate center */
558 /* */
559 /* OUTPUT */
560 /* */
561 /* status Completion status */
562 /* */
563 /* CALLS */
564 /* */
565 /* None */
566 /* */
567 /* CALLED BY */
568 /* */
569 /* _gx_display_driver_1bpp_pixelmap_rotate */
570 /* */
571 /* RELEASE HISTORY */
572 /* */
573 /* DATE NAME DESCRIPTION */
574 /* */
575 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
576 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
577 /* resulting in version 6.1 */
578 /* 06-02-2021 Kenneth Maxwell Modified comment(s), */
579 /* removed unused variable */
580 /* assignment, */
581 /* resulting in version 6.1.7 */
582 /* */
583 /**************************************************************************/
_gx_display_driver_1bpp_pixelmap_simple_transparent_rotate(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,INT angle,INT cx,INT cy)584 static VOID _gx_display_driver_1bpp_pixelmap_simple_transparent_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
585 INT angle, INT cx, INT cy)
586 {
587 GX_UBYTE *get;
588 INT width;
589 INT height;
590 INT x;
591 INT y;
592 GX_RECTANGLE *clip;
593 INT newxpos;
594 INT newypos;
595 GX_UBYTE *put;
596 GX_UBYTE *putrow;
597 INT putstride;
598 GX_UBYTE putmask;
599 INT getstride;
600 GX_UBYTE transmask;
601 GX_UBYTE getmask;
602
603 clip = context -> gx_draw_context_clip;
604 /* 1bpp transparent pixelmap is stored as one bit color, one bit trans-mask. */
605 getstride = (pixelmap -> gx_pixelmap_width + 3) >> 2;
606 putstride = (context -> gx_draw_context_pitch + 7) >> 3;
607 putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
608 putrow += clip -> gx_rectangle_top * putstride;
609 putrow += clip -> gx_rectangle_left >> 3;
610
611 clip = context -> gx_draw_context_clip;
612
613 if (angle == 90)
614 {
615 width = pixelmap -> gx_pixelmap_height;
616
617 newxpos = xpos + cx - (width - 1 - cy);
618 newypos = ypos + cy - cx;
619
620 for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
621 {
622 put = putrow;
623 putmask = (GX_UBYTE)(0x80 >> (clip -> gx_rectangle_left & 0x07));
624
625 transmask = (GX_UBYTE)(0x40 >> ((y & 0x03) << 1));
626 getmask = (GX_UBYTE)(transmask << 1);
627
628 for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
629 {
630 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
631 get += (width - 1 - x) * getstride;
632 get += y >> 2;
633
634 /* if not transparent, draw pixel. else skip. */
635 if (transmask & *(get))
636 {
637 if ((*get) & getmask)
638 {
639 *put |= putmask;
640 }
641 else
642 {
643 *put = (GX_UBYTE)(*put & (~putmask));
644 }
645 }
646
647 putmask >>= 1;
648 if (putmask == 0)
649 {
650 putmask = 0x80;
651 put++;
652 }
653 }
654 putrow += putstride;
655 }
656 }
657 else if (angle == 180)
658 {
659 width = pixelmap -> gx_pixelmap_width;
660 height = pixelmap -> gx_pixelmap_height;
661
662 newxpos = xpos + cx - (width - 1 - cx);
663 newypos = ypos + cy - (height - 1 - cy);
664
665 for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
666 {
667 put = putrow;
668 putmask = (GX_UBYTE)(0x80 >> (clip -> gx_rectangle_left & 0x07));
669
670 for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
671 {
672 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
673 get += (height - 1 - y) * getstride;
674 get += (width - 1 - x) >> 2;
675
676 transmask = (GX_UBYTE)(0x40 >> (((width - 1 - x) & 0x03) << 1));
677
678 /* if not transparent, draw pixel. else skip. */
679 if (transmask & *(get))
680 {
681 getmask = (GX_UBYTE)(transmask << 1);
682 if ((*get) & getmask)
683 {
684 *put |= putmask;
685 }
686 else
687 {
688 *put = (GX_UBYTE)(*put & (~putmask));
689 }
690 }
691
692 putmask >>= 1;
693 if (putmask == 0)
694 {
695 putmask = 0x80;
696 put++;
697 }
698 }
699 putrow += putstride;
700 }
701 }
702 else
703 {
704 height = pixelmap -> gx_pixelmap_width;
705
706 newxpos = xpos + cx - cy;
707 newypos = ypos + cy - (height - 1 - cx);
708
709 for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
710 {
711 put = putrow;
712 putmask = (GX_UBYTE)(0x80 >> (clip -> gx_rectangle_left & 0x07));
713
714 for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
715 {
716 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
717 get += x * getstride;
718 get += (height - 1 - y) >> 2;
719
720 transmask = (GX_UBYTE)(0x40 >> (((height - 1 - y) & 0x03) << 1));
721
722 /* if not transparent, draw pixel. else skip. */
723 if (transmask & *(get))
724 {
725 getmask = (GX_UBYTE)(transmask << 1);
726 if ((*get) & getmask)
727 {
728 *put |= putmask;
729 }
730 else
731 {
732 *put = (GX_UBYTE)(*put & (~putmask));
733 }
734 }
735
736 putmask >>= 1;
737 if (putmask == 0)
738 {
739 putmask = 0x80;
740 put++;
741 }
742 }
743 putrow += putstride;
744 }
745 }
746 }
747
748 /**************************************************************************/
749 /* */
750 /* FUNCTION RELEASE */
751 /* */
752 /* _gx_display_driver_1bpp_pixelmap_rotate PORTABLE C */
753 /* 6.1 */
754 /* AUTHOR */
755 /* */
756 /* Kenneth Maxwell, Microsoft Corporation */
757 /* */
758 /* DESCRIPTION */
759 /* */
760 /* This service rotate a monochrome format pixelmap to canvas memory. */
761 /* */
762 /* INPUT */
763 /* */
764 /* context Drawing context */
765 /* xpos x-coord of top-left draw point*/
766 /* ypos y-coord of top-left draw point*/
767 /* pixelmap Pointer to GX_PIXELMAP struct */
768 /* angle The angle to rotate */
769 /* rot_cx x-coord of rotating center. */
770 /* rot_cy y-coord of rotationg center. */
771 /* */
772 /* OUTPUT */
773 /* */
774 /* status Completion status */
775 /* */
776 /* CALLS */
777 /* */
778 /* _gx_display_driver_1bpp_pixelmap_simple_transparent_rotate */
779 /* Real pixelmap rotate function */
780 /* which rotate image for 90, */
781 /* 180 and 270 degree */
782 /* _gx_display_driver_1bpp_pixelmap_simple_rotate */
783 /* Real pixelmap rotate function */
784 /* which rotate image for 90, */
785 /* 180 and 270 degree */
786 /* _gx_display_driver_1bpp_pixelmap_transparent_rotate */
787 /* Real pixelmap rotate function */
788 /* _gx_display_driver_1bpp_pixelmap_raw_rotate */
789 /* Real pixelmap rotate function */
790 /* */
791 /* CALLED BY */
792 /* */
793 /* Application Code */
794 /* GUIX Internal Code */
795 /* */
796 /* RELEASE HISTORY */
797 /* */
798 /* DATE NAME DESCRIPTION */
799 /* */
800 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
801 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
802 /* resulting in version 6.1 */
803 /* */
804 /**************************************************************************/
_gx_display_driver_1bpp_pixelmap_rotate(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,INT angle,INT rot_cx,INT rot_cy)805 VOID _gx_display_driver_1bpp_pixelmap_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
806 INT angle, INT rot_cx, INT rot_cy)
807 {
808 if (angle % 90 == 0)
809 {
810 /* Simple angle rotate: 90 degree, 180 degree and 270 degree. */
811 if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_TRANSPARENT)
812 {
813 _gx_display_driver_1bpp_pixelmap_simple_transparent_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
814 }
815 else
816 {
817 _gx_display_driver_1bpp_pixelmap_simple_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
818 }
819 }
820 else
821 {
822 if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_TRANSPARENT)
823 {
824 /* no compression or alpha */
825 _gx_display_driver_1bpp_pixelmap_transparent_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
826 }
827 else
828 {
829 /* no compression or alpha */
830 _gx_display_driver_1bpp_pixelmap_raw_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
831 }
832 }
833
834 return;
835 }
836
837