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