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_565rgb_rotated_pixelmap_raw_write PORTABLE C */
35 /* 6.1.3 */
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 /* CALLS */
57 /* */
58 /* None */
59 /* */
60 /* CALLED BY */
61 /* */
62 /* GUIX Internal Code */
63 /* */
64 /* RELEASE HISTORY */
65 /* */
66 /* DATE NAME DESCRIPTION */
67 /* */
68 /* 12-31-2020 Kenneth Maxwell Initial Version 6.1.3 */
69 /* */
70 /**************************************************************************/
_gx_display_driver_565rgb_rotated_pixelmap_raw_write(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap)71 static VOID _gx_display_driver_565rgb_rotated_pixelmap_raw_write(GX_DRAW_CONTEXT *context,
72 INT xpos, INT ypos, GX_PIXELMAP *pixelmap)
73 {
74 INT yval;
75 INT width;
76 USHORT *putrow;
77 USHORT *getrow;
78 GX_RECTANGLE *clip = context -> gx_draw_context_clip;
79 GX_RECTANGLE rotated_clip;
80
81 GX_SWAP_VALS(xpos, ypos);
82
83 if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
84 {
85 rotated_clip.gx_rectangle_left = clip -> gx_rectangle_top;
86 rotated_clip.gx_rectangle_right = clip -> gx_rectangle_bottom;
87 rotated_clip.gx_rectangle_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_right - 1);
88 rotated_clip.gx_rectangle_bottom = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_left - 1);
89 ypos = (context -> gx_draw_context_canvas -> gx_canvas_x_resolution - ypos - pixelmap -> gx_pixelmap_width);
90 }
91 else
92 {
93 rotated_clip.gx_rectangle_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_bottom - 1);
94 rotated_clip.gx_rectangle_right = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_top - 1);
95 rotated_clip.gx_rectangle_top = clip -> gx_rectangle_left;
96 rotated_clip.gx_rectangle_bottom = clip -> gx_rectangle_right;
97 xpos = (context -> gx_draw_context_canvas -> gx_canvas_y_resolution - xpos - pixelmap -> gx_pixelmap_height);
98 }
99
100 putrow = (USHORT *)context -> gx_draw_context_memory;
101 putrow += rotated_clip.gx_rectangle_top * context -> gx_draw_context_pitch;
102 putrow += rotated_clip.gx_rectangle_left;
103
104 getrow = (USHORT *)(pixelmap -> gx_pixelmap_data);
105 getrow += pixelmap -> gx_pixelmap_height * (rotated_clip.gx_rectangle_top - ypos);
106 getrow += (rotated_clip.gx_rectangle_left - xpos);
107
108 width = rotated_clip.gx_rectangle_right - rotated_clip.gx_rectangle_left + 1;
109
110 for (yval = clip -> gx_rectangle_left; yval <= clip -> gx_rectangle_right; yval++)
111 {
112 memcpy(putrow, getrow, (size_t)(width * 2)); /* Use case of memcpy is verified. */
113 putrow += context -> gx_draw_context_pitch;
114 getrow += pixelmap -> gx_pixelmap_height;
115 }
116 }
117
118 /**************************************************************************/
119 /* */
120 /* FUNCTION RELEASE */
121 /* */
122 /* _gx_display_driver_565rgb_rotated_pixelmap_alpha_write PORTABLE C */
123 /* 6.1.3 */
124 /* AUTHOR */
125 /* */
126 /* Kenneth Maxwell, Microsoft Corporation */
127 /* */
128 /* DESCRIPTION */
129 /* */
130 /* Internal helper function that handles writing of uncompressed */
131 /* pixlemap file with alpha channel. */
132 /* */
133 /* INPUT */
134 /* */
135 /* context Drawing context */
136 /* xpos x-coord of top-left draw point*/
137 /* ypos y-coord of top-left draw point*/
138 /* pixelmap Pointer to GX_PIXELMAP struct */
139 /* */
140 /* OUTPUT */
141 /* */
142 /* None */
143 /* */
144 /* CALLS */
145 /* */
146 /* _gx_display_driver_565rgb_pixel_blend Display driver basic pixel */
147 /* blend function */
148 /* */
149 /* CALLED BY */
150 /* */
151 /* GUIX Internal Code */
152 /* */
153 /* RELEASE HISTORY */
154 /* */
155 /* DATE NAME DESCRIPTION */
156 /* */
157 /* 12-31-2020 Kenneth Maxwell Initial Version 6.1.3 */
158 /* */
159 /**************************************************************************/
_gx_display_driver_565rgb_rotated_pixelmap_alpha_write(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap)160 static VOID _gx_display_driver_565rgb_rotated_pixelmap_alpha_write(GX_DRAW_CONTEXT *context,
161 INT xpos, INT ypos, GX_PIXELMAP *pixelmap)
162 {
163 INT skipcount;
164 INT xval;
165 INT yval;
166 USHORT *getrow;
167 GX_UBYTE *getrowalpha;
168 GX_CONST USHORT *get;
169 GX_CONST GX_UBYTE *getalpha;
170
171 GX_RECTANGLE *clip = context -> gx_draw_context_clip;
172 GX_RECTANGLE rotated_clip;
173 void (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR fcolor, GX_UBYTE alpha);
174
175 blend_func = _gx_display_driver_565rgb_pixel_blend;
176
177 GX_SWAP_VALS(xpos, ypos);
178
179 if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
180 {
181 rotated_clip.gx_rectangle_left = clip -> gx_rectangle_top;
182 rotated_clip.gx_rectangle_right = clip -> gx_rectangle_bottom;
183 rotated_clip.gx_rectangle_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_right - 1);
184 rotated_clip.gx_rectangle_bottom = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_left - 1);
185 ypos = (context -> gx_draw_context_canvas -> gx_canvas_x_resolution - ypos - pixelmap -> gx_pixelmap_width);
186 }
187 else
188 {
189 rotated_clip.gx_rectangle_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_bottom - 1);
190 rotated_clip.gx_rectangle_right = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_top - 1);
191 rotated_clip.gx_rectangle_top = clip -> gx_rectangle_left;
192 rotated_clip.gx_rectangle_bottom = clip -> gx_rectangle_right;
193 xpos = (context -> gx_draw_context_canvas -> gx_canvas_y_resolution - xpos - pixelmap -> gx_pixelmap_height);
194 }
195
196 /* Calculate how many pixels to skip. */
197 skipcount = pixelmap -> gx_pixelmap_height * (rotated_clip.gx_rectangle_top - ypos);
198 skipcount += (rotated_clip.gx_rectangle_left - xpos);
199 getrow = (USHORT *)(pixelmap -> gx_pixelmap_data);
200 getrow += skipcount;
201
202 getrowalpha = (GX_UBYTE *)(pixelmap -> gx_pixelmap_aux_data);
203 getrowalpha += skipcount;
204
205 for (yval = rotated_clip.gx_rectangle_top; yval <= rotated_clip.gx_rectangle_bottom; yval++)
206 {
207 get = getrow;
208 getalpha = getrowalpha;
209
210 for (xval = rotated_clip.gx_rectangle_left; xval <= rotated_clip.gx_rectangle_right; xval++)
211 {
212 blend_func(context, xval, yval, *get++, *getalpha++);
213 }
214 getrow += pixelmap -> gx_pixelmap_height;
215 getrowalpha += pixelmap -> gx_pixelmap_height;
216 }
217 }
218
219 /**************************************************************************/
220 /* */
221 /* FUNCTION RELEASE */
222 /* */
223 /* _gx_display_driver_565rgb_rotated_pixelmap_compressed_write */
224 /* PORTABLE C */
225 /* 6.1.3 */
226 /* AUTHOR */
227 /* */
228 /* Kenneth Maxwell, Microsoft Corporation */
229 /* */
230 /* DESCRIPTION */
231 /* */
232 /* Internal helper function that handles writing of compressed */
233 /* pixlemap file without alpha channel. */
234 /* */
235 /* INPUT */
236 /* */
237 /* context Drawing context */
238 /* xpos x-coord of top-left draw point*/
239 /* ypos y-coord of top-left draw point*/
240 /* pixelmap Pointer to GX_PIXELMAP struct */
241 /* */
242 /* OUTPUT */
243 /* */
244 /* None */
245 /* */
246 /* CALLS */
247 /* */
248 /* None */
249 /* */
250 /* CALLED BY */
251 /* */
252 /* GUIX Internal Code */
253 /* */
254 /* RELEASE HISTORY */
255 /* */
256 /* DATE NAME DESCRIPTION */
257 /* */
258 /* 12-31-2020 Kenneth Maxwell Initial Version 6.1.3 */
259 /**************************************************************************/
_gx_display_driver_565rgb_rotated_pixelmap_compressed_write(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap)260 static VOID _gx_display_driver_565rgb_rotated_pixelmap_compressed_write(GX_DRAW_CONTEXT *context,
261 INT xpos, INT ypos, GX_PIXELMAP *pixelmap)
262 {
263 INT yval;
264 INT xval;
265 GX_CONST USHORT *get;
266 USHORT *put;
267 USHORT *putrow;
268 USHORT count;
269 USHORT pixel;
270
271 GX_RECTANGLE *clip = context -> gx_draw_context_clip;
272 GX_RECTANGLE rotated_clip;
273
274 /* Compressed with no alpha is a two-byte count and two-byte pixel value. */
275
276 get = (GX_CONST USHORT *)pixelmap -> gx_pixelmap_data;
277
278 GX_SWAP_VALS(xpos, ypos);
279
280 if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
281 {
282 rotated_clip.gx_rectangle_left = clip -> gx_rectangle_top;
283 rotated_clip.gx_rectangle_right = clip -> gx_rectangle_bottom;
284 rotated_clip.gx_rectangle_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_right - 1);
285 rotated_clip.gx_rectangle_bottom = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_left - 1);
286 ypos = (context -> gx_draw_context_canvas -> gx_canvas_x_resolution - ypos - pixelmap -> gx_pixelmap_width);
287 }
288 else
289 {
290 rotated_clip.gx_rectangle_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_bottom - 1);
291 rotated_clip.gx_rectangle_right = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_top - 1);
292 rotated_clip.gx_rectangle_top = clip -> gx_rectangle_left;
293 rotated_clip.gx_rectangle_bottom = clip -> gx_rectangle_right;
294 xpos = (context -> gx_draw_context_canvas -> gx_canvas_y_resolution - xpos - pixelmap -> gx_pixelmap_height);
295 }
296
297 /* First, skip to the starting row. */
298 for (yval = ypos; yval < rotated_clip.gx_rectangle_top; yval++)
299 {
300 xval = 0;
301 while (xval < pixelmap -> gx_pixelmap_height)
302 {
303 count = *get++;
304
305 if (count & 0x8000)
306 {
307 count = (USHORT)((count & 0x7fff) + 1u);
308
309 /* Skip repeated pixel value. */
310 get++;
311 }
312 else
313 {
314 count++;
315
316 /* Skip raw pixel values. */
317 get += count;
318 }
319 xval += count;
320 }
321 }
322
323 /* Now we are on the first visible row, copy pixels until we get
324 to the enf of the last visible row. */
325 putrow = (USHORT *)context -> gx_draw_context_memory;
326 putrow += rotated_clip.gx_rectangle_top * context -> gx_draw_context_pitch;
327 putrow += xpos;
328
329 while (yval <= rotated_clip.gx_rectangle_bottom)
330 {
331 put = putrow;
332 xval = xpos;
333
334 while (xval < xpos + pixelmap -> gx_pixelmap_height)
335 {
336 count = *get++;
337
338 if (count & 0x8000)
339 {
340 /* Repeated value. */
341 count = (USHORT)((count & 0x7fff) + 1u);
342 pixel = *get++;
343 while (count--)
344 {
345 if (xval >= rotated_clip.gx_rectangle_left &&
346 xval <= rotated_clip.gx_rectangle_right)
347 {
348 *put = pixel;
349 }
350 put++;
351 xval++;
352 }
353 }
354 else
355 {
356 /* String of non-repeated values. */
357 count++;
358
359 while (count--)
360 {
361 if (xval >= rotated_clip.gx_rectangle_left &&
362 xval <= rotated_clip.gx_rectangle_right)
363 {
364 *put = *get;
365 }
366 put++;
367 get++;
368 xval++;
369 }
370 }
371 }
372 putrow += context -> gx_draw_context_pitch;
373 yval++;
374 }
375 }
376
377 /**************************************************************************/
378 /* */
379 /* FUNCTION RELEASE */
380 /* */
381 /* _gx_display_driver_565rgb_rotated_pixelmap_compressed_alpha_write */
382 /* PORTABLE C */
383 /* 6.1.3 */
384 /* AUTHOR */
385 /* */
386 /* Kenneth Maxwell, Microsoft Corporation */
387 /* */
388 /* DESCRIPTION */
389 /* */
390 /* Internal helper function that handles writing of compressed */
391 /* pixlemap file with alpha channel. */
392 /* */
393 /* INPUT */
394 /* */
395 /* context Drawing context */
396 /* xpos x-coord of top-left draw point*/
397 /* ypos y-coord of top-left draw point*/
398 /* pixelmap Pointer to GX_PIXELMAP struct */
399 /* */
400 /* OUTPUT */
401 /* */
402 /* None */
403 /* */
404 /* CALLS */
405 /* */
406 /* _gx_display_driver_565rgb_pixel_blend Display driver basic pixel */
407 /* blend function */
408 /* */
409 /* CALLED BY */
410 /* */
411 /* GUIX Internal Code */
412 /* */
413 /* RELEASE HISTORY */
414 /* */
415 /* DATE NAME DESCRIPTION */
416 /* */
417 /* 12-31-2020 Kenneth Maxwell Initial Version 6.1.3 */
418 /* */
419 /**************************************************************************/
_gx_display_driver_565rgb_rotated_pixelmap_compressed_alpha_write(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap)420 static VOID _gx_display_driver_565rgb_rotated_pixelmap_compressed_alpha_write(GX_DRAW_CONTEXT *context,
421 INT xpos, INT ypos, GX_PIXELMAP *pixelmap)
422 {
423 INT yval;
424 INT xval;
425 GX_CONST GX_UBYTE *get;
426 GX_CONST USHORT *getpixel;
427 USHORT count;
428 USHORT pixel;
429 GX_UBYTE falpha;
430 GX_UBYTE brush_alpha;
431 GX_UBYTE combined_alpha;
432
433 GX_RECTANGLE *clip = context -> gx_draw_context_clip;
434 GX_RECTANGLE rotated_clip;
435 void (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR fcolor, GX_UBYTE alpha);
436
437 blend_func = _gx_display_driver_565rgb_pixel_blend;
438
439 get = pixelmap -> gx_pixelmap_data;
440 brush_alpha = context -> gx_draw_context_brush.gx_brush_alpha;
441
442 GX_SWAP_VALS(xpos, ypos);
443
444 if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
445 {
446 rotated_clip.gx_rectangle_left = clip -> gx_rectangle_top;
447 rotated_clip.gx_rectangle_right = clip -> gx_rectangle_bottom;
448 rotated_clip.gx_rectangle_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_right - 1);
449 rotated_clip.gx_rectangle_bottom = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_left - 1);
450 ypos = (context -> gx_draw_context_canvas -> gx_canvas_x_resolution - ypos - pixelmap -> gx_pixelmap_width);
451 }
452 else
453 {
454 rotated_clip.gx_rectangle_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_bottom - 1);
455 rotated_clip.gx_rectangle_right = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_top - 1);
456 rotated_clip.gx_rectangle_top = clip -> gx_rectangle_left;
457 rotated_clip.gx_rectangle_bottom = clip -> gx_rectangle_right;
458 xpos = (context -> gx_draw_context_canvas -> gx_canvas_y_resolution - xpos - pixelmap -> gx_pixelmap_height);
459 }
460
461 /* Compressed with alpha is byte count, byte alpha, and and two-byte pixel value. */
462
463 /* First, skip to the starting row. */
464 for (yval = ypos; yval < rotated_clip.gx_rectangle_top; yval++)
465 {
466 xval = 0;
467 while (xval < pixelmap -> gx_pixelmap_height)
468 {
469 count = *get;
470
471 if (count & 0x80)
472 {
473 count = (USHORT)((count & 0x7f) + 1u);
474 get += 4; /* Skip repeated pixel value. */
475 }
476 else
477 {
478 count++;
479 get += (count * 4); /* Skip string of non-repeated pixels. */
480 }
481 xval += count;
482 }
483 }
484
485 /* Now we are on the first visible row, copy pixels until we get
486 to the enf of the last visible row. */
487 while (yval <= rotated_clip.gx_rectangle_bottom)
488 {
489 xval = xpos;
490 while (xval < xpos + pixelmap -> gx_pixelmap_height)
491 {
492 count = *get;
493
494 if (count & 0x80)
495 {
496 /* Repeated value. */
497 count = (USHORT)((count & 0x7f) + 1u);
498 falpha = *(get + 1);
499
500 if (falpha)
501 {
502 get += 2;
503
504 getpixel = (USHORT *)get;
505 pixel = *getpixel;
506 get += 2;
507
508 if (brush_alpha == 0xff)
509 {
510 combined_alpha = falpha;
511 }
512 else
513 {
514 combined_alpha = (GX_UBYTE)(falpha * brush_alpha / 255);
515 }
516
517 while (count--)
518 {
519 if (xval >= rotated_clip.gx_rectangle_left &&
520 xval <= rotated_clip.gx_rectangle_right)
521 {
522 blend_func(context, xval, yval, pixel, combined_alpha);
523 }
524 xval++;
525 }
526 }
527 else
528 {
529 get += 4;
530 xval += count;
531 }
532 }
533 else
534 {
535 /* String of non-repeated values. */
536 count++;
537 if (brush_alpha == 0xff)
538 {
539 while (count--)
540 {
541 if (xval >= rotated_clip.gx_rectangle_left &&
542 xval <= rotated_clip.gx_rectangle_right)
543 {
544 falpha = *(get + 1);
545 get += 2;
546 getpixel = (USHORT *)get;
547 pixel = *getpixel;
548 get += 2;
549 blend_func(context, xval, yval, pixel, falpha);
550 }
551 else
552 {
553 get += 4;
554 }
555 xval++;
556 }
557 }
558 else
559 {
560 while (count--)
561 {
562 if (xval >= rotated_clip.gx_rectangle_left &&
563 xval <= rotated_clip.gx_rectangle_right)
564 {
565 falpha = *(get + 1);
566 get += 2;
567 getpixel = (USHORT *)get;
568 pixel = *getpixel;
569 get += 2;
570 combined_alpha = (GX_UBYTE)(falpha * brush_alpha / 255);
571 blend_func(context, xval, yval, pixel, combined_alpha);
572 }
573 else
574 {
575 get += 4;
576 }
577 xval++;
578 }
579 }
580 }
581 }
582 yval++;
583 }
584 }
585
586
587 /**************************************************************************/
588 /* */
589 /* FUNCTION RELEASE */
590 /* */
591 /* _gx_display_driver_565rgb_rotated_palette_pixelmap_raw_write */
592 /* PORTABLE C */
593 /* 6.1.3 */
594 /* AUTHOR */
595 /* */
596 /* Kenneth Maxwell, Microsoft Corporation */
597 /* */
598 /* DESCRIPTION */
599 /* */
600 /* Internal helper function that handles writing of raw pixlemap */
601 /* file without transparent for palette pixelmap */
602 /* */
603 /* INPUT */
604 /* */
605 /* context Drawing context */
606 /* xpos x-coord of top-left draw point*/
607 /* ypos y-coord of top-left draw point*/
608 /* pixelmap Pointer to GX_PIXELMAP struct */
609 /* */
610 /* OUTPUT */
611 /* */
612 /* None */
613 /* */
614 /* CALLS */
615 /* */
616 /* None */
617 /* */
618 /* CALLED BY */
619 /* */
620 /* GUIX Internal Code */
621 /* */
622 /* RELEASE HISTORY */
623 /* */
624 /* DATE NAME DESCRIPTION */
625 /* */
626 /* 12-31-2020 Kenneth Maxwell Initial Version 6.1.3 */
627 /* */
628 /**************************************************************************/
_gx_display_driver_565rgb_rotated_palette_pixelmap_raw_write(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap)629 static VOID _gx_display_driver_565rgb_rotated_palette_pixelmap_raw_write(GX_DRAW_CONTEXT *context,
630 INT xpos, INT ypos, GX_PIXELMAP *pixelmap)
631 {
632 INT xval;
633 INT yval;
634 USHORT *putrow;
635 GX_UBYTE *getrow;
636 USHORT *put;
637 GX_CONST GX_UBYTE *get;
638 GX_COLOR *palette;
639 GX_UBYTE r;
640 GX_UBYTE g;
641 GX_UBYTE b;
642
643 GX_RECTANGLE *clip = context -> gx_draw_context_clip;
644 GX_RECTANGLE rotated_clip;
645
646 GX_SWAP_VALS(xpos, ypos);
647
648 if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
649 {
650 rotated_clip.gx_rectangle_left = clip -> gx_rectangle_top;
651 rotated_clip.gx_rectangle_right = clip -> gx_rectangle_bottom;
652 rotated_clip.gx_rectangle_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_right - 1);
653 rotated_clip.gx_rectangle_bottom = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_left - 1);
654 ypos = (context -> gx_draw_context_canvas -> gx_canvas_x_resolution - ypos - pixelmap -> gx_pixelmap_width);
655 }
656 else
657 {
658 rotated_clip.gx_rectangle_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_bottom - 1);
659 rotated_clip.gx_rectangle_right = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_top - 1);
660 rotated_clip.gx_rectangle_top = clip -> gx_rectangle_left;
661 rotated_clip.gx_rectangle_bottom = clip -> gx_rectangle_right;
662 xpos = (context -> gx_draw_context_canvas -> gx_canvas_y_resolution - xpos - pixelmap -> gx_pixelmap_height);
663 }
664
665 putrow = (USHORT *)context -> gx_draw_context_memory;
666 putrow += rotated_clip.gx_rectangle_top * context -> gx_draw_context_pitch;
667 putrow += rotated_clip.gx_rectangle_left;
668
669 getrow = (GX_UBYTE *)(pixelmap -> gx_pixelmap_data);
670 getrow += pixelmap -> gx_pixelmap_height * (rotated_clip.gx_rectangle_top - ypos);
671 getrow += (rotated_clip.gx_rectangle_left - xpos);
672
673 palette = (GX_COLOR *)pixelmap -> gx_pixelmap_aux_data;
674
675 for (yval = rotated_clip.gx_rectangle_top; yval <= rotated_clip.gx_rectangle_bottom; yval++)
676 {
677 put = putrow;
678 get = getrow;
679
680 for (xval = rotated_clip.gx_rectangle_left; xval <= rotated_clip.gx_rectangle_right; xval++)
681 {
682 r = (GX_UBYTE)(REDVAL_32BPP(palette[*get]) >> 3);
683 g = (GX_UBYTE)(GREENVAL_32BPP(palette[*get]) >> 2);
684 b = (GX_UBYTE)(BLUEVAL_32BPP(palette[*get++]) >> 3);
685 *put++ = (USHORT)ASSEMBLECOLOR_16BPP(r, g, b);
686 }
687 putrow += context -> gx_draw_context_pitch;
688 getrow += pixelmap -> gx_pixelmap_height;
689 }
690 }
691
692 /**************************************************************************/
693 /* */
694 /* FUNCTION RELEASE */
695 /* */
696 /* _gx_display_driver_565rgb_rotated_palette_pixelmap_transparent_raw_ */
697 /* write */
698 /* PORTABLE C */
699 /* 6.1.3 */
700 /* AUTHOR */
701 /* */
702 /* Kenneth Maxwell, Microsoft Corporation */
703 /* */
704 /* DESCRIPTION */
705 /* */
706 /* Internal helper function that handles writing of raw pixlemap */
707 /* file with transparent for palette pixelmap. */
708 /* */
709 /* INPUT */
710 /* */
711 /* context Drawing context */
712 /* xpos x-coord of top-left draw point*/
713 /* ypos y-coord of top-left draw point*/
714 /* pixelmap Pointer to GX_PIXELMAP struct */
715 /* */
716 /* OUTPUT */
717 /* */
718 /* None */
719 /* */
720 /* CALLS */
721 /* */
722 /* None */
723 /* */
724 /* CALLED BY */
725 /* */
726 /* GUIX Internal Code */
727 /* */
728 /* RELEASE HISTORY */
729 /* */
730 /* DATE NAME DESCRIPTION */
731 /* */
732 /* 12-31-2020 Kenneth Maxwell Initial Version 6.1.3 */
733 /* */
734 /**************************************************************************/
_gx_display_driver_565rgb_rotated_palette_pixelmap_transparent_raw_write(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap)735 static VOID _gx_display_driver_565rgb_rotated_palette_pixelmap_transparent_raw_write(GX_DRAW_CONTEXT *context,
736 INT xpos, INT ypos, GX_PIXELMAP *pixelmap)
737 {
738 INT xval;
739 INT yval;
740 USHORT *putrow;
741 GX_UBYTE *getrow;
742 USHORT *put;
743 GX_CONST GX_UBYTE *get;
744 GX_COLOR *palette;
745 GX_UBYTE r;
746 GX_UBYTE g;
747 GX_UBYTE b;
748
749 GX_RECTANGLE *clip = context -> gx_draw_context_clip;
750 GX_RECTANGLE rotated_clip;
751
752 GX_SWAP_VALS(xpos, ypos);
753
754 if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
755 {
756 rotated_clip.gx_rectangle_left = clip -> gx_rectangle_top;
757 rotated_clip.gx_rectangle_right = clip -> gx_rectangle_bottom;
758 rotated_clip.gx_rectangle_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_right - 1);
759 rotated_clip.gx_rectangle_bottom = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_left - 1);
760 ypos = (context -> gx_draw_context_canvas -> gx_canvas_x_resolution - ypos - pixelmap -> gx_pixelmap_width);
761 }
762 else
763 {
764 rotated_clip.gx_rectangle_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_bottom - 1);
765 rotated_clip.gx_rectangle_right = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_top - 1);
766 rotated_clip.gx_rectangle_top = clip -> gx_rectangle_left;
767 rotated_clip.gx_rectangle_bottom = clip -> gx_rectangle_right;
768 xpos = (context -> gx_draw_context_canvas -> gx_canvas_y_resolution - xpos - pixelmap -> gx_pixelmap_height);
769 }
770
771 putrow = (USHORT *)context -> gx_draw_context_memory;
772 putrow += rotated_clip.gx_rectangle_top * context -> gx_draw_context_pitch;
773 putrow += rotated_clip.gx_rectangle_left;
774
775 getrow = (GX_UBYTE *)(pixelmap -> gx_pixelmap_data);
776 getrow += pixelmap -> gx_pixelmap_height * (rotated_clip.gx_rectangle_top - ypos);
777 getrow += (rotated_clip.gx_rectangle_left - xpos);
778
779 palette = (GX_COLOR *)pixelmap -> gx_pixelmap_aux_data;
780
781 for (yval = rotated_clip.gx_rectangle_top; yval <= rotated_clip.gx_rectangle_bottom; yval++)
782 {
783 put = putrow;
784 get = getrow;
785
786 for (xval = rotated_clip.gx_rectangle_left; xval <= rotated_clip.gx_rectangle_right; xval++)
787 {
788 if ((*get) != pixelmap -> gx_pixelmap_transparent_color)
789 {
790 r = (GX_UBYTE)(REDVAL_32BPP(palette[*get]) >> 3);
791 g = (GX_UBYTE)(GREENVAL_32BPP(palette[*get]) >> 2);
792 b = (GX_UBYTE)(BLUEVAL_32BPP(palette[*get]) >> 3);
793 *put = (USHORT)ASSEMBLECOLOR_16BPP(r, g, b);
794 }
795 get++;
796 put++;
797 }
798 putrow += context -> gx_draw_context_pitch;
799 getrow += pixelmap -> gx_pixelmap_height;
800 }
801 }
802
803 /**************************************************************************/
804 /* */
805 /* FUNCTION RELEASE */
806 /* */
807 /* _gx_display_driver_565rgb_rotated_palette_pixelmap_transparent */
808 /* _compressed_write */
809 /* PORTABLE C */
810 /* 6.1.3 */
811 /* AUTHOR */
812 /* */
813 /* Kenneth Maxwell, Microsoft Corporation */
814 /* */
815 /* DESCRIPTION */
816 /* */
817 /* Internal helper function that handles writing of compressed */
818 /* pixlemap file with transparent for palette pixelmap */
819 /* */
820 /* INPUT */
821 /* */
822 /* context Drawing context */
823 /* xpos x-coord of top-left draw point*/
824 /* ypos y-coord of top-left draw point*/
825 /* pixelmap Pointer to GX_PIXELMAP struct */
826 /* */
827 /* OUTPUT */
828 /* */
829 /* None */
830 /* */
831 /* CALLS */
832 /* */
833 /* _gx_display_driver_565rgb_pixel_blend Display driver basic pixel */
834 /* blend function */
835 /* */
836 /* CALLED BY */
837 /* */
838 /* GUIX Internal Code */
839 /* */
840 /* RELEASE HISTORY */
841 /* */
842 /* DATE NAME DESCRIPTION */
843 /* */
844 /* 12-31-2020 Kenneth Maxwell Initial Version 6.1.3 */
845 /**************************************************************************/
_gx_display_driver_565rgb_rotated_palette_pixelmap_transparent_compressed_write(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap)846 static VOID _gx_display_driver_565rgb_rotated_palette_pixelmap_transparent_compressed_write(GX_DRAW_CONTEXT *context,
847 INT xpos, INT ypos, GX_PIXELMAP *pixelmap)
848 {
849 INT yval;
850 INT xval;
851 GX_CONST GX_UBYTE *get;
852 USHORT *put;
853 USHORT *putrow;
854 GX_COLOR *palette;
855 GX_UBYTE brush_alpha;
856 USHORT count;
857 USHORT pixel;
858 GX_UBYTE r;
859 GX_UBYTE g;
860 GX_UBYTE b;
861 GX_RECTANGLE *clip = context -> gx_draw_context_clip;
862 GX_RECTANGLE rotated_clip;
863
864 get = (GX_CONST GX_UBYTE *)pixelmap -> gx_pixelmap_data;
865 brush_alpha = context -> gx_draw_context_brush.gx_brush_alpha;
866
867 GX_SWAP_VALS(xpos, ypos);
868
869 if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
870 {
871 rotated_clip.gx_rectangle_left = clip -> gx_rectangle_top;
872 rotated_clip.gx_rectangle_right = clip -> gx_rectangle_bottom;
873 rotated_clip.gx_rectangle_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_right - 1);
874 rotated_clip.gx_rectangle_bottom = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_left - 1);
875 ypos = (context -> gx_draw_context_canvas -> gx_canvas_x_resolution - ypos - pixelmap -> gx_pixelmap_width);
876 }
877 else
878 {
879 rotated_clip.gx_rectangle_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_bottom - 1);
880 rotated_clip.gx_rectangle_right = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_top - 1);
881 rotated_clip.gx_rectangle_top = clip -> gx_rectangle_left;
882 rotated_clip.gx_rectangle_bottom = clip -> gx_rectangle_right;
883 xpos = (context -> gx_draw_context_canvas -> gx_canvas_y_resolution - xpos - pixelmap -> gx_pixelmap_height);
884 }
885
886 /* Compressed with no alpha is a one-byte count and one-byte index value. */
887
888 /* First, skip to the starting row. */
889 for (yval = ypos; yval < rotated_clip.gx_rectangle_top; yval++)
890 {
891 xval = 0;
892 while (xval < pixelmap -> gx_pixelmap_height)
893 {
894 count = *get++;
895
896 if (count & 0x80)
897 {
898 count = (USHORT)((count & 0x7f) + 1u);
899 get++; /* Skip repeated pixel value. */
900 }
901 else
902 {
903 count++;
904 get += count; /* Skip raw pixel values. */
905 }
906 xval += count;
907 }
908 }
909
910 /* Now we are on the first visible row, copy pixels until we get
911 to the end of the last visible row. */
912 putrow = (USHORT *)context -> gx_draw_context_memory;
913 putrow += rotated_clip.gx_rectangle_top * context -> gx_draw_context_pitch;
914 putrow += xpos;
915
916 palette = (GX_COLOR *)pixelmap -> gx_pixelmap_aux_data;
917
918 while (yval <= rotated_clip.gx_rectangle_bottom)
919 {
920 put = putrow;
921 xval = xpos;
922
923 while (xval < xpos + pixelmap -> gx_pixelmap_height)
924 {
925 count = *get++;
926
927 if (count & 0x80)
928 {
929 /* Count the number of repeated value. */
930 count = (USHORT)((count & 0x7f) + 1u);
931
932 if ((*get) != pixelmap -> gx_pixelmap_transparent_color)
933 {
934 r = (GX_UBYTE)(REDVAL_32BPP(palette[*get]) >> 3);
935 g = (GX_UBYTE)(GREENVAL_32BPP(palette[*get]) >> 2);
936 b = (GX_UBYTE)(BLUEVAL_32BPP(palette[*get]) >> 3);
937
938 if (brush_alpha == 0xff)
939 {
940 while (count--)
941 {
942 if (xval >= rotated_clip.gx_rectangle_left &&
943 xval <= rotated_clip.gx_rectangle_right)
944 {
945 *put = (USHORT)ASSEMBLECOLOR_16BPP(r, g, b);
946 }
947 put++;
948 xval++;
949 }
950 }
951 else
952 {
953 pixel = (USHORT)ASSEMBLECOLOR_16BPP(r, g, b);
954 while (count--)
955 {
956 if (xval >= rotated_clip.gx_rectangle_left &&
957 xval <= rotated_clip.gx_rectangle_right)
958 {
959 _gx_display_driver_565rgb_pixel_blend(context, xval, yval, pixel, brush_alpha);
960 }
961 xval++;
962 }
963 }
964 }
965 else
966 {
967 put += count;
968 xval += count;
969 }
970 get++;
971 }
972 else
973 {
974 /* String of non-repeated values. */
975 count++;
976
977 if (brush_alpha == 0xff)
978 {
979 while (count--)
980 {
981 if ((*get) != pixelmap -> gx_pixelmap_transparent_color)
982 {
983 if (xval >= rotated_clip.gx_rectangle_left &&
984 xval <= rotated_clip.gx_rectangle_right)
985 {
986 r = (GX_UBYTE)(REDVAL_32BPP(palette[*get]) >> 3);
987 g = (GX_UBYTE)(GREENVAL_32BPP(palette[*get]) >> 2);
988 b = (GX_UBYTE)(BLUEVAL_32BPP(palette[*get]) >> 3);
989 *put = (USHORT)ASSEMBLECOLOR_16BPP(r, g, b);
990 }
991 }
992 put++;
993 get++;
994 xval++;
995 }
996 }
997 else
998 {
999 while (count--)
1000 {
1001 if ((*get) != pixelmap -> gx_pixelmap_transparent_color)
1002 {
1003 if (xval >= rotated_clip.gx_rectangle_left &&
1004 xval <= rotated_clip.gx_rectangle_right)
1005 {
1006 r = (GX_UBYTE)(REDVAL_32BPP(palette[*get]) >> 3);
1007 g = (GX_UBYTE)(GREENVAL_32BPP(palette[*get]) >> 2);
1008 b = (GX_UBYTE)(BLUEVAL_32BPP(palette[*get]) >> 3);
1009 pixel = (USHORT)ASSEMBLECOLOR_16BPP(r, g, b);
1010 _gx_display_driver_565rgb_pixel_blend(context, xval, yval, pixel, brush_alpha);
1011 }
1012 }
1013 get++;
1014 xval++;
1015 }
1016 }
1017 }
1018 }
1019 putrow += context -> gx_draw_context_pitch;
1020 yval++;
1021 }
1022 }
1023
1024
1025 /**************************************************************************/
1026 /* */
1027 /* FUNCTION RELEASE */
1028 /* */
1029 /* _gx_display_driver_565rgb_rotated_palette_pixelmap_compressed_write */
1030 /* PORTABLE C */
1031 /* 6.1.3 */
1032 /* AUTHOR */
1033 /* */
1034 /* Kenneth Maxwell, Microsoft Corporation */
1035 /* */
1036 /* DESCRIPTION */
1037 /* */
1038 /* Internal helper function that handles writing of compressed */
1039 /* pixlemap file without alpha channel for palette pixelmap. */
1040 /* */
1041 /* INPUT */
1042 /* */
1043 /* context Drawing context */
1044 /* xpos x-coord of top-left draw point*/
1045 /* ypos y-coord of top-left draw point*/
1046 /* pixelmap Pointer to GX_PIXELMAP struct */
1047 /* */
1048 /* OUTPUT */
1049 /* */
1050 /* None */
1051 /* */
1052 /* CALLS */
1053 /* */
1054 /* None */
1055 /* */
1056 /* CALLED BY */
1057 /* */
1058 /* GUIX Internal Code */
1059 /* */
1060 /* RELEASE HISTORY */
1061 /* */
1062 /* DATE NAME DESCRIPTION */
1063 /* */
1064 /* 12-31-2020 Kenneth Maxwell Initial Version 6.1.3 */
1065 /**************************************************************************/
_gx_display_driver_565rgb_rotated_palette_pixelmap_compressed_write(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap)1066 static VOID _gx_display_driver_565rgb_rotated_palette_pixelmap_compressed_write(GX_DRAW_CONTEXT *context,
1067 INT xpos, INT ypos, GX_PIXELMAP *pixelmap)
1068 {
1069 INT yval;
1070 INT xval;
1071 GX_CONST GX_UBYTE *get;
1072 USHORT *put;
1073 USHORT *putrow;
1074 GX_COLOR *palette;
1075 USHORT count;
1076 GX_UBYTE r;
1077 GX_UBYTE g;
1078 GX_UBYTE b;
1079 GX_UBYTE brush_alpha;
1080 GX_RECTANGLE *clip = context -> gx_draw_context_clip;
1081 GX_RECTANGLE rotated_clip;
1082
1083 get = (GX_CONST GX_UBYTE *)pixelmap -> gx_pixelmap_data;
1084 brush_alpha = context -> gx_draw_context_brush.gx_brush_alpha;
1085
1086 GX_SWAP_VALS(xpos, ypos);
1087
1088 if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
1089 {
1090 rotated_clip.gx_rectangle_left = clip -> gx_rectangle_top;
1091 rotated_clip.gx_rectangle_right = clip -> gx_rectangle_bottom;
1092 rotated_clip.gx_rectangle_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_right - 1);
1093 rotated_clip.gx_rectangle_bottom = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_left - 1);
1094 ypos = (context -> gx_draw_context_canvas -> gx_canvas_x_resolution - ypos - pixelmap -> gx_pixelmap_width);
1095 }
1096 else
1097 {
1098 rotated_clip.gx_rectangle_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_bottom - 1);
1099 rotated_clip.gx_rectangle_right = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_top - 1);
1100 rotated_clip.gx_rectangle_top = clip -> gx_rectangle_left;
1101 rotated_clip.gx_rectangle_bottom = clip -> gx_rectangle_right;
1102 xpos = (context -> gx_draw_context_canvas -> gx_canvas_y_resolution - xpos - pixelmap -> gx_pixelmap_height);
1103 }
1104
1105 /* Compressed with no alpha is a one-byte count and one-byte index value. */
1106
1107 /* First, skip to the starting row. */
1108 for (yval = ypos; yval < rotated_clip.gx_rectangle_top; yval++)
1109 {
1110 xval = 0;
1111 while (xval < pixelmap -> gx_pixelmap_height)
1112 {
1113 count = *get++;
1114
1115 if (count & 0x80)
1116 {
1117 count = (USHORT)((count & 0x7f) + 1u);
1118 get++; /* Skip repeated pixel value. */
1119 }
1120 else
1121 {
1122 count++;
1123 get += count; /* Skip raw pixel values. */
1124 }
1125 xval += count;
1126 }
1127 }
1128
1129 /* Now we are on the first visible row, copy pixels until we get
1130 to the end of the last visible row. */
1131 putrow = (USHORT *)context -> gx_draw_context_memory;
1132 putrow += rotated_clip.gx_rectangle_top * context -> gx_draw_context_pitch;
1133 putrow += xpos;
1134
1135 palette = (GX_COLOR *)pixelmap -> gx_pixelmap_aux_data;
1136
1137 while (yval <= rotated_clip.gx_rectangle_bottom)
1138 {
1139 put = putrow;
1140 xval = xpos;
1141
1142 while (xval < xpos + pixelmap -> gx_pixelmap_height)
1143 {
1144 count = *get++;
1145
1146 if (count & 0x80)
1147 {
1148 /* Repeated value. */
1149 count = (USHORT)((count & 0x7f) + 1u);
1150
1151 r = (GX_UBYTE)(REDVAL_32BPP(palette[*get]) >> 3);
1152 g = (GX_UBYTE)(GREENVAL_32BPP(palette[*get]) >> 2);
1153 b = (GX_UBYTE)(BLUEVAL_32BPP(palette[*get++]) >> 3);
1154
1155 if (brush_alpha == 0xff)
1156 {
1157 while (count--)
1158 {
1159 if (xval >= rotated_clip.gx_rectangle_left &&
1160 xval <= rotated_clip.gx_rectangle_right)
1161 {
1162 *put = (USHORT)ASSEMBLECOLOR_16BPP(r, g, b);
1163 }
1164 put++;
1165 xval++;
1166 }
1167 }
1168 else
1169 {
1170 while (count--)
1171 {
1172 if (xval >= rotated_clip.gx_rectangle_left &&
1173 xval <= rotated_clip.gx_rectangle_right)
1174 {
1175 _gx_display_driver_565rgb_pixel_blend(context, xval, yval, (USHORT)ASSEMBLECOLOR_16BPP(r, g, b), brush_alpha);
1176 }
1177 xval++;
1178 }
1179 }
1180 }
1181 else
1182 {
1183 /* String of non-repeated values. */
1184 count++;
1185 if (brush_alpha == 0xff)
1186 {
1187 while (count--)
1188 {
1189 if (xval >= rotated_clip.gx_rectangle_left &&
1190 xval <= rotated_clip.gx_rectangle_right)
1191 {
1192 r = (GX_UBYTE)(REDVAL_32BPP(palette[*get]) >> 3);
1193 g = (GX_UBYTE)(GREENVAL_32BPP(palette[*get]) >> 2);
1194 b = (GX_UBYTE)(BLUEVAL_32BPP(palette[*get]) >> 3);
1195 *put = (USHORT)ASSEMBLECOLOR_16BPP(r, g, b);
1196 }
1197
1198 put++;
1199 get++;
1200 xval++;
1201 }
1202 }
1203 else
1204 {
1205 while (count--)
1206 {
1207 if (xval >= rotated_clip.gx_rectangle_left &&
1208 xval <= rotated_clip.gx_rectangle_right)
1209 {
1210 r = (GX_UBYTE)(REDVAL_32BPP(palette[*get]) >> 3);
1211 g = (GX_UBYTE)(GREENVAL_32BPP(palette[*get]) >> 2);
1212 b = (GX_UBYTE)(BLUEVAL_32BPP(palette[*get]) >> 3);
1213 _gx_display_driver_565rgb_pixel_blend(context, xval, yval, (USHORT)ASSEMBLECOLOR_16BPP(r, g, b), brush_alpha);
1214 }
1215
1216 get++;
1217 xval++;
1218 }
1219 }
1220 }
1221 }
1222 putrow += context -> gx_draw_context_pitch;
1223 yval++;
1224 }
1225 }
1226
1227 /**************************************************************************/
1228 /* */
1229 /* FUNCTION RELEASE */
1230 /* */
1231 /* _gx_display_driver_16bpp_rotated_4444argb_pixelmap_raw_write */
1232 /* PORTABLE C */
1233 /* 6.1.3 */
1234 /* AUTHOR */
1235 /* */
1236 /* Kenneth Maxwell, Microsoft Corporation */
1237 /* */
1238 /* DESCRIPTION */
1239 /* */
1240 /* Internal helper function that handles writing of uncompressed */
1241 /* pixlemap file with alpha channel of 4444argb format. */
1242 /* */
1243 /* INPUT */
1244 /* */
1245 /* context Drawing context */
1246 /* xpos x-coord of top-left draw point*/
1247 /* ypos y-coord of top-left draw point*/
1248 /* pixelmap Pointer to GX_PIXELMAP struct */
1249 /* */
1250 /* OUTPUT */
1251 /* */
1252 /* None */
1253 /* */
1254 /* CALLS */
1255 /* */
1256 /* _gx_display_driver_565rgb_pixel_blend Display driver basic pixel */
1257 /* blend function */
1258 /* _gx_display_driver_16bpp_pixel_write Display driver basic pixel */
1259 /* write function */
1260 /* */
1261 /* CALLED BY */
1262 /* */
1263 /* GUIX Internal Code */
1264 /* */
1265 /* RELEASE HISTORY */
1266 /* */
1267 /* DATE NAME DESCRIPTION */
1268 /* */
1269 /* 12-31-2020 Kenneth Maxwell Initial Version 6.1.3 */
1270 /* */
1271 /**************************************************************************/
_gx_display_driver_16bpp_rotated_4444argb_pixelmap_raw_write(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap)1272 static VOID _gx_display_driver_16bpp_rotated_4444argb_pixelmap_raw_write(GX_DRAW_CONTEXT *context,
1273 INT xpos, INT ypos, GX_PIXELMAP *pixelmap)
1274 {
1275 INT skipcount;
1276 INT xval;
1277 INT yval;
1278 USHORT *getrow;
1279 GX_CONST USHORT *get;
1280 UCHAR alpha_value;
1281 USHORT pixel;
1282
1283 GX_RECTANGLE *clip = context -> gx_draw_context_clip;
1284 GX_RECTANGLE rotated_clip;
1285
1286 GX_SWAP_VALS(xpos, ypos);
1287
1288 if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
1289 {
1290 rotated_clip.gx_rectangle_left = clip -> gx_rectangle_top;
1291 rotated_clip.gx_rectangle_right = clip -> gx_rectangle_bottom;
1292 rotated_clip.gx_rectangle_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_right - 1);
1293 rotated_clip.gx_rectangle_bottom = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_left - 1);
1294 ypos = (context -> gx_draw_context_canvas -> gx_canvas_x_resolution - ypos - pixelmap -> gx_pixelmap_width);
1295 }
1296 else
1297 {
1298 rotated_clip.gx_rectangle_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_bottom - 1);
1299 rotated_clip.gx_rectangle_right = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_top - 1);
1300 rotated_clip.gx_rectangle_top = clip -> gx_rectangle_left;
1301 rotated_clip.gx_rectangle_bottom = clip -> gx_rectangle_right;
1302 xpos = (context -> gx_draw_context_canvas -> gx_canvas_y_resolution - xpos - pixelmap -> gx_pixelmap_height);
1303 }
1304
1305 /* Calculate how many pixels to skip. */
1306 skipcount = pixelmap -> gx_pixelmap_height * (rotated_clip.gx_rectangle_top - ypos);
1307 skipcount += (rotated_clip.gx_rectangle_left - xpos);
1308 getrow = (USHORT *)(pixelmap -> gx_pixelmap_data);
1309 getrow += skipcount;
1310
1311 for (yval = rotated_clip.gx_rectangle_top; yval <= rotated_clip.gx_rectangle_bottom; yval++)
1312 {
1313 get = getrow;
1314
1315 for (xval = rotated_clip.gx_rectangle_left; xval <= rotated_clip.gx_rectangle_right; xval++)
1316 {
1317 /* 0x000f- -> b , 0x00f0- -> g , 0x0f00- -> r , 0xf000- -> a */
1318 /* 4444bgra - -> 565rgb */
1319 alpha_value = (UCHAR)(((*get) & 0xf000) >> 8);
1320 alpha_value = alpha_value | (alpha_value >> 4);
1321 if (alpha_value)
1322 {
1323 pixel = (USHORT)((((*get) & 0x0f00) << 4) | (((*get) & 0x00f0) << 3) | (((*get) & 0x000f) << 1));
1324 if (alpha_value == 0xff)
1325 {
1326 _gx_display_driver_16bpp_pixel_write(context, xval, yval, pixel);
1327 }
1328 else
1329 {
1330 _gx_display_driver_565rgb_pixel_blend(context, xval, yval, pixel, alpha_value);
1331 }
1332 }
1333 get++;
1334 }
1335 getrow += pixelmap -> gx_pixelmap_height;
1336 }
1337 }
1338 /**************************************************************************/
1339 /* */
1340 /* FUNCTION RELEASE */
1341 /* */
1342 /* _gx_display_driver_16bpp_rotated_4444argb_pixelmap_compressed_write */
1343 /* PORTABLE C */
1344 /* 6.1.3 */
1345 /* AUTHOR */
1346 /* */
1347 /* Kenneth Maxwell, Microsoft Corporation */
1348 /* */
1349 /* DESCRIPTION */
1350 /* */
1351 /* Internal helper function that handles writing of compressed */
1352 /* pixelmap data of format 4444argb in 16bpp drivers. */
1353 /* */
1354 /* INPUT */
1355 /* */
1356 /* context Drawing context */
1357 /* xpos x-coord of top-left draw point*/
1358 /* ypos y-coord of top-left draw point*/
1359 /* pixelmap Pointer to GX_PIXELMAP struct */
1360 /* */
1361 /* OUTPUT */
1362 /* */
1363 /* None */
1364 /* */
1365 /* CALLS */
1366 /* */
1367 /* _gx_display_driver_565rgb_pixel_blend Display driver basic pixel */
1368 /* blend function */
1369 /* _gx_display_driver_16bpp_pixel_write Display driver basic pixel */
1370 /* write function */
1371 /* */
1372 /* CALLED BY */
1373 /* */
1374 /* GUIX Internal Code */
1375 /* */
1376 /* RELEASE HISTORY */
1377 /* */
1378 /* DATE NAME DESCRIPTION */
1379 /* */
1380 /* 12-31-2020 Kenneth Maxwell Initial Version 6.1.3 */
1381 /**************************************************************************/
_gx_display_driver_16bpp_rotated_4444argb_pixelmap_compressed_write(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap)1382 static VOID _gx_display_driver_16bpp_rotated_4444argb_pixelmap_compressed_write(GX_DRAW_CONTEXT *context,
1383 INT xpos, INT ypos, GX_PIXELMAP *pixelmap)
1384 {
1385 INT yval;
1386 INT xval;
1387 GX_CONST USHORT *get;
1388 USHORT count;
1389 USHORT pixel;
1390 GX_UBYTE alpha_value;
1391 GX_UBYTE combined_alpha;
1392 GX_UBYTE brush_alpha;
1393 GX_UBYTE r;
1394 GX_UBYTE g;
1395 GX_UBYTE b;
1396
1397 GX_RECTANGLE *clip = context -> gx_draw_context_clip;
1398 GX_RECTANGLE rotated_clip;
1399
1400 GX_SWAP_VALS(xpos, ypos);
1401
1402 if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
1403 {
1404 rotated_clip.gx_rectangle_left = clip -> gx_rectangle_top;
1405 rotated_clip.gx_rectangle_right = clip -> gx_rectangle_bottom;
1406 rotated_clip.gx_rectangle_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_right - 1);
1407 rotated_clip.gx_rectangle_bottom = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - clip -> gx_rectangle_left - 1);
1408 ypos = (context -> gx_draw_context_canvas -> gx_canvas_x_resolution - ypos - pixelmap -> gx_pixelmap_width);
1409 }
1410 else
1411 {
1412 rotated_clip.gx_rectangle_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_bottom - 1);
1413 rotated_clip.gx_rectangle_right = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - clip -> gx_rectangle_top - 1);
1414 rotated_clip.gx_rectangle_top = clip -> gx_rectangle_left;
1415 rotated_clip.gx_rectangle_bottom = clip -> gx_rectangle_right;
1416 xpos = (context -> gx_draw_context_canvas -> gx_canvas_y_resolution - xpos - pixelmap -> gx_pixelmap_height);
1417 }
1418
1419 get = (GX_CONST USHORT *)pixelmap -> gx_pixelmap_data;
1420 brush_alpha = context -> gx_draw_context_brush.gx_brush_alpha;
1421
1422 /* First, skip to the starting row. */
1423 for (yval = ypos; yval < rotated_clip.gx_rectangle_top; yval++)
1424 {
1425 xval = 0;
1426 while (xval < pixelmap -> gx_pixelmap_height)
1427 {
1428 count = *get++;
1429
1430 if (count & 0x8000)
1431 {
1432 count = (USHORT)((count & 0x7fff) + 1u);
1433 get++; /* Skip repeated pixel value. */
1434 }
1435 else
1436 {
1437 count++;
1438 get += count; /* Skip raw pixel values. */
1439 }
1440 xval += count;
1441 }
1442 }
1443
1444 /* Now we are on the first visible row, copy pixels until we get
1445 to the enf of the last visible row. */
1446 while (yval <= rotated_clip.gx_rectangle_bottom)
1447 {
1448 xval = xpos;
1449
1450 while (xval < xpos + pixelmap -> gx_pixelmap_height)
1451 {
1452 count = *get++;
1453
1454 if (count & 0x8000)
1455 {
1456 /* Repeated value. */
1457 count = (USHORT)((count & 0x7fff) + 1u);
1458 pixel = *get++;
1459 alpha_value = (GX_UBYTE)((pixel & 0xf000) >> 8);
1460 alpha_value = (alpha_value >> 4) | alpha_value;
1461 if (alpha_value)
1462 {
1463 r = (GX_UBYTE)((pixel & 0x0f00) >> 7);
1464 g = (GX_UBYTE)((pixel & 0x00f0) >> 2);
1465 b = (GX_UBYTE)((pixel & 0x000f) << 1);
1466 pixel = (USHORT)ASSEMBLECOLOR_16BPP(r, g, b);
1467
1468 if (brush_alpha == 0xff)
1469 {
1470 while (count--)
1471 {
1472 if (xval >= rotated_clip.gx_rectangle_left &&
1473 xval <= rotated_clip.gx_rectangle_right)
1474 {
1475 if (alpha_value == 0xff)
1476 {
1477 _gx_display_driver_16bpp_pixel_write(context, xval, yval, pixel);
1478 }
1479 else
1480 {
1481 _gx_display_driver_565rgb_pixel_blend(context, xval, yval, pixel, alpha_value);
1482 }
1483 }
1484 xval++;
1485 }
1486 }
1487 else
1488 {
1489 while (count--)
1490 {
1491 if (xval >= rotated_clip.gx_rectangle_left &&
1492 xval <= rotated_clip.gx_rectangle_right)
1493 {
1494 combined_alpha = (GX_UBYTE)(brush_alpha * alpha_value / 255);
1495 _gx_display_driver_565rgb_pixel_blend(context, xval, yval, pixel, combined_alpha);
1496 }
1497 xval++;
1498 }
1499 }
1500 }
1501 else
1502 {
1503 while (count--)
1504 {
1505 xval++;
1506 }
1507 }
1508 }
1509 else
1510 {
1511 /* String of non-repeated values. */
1512 count++;
1513
1514 if (brush_alpha == 0xff)
1515 {
1516 while (count--)
1517 {
1518 if (xval >= rotated_clip.gx_rectangle_left &&
1519 xval <= rotated_clip.gx_rectangle_right)
1520 {
1521 pixel = *get;
1522 alpha_value = (GX_UBYTE)((pixel & 0xf000) >> 8);
1523 alpha_value = (alpha_value >> 4) | alpha_value;
1524 r = (GX_UBYTE)((pixel & 0x0f00) >> 7);
1525 g = (GX_UBYTE)((pixel & 0x00f0) >> 2);
1526 b = (GX_UBYTE)((pixel & 0x000f) << 1);
1527 pixel = (USHORT)ASSEMBLECOLOR_16BPP(r, g, b);
1528 if (alpha_value)
1529 {
1530 if (alpha_value == 0xff)
1531 {
1532 _gx_display_driver_16bpp_pixel_write(context, xval, yval, pixel);
1533 }
1534 else
1535 {
1536 _gx_display_driver_565rgb_pixel_blend(context, xval, yval, pixel, alpha_value);
1537 }
1538 }
1539 }
1540 get++;
1541 xval++;
1542 }
1543 }
1544 else
1545 {
1546 while (count--)
1547 {
1548 if (xval >= rotated_clip.gx_rectangle_left &&
1549 xval <= rotated_clip.gx_rectangle_right)
1550 {
1551 pixel = *get;
1552 alpha_value = (GX_UBYTE)((pixel & 0xf000) >> 8);
1553 alpha_value = (alpha_value >> 4) | alpha_value;
1554 r = (GX_UBYTE)((pixel & 0x0f00) >> 7);
1555 g = (GX_UBYTE)((pixel & 0x00f0) >> 2);
1556 b = (GX_UBYTE)((pixel & 0x000f) << 1);
1557 pixel = (USHORT)ASSEMBLECOLOR_16BPP(r, g, b);
1558 combined_alpha = (GX_UBYTE)(brush_alpha * alpha_value / 255);
1559 _gx_display_driver_565rgb_pixel_blend(context, xval, yval, pixel, combined_alpha);
1560 }
1561 get++;
1562 xval++;
1563 }
1564 }
1565 }
1566 }
1567 yval++;
1568 }
1569 }
1570
1571 /**************************************************************************/
1572 /* */
1573 /* FUNCTION RELEASE */
1574 /* */
1575 /* _gx_display_driver_565rgb_rotated_pixelmap_draw PORTABLE C */
1576 /* 6.1.3 */
1577 /* AUTHOR */
1578 /* */
1579 /* Kenneth Maxwell, Microsoft Corporation */
1580 /* */
1581 /* DESCRIPTION */
1582 /* */
1583 /* 565rgb screen driver pixelmap drawing function that handles */
1584 /* compressed or uncompress, with or without alpha channel. */
1585 /* */
1586 /* INPUT */
1587 /* */
1588 /* context Drawing context */
1589 /* xpos x-coord of top-left draw point*/
1590 /* ypos y-coord of top-left draw point*/
1591 /* pixelmap Pointer to GX_PIXELMAP struct */
1592 /* */
1593 /* OUTPUT */
1594 /* */
1595 /* None */
1596 /* */
1597 /* CALLS */
1598 /* */
1599 /* _gx_display_driver_565rgb_rotated_pixelmap_compressed_alpha_write */
1600 /* _gx_display_driver_565rgb_rotated_pixelmap_alpha_write */
1601 /* _gx_display_driver_565rgb_rotated_pixelmap_compressed_write */
1602 /* _gx_display_driver_565rgb_rotated_pixelmap_raw_write */
1603 /* _gx_display_driver_565rgb_rotated_palette_pixelmap_compressed_write*/
1604 /* _gx_display_driver_565rgb_rotated_palette_pixelmap_raw_write */
1605 /* _gx_display_driver_16bpp_rotated_4444argb_pixelmap_raw_write */
1606 /* _gx_display_driver_565rgb_rotated_palette_pixelmap_transparent_ */
1607 /* compressed_write */
1608 /* _gx_display_driver_565rgb_palette_pixelmap_transparent_raw_write */
1609 /* _gx_display_driver_16bpp_4444argb_pixelmap_compressed_write */
1610 /* _gx_display_driver_565rgb_pixelmap_blend */
1611 /* */
1612 /* CALLED BY */
1613 /* */
1614 /* GUIX Internal Code */
1615 /* */
1616 /* RELEASE HISTORY */
1617 /* */
1618 /* DATE NAME DESCRIPTION */
1619 /* */
1620 /* 12-31-2020 Kenneth Maxwell Initial Version 6.1.3 */
1621 /* */
1622 /**************************************************************************/
_gx_display_driver_565rgb_rotated_pixelmap_draw(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap)1623 VOID _gx_display_driver_565rgb_rotated_pixelmap_draw(GX_DRAW_CONTEXT *context,
1624 INT xpos, INT ypos, GX_PIXELMAP *pixelmap)
1625 {
1626 GX_BOOL drawn = GX_FALSE;
1627 GX_UBYTE brush_alpha = context -> gx_draw_context_brush.gx_brush_alpha;
1628
1629 if (brush_alpha == 0)
1630 {
1631 /* Draw nothing here. Just return. */
1632 return;
1633 }
1634
1635 switch (pixelmap -> gx_pixelmap_format)
1636 {
1637 case GX_COLOR_FORMAT_8BIT_PALETTE:
1638 if (pixelmap -> gx_pixelmap_aux_data == GX_NULL)
1639 {
1640 break;
1641 }
1642
1643 if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_TRANSPARENT)
1644 {
1645 if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_COMPRESSED)
1646 {
1647 /* Compressed with. */
1648 _gx_display_driver_565rgb_rotated_palette_pixelmap_transparent_compressed_write(context, xpos, ypos, pixelmap);
1649 drawn = GX_TRUE;
1650 }
1651 else
1652 {
1653 /* No compression. */
1654 if (brush_alpha == 0xff)
1655 {
1656 _gx_display_driver_565rgb_rotated_palette_pixelmap_transparent_raw_write(context, xpos, ypos, pixelmap);
1657 drawn = GX_TRUE;
1658 }
1659 }
1660 }
1661 else
1662 {
1663 if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_COMPRESSED)
1664 {
1665 /* Compressed with. */
1666
1667 _gx_display_driver_565rgb_rotated_palette_pixelmap_compressed_write(context, xpos, ypos, pixelmap);
1668 drawn = GX_TRUE;
1669 }
1670 else
1671 {
1672 /* No compression. */
1673 if (brush_alpha == 0xff)
1674 {
1675 _gx_display_driver_565rgb_rotated_palette_pixelmap_raw_write(context, xpos, ypos, pixelmap);
1676 drawn = GX_TRUE;
1677 }
1678 }
1679 }
1680 break;
1681
1682 case GX_COLOR_FORMAT_565BGR:
1683 case GX_COLOR_FORMAT_565RGB:
1684 if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
1685 {
1686 if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_COMPRESSED)
1687 {
1688 /* Has both compression and alpha. */
1689 _gx_display_driver_565rgb_rotated_pixelmap_compressed_alpha_write(context,
1690 xpos, ypos, pixelmap);
1691 drawn = GX_TRUE;
1692 }
1693 else
1694 {
1695 /* Alpha, no compression. */
1696 if (brush_alpha == 0xff)
1697 {
1698 _gx_display_driver_565rgb_rotated_pixelmap_alpha_write(context, xpos, ypos, pixelmap);
1699 drawn = GX_TRUE;
1700 }
1701 }
1702 }
1703 else
1704 {
1705 if (brush_alpha == 0xff)
1706 {
1707 if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_COMPRESSED)
1708 {
1709 /* Compressed with no alpha. */
1710 _gx_display_driver_565rgb_rotated_pixelmap_compressed_write(context,
1711 xpos, ypos, pixelmap);
1712 }
1713 else
1714 {
1715 /* No compression or alpha. */
1716 _gx_display_driver_565rgb_rotated_pixelmap_raw_write(context,
1717 xpos, ypos, pixelmap);
1718 }
1719 drawn = GX_TRUE;
1720 }
1721 }
1722 break;
1723
1724 case GX_COLOR_FORMAT_4444ARGB:
1725 if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_COMPRESSED)
1726 {
1727 /* Not write yet. */
1728 _gx_display_driver_16bpp_rotated_4444argb_pixelmap_compressed_write(context, xpos, ypos, pixelmap);
1729 drawn = GX_TRUE;
1730 }
1731 else
1732 {
1733 if (brush_alpha == 0xff)
1734 {
1735 _gx_display_driver_16bpp_rotated_4444argb_pixelmap_raw_write(context, xpos, ypos, pixelmap);
1736 drawn = GX_TRUE;
1737 }
1738 }
1739 break;
1740
1741 default:
1742 drawn = GX_TRUE;
1743 break;
1744 }
1745
1746 if ((!drawn) && (brush_alpha != 0xff))
1747 {
1748 _gx_display_driver_565rgb_rotated_pixelmap_blend(context, xpos, ypos, pixelmap, brush_alpha);
1749 }
1750
1751 return;
1752 }
1753
1754