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 
21 #define REDVAL(_c)   (GX_UBYTE)(((_c) >> 10) & 0x1f)
22 #define GREENVAL(_c) (GX_UBYTE)(((_c) >> 5) & 0x1f)
23 #define BLUEVAL(_c)  (GX_UBYTE)(((_c)) & 0x1f)
24 
25 #define ASSEMBLECOLOR(_r, _g, _b) \
26     ((((_r) & 0x1f) << 10) |      \
27      (((_g) & 0x1f) << 5) |       \
28      (((_b) & 0x1f)))
29 
30 #define GX_SOURCE_CODE
31 
32 /* Include necessary system files.  */
33 
34 #include "gx_api.h"
35 #include "gx_display.h"
36 #include "gx_context.h"
37 #include "gx_utility.h"
38 #include "gx_system.h"
39 
40 /**************************************************************************/
41 /*                                                                        */
42 /*  FUNCTION                                               RELEASE        */
43 /*                                                                        */
44 /*    _gx_display_driver_1555xrgb_pixelmap_raw_rotate     PORTABLE C      */
45 /*                                                           6.1.10       */
46 /*  AUTHOR                                                                */
47 /*                                                                        */
48 /*    Kenneth Maxwell, Microsoft Corporation                              */
49 /*                                                                        */
50 /*  DESCRIPTION                                                           */
51 /*                                                                        */
52 /*    Internal helper function that rotate an 1555xrgb format pixelmap    */
53 /*    without compression, without alpha.                                 */
54 /*                                                                        */
55 /*  INPUT                                                                 */
56 /*                                                                        */
57 /*    context                               Drawing context               */
58 /*    xpos                                  x-coord of top-left draw point*/
59 /*    ypos                                  y-coord of top-left draw point*/
60 /*    pixelmap                              Pointer to GX_PIXELMAP struct */
61 /*    angle                                 The angle to rotate           */
62 /*    cx                                    x-coord of rotate center      */
63 /*    cy                                    y-coord of rotate center      */
64 /*                                                                        */
65 /*  OUTPUT                                                                */
66 /*                                                                        */
67 /*    status                                Completion status             */
68 /*                                                                        */
69 /*  CALLS                                                                 */
70 /*                                                                        */
71 /*    _gx_utility_math_cos                  Compute the cosine value      */
72 /*    _gx_utility_math_sin                  Compute the sine value        */
73 /*    [gx_display_driver_pixel_blend]       Display driver basic pixel    */
74 /*                                             blend function             */
75 /*                                                                        */
76 /*  CALLED BY                                                             */
77 /*                                                                        */
78 /*    GUIX Internal Code                                                  */
79 /*                                                                        */
80 /*  RELEASE HISTORY                                                       */
81 /*                                                                        */
82 /*    DATE              NAME                      DESCRIPTION             */
83 /*                                                                        */
84 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
85 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
86 /*                                            resulting in version 6.1    */
87 /*  01-31-2022     Ting Zhu                 Modified comment(s),          */
88 /*                                            corrected logic,            */
89 /*                                            resulting in version 6.1.10 */
90 /*                                                                        */
91 /**************************************************************************/
_gx_display_driver_1555xrgb_pixelmap_raw_rotate(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,INT angle,INT cx,INT cy)92 static VOID _gx_display_driver_1555xrgb_pixelmap_raw_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
93                                                             INT angle, INT cx, INT cy)
94 {
95 USHORT       *get;
96 INT           srcxres;
97 INT           srcyres;
98 INT           cosv;
99 INT           sinv;
100 INT           alpha;
101 USHORT        red;
102 USHORT        green;
103 USHORT        blue;
104 INT           idxminx;
105 INT           idxmaxx;
106 INT           idxmaxy;
107 INT          *mx;
108 INT          *my;
109 INT           xres;
110 INT           yres;
111 INT           x;
112 INT           y;
113 INT           xx;
114 INT           yy;
115 USHORT        a;
116 USHORT        b;
117 USHORT        c;
118 USHORT        d;
119 INT           xdiff;
120 INT           ydiff;
121 INT           newxpos;
122 INT           newypos;
123 GX_DISPLAY   *display;
124 GX_RECTANGLE *clip;
125 VOID          (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR color, GX_UBYTE alpha);
126 
127     clip = context -> gx_draw_context_clip;
128     display = context -> gx_draw_context_display;
129     blend_func = display -> gx_display_driver_pixel_blend;
130 
131     if (!blend_func)
132     {
133         return;
134     }
135 
136     mx = _gx_system_scratchpad;
137     my = mx + 4;
138 
139     mx[0] = mx[3] = -1;
140     mx[1] = mx[2] = 1;
141 
142     my[0] = my[1] = 1;
143     my[2] = my[3] = -1;
144 
145     idxminx = (angle / 90) & 0x3;
146     idxmaxx = (idxminx + 2) & 0x3;
147     idxmaxy = (idxminx + 1) & 0x3;
148 
149     /* Calculate the source x and y center. */
150     srcxres = pixelmap -> gx_pixelmap_width >> 1;
151     srcyres = pixelmap -> gx_pixelmap_height >> 1;
152 
153     cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
154     sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
155 
156     xres = GX_FIXED_VAL_TO_INT(mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv);
157     yres = GX_FIXED_VAL_TO_INT(my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv);
158 
159     /* Calculate the new rotation axis. */
160 
161     xres = GX_FIXED_VAL_TO_INT((cx - srcxres) * cosv - (cy - srcyres) * sinv) + xres;
162     yres = GX_FIXED_VAL_TO_INT((cy - srcyres) * cosv + (cx - srcxres) * sinv) + yres;
163 
164     newxpos = xpos + cx - xres;
165     newypos = ypos + cy - yres;
166 
167     /* Loop through the destination's pixels.  */
168     for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
169     {
170         for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
171         {
172             xx = (x - xres) * cosv + (y - yres) * sinv;
173             yy = (y - yres) * cosv - (x - xres) * sinv;
174 
175             xdiff = GX_FIXED_VAL_TO_INT(xx << 8) & 0xff;
176             ydiff = GX_FIXED_VAL_TO_INT(yy << 8) & 0xff;
177 
178             xx = GX_FIXED_VAL_TO_INT(xx) + cx;
179             yy = GX_FIXED_VAL_TO_INT(yy) + cy;
180 
181             if ((xx >= -1) && (xx < pixelmap -> gx_pixelmap_width) &&
182                 (yy >= -1) && (yy < pixelmap -> gx_pixelmap_height))
183             {
184                 if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_width - 1) &&
185                     (yy >= 0) && (yy < pixelmap -> gx_pixelmap_height - 1))
186                 {
187                     get = (USHORT *)pixelmap -> gx_pixelmap_data;
188                     get += yy * pixelmap -> gx_pixelmap_width;
189                     get += xx;
190 
191                     a = *get;
192                     b = *(get + 1);
193                     c = *(get + pixelmap -> gx_pixelmap_width);
194                     d = *(get + pixelmap -> gx_pixelmap_width + 1);
195 
196                     alpha = 0xff;
197                 }
198                 else
199                 {
200                     get = (USHORT *)pixelmap -> gx_pixelmap_data;
201 
202                     a = 0;
203                     b = 0;
204                     c = 0;
205                     d = 0;
206                     alpha = 0;
207 
208                     if (xx == -1)
209                     {
210                         /* handle left edge.  */
211                         if (yy >= 0)
212                         {
213                             b = *(get + yy * pixelmap -> gx_pixelmap_width);
214                             alpha += xdiff * (256 - ydiff);
215                         }
216 
217                         if (yy < pixelmap -> gx_pixelmap_height - 1)
218                         {
219                             d = *(get + (yy + 1) * pixelmap -> gx_pixelmap_width);
220                             alpha += xdiff * ydiff;
221                         }
222                     }
223                     else if (yy == -1)
224                     {
225                         /* handle top edge.  */
226                         c = *(get + xx);
227                         alpha += ydiff * (256 - xdiff);
228 
229                         if (xx < pixelmap -> gx_pixelmap_width - 1)
230                         {
231                             d = *(get + xx + 1);
232                             alpha += xdiff * ydiff;
233                         }
234                     }
235                     else if (xx == pixelmap -> gx_pixelmap_width - 1)
236                     {
237                         /* handle right edget. */
238                         a = *(get + yy * pixelmap -> gx_pixelmap_width + xx);
239                         alpha += (256 - xdiff) * (256 - ydiff);
240 
241                         if (yy < pixelmap -> gx_pixelmap_height - 1)
242                         {
243                             c = *(get + (yy + 1) * pixelmap -> gx_pixelmap_width + xx);
244                             alpha += ydiff * (256 - xdiff);
245                         }
246                     }
247                     else
248                     {
249                         /* handle bottom edge. */
250                         a = *(get + yy * pixelmap -> gx_pixelmap_width + xx);
251                         alpha += (256 - xdiff) * (256 - ydiff);
252 
253                         b = *(get + yy * pixelmap -> gx_pixelmap_width + xx + 1);
254                         alpha += xdiff * (256 - ydiff);
255                     }
256 
257                     alpha >>= 8;
258                 }
259 
260                 red = (USHORT)((REDVAL(a) * (256 - xdiff) * (256 - ydiff) +
261                                 REDVAL(b) * xdiff * (256 - ydiff) +
262                                 REDVAL(c) * ydiff * (256 - xdiff) +
263                                 REDVAL(d) * xdiff * ydiff) >> 16);
264 
265                 green = (USHORT)((GREENVAL(a) * (256 - xdiff) * (256 - ydiff) +
266                                   GREENVAL(b) * xdiff * (256 - ydiff) +
267                                   GREENVAL(c) * ydiff * (256 - xdiff) +
268                                   GREENVAL(d) * xdiff * ydiff) >> 16);
269 
270                 blue = (USHORT)((BLUEVAL(a) * (256 - xdiff) * (256 - ydiff) +
271                                  BLUEVAL(b) * xdiff * (256 - ydiff) +
272                                  BLUEVAL(c) * ydiff * (256 - xdiff) +
273                                  BLUEVAL(d) * xdiff * ydiff) >> 16);
274 
275                 if ((alpha > 0) && (alpha < 0xff))
276                 {
277                     red = (USHORT)((red << 8) / alpha);
278                     green = (USHORT)((green << 8) / alpha);
279                     blue = (USHORT)((blue << 8) / alpha);
280                 }
281 
282                 red = red > 31 ? 31 : red;
283                 green = green > 63 ? 63 : green;
284                 blue = blue > 31 ? 31 : blue;
285                 alpha = alpha > 255 ? 255 : alpha;
286 
287                 blend_func(context, x + newxpos, y + newypos, (GX_COLOR)ASSEMBLECOLOR(red, green, blue), (GX_UBYTE)alpha);
288             }
289         }
290     }
291 }
292 
293 /**************************************************************************/
294 /*                                                                        */
295 /*  FUNCTION                                               RELEASE        */
296 /*                                                                        */
297 /*    _gx_display_driver_1555xrgb_pixelmap_alpha_rotate   PORTABLE C      */
298 /*                                                           6.1.10       */
299 /*  AUTHOR                                                                */
300 /*                                                                        */
301 /*    Kenneth Maxwell, Microsoft Corporation                              */
302 /*                                                                        */
303 /*  DESCRIPTION                                                           */
304 /*                                                                        */
305 /*    Internal helper function that rotate an 1555xrgb format pixelmap    */
306 /*    without compression, with alpha.                                    */
307 /*                                                                        */
308 /*  INPUT                                                                 */
309 /*                                                                        */
310 /*    context                               Drawing context               */
311 /*    xpos                                  x-coord of top-left draw point*/
312 /*    ypos                                  y-coord of top-left draw point*/
313 /*    pixelmap                              Pointer to GX_PIXELMAP struct */
314 /*    angle                                 The angle to rotate           */
315 /*    cx                                    x-coord of rotate center      */
316 /*    cy                                    y-coord of rotate center      */
317 /*                                                                        */
318 /*  OUTPUT                                                                */
319 /*                                                                        */
320 /*    status                                Completion status             */
321 /*                                                                        */
322 /*  CALLS                                                                 */
323 /*                                                                        */
324 /*    _gx_utility_math_cos                  Compute the cosine value      */
325 /*    _gx_utility_math_sin                  Compute the sine value        */
326 /*    [gx_display_driver_pixel_blend]       Display driver basic pixel    */
327 /*                                             blend function             */
328 /*                                                                        */
329 /*  CALLED BY                                                             */
330 /*                                                                        */
331 /*    GUIX Internal Code                                                  */
332 /*                                                                        */
333 /*  RELEASE HISTORY                                                       */
334 /*                                                                        */
335 /*    DATE              NAME                      DESCRIPTION             */
336 /*                                                                        */
337 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
338 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
339 /*                                            resulting in version 6.1    */
340 /*  01-31-2022     Ting Zhu                 Modified comment(s),          */
341 /*                                            corrected logic,            */
342 /*                                            resulting in version 6.1.10 */
343 /*                                                                        */
344 /**************************************************************************/
_gx_display_driver_1555xrgb_pixelmap_alpha_rotate(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,INT angle,INT cx,INT cy)345 static VOID _gx_display_driver_1555xrgb_pixelmap_alpha_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
346                                                               INT angle, INT cx, INT cy)
347 {
348 USHORT       *get;
349 GX_UBYTE     *getalpha;
350 INT           srcxres;
351 INT           srcyres;
352 INT           cosv;
353 INT           sinv;
354 USHORT        red;
355 USHORT        green;
356 USHORT        blue;
357 INT           idxminx;
358 INT           idxmaxx;
359 INT           idxmaxy;
360 INT          *mx;
361 INT          *my;
362 INT           xres;
363 INT           yres;
364 INT           x;
365 INT           y;
366 INT           xx;
367 INT           yy;
368 USHORT        a;
369 USHORT        b;
370 USHORT        c;
371 USHORT        d;
372 USHORT        alpha[4];
373 INT           xdiff;
374 INT           ydiff;
375 INT           newxpos;
376 INT           newypos;
377 GX_DISPLAY   *display;
378 GX_RECTANGLE *clip;
379 VOID          (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR color, GX_UBYTE alpha);
380 
381     clip = context -> gx_draw_context_clip;
382     display = context -> gx_draw_context_display;
383     blend_func = display -> gx_display_driver_pixel_blend;
384 
385     if (!blend_func)
386     {
387         return;
388     }
389 
390     mx = _gx_system_scratchpad;
391     my = mx + 4;
392 
393     mx[0] = mx[3] = -1;
394     mx[1] = mx[2] = 1;
395 
396     my[0] = my[1] = 1;
397     my[2] = my[3] = -1;
398 
399     idxminx = (angle / 90) & 0x3;
400     idxmaxx = (idxminx + 2) & 0x3;
401     idxmaxy = (idxminx + 1) & 0x3;
402 
403     /* Calculate the source x and y center. */
404     srcxres = pixelmap -> gx_pixelmap_width >> 1;
405     srcyres = pixelmap -> gx_pixelmap_height >> 1;
406 
407     cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
408     sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
409 
410     xres = GX_FIXED_VAL_TO_INT(mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv);
411     yres = GX_FIXED_VAL_TO_INT(my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv);
412 
413     xres = GX_FIXED_VAL_TO_INT((cx - srcxres) * cosv - (cy - srcyres) * sinv) + xres;
414     yres = GX_FIXED_VAL_TO_INT((cy - srcyres) * cosv + (cx - srcxres) * sinv) + yres;
415 
416     newxpos = xpos + cx - xres;
417     newypos = ypos + cy - yres;
418 
419     /* Loop through the source's pixels.  */
420     for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
421     {
422         for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
423         {
424             xx = (x - xres) * cosv + (y - yres) * sinv;
425             yy = (y - yres) * cosv - (x - xres) * sinv;
426 
427             xdiff = GX_FIXED_VAL_TO_INT(xx << 8) & 0xff;
428             ydiff = GX_FIXED_VAL_TO_INT(yy << 8) & 0xff;
429 
430             xx = GX_FIXED_VAL_TO_INT(xx) + cx;
431             yy = GX_FIXED_VAL_TO_INT(yy) + cy;
432 
433             if ((xx >= -1) && (xx < pixelmap -> gx_pixelmap_width) &&
434                 (yy >= -1) && (yy < pixelmap -> gx_pixelmap_height))
435             {
436                 if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_width - 1) && \
437                     (yy >= 0) && (yy < pixelmap -> gx_pixelmap_height - 1))
438                 {
439                     get = (USHORT *)pixelmap -> gx_pixelmap_data;
440                     get += yy * pixelmap -> gx_pixelmap_width;
441                     get += xx;
442 
443                     getalpha = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
444                     getalpha += yy * pixelmap -> gx_pixelmap_width;
445                     getalpha += xx;
446 
447                     a = *get;
448                     alpha[0] = *getalpha;
449 
450                     b = *(get + 1);
451                     alpha[1] = *(getalpha + 1);
452 
453                     c = *(get + pixelmap -> gx_pixelmap_width);
454                     alpha[2] = *(getalpha + pixelmap -> gx_pixelmap_width);
455 
456                     d = *(get + pixelmap -> gx_pixelmap_width + 1);
457                     alpha[3] = *(getalpha + pixelmap -> gx_pixelmap_width + 1);
458                 }
459                 else
460                 {
461                     get = (USHORT *)pixelmap -> gx_pixelmap_data;
462                     getalpha = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
463 
464                     a = 0;
465                     b = 0;
466                     c = 0;
467                     d = 0;
468 
469                     if (xx == -1)
470                     {
471                         /* handle left edge.  */
472                         if (yy >= 0)
473                         {
474                             b = *(get + yy * pixelmap -> gx_pixelmap_width);
475                             alpha[1] = *(getalpha + yy * pixelmap -> gx_pixelmap_width);
476                         }
477 
478                         if (yy < pixelmap -> gx_pixelmap_height - 1)
479                         {
480                             d = *(get + (yy + 1) * pixelmap -> gx_pixelmap_width);
481                             alpha[3] = *(getalpha + (yy + 1) * pixelmap -> gx_pixelmap_width);
482                         }
483                     }
484                     else if (yy == -1)
485                     {
486                         /* handle top edge.  */
487                         c = *(get + xx);
488                         alpha[2] = *(getalpha + xx);
489 
490                         if (xx < pixelmap -> gx_pixelmap_width - 1)
491                         {
492                             d = *(get + xx + 1);
493                             alpha[3] = *(getalpha + xx + 1);
494                         }
495                     }
496                     else if (xx == pixelmap -> gx_pixelmap_width - 1)
497                     {
498                         /* handle right edget. */
499                         a = *(get + yy * pixelmap -> gx_pixelmap_width + xx);
500                         alpha[0] = *(getalpha + yy * pixelmap -> gx_pixelmap_width + xx);
501 
502                         if (yy < pixelmap -> gx_pixelmap_height - 1)
503                         {
504                             c = *(get + (yy + 1) * pixelmap -> gx_pixelmap_width + xx);
505                             alpha[2] = *(getalpha + (yy + 1) * pixelmap -> gx_pixelmap_width + xx);
506                         }
507                     }
508                     else
509                     {
510                         /* handle bottom edge. */
511                         a = *(get + yy * pixelmap -> gx_pixelmap_width + xx);
512                         alpha[0] = *(getalpha + yy * pixelmap -> gx_pixelmap_width + xx);
513 
514                         b = *(get + yy * pixelmap -> gx_pixelmap_width + xx + 1);
515                         alpha[1] = *(getalpha + yy * pixelmap -> gx_pixelmap_width + xx + 1);
516                     }
517 
518                     if (!a)
519                     {
520                         alpha[0] = 0;
521                     }
522 
523                     if (!b)
524                     {
525                         alpha[1] = 0;
526                     }
527 
528                     if (!c)
529                     {
530                         alpha[2] = 0;
531                     }
532 
533                     if (!d)
534                     {
535                         alpha[3] = 0;
536                     }
537                 }
538 
539                 red = (USHORT)((REDVAL(a) * alpha[0] * (256 - xdiff) * (256 - ydiff) +
540                                 REDVAL(b) * alpha[1] * xdiff * (256 - ydiff) +
541                                 REDVAL(c) * alpha[2] * ydiff * (256 - xdiff) +
542                                 REDVAL(d) * alpha[3] * xdiff * ydiff) >> 16);
543 
544                 green = (USHORT)((GREENVAL(a) * alpha[0] * (256 - xdiff) * (256 - ydiff) +
545                                   GREENVAL(b) * alpha[1] * xdiff * (256 - ydiff) +
546                                   GREENVAL(c) * alpha[2] * ydiff * (256 - xdiff) +
547                                   GREENVAL(d) * alpha[3] * xdiff * ydiff) >> 16);
548 
549                 blue = (USHORT)((BLUEVAL(a) * alpha[0] * (256 - xdiff) * (256 - ydiff) +
550                                  BLUEVAL(b) * alpha[1] * xdiff * (256 - ydiff) +
551                                  BLUEVAL(c) * alpha[2] * ydiff * (256 - xdiff) +
552                                  BLUEVAL(d) * alpha[3] * xdiff * ydiff) >> 16);
553 
554                 alpha[0] = (USHORT)((alpha[0] * (256 - xdiff) * (256 - ydiff) +
555                                      alpha[1] * xdiff * (256 - ydiff) +
556                                      alpha[2] * ydiff * (256 - xdiff) +
557                                      alpha[3] * xdiff * ydiff) >> 16);
558 
559                 if (alpha[0])
560                 {
561                     red /= alpha[0];
562                     green /= alpha[0];
563                     blue /= alpha[0];
564                 }
565 
566                 red = red > 31 ? 31 : red;
567                 green = green > 63 ? 63 : green;
568                 blue = blue > 31 ? 31 : blue;
569                 alpha[0] = alpha[0] > 255 ? 255 : alpha[0];
570 
571                 blend_func(context, x + newxpos, y + newypos, (GX_COLOR)ASSEMBLECOLOR(red, green, blue), (GX_UBYTE)alpha[0]);
572             }
573         }
574     }
575 }
576 
577 /**************************************************************************/
578 /*                                                                        */
579 /*  FUNCTION                                               RELEASE        */
580 /*                                                                        */
581 /*    _gx_display_driver_1555xrgb_pixelmap_rotate         PORTABLE C      */
582 /*                                                           6.1          */
583 /*  AUTHOR                                                                */
584 /*                                                                        */
585 /*    Kenneth Maxwell, Microsoft Corporation                              */
586 /*                                                                        */
587 /*  DESCRIPTION                                                           */
588 /*                                                                        */
589 /*    This service rotate a pixelmap directly to canvas memory.           */
590 /*                                                                        */
591 /*  INPUT                                                                 */
592 /*                                                                        */
593 /*    context                               Drawing context               */
594 /*    xpos                                  x-coord of top-left draw point*/
595 /*    ypos                                  y-coord of top-left draw point*/
596 /*    pixelmap                              Pointer to GX_PIXELMAP struct */
597 /*    angle                                 The angle to rotate           */
598 /*    rot_cx                                x-coord of rotating center.   */
599 /*    rot_cy                                y-coord of rotationg center.  */
600 /*                                                                        */
601 /*  OUTPUT                                                                */
602 /*                                                                        */
603 /*    status                                Completion status             */
604 /*                                                                        */
605 /*  CALLS                                                                 */
606 /*                                                                        */
607 /*    _gx_display_driver_16bpp_pixelmap_rotate                            */
608 /*                                          Rotate 16bpp format pixelmap  */
609 /*    _gx_display_driver_1555xrgb_pixelmap_alpha_rotate                   */
610 /*                                          Rotate 1555xrgb format        */
611 /*                                            pixelmap with alpha         */
612 /*    _gx_display_driver_1555xrgb_pixelmap_rotate                         */
613 /*                                          Rotate 1555xrgb format        */
614 /*                                            pixelmap with alpha         */
615 /*                                                                        */
616 /*  CALLED BY                                                             */
617 /*                                                                        */
618 /*    GUIX Internal Code                                                  */
619 /*                                                                        */
620 /*  RELEASE HISTORY                                                       */
621 /*                                                                        */
622 /*    DATE              NAME                      DESCRIPTION             */
623 /*                                                                        */
624 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
625 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
626 /*                                            resulting in version 6.1    */
627 /*                                                                        */
628 /**************************************************************************/
_gx_display_driver_1555xrgb_pixelmap_rotate(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,INT angle,INT rot_cx,INT rot_cy)629 VOID _gx_display_driver_1555xrgb_pixelmap_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
630                                                  INT angle, INT rot_cx, INT rot_cy)
631 {
632     switch (pixelmap -> gx_pixelmap_format)
633     {
634     case GX_COLOR_FORMAT_1555XRGB:
635         if (angle % 90 == 0)
636         {
637             /* Simple angle rotate: 90 degree, 180 degree and 270 degree.  */
638             if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
639             {
640                 _gx_display_driver_16bpp_pixelmap_simple_alpha_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
641             }
642             else
643             {
644                 _gx_display_driver_16bpp_pixelmap_simple_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
645             }
646             break;
647         }
648         else
649         {
650             if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
651             {
652                 /* alpha, no compression */
653                 _gx_display_driver_1555xrgb_pixelmap_alpha_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
654             }
655             else
656             {
657 
658                 /* no compression or alpha */
659                 _gx_display_driver_1555xrgb_pixelmap_raw_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
660             }
661         }
662         break;
663     }
664 
665     return;
666 }
667 
668