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_8bpp_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 alpha.                                                    */
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 /*    None                                                                */
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_8bpp_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_8bpp_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_8bpp_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 
105     clip = context -> gx_draw_context_clip;
106 
107     /* Set transparent color.  */
108     idxminx = (angle / 90) & 0x3;
109     idxmaxx = (idxminx + 2) & 0x3;
110     idxmaxy = (idxminx + 1) & 0x3;
111 
112     /* Calculate the source x and y center. */
113     srcxres = pixelmap -> gx_pixelmap_width >> 1;
114     srcyres = pixelmap -> gx_pixelmap_height >> 1;
115 
116     cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
117     sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
118 
119     xres = GX_FIXED_VAL_TO_INT((mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv));
120     yres = GX_FIXED_VAL_TO_INT((my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv));
121 
122     putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
123     putrow += clip -> gx_rectangle_top * context -> gx_draw_context_pitch;
124     putrow += clip -> gx_rectangle_left;
125 
126     /* Calculate the new rotation axis. */
127     xres = GX_FIXED_VAL_TO_INT((cx - srcxres) * cosv - (cy - srcyres) * sinv) + xres;
128     yres = GX_FIXED_VAL_TO_INT((cy - srcyres) * cosv + (cx - srcxres) * sinv) + yres;
129 
130     newxpos = xpos + cx - xres;
131     newypos = ypos + cy - yres;
132 
133     /* For every pixel in destination bitmap, find its position in source bitmap,
134        and set the pixel with the value in source bitmap.  */
135     for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
136     {
137         put = putrow;
138 
139         for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
140         {
141             xx = GX_FIXED_VAL_TO_INT((x - xres) * cosv + (y - yres) * sinv) + cx;
142             yy = GX_FIXED_VAL_TO_INT((y - yres) * cosv - (x - xres) * sinv) + cy;
143 
144             if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_width) &&
145                 (yy >= 0) && (yy < pixelmap -> gx_pixelmap_height))
146             {
147                 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
148                 get += yy * pixelmap -> gx_pixelmap_width;
149                 get += xx;
150 
151                 *put = *get;
152             }
153 
154             put++;
155         }
156         putrow += context -> gx_draw_context_pitch;
157     }
158 }
159 
160 /**************************************************************************/
161 /*                                                                        */
162 /*  FUNCTION                                               RELEASE        */
163 /*                                                                        */
164 /*    _gx_display_driver_8bpp_pixelmap_transparent_rotate PORTABLE C      */
165 /*                                                           6.1.10       */
166 /*  AUTHOR                                                                */
167 /*                                                                        */
168 /*    Kenneth Maxwell, Microsoft Corporation                              */
169 /*                                                                        */
170 /*  DESCRIPTION                                                           */
171 /*                                                                        */
172 /*    Internal helper function that rotate an uncompressed pixelmap       */
173 /*      without alpha.                                                    */
174 /*                                                                        */
175 /*  INPUT                                                                 */
176 /*                                                                        */
177 /*    context                               Drawing context               */
178 /*    xpos                                  x-coord of top-left draw point*/
179 /*    ypos                                  y-coord of top-left draw point*/
180 /*    pixelmap                              Pointer to GX_PIXELMAP struct */
181 /*    angle                                 The angle to rotate           */
182 /*    cx                                    x-coord of rotate center      */
183 /*    cy                                    y-coord of rotate center      */
184 /*                                                                        */
185 /*  OUTPUT                                                                */
186 /*                                                                        */
187 /*    None                                                                */
188 /*                                                                        */
189 /*  CALLS                                                                 */
190 /*                                                                        */
191 /*    _gx_utility_math_cos                  Compute the cosine value      */
192 /*    _gx_utility_math_sin                  Compute the sine value        */
193 /*                                                                        */
194 /*  CALLED BY                                                             */
195 /*                                                                        */
196 /*    GUIX Internal Code                                                  */
197 /*                                                                        */
198 /*  RELEASE HISTORY                                                       */
199 /*                                                                        */
200 /*    DATE              NAME                      DESCRIPTION             */
201 /*                                                                        */
202 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
203 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
204 /*                                            resulting in version 6.1    */
205 /*  01-31-2022     Ting Zhu                 Modified comment(s),          */
206 /*                                            corrected logic,            */
207 /*                                            resulting in version 6.1.10 */
208 /*                                                                        */
209 /**************************************************************************/
_gx_display_driver_8bpp_pixelmap_transparent_rotate(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,INT angle,INT cx,INT cy)210 static VOID _gx_display_driver_8bpp_pixelmap_transparent_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
211                                                                 INT angle, INT cx, INT cy)
212 {
213 GX_UBYTE     *putrow;
214 GX_UBYTE     *put;
215 GX_UBYTE     *get;
216 INT           srcxres;
217 INT           srcyres;
218 INT           cosv;
219 INT           sinv;
220 INT           idxminx;
221 INT           idxmaxx;
222 INT           idxmaxy;
223 INT           mx[] = {-1, 1, 1, -1};
224 INT           my[] = {1, 1, -1, -1};
225 INT           xres;
226 INT           yres;
227 INT           x;
228 INT           y;
229 INT           xx;
230 INT           yy;
231 GX_RECTANGLE *clip;
232 INT           newxpos;
233 INT           newypos;
234 
235     clip = context -> gx_draw_context_clip;
236 
237     /* Set transparent color.  */
238     idxminx = (angle / 90) & 0x3;
239     idxmaxx = (idxminx + 2) & 0x3;
240     idxmaxy = (idxminx + 1) & 0x3;
241 
242     /* Calculate the source x and y center. */
243     srcxres = pixelmap -> gx_pixelmap_width >> 1;
244     srcyres = pixelmap -> gx_pixelmap_height >> 1;
245 
246     cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
247     sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
248 
249     xres = GX_FIXED_VAL_TO_INT((mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv));
250     yres = GX_FIXED_VAL_TO_INT((my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv));
251 
252     putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
253     putrow += clip -> gx_rectangle_top * context -> gx_draw_context_pitch;
254     putrow += clip -> gx_rectangle_left;
255 
256     /* Calculate the new rotation axis. */
257     x = (cx - srcxres) * cosv - (cy - srcyres) * sinv;
258     y = (cy - srcyres) * cosv + (cx - srcxres) * sinv;
259 
260     xres = GX_FIXED_VAL_TO_INT(x) + xres;
261     yres = GX_FIXED_VAL_TO_INT(y) + yres;
262 
263     newxpos = xpos + cx - xres;
264     newypos = ypos + cy - yres;
265 
266     /* For every pixel in destination bitmap, find its position in source bitmap,
267        and set the pixel with the value in source bitmap.  */
268     for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
269     {
270         put = putrow;
271 
272         for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
273         {
274             xx = GX_FIXED_VAL_TO_INT((x - xres) * cosv + (y - yres) * sinv) + cx;
275             yy = GX_FIXED_VAL_TO_INT((y - yres) * cosv - (x - xres) * sinv) + cy;
276 
277             if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_width) &&
278                 (yy >= 0) && (yy < pixelmap -> gx_pixelmap_height))
279             {
280                 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
281                 get += yy * pixelmap -> gx_pixelmap_width;
282                 get += xx;
283 
284                 if ((*get) != pixelmap -> gx_pixelmap_transparent_color)
285                 {
286                     *put = *get;
287                 }
288             }
289             put++;
290         }
291         putrow += context -> gx_draw_context_pitch;
292     }
293 }
294 
295 /**************************************************************************/
296 /*                                                                        */
297 /*  FUNCTION                                               RELEASE        */
298 /*                                                                        */
299 /*    _gx_display_driver_8bpp_pixelmap_simple_rotate      PORTABLE C      */
300 /*                                                           6.1.7        */
301 /*  AUTHOR                                                                */
302 /*                                                                        */
303 /*    Kenneth Maxwell, Microsoft Corporation                              */
304 /*                                                                        */
305 /*  DESCRIPTION                                                           */
306 /*                                                                        */
307 /*    Internal help function that hangles 90, 180 and 270 degree pixelmap */
308 /*    rotation.                                                           */
309 /*                                                                        */
310 /*  INPUT                                                                 */
311 /*                                                                        */
312 /*    context                               Drawing context               */
313 /*    xpos                                  x-coord of top-left draw point*/
314 /*    ypos                                  y-coord of top-left draw point*/
315 /*    pixelmap                              Pointer to GX_PIXELMAP struct */
316 /*    angle                                 The angle to rotate           */
317 /*    cx                                    x-coord of rotate center      */
318 /*    cy                                    y-coord of rotate center      */
319 /*                                                                        */
320 /*  OUTPUT                                                                */
321 /*                                                                        */
322 /*    None                                                                */
323 /*                                                                        */
324 /*  CALLS                                                                 */
325 /*                                                                        */
326 /*    None                                                                */
327 /*                                                                        */
328 /*  CALLED BY                                                             */
329 /*                                                                        */
330 /*    _gx_display_driver_8bpp_pixelmap_rotate                             */
331 /*                                                                        */
332 /*  RELEASE HISTORY                                                       */
333 /*                                                                        */
334 /*    DATE              NAME                      DESCRIPTION             */
335 /*                                                                        */
336 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
337 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
338 /*                                            resulting in version 6.1    */
339 /*  06-02-2021     Kenneth Maxwell          Modified comment(s),          */
340 /*                                            removed unused variable     */
341 /*                                            assignment,                 */
342 /*                                            resulting in version 6.1.7  */
343 /*                                                                        */
344 /**************************************************************************/
_gx_display_driver_8bpp_pixelmap_simple_rotate(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,INT angle,INT cx,INT cy)345 VOID _gx_display_driver_8bpp_pixelmap_simple_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
346                                                            INT angle, INT cx, INT cy)
347 {
348 GX_UBYTE     *putrow;
349 GX_UBYTE     *put;
350 GX_UBYTE     *get;
351 INT           width;
352 INT           height;
353 INT           x;
354 INT           y;
355 GX_RECTANGLE *clip;
356 INT           newxpos;
357 INT           newypos;
358 
359     clip = context -> gx_draw_context_clip;
360 
361     if (angle == 90)
362     {
363         width = pixelmap -> gx_pixelmap_height;
364         height = pixelmap -> gx_pixelmap_width;
365 
366         newxpos = xpos + cx - (width - 1 - cy);
367         newypos = ypos + cy - cx;
368 
369         putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
370         putrow += clip -> gx_rectangle_top * context -> gx_draw_context_pitch;
371         putrow += clip -> gx_rectangle_left;
372 
373         for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
374         {
375             put = putrow;
376 
377             for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
378             {
379                 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
380                 get += (width - 1 - x) * height;
381                 get += y;
382 
383                 *put++ = *get;
384             }
385 
386             putrow += context -> gx_draw_context_pitch;
387         }
388     }
389     else if (angle == 180)
390     {
391 
392         width = pixelmap -> gx_pixelmap_width;
393         height = pixelmap -> gx_pixelmap_height;
394 
395         newxpos = xpos + cx - (width - 1 - cx);
396         newypos = ypos + cy - (height - 1 - cy);
397 
398         putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
399         putrow += clip -> gx_rectangle_top * context -> gx_draw_context_pitch;
400         putrow += clip -> gx_rectangle_left;
401 
402         for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
403         {
404             put = putrow;
405             for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
406             {
407                 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
408                 get += (height - 1 - y) * width;
409                 get += width - 1 - x;
410 
411                 *put++ = *get;
412             }
413 
414             putrow += context -> gx_draw_context_pitch;
415         }
416     }
417     else
418     {
419         height = pixelmap -> gx_pixelmap_width;
420 
421         newxpos = xpos + cx - cy;
422         newypos = ypos + cx - (height - 1 - cy);
423 
424         putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
425         putrow += clip -> gx_rectangle_top * context -> gx_draw_context_pitch;
426         putrow += clip -> gx_rectangle_left;
427 
428         for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
429         {
430             put = putrow;
431 
432             for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
433             {
434                 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
435                 get += x * height;
436                 get += height - 1 - y;
437 
438                 *put++ = *get;
439             }
440 
441             putrow += context -> gx_draw_context_pitch;
442         }
443     }
444 }
445 
446 /**************************************************************************/
447 /*                                                                        */
448 /*  FUNCTION                                               RELEASE        */
449 /*                                                                        */
450 /*    _gx_display_driver_8bpp_pixelmap_simple_transparent_rotate          */
451 /*                                                        PORTABLE C      */
452 /*                                                           6.1.7        */
453 /*  AUTHOR                                                                */
454 /*                                                                        */
455 /*    Kenneth Maxwell, Microsoft Corporation                              */
456 /*                                                                        */
457 /*  DESCRIPTION                                                           */
458 /*                                                                        */
459 /*    Internal help function that hangles 90, 180 and 270 degree pixelmap */
460 /*    rotation.                                                           */
461 /*                                                                        */
462 /*  INPUT                                                                 */
463 /*                                                                        */
464 /*    context                               Drawing context               */
465 /*    xpos                                  x-coord of top-left draw point*/
466 /*    ypos                                  y-coord of top-left draw point*/
467 /*    pixelmap                              Pointer to GX_PIXELMAP struct */
468 /*    angle                                 The angle to rotate           */
469 /*    cx                                    x-coord of rotate center      */
470 /*    cy                                    y-coord of rotate center      */
471 /*                                                                        */
472 /*  OUTPUT                                                                */
473 /*                                                                        */
474 /*    None                                                                */
475 /*                                                                        */
476 /*  CALLS                                                                 */
477 /*                                                                        */
478 /*    None                                                                */
479 /*                                                                        */
480 /*  CALLED BY                                                             */
481 /*                                                                        */
482 /*    _gx_display_driver_8bpp_pixelmap_rotate                             */
483 /*                                                                        */
484 /*  RELEASE HISTORY                                                       */
485 /*                                                                        */
486 /*    DATE              NAME                      DESCRIPTION             */
487 /*                                                                        */
488 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
489 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
490 /*                                            resulting in version 6.1    */
491 /*  06-02-2021     Kenneth Maxwell          Modified comment(s),          */
492 /*                                            removed unused variable     */
493 /*                                            assignment,                 */
494 /*                                            resulting in version 6.1.7  */
495 /*                                                                        */
496 /**************************************************************************/
_gx_display_driver_8bpp_pixelmap_simple_transparent_rotate(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,INT angle,INT cx,INT cy)497 static VOID _gx_display_driver_8bpp_pixelmap_simple_transparent_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
498                                                                        INT angle, INT cx, INT cy)
499 {
500 GX_UBYTE     *putrow;
501 GX_UBYTE     *put;
502 GX_UBYTE     *get;
503 INT           width;
504 INT           height;
505 INT           x;
506 INT           y;
507 GX_RECTANGLE *clip;
508 INT           newxpos;
509 INT           newypos;
510 
511     clip = context -> gx_draw_context_clip;
512 
513     if (angle == 90)
514     {
515         width = pixelmap -> gx_pixelmap_height;
516         height = pixelmap -> gx_pixelmap_width;
517 
518         newxpos = xpos + cx - (width - 1 - cy);
519         newypos = ypos + cy - cx;
520 
521         putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
522         putrow += clip -> gx_rectangle_top * context -> gx_draw_context_pitch;
523         putrow += clip -> gx_rectangle_left;
524 
525         for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
526         {
527             put = putrow;
528 
529             for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
530             {
531                 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
532                 get += (width - 1 - x) * height;
533                 get += y;
534 
535                 if ((*get) != pixelmap -> gx_pixelmap_transparent_color)
536                 {
537                     *put = *get;
538                 }
539                 put++;
540             }
541             putrow += context -> gx_draw_context_pitch;
542         }
543     }
544     else if (angle == 180)
545     {
546 
547         width = pixelmap -> gx_pixelmap_width;
548         height = pixelmap -> gx_pixelmap_height;
549 
550         newxpos = xpos + cx - (width - 1 - cx);
551         newypos = ypos + cy - (height - 1 - cy);
552 
553         putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
554         putrow += clip -> gx_rectangle_top * context -> gx_draw_context_pitch;
555         putrow += clip -> gx_rectangle_left;
556 
557         for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
558         {
559             put = putrow;
560             for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
561             {
562                 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
563                 get += (height - 1 - y) * width;
564                 get += width - 1 - x;
565 
566                 if ((*get) != pixelmap -> gx_pixelmap_transparent_color)
567                 {
568                     *put = *get;
569                 }
570                 put++;
571             }
572 
573             putrow += context -> gx_draw_context_pitch;
574         }
575     }
576     else
577     {
578         height = pixelmap -> gx_pixelmap_width;
579 
580         newxpos = xpos + cx - cy;
581         newypos = ypos + cx - (height - 1 - cy);
582 
583         putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
584         putrow += clip -> gx_rectangle_top * context -> gx_draw_context_pitch;
585         putrow += clip -> gx_rectangle_left;
586 
587         for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
588         {
589             put = putrow;
590 
591             for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
592             {
593                 get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
594                 get += x * height;
595                 get += height - 1 - y;
596 
597                 if ((*get) != pixelmap -> gx_pixelmap_transparent_color)
598                 {
599                     *put = *get;
600                 }
601                 put++;
602             }
603 
604             putrow += context -> gx_draw_context_pitch;
605         }
606     }
607 }
608 
609 /**************************************************************************/
610 /*                                                                        */
611 /*  FUNCTION                                               RELEASE        */
612 /*                                                                        */
613 /*    _gx_display_driver_8bpp_pixelmap_rotate             PORTABLE C      */
614 /*                                                           6.1          */
615 /*  AUTHOR                                                                */
616 /*                                                                        */
617 /*    Kenneth Maxwell, Microsoft Corporation                              */
618 /*                                                                        */
619 /*  DESCRIPTION                                                           */
620 /*                                                                        */
621 /*    This service rotate a pixelmap directly to canvas memory.           */
622 /*                                                                        */
623 /*  INPUT                                                                 */
624 /*                                                                        */
625 /*    context                               Drawing context               */
626 /*    xpos                                  x-coord of top-left draw point*/
627 /*    ypos                                  y-coord of top-left draw point*/
628 /*    pixelmap                              Pointer to GX_PIXELMAP struct */
629 /*    angle                                 The angle to rotate           */
630 /*    rot_cx                                x-coord of rotating center.   */
631 /*    rot_cy                                y-coord of rotationg center.  */
632 /*                                                                        */
633 /*  OUTPUT                                                                */
634 /*                                                                        */
635 /*    status                                Completion status             */
636 /*                                                                        */
637 /*  CALLS                                                                 */
638 /*                                                                        */
639 /*    _gx_display_driver_8bpp_pixelmap_simple_transparent_rotate          */
640 /*                                          Real display driver pixelmap  */
641 /*                                            roate function              */
642 /*    _gx_display_driver_8bpp_pixelmap_simple_rotate                      */
643 /*                                          Real display driver pixelmap  */
644 /*                                            roate function              */
645 /*    _gx_display_driver_8bpp_pixelmap_transparent_rotate                 */
646 /*                                          Real display driver pixelmap  */
647 /*                                            roate function              */
648 /*    _gx_display_driver_8bpp_pixelmap_raw_rotate                         */
649 /*                                          Real display driver pixelmap  */
650 /*                                            roate function              */
651 /*                                                                        */
652 /*  CALLED BY                                                             */
653 /*                                                                        */
654 /*    Application Code                                                    */
655 /*    GUIX Internal Code                                                  */
656 /*                                                                        */
657 /*  RELEASE HISTORY                                                       */
658 /*                                                                        */
659 /*    DATE              NAME                      DESCRIPTION             */
660 /*                                                                        */
661 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
662 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
663 /*                                            resulting in version 6.1    */
664 /*                                                                        */
665 /**************************************************************************/
_gx_display_driver_8bpp_pixelmap_rotate(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,INT angle,INT rot_cx,INT rot_cy)666 VOID _gx_display_driver_8bpp_pixelmap_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
667                                              INT angle, INT rot_cx, INT rot_cy)
668 {
669     if (angle % 90 == 0)
670     {
671         /* Simple angle rotate: 90 degree, 180 degree and 270 degree.  */
672         if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_TRANSPARENT)
673         {
674             _gx_display_driver_8bpp_pixelmap_simple_transparent_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
675         }
676         else
677         {
678             _gx_display_driver_8bpp_pixelmap_simple_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
679         }
680     }
681     else
682     {
683         if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_TRANSPARENT)
684         {
685             /* no compression or alpha */
686             _gx_display_driver_8bpp_pixelmap_transparent_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
687         }
688         else
689         {
690             /* no compression or alpha */
691             _gx_display_driver_8bpp_pixelmap_raw_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
692         }
693     }
694 
695     return;
696 }
697 
698