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