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