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