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 /** Dispaly Management (Dispaly) */
18 /** */
19 /**************************************************************************/
20
21 #define GX_SOURCE_CODE
22
23
24 /* Include necessary system files. */
25
26 #include "gx_api.h"
27 #include "gx_system.h"
28 #include "gx_display.h"
29
30 #if defined GX_BRUSH_ALPHA_SUPPORT
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _gx_display_driver_generic_alphamap_raw_alpha_draw PORTABLE C */
37 /* 6.1 */
38 /* AUTHOR */
39 /* */
40 /* Kenneth Maxwell, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* Internal helper function that handles writing with brush alpha */
45 /* of uncompressed alpha map file. */
46 /* */
47 /* INPUT */
48 /* */
49 /* context Drawing context */
50 /* xpos x-coord of top-left draw point*/
51 /* ypos y-coord of top-left draw point*/
52 /* pixelmap Pointer to GX_PIXELMAP struct */
53 /* alpha alpha value from 0 to 255 */
54 /* */
55 /* OUTPUT */
56 /* */
57 /* None */
58 /* */
59 /* CALLS */
60 /* */
61 /* [gx_display_driver_pixel_blend] Basic display driver pixel */
62 /* blend function */
63 /* */
64 /* CALLED BY */
65 /* */
66 /* _gx_display_driver_generic_alphamap_draw */
67 /* */
68 /* RELEASE HISTORY */
69 /* */
70 /* DATE NAME DESCRIPTION */
71 /* */
72 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
73 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
74 /* resulting in version 6.1 */
75 /* */
76 /**************************************************************************/
_gx_display_driver_generic_alphamap_raw_alpha_draw(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pmp,GX_UBYTE alpha)77 static VOID _gx_display_driver_generic_alphamap_raw_alpha_draw(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pmp, GX_UBYTE alpha)
78 {
79 INT xval;
80 INT yval;
81 GX_UBYTE *getrowalpha;
82 GX_CONST GX_UBYTE *getalpha;
83 GX_UBYTE combined_alpha;
84 GX_COLOR fill_color;
85 GX_RECTANGLE *clip;
86 VOID (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR fcolor, GX_UBYTE alpha);
87
88 /* Pick up clip rectangle. */
89 clip = context -> gx_draw_context_clip;
90
91 blend_func = context -> gx_draw_context_display -> gx_display_driver_pixel_blend;
92
93 if (blend_func == GX_NULL)
94 {
95 return;
96 }
97
98 /* Pick up context fill color. */
99 fill_color = context -> gx_draw_context_brush.gx_brush_fill_color;
100
101 getrowalpha = (UCHAR *)(pmp -> gx_pixelmap_data);
102 getrowalpha += (pmp -> gx_pixelmap_width) * (clip -> gx_rectangle_top - ypos);
103 getrowalpha += (clip -> gx_rectangle_left - xpos);
104
105 for (yval = clip -> gx_rectangle_top; yval <= clip -> gx_rectangle_bottom; yval++)
106 {
107 getalpha = getrowalpha;
108
109 for (xval = clip -> gx_rectangle_left; xval <= clip -> gx_rectangle_right; xval++)
110 {
111 combined_alpha = (GX_UBYTE)((*getalpha++) * alpha / 255);
112 blend_func(context, xval, yval, fill_color, combined_alpha);
113 }
114
115 getrowalpha += pmp -> gx_pixelmap_width;
116 }
117 }
118
119 /**************************************************************************/
120 /* */
121 /* FUNCTION RELEASE */
122 /* */
123 /* _gx_display_driver_generic_alphamap_c_alpha_draw PORTABLE C */
124 /* 6.1 */
125 /* AUTHOR */
126 /* */
127 /* Kenneth Maxwell, Microsoft Corporation */
128 /* */
129 /* DESCRIPTION */
130 /* */
131 /* Internal helper function that handles writing with brush alpha */
132 /* of compressed alpha map file. */
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 /* alpha alpha value from 0 to 255 */
141 /* */
142 /* OUTPUT */
143 /* */
144 /* None */
145 /* */
146 /* CALLS */
147 /* */
148 /* [gx_display_driver_pixel_blend] Basic display driver pixel */
149 /* blend function */
150 /* */
151 /* CALLED BY */
152 /* */
153 /* _gx_display_driver_generic_alphamap_draw */
154 /* */
155 /* RELEASE HISTORY */
156 /* */
157 /* DATE NAME DESCRIPTION */
158 /* */
159 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
160 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
161 /* resulting in version 6.1 */
162 /* */
163 /**************************************************************************/
_gx_display_driver_generic_alphamap_compressed_alpha_draw(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pmp,GX_UBYTE alpha)164 static VOID _gx_display_driver_generic_alphamap_compressed_alpha_draw(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pmp, GX_UBYTE alpha)
165 {
166 INT yval;
167 INT xval;
168 GX_CONST GX_UBYTE *get;
169 GX_UBYTE count;
170 GX_UBYTE falpha;
171 GX_COLOR fill_color;
172 GX_RECTANGLE *clip;
173 GX_UBYTE combined_alpha;
174 VOID (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR fcolor, GX_UBYTE alpha);
175
176 /* Pick up clip rectangle. */
177 clip = context -> gx_draw_context_clip;
178
179 blend_func = context -> gx_draw_context_display -> gx_display_driver_pixel_blend;
180
181 if (blend_func == GX_NULL)
182 {
183 return;
184 }
185
186 /* Pick up context fill color. */
187 fill_color = context -> gx_draw_context_brush.gx_brush_fill_color;
188
189 get = (GX_CONST GX_UBYTE *)pmp -> gx_pixelmap_data;
190
191 /* compressed with no alpha is a two-byte count and two-byte pixel value */
192
193 /* first, skip to the starting row */
194 for (yval = ypos; yval < clip -> gx_rectangle_top; yval++)
195 {
196 xval = 0;
197 while (xval < pmp -> gx_pixelmap_width)
198 {
199 count = *get++;
200
201 if (count & 0x80)
202 {
203 count = (GX_UBYTE)((count & 0x7f) + 1);
204 get++; /* skip repeated pixel value */
205 }
206 else
207 {
208 count++;
209 get += count; /* skip raw pixel values */
210 }
211 xval += count;
212 }
213 }
214
215 /* now we are on the first visible row, copy pixels until we get
216 to the enf of the last visible row
217 */
218
219 while (yval <= clip -> gx_rectangle_bottom)
220 {
221 xval = xpos;
222
223 while (xval < xpos + pmp -> gx_pixelmap_width)
224 {
225 count = *get++;
226
227 if (count & 0x80)
228 {
229 /* repeated value */
230 count = (GX_UBYTE)((count & 0x7f) + 1);
231 falpha = *get++;
232
233 while (count--)
234 {
235 if (xval >= clip -> gx_rectangle_left &&
236 xval <= clip -> gx_rectangle_right)
237 {
238 combined_alpha = (GX_UBYTE)(falpha * alpha / 255);
239 blend_func(context, xval, yval, fill_color, combined_alpha);
240 }
241 xval++;
242 }
243 }
244 else
245 {
246 /* string of non-repeated values */
247 count++;
248 while (count--)
249 {
250 if (xval >= clip -> gx_rectangle_left &&
251 xval <= clip -> gx_rectangle_right)
252 {
253 combined_alpha = (GX_UBYTE)((*get) * alpha / 255);
254 blend_func(context, xval, yval, fill_color, combined_alpha);
255 }
256 get++;
257 xval++;
258 }
259 }
260 }
261 yval++;
262 }
263 }
264 #endif /* GX_BRUSH_ALPHA_SUPPORT*/
265
266 /**************************************************************************/
267 /* */
268 /* FUNCTION RELEASE */
269 /* */
270 /* _gx_display_driver_generic_alphamap_raw_draw PORTABLE C */
271 /* 6.1 */
272 /* AUTHOR */
273 /* */
274 /* Kenneth Maxwell, Microsoft Corporation */
275 /* */
276 /* DESCRIPTION */
277 /* */
278 /* Internal helper function that handles writing of uncompressed */
279 /* alpha map file. */
280 /* */
281 /* INPUT */
282 /* */
283 /* context Drawing context */
284 /* xpos x-coord of top-left draw point*/
285 /* ypos y-coord of top-left draw point*/
286 /* pixelmap Pointer to GX_PIXELMAP struct */
287 /* */
288 /* OUTPUT */
289 /* */
290 /* None */
291 /* */
292 /* CALLS */
293 /* */
294 /* [gx_display_driver_pixel_blend] Basic display driver pixel */
295 /* blend function */
296 /* */
297 /* CALLED BY */
298 /* */
299 /* _gx_display_driver_generic_alphamap_draw */
300 /* */
301 /* RELEASE HISTORY */
302 /* */
303 /* DATE NAME DESCRIPTION */
304 /* */
305 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
306 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
307 /* resulting in version 6.1 */
308 /* */
309 /**************************************************************************/
_gx_display_driver_generic_alphamap_raw_draw(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pmp)310 static VOID _gx_display_driver_generic_alphamap_raw_draw(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pmp)
311 {
312 INT xval;
313 INT yval;
314 GX_UBYTE *getrowalpha;
315 GX_CONST GX_UBYTE *getalpha;
316 GX_COLOR fill_color;
317 GX_RECTANGLE *clip;
318 VOID (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR fcolor, GX_UBYTE alpha);
319
320 /* Pick up clip rectangle. */
321 clip = context -> gx_draw_context_clip;
322
323 blend_func = context -> gx_draw_context_display -> gx_display_driver_pixel_blend;
324
325 if (blend_func == GX_NULL)
326 {
327 return;
328 }
329
330 /* Pick up context fill color. */
331 fill_color = context -> gx_draw_context_brush.gx_brush_fill_color;
332
333 getrowalpha = (UCHAR *)(pmp -> gx_pixelmap_data);
334 getrowalpha += (pmp -> gx_pixelmap_width) * (clip -> gx_rectangle_top - ypos);
335 getrowalpha += (clip -> gx_rectangle_left - xpos);
336
337 for (yval = clip -> gx_rectangle_top; yval <= clip -> gx_rectangle_bottom; yval++)
338 {
339 getalpha = getrowalpha;
340
341 for (xval = clip -> gx_rectangle_left; xval <= clip -> gx_rectangle_right; xval++)
342 {
343 blend_func(context, xval, yval, fill_color, *getalpha++);
344 }
345
346 getrowalpha += pmp -> gx_pixelmap_width;
347 }
348 }
349
350 /**************************************************************************/
351 /* */
352 /* FUNCTION RELEASE */
353 /* */
354 /* _gx_display_driver_generic_alphamap_compressed_draw PORTABLE C */
355 /* 6.1 */
356 /* AUTHOR */
357 /* */
358 /* Kenneth Maxwell, Microsoft Corporation */
359 /* */
360 /* DESCRIPTION */
361 /* */
362 /* Internal helper function that handles writing of compressed */
363 /* alpha map file. */
364 /* */
365 /* INPUT */
366 /* */
367 /* context Drawing context */
368 /* xpos x-coord of top-left draw point*/
369 /* ypos y-coord of top-left draw point*/
370 /* pixelmap Pointer to GX_PIXELMAP struct */
371 /* */
372 /* OUTPUT */
373 /* */
374 /* None */
375 /* */
376 /* CALLS */
377 /* */
378 /* [gx_display_driver_pixel_blend] Basic display driver pixel */
379 /* blend function */
380 /* */
381 /* CALLED BY */
382 /* */
383 /* _gx_display_driver_generic_alphamap_draw */
384 /* */
385 /* RELEASE HISTORY */
386 /* */
387 /* DATE NAME DESCRIPTION */
388 /* */
389 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
390 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
391 /* resulting in version 6.1 */
392 /* */
393 /**************************************************************************/
_gx_display_driver_generic_alphamap_compressed_draw(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pmp)394 static VOID _gx_display_driver_generic_alphamap_compressed_draw(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pmp)
395 {
396 INT yval;
397 INT xval;
398 GX_CONST GX_UBYTE *get;
399 GX_UBYTE count;
400 GX_UBYTE pixel;
401 GX_COLOR fill_color;
402 GX_RECTANGLE *clip;
403 VOID (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR fcolor, GX_UBYTE alpha);
404
405 /* Pick up clip rectangle. */
406 clip = context -> gx_draw_context_clip;
407
408 blend_func = context -> gx_draw_context_display -> gx_display_driver_pixel_blend;
409
410 if (blend_func == GX_NULL)
411 {
412 return;
413 }
414
415 /* Pick up context fill color. */
416 fill_color = context -> gx_draw_context_brush.gx_brush_fill_color;
417
418 get = (GX_CONST GX_UBYTE *)pmp -> gx_pixelmap_data;
419
420 /* compressed with no alpha is a two-byte count and two-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 < pmp -> gx_pixelmap_width)
427 {
428 count = *get++;
429
430 if (count & 0x80)
431 {
432 count = (GX_UBYTE)((count & 0x7f) + 1);
433 get++; /* skip repeated pixel value */
434 }
435 else
436 {
437 count++;
438 get += count; /* skip raw pixel values */
439 }
440 xval += count;
441 }
442 }
443
444 /* now we are on the first visible row, copy pixels until we get
445 to the enf of the last visible row
446 */
447
448 while (yval <= clip -> gx_rectangle_bottom)
449 {
450 xval = xpos;
451
452 while (xval < xpos + pmp -> gx_pixelmap_width)
453 {
454 count = *get++;
455
456 if (count & 0x80)
457 {
458 /* repeated value */
459 count = (GX_UBYTE)((count & 0x7f) + 1);
460 pixel = *get++;
461
462 while (count--)
463 {
464 if (xval >= clip -> gx_rectangle_left &&
465 xval <= clip -> gx_rectangle_right)
466 {
467 blend_func(context, xval, yval, fill_color, pixel);
468 }
469 xval++;
470 }
471 }
472 else
473 {
474 /* string of non-repeated values */
475 count++;
476 while (count--)
477 {
478 if (xval >= clip -> gx_rectangle_left &&
479 xval <= clip -> gx_rectangle_right)
480 {
481 blend_func(context, xval, yval, fill_color, *get);
482 }
483 get++;
484 xval++;
485 }
486 }
487 }
488 yval++;
489 }
490 }
491
492 /**************************************************************************/
493 /* */
494 /* FUNCTION RELEASE */
495 /* */
496 /* _gx_display_driver_generic_alphamap_draw PORTABLE C */
497 /* 6.1 */
498 /* AUTHOR */
499 /* */
500 /* Kenneth Maxwell, Microsoft Corporation */
501 /* */
502 /* DESCRIPTION */
503 /* */
504 /* This function blends the context fill color with the canvas */
505 /* background. */
506 /* */
507 /* INPUT */
508 /* */
509 /* context Drawing context */
510 /* xpos x-coord of top-left draw point*/
511 /* ypos y-coord of top-left draw point*/
512 /* pmp Pointer to GX_PIXELMAP struct */
513 /* */
514 /* OUTPUT */
515 /* */
516 /* status Completion status */
517 /* */
518 /* CALLS */
519 /* */
520 /* _gx_display_driver_generic_alphamap_compressed_alpha_draw */
521 /* Real display driver alphamap */
522 /* draw function */
523 /* _gx_display_driver_generic_alphamap_raw_alpha_draw */
524 /* Real display driver alphamap */
525 /* draw function */
526 /* _gx_display_driver_generic_alphamap_compressed_draw */
527 /* Real display driver alphamap */
528 /* draw function */
529 /* _gx_display_driver_generic_alphamap_raw_draw */
530 /* Real display driver alphamap */
531 /* draw function */
532 /* */
533 /* CALLED BY */
534 /* */
535 /* Application Code */
536 /* GUIX default draw funtions */
537 /* */
538 /* RELEASE HISTORY */
539 /* */
540 /* DATE NAME DESCRIPTION */
541 /* */
542 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
543 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
544 /* resulting in version 6.1 */
545 /* */
546 /**************************************************************************/
_gx_display_driver_generic_alphamap_draw(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pmp)547 VOID _gx_display_driver_generic_alphamap_draw(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pmp)
548 {
549 #if defined GX_BRUSH_ALPHA_SUPPORT
550 GX_UBYTE alpha;
551
552 alpha = context -> gx_draw_context_brush.gx_brush_alpha;
553 if (alpha == 0)
554 {
555 /* Nothing to drawn. Just return. */
556 return;
557 }
558
559 if (alpha != 0xff)
560 {
561 if (pmp -> gx_pixelmap_flags & GX_PIXELMAP_COMPRESSED)
562 {
563 _gx_display_driver_generic_alphamap_compressed_alpha_draw(context, xpos, ypos, pmp, alpha);
564 }
565 else
566 {
567 _gx_display_driver_generic_alphamap_raw_alpha_draw(context, xpos, ypos, pmp, alpha);
568 }
569 return;
570 }
571 #endif
572
573 if (pmp -> gx_pixelmap_flags & GX_PIXELMAP_COMPRESSED)
574 {
575 _gx_display_driver_generic_alphamap_compressed_draw(context, xpos, ypos, pmp);
576 }
577 else
578 {
579 _gx_display_driver_generic_alphamap_raw_draw(context, xpos, ypos, pmp);
580 }
581 }
582
583