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