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