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