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