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