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 /*                                                                        */
33 /*  FUNCTION                                               RELEASE        */
34 /*                                                                        */
35 /*    _gx_display_driver_4444argb_pixelmap_alpha_write    PORTABLE C      */
36 /*                                                           6.1          */
37 /*  AUTHOR                                                                */
38 /*                                                                        */
39 /*    Kenneth Maxwell, Microsoft Corporation                              */
40 /*                                                                        */
41 /*  DESCRIPTION                                                           */
42 /*                                                                        */
43 /*    Internal helper function that handles writing of uncompressed       */
44 /*    pixlemap file with alpha channel.                                   */
45 /*                                                                        */
46 /*  INPUT                                                                 */
47 /*                                                                        */
48 /*    context                               Drawing context               */
49 /*    xpos                                  x-coord of top-left draw point*/
50 /*    ypos                                  y-coord of top-left draw point*/
51 /*    pixelmap                              Pointer to GX_PIXELMAP struct */
52 /*                                                                        */
53 /*  OUTPUT                                                                */
54 /*                                                                        */
55 /*    None                                                                */
56 /*                                                                        */
57 /*  CALLS                                                                 */
58 /*                                                                        */
59 /*    [gx_display_driver_pixel_blend]       Basic display driver pixel    */
60 /*                                            blend function              */
61 /*                                                                        */
62 /*  CALLED BY                                                             */
63 /*                                                                        */
64 /*    _gx_display_driver_4444argb_pixelmap_draw                           */
65 /*                                                                        */
66 /*  RELEASE HISTORY                                                       */
67 /*                                                                        */
68 /*    DATE              NAME                      DESCRIPTION             */
69 /*                                                                        */
70 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
71 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
72 /*                                            resulting in version 6.1    */
73 /*                                                                        */
74 /**************************************************************************/
_gx_display_driver_4444argb_pixelmap_alpha_write(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap)75 static VOID _gx_display_driver_4444argb_pixelmap_alpha_write(GX_DRAW_CONTEXT *context,
76                                                            INT xpos, INT ypos, GX_PIXELMAP *pixelmap)
77 {
78 INT              skipcount;
79 INT              xval;
80 INT              yval;
81 USHORT          *getrow;
82 GX_CONST USHORT *get;
83 USHORT           pixel;
84 GX_UBYTE         alpha;
85 GX_UBYTE         brush_alpha;
86 VOID           (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR color, GX_UBYTE alpha);
87 GX_RECTANGLE    *clip = context -> gx_draw_context_clip;
88 
89     brush_alpha = context -> gx_draw_context_brush.gx_brush_alpha;
90     blend_func = context -> gx_draw_context_display -> gx_display_driver_pixel_blend;
91     if (!blend_func)
92     {
93         return;
94     }
95 
96     /* calculate how many pixels to skip */
97     skipcount = (pixelmap -> gx_pixelmap_width) * (clip -> gx_rectangle_top - ypos);
98     skipcount += (clip -> gx_rectangle_left - xpos);
99     getrow = (USHORT *)(pixelmap -> gx_pixelmap_data);
100     getrow += skipcount;
101 
102     for (yval = clip -> gx_rectangle_top; yval <= clip -> gx_rectangle_bottom; yval++)
103     {
104         get = getrow;
105 
106         for (xval = clip -> gx_rectangle_left; xval <= clip -> gx_rectangle_right; xval++)
107         {
108             pixel = *get++;
109             alpha = (GX_UBYTE)(pixel >> 12);
110             if (alpha)
111             {
112                 blend_func(context, xval, yval, pixel, brush_alpha);
113             }
114         }
115         getrow += pixelmap -> gx_pixelmap_width;
116     }
117 }
118 
119 /**************************************************************************/
120 /*                                                                        */
121 /*  FUNCTION                                               RELEASE        */
122 /*                                                                        */
123 /*    _gx_display_driver_4444argb_pixelmap_raw_write      PORTABLE C      */
124 /*                                                           6.1          */
125 /*  AUTHOR                                                                */
126 /*                                                                        */
127 /*    Kenneth Maxwell, Microsoft Corporation                              */
128 /*                                                                        */
129 /*  DESCRIPTION                                                           */
130 /*                                                                        */
131 /*    Internal helper function that handles writing of uncompressed       */
132 /*    pixlemap file with 0xf alpha channel value.                         */
133 /*                                                                        */
134 /*  INPUT                                                                 */
135 /*                                                                        */
136 /*    context                               Drawing context               */
137 /*    xpos                                  x-coord of top-left draw point*/
138 /*    ypos                                  y-coord of top-left draw point*/
139 /*    pixelmap                              Pointer to GX_PIXELMAP struct */
140 /*                                                                        */
141 /*  OUTPUT                                                                */
142 /*                                                                        */
143 /*    None                                                                */
144 /*                                                                        */
145 /*  CALLS                                                                 */
146 /*                                                                        */
147 /*    None                                                                */
148 /*                                                                        */
149 /*  CALLED BY                                                             */
150 /*                                                                        */
151 /*    _gx_display_driver_4444argb_pixelmap_draw                           */
152 /*                                                                        */
153 /*  RELEASE HISTORY                                                       */
154 /*                                                                        */
155 /*    DATE              NAME                      DESCRIPTION             */
156 /*                                                                        */
157 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
158 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
159 /*                                            resulting in version 6.1    */
160 /*                                                                        */
161 /**************************************************************************/
_gx_display_driver_4444argb_pixelmap_raw_write(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap)162 static VOID _gx_display_driver_4444argb_pixelmap_raw_write(GX_DRAW_CONTEXT *context,
163                                                            INT xpos, INT ypos, GX_PIXELMAP *pixelmap)
164 {
165 INT           skipcount;
166 INT           xval;
167 INT           yval;
168 USHORT       *getrow;
169 GX_CONST USHORT *get;
170 USHORT        pixel;
171 USHORT       *put;
172 USHORT       *putrow;
173 GX_RECTANGLE *clip = context -> gx_draw_context_clip;
174 
175     /* calculate how many pixels to skip */
176     skipcount = (pixelmap -> gx_pixelmap_width) * (clip -> gx_rectangle_top - ypos);
177     skipcount += (clip -> gx_rectangle_left - xpos);
178     getrow = (USHORT *)(pixelmap -> gx_pixelmap_data);
179     getrow += skipcount;
180 
181     putrow = (USHORT *)context -> gx_draw_context_memory;
182     putrow += (clip -> gx_rectangle_top) * context -> gx_draw_context_pitch;
183     putrow += clip -> gx_rectangle_left;
184 
185     for (yval = clip -> gx_rectangle_top; yval <= clip -> gx_rectangle_bottom; yval++)
186     {
187         get = getrow;
188         put = putrow;
189 
190         for (xval = clip -> gx_rectangle_left; xval <= clip -> gx_rectangle_right; xval++)
191         {
192             /*Or with 0xf000 to make sure it has no alpha.*/
193             pixel = (*get++) | 0xf000;
194             *put++ = pixel;
195         }
196         getrow += pixelmap -> gx_pixelmap_width;
197         putrow += context -> gx_draw_context_pitch;
198     }
199 }
200 
201 /**************************************************************************/
202 /*                                                                        */
203 /*  FUNCTION                                               RELEASE        */
204 /*                                                                        */
205 /*    _gx_display_driver_4444argb_pixelmap_c_a_write     PORTABLE C       */
206 /*                                                           6.1          */
207 /*  AUTHOR                                                                */
208 /*                                                                        */
209 /*    Kenneth Maxwell, Microsoft Corporation                              */
210 /*                                                                        */
211 /*  DESCRIPTION                                                           */
212 /*                                                                        */
213 /*    Internal helper function that handles writing of compressed         */
214 /*    pixlemap file with alpha channel.                                   */
215 /*                                                                        */
216 /*  INPUT                                                                 */
217 /*                                                                        */
218 /*    context                               Drawing context               */
219 /*    xpos                                  x-coord of top-left draw point*/
220 /*    ypos                                  y-coord of top-left draw point*/
221 /*    pixelmap                              Pointer to GX_PIXELMAP struct */
222 /*                                                                        */
223 /*  OUTPUT                                                                */
224 /*                                                                        */
225 /*    None                                                                */
226 /*                                                                        */
227 /*  CALLS                                                                 */
228 /*                                                                        */
229 /*    [gx_display_driver_pixel_blend]       Basic display driver pixel    */
230 /*                                            blend function              */
231 /*                                                                        */
232 /*  CALLED BY                                                             */
233 /*                                                                        */
234 /*    _gx_display_driver_4444argb_pixelmap_draw                           */
235 /*                                                                        */
236 /*  RELEASE HISTORY                                                       */
237 /*                                                                        */
238 /*    DATE              NAME                      DESCRIPTION             */
239 /*                                                                        */
240 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
241 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
242 /*                                            resulting in version 6.1    */
243 /*                                                                        */
244 /**************************************************************************/
_gx_display_driver_4444argb_pixelmap_compressed_alpha_write(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap)245 static VOID _gx_display_driver_4444argb_pixelmap_compressed_alpha_write(GX_DRAW_CONTEXT *context,
246                                                                         INT xpos, INT ypos, GX_PIXELMAP *pixelmap)
247 {
248 INT           yval;
249 INT           xval;
250 GX_CONST USHORT *get;
251 USHORT        count;
252 USHORT        pixel;
253 GX_UBYTE      alpha;
254 GX_UBYTE      brush_alpha;
255 VOID        (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR fcolor, GX_UBYTE alpha);
256 GX_RECTANGLE *clip = context -> gx_draw_context_clip;
257 
258     get = (GX_CONST USHORT *)pixelmap -> gx_pixelmap_data;
259     brush_alpha = context -> gx_draw_context_brush.gx_brush_alpha;
260     blend_func = context -> gx_draw_context_display -> gx_display_driver_pixel_blend;
261 
262     if (blend_func == GX_NULL)
263     {
264         return;
265     }
266 
267     /* first, skip to the starting row */
268     for (yval = ypos; yval < clip -> gx_rectangle_top; yval++)
269     {
270         xval = 0;
271         while (xval < pixelmap -> gx_pixelmap_width)
272         {
273             count = *get++;
274 
275             if (count & 0x8000)
276             {
277                 count = (USHORT)((count & 0x7fff) + 1);
278                 get++;      /* skip repeated pixel value */
279             }
280             else
281             {
282                 count++;
283                 get += count;   /* skip raw pixel values */
284             }
285             xval += count;
286         }
287     }
288 
289     /* now we are on the first visible row, copy pixels until we get
290        to the enf of the last visible row
291      */
292     while (yval <= clip -> gx_rectangle_bottom)
293     {
294         xval = xpos;
295 
296         while (xval < xpos + pixelmap -> gx_pixelmap_width)
297         {
298             count = *get++;
299 
300             if (count & 0x8000)
301             {
302                 /* repeated value */
303                 count = (USHORT)((count & 0x7fff) + 1);
304                 pixel = *get++;
305                 alpha = (GX_UBYTE)(pixel >> 12);
306 
307                 if (alpha)
308                 {
309                     while (count--)
310                     {
311                         if (xval >= clip -> gx_rectangle_left &&
312                             xval <= clip -> gx_rectangle_right)
313                         {
314                             blend_func(context, xval, yval, pixel, brush_alpha);
315                         }
316                         xval++;
317                     }
318                 }
319                 else
320                 {
321                     xval += count;
322                 }
323             }
324             else
325             {
326                 /* string of non-repeated values */
327                 count++;
328                 while (count--)
329                 {
330                     if (xval >= clip -> gx_rectangle_left &&
331                         xval <= clip -> gx_rectangle_right)
332                     {
333                         blend_func(context, xval, yval, *get, brush_alpha);
334                     }
335                     get++;
336                     xval++;
337                 }
338             }
339         }
340         yval++;
341     }
342 }
343 
344 /**************************************************************************/
345 /*                                                                        */
346 /*  FUNCTION                                               RELEASE        */
347 /*                                                                        */
348 /*    _gx_display_driver_4444argb_pixelmap_compressed_write               */
349 /*                                                        PORTABLE C      */
350 /*                                                           6.1          */
351 /*  AUTHOR                                                                */
352 /*                                                                        */
353 /*    Kenneth Maxwell, Microsoft Corporation                              */
354 /*                                                                        */
355 /*  DESCRIPTION                                                           */
356 /*                                                                        */
357 /*    Internal helper function that handles writing of compressed         */
358 /*    pixlemap file without alpha channel.                                */
359 /*                                                                        */
360 /*  INPUT                                                                 */
361 /*                                                                        */
362 /*    context                               Drawing context               */
363 /*    xpos                                  x-coord of top-left draw point*/
364 /*    ypos                                  y-coord of top-left draw point*/
365 /*    pixelmap                              Pointer to GX_PIXELMAP struct */
366 /*                                                                        */
367 /*  OUTPUT                                                                */
368 /*                                                                        */
369 /*    None                                                                */
370 /*                                                                        */
371 /*  CALLS                                                                 */
372 /*                                                                        */
373 /*    None                                                                */
374 /*                                                                        */
375 /*  CALLED BY                                                             */
376 /*                                                                        */
377 /*    _gx_display_driver_4444argb_pixelmap_draw                           */
378 /*                                                                        */
379 /*  RELEASE HISTORY                                                       */
380 /*                                                                        */
381 /*    DATE              NAME                      DESCRIPTION             */
382 /*                                                                        */
383 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
384 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
385 /*                                            resulting in version 6.1    */
386 /*                                                                        */
387 /**************************************************************************/
_gx_display_driver_4444argb_pixelmap_compressed_write(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap)388 static VOID _gx_display_driver_4444argb_pixelmap_compressed_write(GX_DRAW_CONTEXT *context,
389                                                                   INT xpos, INT ypos, GX_PIXELMAP *pixelmap)
390 {
391 INT               yval;
392 INT               xval;
393 GX_CONST USHORT  *get;
394 USHORT            count;
395 USHORT            pixel;
396 USHORT           *put;
397 USHORT           *putrow;
398 GX_RECTANGLE     *clip = context -> gx_draw_context_clip;
399 
400     get = (GX_CONST USHORT *)pixelmap -> gx_pixelmap_data;
401 
402     /* first, skip to the starting row */
403     for (yval = ypos; yval < clip -> gx_rectangle_top; yval++)
404     {
405         xval = 0;
406         while (xval < pixelmap -> gx_pixelmap_width)
407         {
408             count = *get++;
409 
410             if (count & 0x8000)
411             {
412                 count = (USHORT)((count & 0x7fff) + 1);
413                 get++;      /* skip repeated pixel value */
414             }
415             else
416             {
417                 count++;
418                 get += count;   /* skip raw pixel values */
419             }
420             xval += count;
421         }
422     }
423 
424     /* now we are on the first visible row, copy pixels until we get
425     to the enf of the last visible row
426     */
427     putrow = (USHORT *)context -> gx_draw_context_memory;
428     putrow += clip -> gx_rectangle_top * context -> gx_draw_context_pitch;
429     putrow += clip -> gx_rectangle_left;
430 
431     while (yval <= clip -> gx_rectangle_bottom)
432     {
433         xval = xpos;
434         put = putrow;
435 
436         while (xval < xpos + pixelmap -> gx_pixelmap_width)
437         {
438             count = *get++;
439 
440             if (count & 0x8000)
441             {
442                 /* repeated value */
443                 count = (USHORT)((count & 0x7fff) + 1);
444                 /*Or with 0xf000 to make sure it has no alpha.*/
445                 pixel = (*get++) | 0xf000 ;
446                 while (count--)
447                 {
448                     if (xval >= clip -> gx_rectangle_left &&
449                         xval <= clip -> gx_rectangle_right)
450                     {
451                         *put++ = pixel;
452                     }
453                     xval++;
454                 }
455             }
456             else
457             {
458                 /* string of non-repeated values */
459                 count++;
460                 while (count--)
461                 {
462                     if (xval >= clip -> gx_rectangle_left &&
463                         xval <= clip -> gx_rectangle_right)
464                     {
465                         /*Or with 0xf000 to make sure it has no alpha.*/
466                         pixel = (*get) | 0xf000;
467                         *put++ = pixel;
468                     }
469                     get++;
470                     xval++;
471                 }
472             }
473         }
474         putrow += context -> gx_draw_context_pitch;
475         yval++;
476     }
477 }
478 /**************************************************************************/
479 /*                                                                        */
480 /*  FUNCTION                                               RELEASE        */
481 /*                                                                        */
482 /*    _gx_display_driver_4444argb_pixelmap_draw           PORTABLE C      */
483 /*                                                           6.1          */
484 /*  AUTHOR                                                                */
485 /*                                                                        */
486 /*    Kenneth Maxwell, Microsoft Corporation                              */
487 /*                                                                        */
488 /*  DESCRIPTION                                                           */
489 /*                                                                        */
490 /*    565rgb screen driver pixelmap drawing function that handles         */
491 /*    compressed or uncompress, with or without alpha channel.            */
492 /*                                                                        */
493 /*  INPUT                                                                 */
494 /*                                                                        */
495 /*    context                               Drawing context               */
496 /*    xpos                                  x-coord of top-left draw point*/
497 /*    ypos                                  y-coord of top-left draw point*/
498 /*    pixelmap                              Pointer to GX_PIXELMAP struct */
499 /*                                                                        */
500 /*  OUTPUT                                                                */
501 /*                                                                        */
502 /*    None                                                                */
503 /*                                                                        */
504 /*  CALLS                                                                 */
505 /*                                                                        */
506 /*    _gx_display_driver_4444argb_pixelmap_compressed_alpha_write         */
507 /*                                          Real display driver pixelmap  */
508 /*                                            draw function               */
509 /*    _gx_display_driver_4444argb_pixelmap_compressed_write               */
510 /*                                          Real display driver pixelmap  */
511 /*                                            draw function               */
512 /*    _gx_display_driver_4444argb_pixelmap_alpha_write                    */
513 /*                                          Real display driver pixelmap  */
514 /*                                            draw function               */
515 /*    _gx_display_driver_4444argb_pixelmap_raw_write                      */
516 /*                                          Real display driver pixelmap  */
517 /*                                            draw function               */
518 /*    _gx_display_driver_4444argb_pixelmap_blend                          */
519 /*                                          Basic display driver pixelmap */
520 /*                                            blend function              */
521 /*                                                                        */
522 /*  CALLED BY                                                             */
523 /*                                                                        */
524 /*    GUIX Internal Code                                                  */
525 /*                                                                        */
526 /*  RELEASE HISTORY                                                       */
527 /*                                                                        */
528 /*    DATE              NAME                      DESCRIPTION             */
529 /*                                                                        */
530 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
531 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
532 /*                                            resulting in version 6.1    */
533 /*                                                                        */
534 /**************************************************************************/
_gx_display_driver_4444argb_pixelmap_draw(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap)535 VOID _gx_display_driver_4444argb_pixelmap_draw(GX_DRAW_CONTEXT *context,
536                                                INT xpos, INT ypos, GX_PIXELMAP *pixelmap)
537 {
538 GX_BOOL   drawn = GX_FALSE;
539 GX_UBYTE  brush_alpha = context -> gx_draw_context_brush.gx_brush_alpha;
540 
541     if (brush_alpha == 0)
542     {
543         /* Draw nothing here. Just return. */
544         return;
545     }
546 
547     switch (pixelmap -> gx_pixelmap_format)
548     {
549     case GX_COLOR_FORMAT_4444ARGB:
550         if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_COMPRESSED)
551         {
552             if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
553             {
554                 _gx_display_driver_4444argb_pixelmap_compressed_alpha_write(context, xpos, ypos, pixelmap);
555                 drawn = GX_TRUE;
556             }
557             else
558             {
559                 if (brush_alpha == 0xff)
560                 {
561                     _gx_display_driver_4444argb_pixelmap_compressed_write(context, xpos, ypos, pixelmap);
562                     drawn = GX_TRUE;
563                 }
564             }
565         }
566         else
567         {
568             if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
569             {
570                 _gx_display_driver_4444argb_pixelmap_alpha_write(context, xpos, ypos, pixelmap);
571                 drawn = GX_TRUE;
572             }
573             else
574             {
575                 if (brush_alpha == 0xff)
576                 {
577                     _gx_display_driver_4444argb_pixelmap_raw_write(context, xpos, ypos, pixelmap);
578                     drawn = GX_TRUE;
579                 }
580             }
581         }
582         break;
583 
584     default:
585         drawn = GX_TRUE;
586         break;
587     }
588 
589     if (!drawn)
590     {
591         _gx_display_driver_4444argb_pixelmap_blend(context, xpos, ypos, pixelmap, brush_alpha);
592     }
593 
594     return;
595 }
596 
597