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 GX_SOURCE_CODE
22 
23 
24 /* Include necessary system files.  */
25 
26 #include "gx_api.h"
27 #include "gx_display.h"
28 #include "gx_context.h"
29 
30 /**************************************************************************/
31 /*                                                                        */
32 /*  FUNCTION                                               RELEASE        */
33 /*                                                                        */
34 /*    _gx_display_driver_16bpp_rotated_pixelmap_raw_blend PORTABLE C      */
35 /*                                                           6.1.3        */
36 /*  AUTHOR                                                                */
37 /*                                                                        */
38 /*    Kenneth Maxwell, Microsoft Corporation                              */
39 /*                                                                        */
40 /*  DESCRIPTION                                                           */
41 /*                                                                        */
42 /*    Internal helper function that handles blending of uncompressed      */
43 /*    pixlemap file                                                       */
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 /*    alpha                                 blending value 0 to 255       */
52 /*                                                                        */
53 /*  OUTPUT                                                                */
54 /*                                                                        */
55 /*    None                                                                */
56 /*                                                                        */
57 /*  CALLS                                                                 */
58 /*                                                                        */
59 /*    [gx_display_driver_pixel_blend]        Display driver basic pixel   */
60 /*                                             blend function             */
61 /*                                                                        */
62 /*  CALLED BY                                                             */
63 /*                                                                        */
64 /*    GUIX Internal Code                                                  */
65 /*                                                                        */
66 /*  RELEASE HISTORY                                                       */
67 /*                                                                        */
68 /*    DATE              NAME                      DESCRIPTION             */
69 /*                                                                        */
70 /*  12-31-2020     Kenneth Maxwell          Initial Version 6.1.3         */
71 /*                                                                        */
72 /**************************************************************************/
_gx_display_driver_16bpp_rotated_pixelmap_raw_blend(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,GX_UBYTE alpha)73 static VOID _gx_display_driver_16bpp_rotated_pixelmap_raw_blend(GX_DRAW_CONTEXT *context,
74                                                                 INT xpos, INT ypos, GX_PIXELMAP *pixelmap, GX_UBYTE alpha)
75 {
76 int           xval;
77 int           yval;
78 USHORT       *get;
79 USHORT       *getrow;
80 USHORT        pixel;
81 
82 GX_RECTANGLE *clip = context -> gx_draw_context_clip;
83 GX_RECTANGLE  rotated_clip;
84 
85     GX_SWAP_VALS(xpos, ypos);
86 
87     if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
88     {
89         rotated_clip.gx_rectangle_left = clip -> gx_rectangle_top;
90         rotated_clip.gx_rectangle_right = clip -> gx_rectangle_bottom;
91         rotated_clip.gx_rectangle_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_right - 1);
92         rotated_clip.gx_rectangle_bottom = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_left - 1);
93         ypos = (context -> gx_draw_context_canvas -> gx_canvas_x_resolution - ypos - pixelmap -> gx_pixelmap_width);
94     }
95     else
96     {
97         rotated_clip.gx_rectangle_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_bottom - 1);
98         rotated_clip.gx_rectangle_right = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_top - 1);
99         rotated_clip.gx_rectangle_top = clip -> gx_rectangle_left;
100         rotated_clip.gx_rectangle_bottom = clip -> gx_rectangle_right;
101         xpos = (context -> gx_draw_context_canvas -> gx_canvas_y_resolution - xpos - pixelmap -> gx_pixelmap_height);
102     }
103 
104     getrow = (USHORT *)(pixelmap -> gx_pixelmap_data);
105     getrow += pixelmap -> gx_pixelmap_height * (rotated_clip.gx_rectangle_top - ypos);
106     getrow += (rotated_clip.gx_rectangle_left - xpos);
107 
108     for (yval = rotated_clip.gx_rectangle_top; yval <= rotated_clip.gx_rectangle_bottom; yval++)
109     {
110         get = getrow;
111         for (xval = rotated_clip.gx_rectangle_left; xval <= rotated_clip.gx_rectangle_right; xval++)
112         {
113             pixel = *get++;
114             _gx_display_driver_565rgb_pixel_blend(context, xval, yval, pixel, alpha);
115         }
116         getrow += pixelmap -> gx_pixelmap_height;
117     }
118 }
119 
120 /**************************************************************************/
121 /*                                                                        */
122 /*  FUNCTION                                               RELEASE        */
123 /*                                                                        */
124 /*    _gx_display_driver_565rgb_rotated_pixelmap_alpha_blend              */
125 /*                                                        PORTABLE C      */
126 /*                                                           6.1.3        */
127 /*  AUTHOR                                                                */
128 /*                                                                        */
129 /*    Kenneth Maxwell, Microsoft Corporation                              */
130 /*                                                                        */
131 /*  DESCRIPTION                                                           */
132 /*                                                                        */
133 /*    Internal helper function that handles blending of uncompressed      */
134 /*    pixelmap file with alpha channel.                                   */
135 /*                                                                        */
136 /*  INPUT                                                                 */
137 /*                                                                        */
138 /*    context                               Drawing context               */
139 /*    xpos                                  x-coord of top-left draw point*/
140 /*    ypos                                  y-coord of top-left draw point*/
141 /*    pixelmap                              Pointer to GX_PIXELMAP struct */
142 /*    alpha                                 blending value 0 to 255       */
143 /*                                                                        */
144 /*  OUTPUT                                                                */
145 /*                                                                        */
146 /*    None                                                                */
147 /*                                                                        */
148 /*  CALLS                                                                 */
149 /*                                                                        */
150 /*    _gx_display_driver_565rgb_pixel_blend  Display driver basic pixel   */
151 /*                                             blend function             */
152 /*  CALLED BY                                                             */
153 /*                                                                        */
154 /*    GUIX Internal Code                                                  */
155 /*                                                                        */
156 /*  RELEASE HISTORY                                                       */
157 /*                                                                        */
158 /*    DATE              NAME                      DESCRIPTION             */
159 /*                                                                        */
160 /*  12-31-2020     Kenneth Maxwell          Initial Version 6.1.3         */
161 /*                                                                        */
162 /**************************************************************************/
_gx_display_driver_565rgb_rotated_pixelmap_alpha_blend(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,GX_UBYTE alpha)163 static VOID _gx_display_driver_565rgb_rotated_pixelmap_alpha_blend(GX_DRAW_CONTEXT *context,
164                                                                    INT xpos, INT ypos, GX_PIXELMAP *pixelmap, GX_UBYTE alpha)
165 {
166 INT           skipcount;
167 INT           xval;
168 INT           yval;
169 USHORT       *getrow;
170 GX_UBYTE     *getrowalpha;
171 USHORT       *get;
172 USHORT        pixel;
173 GX_UBYTE     *getalpha;
174 INT           combined_alpha;
175 GX_UBYTE      internal_alpha;
176 
177 GX_RECTANGLE *clip = context -> gx_draw_context_clip;
178 GX_RECTANGLE  rotated_clip;
179 
180     GX_SWAP_VALS(xpos, ypos);
181 
182     if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
183     {
184         rotated_clip.gx_rectangle_left = clip -> gx_rectangle_top;
185         rotated_clip.gx_rectangle_right = clip -> gx_rectangle_bottom;
186         rotated_clip.gx_rectangle_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_right - 1);
187         rotated_clip.gx_rectangle_bottom = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_left - 1);
188         ypos = (context -> gx_draw_context_canvas -> gx_canvas_x_resolution - ypos - pixelmap -> gx_pixelmap_width);
189     }
190     else
191     {
192         rotated_clip.gx_rectangle_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_bottom - 1);
193         rotated_clip.gx_rectangle_right = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_top - 1);
194         rotated_clip.gx_rectangle_top = clip -> gx_rectangle_left;
195         rotated_clip.gx_rectangle_bottom = clip -> gx_rectangle_right;
196         xpos = (context -> gx_draw_context_canvas -> gx_canvas_y_resolution - xpos - pixelmap -> gx_pixelmap_height);
197     }
198 
199     /* Calculate how many pixels to skip. */
200     skipcount = (pixelmap -> gx_pixelmap_height) * (rotated_clip.gx_rectangle_top - ypos);
201     skipcount += (rotated_clip.gx_rectangle_left - xpos);
202     getrow = (USHORT *)(pixelmap -> gx_pixelmap_data);
203     getrow += skipcount;
204 
205     getrowalpha = (GX_UBYTE *)(pixelmap -> gx_pixelmap_aux_data);
206     getrowalpha += skipcount;
207 
208     for (yval = rotated_clip.gx_rectangle_top; yval <= rotated_clip.gx_rectangle_bottom; yval++)
209     {
210         get = getrow;
211         getalpha = getrowalpha;
212 
213         for (xval = rotated_clip.gx_rectangle_left; xval <= rotated_clip.gx_rectangle_right; xval++)
214         {
215             internal_alpha = *getalpha++;
216             if (internal_alpha)
217             {
218                 combined_alpha = internal_alpha * alpha;
219                 combined_alpha /= 255;
220                 pixel = *get;
221                 _gx_display_driver_565rgb_pixel_blend(context, xval, yval, pixel, (GX_UBYTE)combined_alpha);
222             }
223             get++;
224         }
225         getrow += pixelmap -> gx_pixelmap_height;
226         getrowalpha += pixelmap -> gx_pixelmap_height;
227     }
228 }
229 
230 /**************************************************************************/
231 /*                                                                        */
232 /*  FUNCTION                                               RELEASE        */
233 /*                                                                        */
234 /*    _gx_display_driver_16bpp_rotated_pixelmap_compressed_blend          */
235 /*                                                        PORTABLE C      */
236 /*                                                           6.1.3        */
237 /*  AUTHOR                                                                */
238 /*                                                                        */
239 /*    Kenneth Maxwell, Microsoft Corporation                              */
240 /*                                                                        */
241 /*  DESCRIPTION                                                           */
242 /*                                                                        */
243 /*    Internal helper function that handles blending of compressed        */
244 /*    pixlemap file .                                                     */
245 /*                                                                        */
246 /*  INPUT                                                                 */
247 /*                                                                        */
248 /*    context                               Drawing context               */
249 /*    xpos                                  x-coord of top-left draw point*/
250 /*    ypos                                  y-coord of top-left draw point*/
251 /*    pixelmap                              Pointer to GX_PIXELMAP struct */
252 /*    alpha                                 blending value 0 to 255       */
253 /*                                                                        */
254 /*  OUTPUT                                                                */
255 /*                                                                        */
256 /*    None                                                                */
257 /*                                                                        */
258 /*  CALLS                                                                 */
259 /*                                                                        */
260 /*     [gx_display_driver_pixel_blend]       Display driver basic pixel   */
261 /*                                             blend function             */
262 /*                                                                        */
263 /*  CALLED BY                                                             */
264 /*                                                                        */
265 /*    GUIX Internal Code                                                  */
266 /*                                                                        */
267 /*  RELEASE HISTORY                                                       */
268 /*                                                                        */
269 /*    DATE              NAME                      DESCRIPTION             */
270 /*                                                                        */
271 /*  12-31-2020     Kenneth Maxwell          Initial Version 6.1.3         */
272 /*                                                                        */
273 /**************************************************************************/
_gx_display_driver_16bpp_rotated_pixelmap_compressed_blend(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,GX_UBYTE alpha)274 static VOID _gx_display_driver_16bpp_rotated_pixelmap_compressed_blend(GX_DRAW_CONTEXT *context,
275                                                                        INT xpos, INT ypos, GX_PIXELMAP *pixelmap, GX_UBYTE alpha)
276 {
277 int              yval;
278 int              xval;
279 GX_CONST USHORT *get;
280 USHORT           count;
281 USHORT           pixel;
282 VOID             (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR fcolor, GX_UBYTE alpha);
283 GX_RECTANGLE    *clip = context -> gx_draw_context_clip;
284 GX_RECTANGLE     rotated_clip;
285 
286     blend_func = _gx_display_driver_565rgb_pixel_blend;
287 
288     get = (GX_CONST USHORT *)pixelmap -> gx_pixelmap_data;
289 
290     GX_SWAP_VALS(xpos, ypos);
291 
292     if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
293     {
294         rotated_clip.gx_rectangle_left = clip -> gx_rectangle_top;
295         rotated_clip.gx_rectangle_right = clip -> gx_rectangle_bottom;
296         rotated_clip.gx_rectangle_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_right - 1);
297         rotated_clip.gx_rectangle_bottom = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_left - 1);
298         ypos = (context -> gx_draw_context_canvas -> gx_canvas_x_resolution - ypos - pixelmap -> gx_pixelmap_width);
299     }
300     else
301     {
302         rotated_clip.gx_rectangle_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_bottom - 1);
303         rotated_clip.gx_rectangle_right = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_top - 1);
304         rotated_clip.gx_rectangle_top = clip -> gx_rectangle_left;
305         rotated_clip.gx_rectangle_bottom = clip -> gx_rectangle_right;
306         xpos = (context -> gx_draw_context_canvas -> gx_canvas_y_resolution - xpos - pixelmap -> gx_pixelmap_height);
307     }
308 
309     /* Compressed with no alpha is a two-byte count and two-byte pixel value. */
310 
311     /* First, skip to the starting row. */
312     for (yval = ypos; yval < rotated_clip.gx_rectangle_top; yval++)
313     {
314         xval = 0;
315         while (xval < pixelmap -> gx_pixelmap_height)
316         {
317             count = *get++;
318 
319             if (count & 0x8000)
320             {
321                 count = (USHORT)((count & 0x7fff) + 1);
322 
323                 /* Skip repeated pixel value.  */
324                 get++;
325             }
326             else
327             {
328                 count++;
329 
330                 /* Skip raw pixel values.  */
331                 get += count;
332             }
333             xval += count;
334         }
335     }
336 
337     while (yval <= rotated_clip.gx_rectangle_bottom)
338     {
339         xval = xpos;
340 
341         while (xval < xpos + pixelmap -> gx_pixelmap_height)
342         {
343             count = *get++;
344 
345             if (count & 0x8000)
346             {
347                 /* Repeated value.  */
348                 count = (USHORT)((count & 0x7fff) + 1);
349                 pixel = *get++;
350 
351                 while (count--)
352                 {
353                     if (xval >= rotated_clip.gx_rectangle_left &&
354                         xval <= rotated_clip.gx_rectangle_right)
355                     {
356                         blend_func(context, xval, yval, pixel, alpha);
357                     }
358                     xval++;
359                 }
360             }
361             else
362             {
363                 /* String of non-repeated values. */
364                 count++;
365                 while (count--)
366                 {
367                     if (xval >= rotated_clip.gx_rectangle_left &&
368                         xval <= rotated_clip.gx_rectangle_right)
369                     {
370                         pixel = *get;
371                         blend_func(context, xval, yval, pixel, alpha);
372                     }
373                     get++;
374                     xval++;
375                 }
376             }
377         }
378         yval++;
379     }
380 }
381 
382 /**************************************************************************/
383 /*                                                                        */
384 /*  FUNCTION                                               RELEASE        */
385 /*                                                                        */
386 /*    _gx_display_driver_565rgb_rotated_palette_pixelmap_raw_blend        */
387 /*                                                          PORTABLE C    */
388 /*                                                           6.1.3        */
389 /*  AUTHOR                                                                */
390 /*                                                                        */
391 /*    Kenneth Maxwell, Microsoft Corporation                              */
392 /*                                                                        */
393 /*  DESCRIPTION                                                           */
394 /*                                                                        */
395 /*    Internal helper function that handles blending of raw pixlemap      */
396 /*    file without transparent for palette pixelmap.                      */
397 /*                                                                        */
398 /*  INPUT                                                                 */
399 /*                                                                        */
400 /*    context                               Drawing context               */
401 /*    xpos                                  x-coord of top-left draw point*/
402 /*    ypos                                  y-coord of top-left draw point*/
403 /*    pixelmap                              Pointer to GX_PIXELMAP struct */
404 /*    alpha                                 blending value 0 to 255       */
405 /*                                                                        */
406 /*  OUTPUT                                                                */
407 /*                                                                        */
408 /*    None                                                                */
409 /*                                                                        */
410 /*  CALLS                                                                 */
411 /*                                                                        */
412 /*    _gx_display_driver_565rgb_pixel_blend  Display driver basic pixel   */
413 /*                                             blend function             */
414 /*                                                                        */
415 /*  CALLED BY                                                             */
416 /*                                                                        */
417 /*    GUIX Internal Code                                                  */
418 /*                                                                        */
419 /*  RELEASE HISTORY                                                       */
420 /*                                                                        */
421 /*    DATE              NAME                      DESCRIPTION             */
422 /*                                                                        */
423 /*  12-31-2020     Kenneth Maxwell          Initial Version 6.1.3         */
424 /*                                                                        */
425 /**************************************************************************/
_gx_display_driver_565rgb_rotated_palette_pixelmap_raw_blend(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,GX_UBYTE alpha)426 static VOID _gx_display_driver_565rgb_rotated_palette_pixelmap_raw_blend(GX_DRAW_CONTEXT *context,
427                                                                          INT xpos, INT ypos, GX_PIXELMAP *pixelmap, GX_UBYTE alpha)
428 {
429 INT                xval;
430 INT                yval;
431 GX_UBYTE          *getrow;
432 GX_CONST GX_UBYTE *get;
433 GX_COLOR          *palette;
434 USHORT             pixel;
435 GX_UBYTE           r;
436 GX_UBYTE           g;
437 GX_UBYTE           b;
438 
439 GX_RECTANGLE      *clip = context -> gx_draw_context_clip;
440 GX_RECTANGLE       rotated_clip;
441 
442     GX_SWAP_VALS(xpos, ypos);
443 
444     if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
445     {
446         rotated_clip.gx_rectangle_left = clip -> gx_rectangle_top;
447         rotated_clip.gx_rectangle_right = clip -> gx_rectangle_bottom;
448         rotated_clip.gx_rectangle_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_right - 1);
449         rotated_clip.gx_rectangle_bottom = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_left - 1);
450         ypos = (context -> gx_draw_context_canvas -> gx_canvas_x_resolution - ypos - pixelmap -> gx_pixelmap_width);
451     }
452     else
453     {
454         rotated_clip.gx_rectangle_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_bottom - 1);
455         rotated_clip.gx_rectangle_right = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_top - 1);
456         rotated_clip.gx_rectangle_top = clip -> gx_rectangle_left;
457         rotated_clip.gx_rectangle_bottom = clip -> gx_rectangle_right;
458         xpos = (context -> gx_draw_context_canvas -> gx_canvas_y_resolution - xpos - pixelmap -> gx_pixelmap_height);
459     }
460 
461     getrow = (GX_UBYTE *)(pixelmap -> gx_pixelmap_data);
462     getrow += pixelmap -> gx_pixelmap_height * (rotated_clip.gx_rectangle_top - ypos);
463     getrow += (rotated_clip.gx_rectangle_left - xpos);
464 
465     palette = (GX_COLOR *)pixelmap -> gx_pixelmap_aux_data;
466 
467     for (yval = rotated_clip.gx_rectangle_top; yval <= rotated_clip.gx_rectangle_bottom; yval++)
468     {
469         get = getrow;
470 
471         for (xval = rotated_clip.gx_rectangle_left; xval <= rotated_clip.gx_rectangle_right; xval++)
472         {
473             r = (GX_UBYTE)(REDVAL_32BPP(palette[*get]) >> 3);
474             g = (GX_UBYTE)(GREENVAL_32BPP(palette[*get]) >> 2);
475             b = (GX_UBYTE)(BLUEVAL_32BPP(palette[*get++]) >> 3);
476             pixel = (USHORT)ASSEMBLECOLOR_16BPP(r, g, b);
477             _gx_display_driver_565rgb_pixel_blend(context, xval, yval, pixel, alpha);
478         }
479         getrow += pixelmap -> gx_pixelmap_height;
480     }
481 }
482 
483 /**************************************************************************/
484 /*                                                                        */
485 /*  FUNCTION                                               RELEASE        */
486 /*                                                                        */
487 /*    _gx_display_driver_565rgb_rotated_palette_pixelmap_transparent_blend*/
488 /*                                                        PORTABLE C      */
489 /*                                                           6.1.3        */
490 /*  AUTHOR                                                                */
491 /*                                                                        */
492 /*    Kenneth Maxwell, Microsoft Corporation                              */
493 /*                                                                        */
494 /*  DESCRIPTION                                                           */
495 /*                                                                        */
496 /*    Internal helper function that handles blending of raw pixlemap      */
497 /*    file with transparent for palette pixelmap.                         */
498 /*                                                                        */
499 /*  INPUT                                                                 */
500 /*                                                                        */
501 /*    context                               Drawing context               */
502 /*    xpos                                  x-coord of top-left draw point*/
503 /*    ypos                                  y-coord of top-left draw point*/
504 /*    pixelmap                              Pointer to GX_PIXELMAP struct */
505 /*    alpha                                 blending value 0 to 255       */
506 /*                                                                        */
507 /*  OUTPUT                                                                */
508 /*                                                                        */
509 /*    None                                                                */
510 /*                                                                        */
511 /*  CALLS                                                                 */
512 /*                                                                        */
513 /*    _gx_display_driver_565rgb_pixel_blend  Display driver basic pixel   */
514 /*                                             blend function             */
515 /*                                                                        */
516 /*  CALLED BY                                                             */
517 /*                                                                        */
518 /*    GUIX Internal Code                                                  */
519 /*                                                                        */
520 /*  RELEASE HISTORY                                                       */
521 /*                                                                        */
522 /*    DATE              NAME                      DESCRIPTION             */
523 /*                                                                        */
524 /*  12-31-2020     Kenneth Maxwell          Initial Version 6.1.3         */
525 /*                                                                        */
526 /**************************************************************************/
_gx_display_driver_565rgb_rotated_palette_pixelmap_transparent_blend(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,GX_UBYTE alpha)527 static VOID _gx_display_driver_565rgb_rotated_palette_pixelmap_transparent_blend(GX_DRAW_CONTEXT *context,
528                                                                                  INT xpos, INT ypos, GX_PIXELMAP *pixelmap, GX_UBYTE alpha)
529 {
530 INT                xval;
531 INT                yval;
532 GX_UBYTE          *getrow;
533 GX_CONST GX_UBYTE *get;
534 GX_COLOR          *palette;
535 USHORT             pixel;
536 GX_UBYTE           r;
537 GX_UBYTE           g;
538 GX_UBYTE           b;
539 
540 GX_RECTANGLE      *clip = context -> gx_draw_context_clip;
541 GX_RECTANGLE       rotated_clip;
542 
543     GX_SWAP_VALS(xpos, ypos);
544 
545     if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
546     {
547         rotated_clip.gx_rectangle_left = clip -> gx_rectangle_top;
548         rotated_clip.gx_rectangle_right = clip -> gx_rectangle_bottom;
549         rotated_clip.gx_rectangle_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_right - 1);
550         rotated_clip.gx_rectangle_bottom = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_left - 1);
551         ypos = (context -> gx_draw_context_canvas -> gx_canvas_x_resolution - ypos - pixelmap -> gx_pixelmap_width);
552     }
553     else
554     {
555         rotated_clip.gx_rectangle_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_bottom - 1);
556         rotated_clip.gx_rectangle_right = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_top - 1);
557         rotated_clip.gx_rectangle_top = clip -> gx_rectangle_left;
558         rotated_clip.gx_rectangle_bottom = clip -> gx_rectangle_right;
559         xpos = (context -> gx_draw_context_canvas -> gx_canvas_y_resolution - xpos - pixelmap -> gx_pixelmap_height);
560     }
561 
562     getrow = (GX_UBYTE *)(pixelmap -> gx_pixelmap_data);
563     getrow += pixelmap -> gx_pixelmap_height * (rotated_clip.gx_rectangle_top - ypos);
564     getrow += (rotated_clip.gx_rectangle_left - xpos);
565 
566     palette = (GX_COLOR *)pixelmap -> gx_pixelmap_aux_data;
567 
568     for (yval = rotated_clip.gx_rectangle_top; yval <= rotated_clip.gx_rectangle_bottom; yval++)
569     {
570         get = getrow;
571 
572         for (xval = rotated_clip.gx_rectangle_left; xval <= rotated_clip.gx_rectangle_right; xval++)
573         {
574             if ((*get) != pixelmap -> gx_pixelmap_transparent_color)
575             {
576                 r = (GX_UBYTE)(REDVAL_32BPP(palette[*get]) >> 3);
577                 g = (GX_UBYTE)(GREENVAL_32BPP(palette[*get]) >> 2);
578                 b = (GX_UBYTE)(BLUEVAL_32BPP(palette[*get]) >> 3);
579                 pixel = (USHORT)ASSEMBLECOLOR_16BPP(r, g, b);
580                 _gx_display_driver_565rgb_pixel_blend(context, xval, yval, pixel, alpha);
581             }
582             get++;
583         }
584         getrow += pixelmap -> gx_pixelmap_height;
585     }
586 }
587 
588 /**************************************************************************/
589 /*                                                                        */
590 /*  FUNCTION                                               RELEASE        */
591 /*                                                                        */
592 /*    _gx_display_driver_565rgb_rotated_4444argb_pixelmap_raw_blend       */
593 /*                                                         PORTABLE C     */
594 /*                                                           6.1.3        */
595 /*  AUTHOR                                                                */
596 /*                                                                        */
597 /*    Kenneth Maxwell, Microsoft Corporation                              */
598 /*                                                                        */
599 /*  DESCRIPTION                                                           */
600 /*                                                                        */
601 /*    Internal helper function that handles blending of uncompressed      */
602 /*    pixlemap file with alpha channel of 4444argb format.                */
603 /*                                                                        */
604 /*  INPUT                                                                 */
605 /*                                                                        */
606 /*    context                               Drawing context               */
607 /*    xpos                                  x-coord of top-left draw point*/
608 /*    ypos                                  y-coord of top-left draw point*/
609 /*    pixelmap                              Pointer to GX_PIXELMAP struct */
610 /*    alpha                                 blending value 0 to 255       */
611 /*                                                                        */
612 /*  OUTPUT                                                                */
613 /*                                                                        */
614 /*    None                                                                */
615 /*                                                                        */
616 /*  CALLS                                                                 */
617 /*                                                                        */
618 /*    _gx_display_driver_565rgb_pixel_blend  Display driver basic pixel   */
619 /*                                             blend function             */
620 /*                                                                        */
621 /*  CALLED BY                                                             */
622 /*                                                                        */
623 /*    GUIX Internal Code                                                  */
624 /*                                                                        */
625 /*  RELEASE HISTORY                                                       */
626 /*                                                                        */
627 /*    DATE              NAME                      DESCRIPTION             */
628 /*                                                                        */
629 /*  12-31-2020     Kenneth Maxwell          Initial Version 6.1.3         */
630 /*                                                                        */
631 /**************************************************************************/
_gx_display_driver_565rgb_rotated_4444argb_pixelmap_raw_blend(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,GX_UBYTE alpha)632 static VOID _gx_display_driver_565rgb_rotated_4444argb_pixelmap_raw_blend(GX_DRAW_CONTEXT *context,
633                                                                           INT xpos, INT ypos, GX_PIXELMAP *pixelmap, GX_UBYTE alpha)
634 {
635 INT              skipcount;
636 INT              xval;
637 INT              yval;
638 USHORT          *getrow;
639 GX_CONST USHORT *get;
640 UCHAR            alpha_value;
641 GX_UBYTE         combined_alpha;
642 USHORT           pixel;
643 
644 GX_RECTANGLE    *clip = context -> gx_draw_context_clip;
645 GX_RECTANGLE     rotated_clip;
646 
647     GX_SWAP_VALS(xpos, ypos);
648 
649     if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
650     {
651         rotated_clip.gx_rectangle_left = clip -> gx_rectangle_top;
652         rotated_clip.gx_rectangle_right = clip -> gx_rectangle_bottom;
653         rotated_clip.gx_rectangle_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_right - 1);
654         rotated_clip.gx_rectangle_bottom = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_left - 1);
655         ypos = (context -> gx_draw_context_canvas -> gx_canvas_x_resolution - ypos - pixelmap -> gx_pixelmap_width);
656     }
657     else
658     {
659         rotated_clip.gx_rectangle_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_bottom - 1);
660         rotated_clip.gx_rectangle_right = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_top - 1);
661         rotated_clip.gx_rectangle_top = clip -> gx_rectangle_left;
662         rotated_clip.gx_rectangle_bottom = clip -> gx_rectangle_right;
663         xpos = (context -> gx_draw_context_canvas -> gx_canvas_y_resolution - xpos - pixelmap -> gx_pixelmap_height);
664     }
665 
666     /* Calculate how many pixels to skip.  */
667     skipcount = (pixelmap -> gx_pixelmap_height) * (rotated_clip.gx_rectangle_top - ypos);
668     skipcount += (rotated_clip.gx_rectangle_left - xpos);
669     getrow = (USHORT *)(pixelmap -> gx_pixelmap_data);
670     getrow += skipcount;
671 
672     for (yval = rotated_clip.gx_rectangle_top; yval <= rotated_clip.gx_rectangle_bottom; yval++)
673     {
674         get = getrow;
675 
676         for (xval = rotated_clip.gx_rectangle_left; xval <= rotated_clip.gx_rectangle_right; xval++)
677         {
678             /* 0x000f- -> b , 0x00f0- -> g , 0x0f00- -> r , 0xf000- -> a */
679             /* 4444bgra - ->  565rgb */
680             alpha_value = (UCHAR)(((*get) & 0xf000) >> 8);
681             if (alpha_value)
682             {
683                 alpha_value = alpha_value | (alpha_value >> 4);
684                 pixel = (USHORT)((((*get) & 0x0f00) << 4) | (((*get) & 0x00f0) << 3) | (((*get) & 0x000f) << 1));
685                 combined_alpha = (GX_UBYTE)(alpha * alpha_value / 255);
686                 _gx_display_driver_565rgb_pixel_blend(context, xval, yval, pixel, combined_alpha);
687             }
688             get++;
689         }
690         getrow += pixelmap -> gx_pixelmap_height;
691     }
692 }
693 
694 /**************************************************************************/
695 /*                                                                        */
696 /*  FUNCTION                                               RELEASE        */
697 /*                                                                        */
698 /*    _gx_display_driver_565rgb_rotated_pixelmap_blend    PORTABLE C      */
699 /*                                                           6.1.3        */
700 /*  AUTHOR                                                                */
701 /*                                                                        */
702 /*    Kenneth Maxwell, Microsoft Corporation                              */
703 /*                                                                        */
704 /*  DESCRIPTION                                                           */
705 /*                                                                        */
706 /*    Driver entry point for pixelmap blending function that handles      */
707 /*    compressed or uncompress, with or without alpha channel.            */
708 /*                                                                        */
709 /*  INPUT                                                                 */
710 /*                                                                        */
711 /*    context                               Drawing context               */
712 /*    xpos                                  x-coord of top-left draw point*/
713 /*    ypos                                  y-coord of top-left draw point*/
714 /*    pixelmap                              Pointer to GX_PIXELMAP struct */
715 /*    alpha                                 blending value 0 to 255       */
716 /*                                                                        */
717 /*  OUTPUT                                                                */
718 /*                                                                        */
719 /*    None                                                                */
720 /*                                                                        */
721 /*  CALLS                                                                 */
722 /*                                                                        */
723 /*    _gx_display_driver_565rgb_rotated_palette_pixelmap_transparent_blend*/
724 /*    _gx_display_driver_565rgb_rotated_palette_pixelmap_raw_blend        */
725 /*    _gx_display_driver_565rgb_rotated_4444argb_pixelmap_raw_blend       */
726 /*    _gx_display_driver_565rgb_rotated_pixelmap_alpha_blend              */
727 /*    _gx_display_driver_16bpp_rotated_pixelmap_compressed_blend          */
728 /*    _gx_display_driver_16bpp_rotated_pixelmap_raw_blend                 */
729 /*                                                                        */
730 /*  CALLED BY                                                             */
731 /*                                                                        */
732 /*    GUIX Internal Code                                                  */
733 /*                                                                        */
734 /*  RELEASE HISTORY                                                       */
735 /*                                                                        */
736 /*    DATE              NAME                      DESCRIPTION             */
737 /*                                                                        */
738 /*  12-31-2020     Kenneth Maxwell          Initial Version 6.1.3         */
739 /*                                                                        */
740 /**************************************************************************/
_gx_display_driver_565rgb_rotated_pixelmap_blend(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,GX_UBYTE alpha)741 VOID _gx_display_driver_565rgb_rotated_pixelmap_blend(GX_DRAW_CONTEXT *context,
742                                                       INT xpos, INT ypos, GX_PIXELMAP *pixelmap, GX_UBYTE alpha)
743 {
744     if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_COMPRESSED)
745     {
746         if (pixelmap -> gx_pixelmap_format != GX_COLOR_FORMAT_565RGB)
747         {
748             return;
749         }
750     }
751 
752     switch (pixelmap -> gx_pixelmap_format)
753     {
754     case GX_COLOR_FORMAT_8BIT_PALETTE:
755         if (pixelmap -> gx_pixelmap_aux_data == GX_NULL)
756         {
757             break;
758         }
759 
760         if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_TRANSPARENT)
761         {
762             _gx_display_driver_565rgb_rotated_palette_pixelmap_transparent_blend(context, xpos, ypos, pixelmap, alpha);
763         }
764         else
765         {
766             _gx_display_driver_565rgb_rotated_palette_pixelmap_raw_blend(context, xpos, ypos, pixelmap, alpha);
767         }
768         break;
769 
770     case GX_COLOR_FORMAT_4444ARGB:
771         _gx_display_driver_565rgb_rotated_4444argb_pixelmap_raw_blend(context, xpos, ypos, pixelmap, alpha);
772         break;
773 
774     case GX_COLOR_FORMAT_565RGB:
775         if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
776         {
777             _gx_display_driver_565rgb_rotated_pixelmap_alpha_blend(context, xpos, ypos, pixelmap, alpha);
778         }
779         else
780         {
781             if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_COMPRESSED)
782             {
783                 _gx_display_driver_16bpp_rotated_pixelmap_compressed_blend(context, xpos, ypos, pixelmap, alpha);
784             }
785             else
786             {
787                 _gx_display_driver_16bpp_rotated_pixelmap_raw_blend(context, xpos, ypos, pixelmap, alpha);
788             }
789         }
790         break;
791 
792     default:
793         return;
794     }
795 }
796 
797