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