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