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_1bpp_horizontal_pixelmap_line_raw_write */
35 /* PORTABLE C */
36 /* 6.1 */
37 /* AUTHOR */
38 /* */
39 /* Kenneth Maxwell, Microsoft Corporation */
40 /* */
41 /* DESCRIPTION */
42 /* */
43 /* Internal helper function that handles writing of uncompressed */
44 /* pixlemap file without transparency. */
45 /* */
46 /* INPUT */
47 /* */
48 /* context Drawing context */
49 /* xstart x-coord of line left */
50 /* xend x-coord of line right */
51 /* y y-coord of line top */
52 /* info GX_FILL_PIXELMAP_INFO struct */
53 /* */
54 /* OUTPUT */
55 /* */
56 /* None */
57 /* */
58 /* CALLS */
59 /* */
60 /* None */
61 /* */
62 /* CALLED BY */
63 /* */
64 /* GUIX Internal Code */
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_1bpp_horizontal_pixelmap_line_raw_write(GX_DRAW_CONTEXT * context,INT xstart,INT xend,INT y,GX_FILL_PIXELMAP_INFO * info)75 static VOID _gx_display_driver_1bpp_horizontal_pixelmap_line_raw_write(GX_DRAW_CONTEXT *context,
76 INT xstart, INT xend, INT y,
77 GX_FILL_PIXELMAP_INFO *info)
78 {
79 INT xval;
80 const GX_UBYTE *get;
81 GX_UBYTE *put;
82 GX_UBYTE getmask;
83 GX_UBYTE putmask;
84 INT getstride;
85 INT putstride;
86 INT pic_width;
87 INT offset;
88 GX_UBYTE pixel;
89 GX_PIXELMAP *pixelmap;
90
91 pixelmap = info -> pixelmap;
92
93 pic_width = pixelmap -> gx_pixelmap_width;
94 get = info -> current_pixel_ptr;
95 getstride = (pic_width + 7) >> 3;
96
97 if ((info -> draw) && (xstart <= xend))
98 {
99 putstride = (context -> gx_draw_context_pitch + 7) >> 3;
100 put = (GX_UBYTE *)context -> gx_draw_context_memory;
101 put += y * putstride;
102 put += xstart >> 3;
103
104 putmask = (GX_UBYTE)(0x80 >> (xstart & 0x07));
105
106 /*calculate the offset.*/
107 offset = (info -> x_offset % pic_width);
108
109 for (xval = xstart; xval <= xend; xval++)
110 {
111 pixel = *(get + (offset >> 3));
112 getmask = (GX_UBYTE)(0x80 >> (offset & 0x07));
113 if (pixel & getmask)
114 {
115 *put |= putmask;
116 }
117 else
118 {
119 *put &= (GX_UBYTE)(~putmask);
120 }
121 offset++;
122
123 if (offset >= pic_width)
124 {
125 offset -= pic_width;
126 }
127
128 putmask >>= 1;
129 if (putmask == 0)
130 {
131 put++;
132 putmask = 0x80;
133 }
134 }
135 }
136
137 /*This line is drawn. Update the pointer position for next row.*/
138 info -> current_pixel_ptr += (UINT)getstride * sizeof(GX_UBYTE);
139 }
140
141 /**************************************************************************/
142 /* */
143 /* FUNCTION RELEASE */
144 /* */
145 /* _gx_display_driver_1bpp_horizontal_pixelmap_line_t_write */
146 /* PORTABLE C */
147 /* 6.1 */
148 /* AUTHOR */
149 /* */
150 /* Kenneth Maxwell, Microsoft Corporation */
151 /* */
152 /* DESCRIPTION */
153 /* */
154 /* Internal helper function that handles writing of uncompressed */
155 /* pixlemap file with transparent. */
156 /* */
157 /* INPUT */
158 /* */
159 /* context Drawing context */
160 /* xstart x-coord of line left */
161 /* xend x-coord of line right */
162 /* y y-coord of line top */
163 /* info GX_FILL_PIXELMAP_INFO struct */
164 /* */
165 /* OUTPUT */
166 /* */
167 /* None */
168 /* */
169 /* CALLS */
170 /* */
171 /* None */
172 /* */
173 /* CALLED BY */
174 /* */
175 /* GUIX Internal Code */
176 /* */
177 /* RELEASE HISTORY */
178 /* */
179 /* DATE NAME DESCRIPTION */
180 /* */
181 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
182 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
183 /* resulting in version 6.1 */
184 /* */
185 /**************************************************************************/
_gx_display_driver_1bpp_horizontal_pixelmap_line_transparent_write(GX_DRAW_CONTEXT * context,INT xstart,INT xend,INT y,GX_FILL_PIXELMAP_INFO * info)186 static VOID _gx_display_driver_1bpp_horizontal_pixelmap_line_transparent_write(GX_DRAW_CONTEXT *context,
187 INT xstart, INT xend, INT y, GX_FILL_PIXELMAP_INFO *info)
188 {
189 INT xval;
190 const GX_UBYTE *get;
191 GX_UBYTE *put;
192 GX_UBYTE putmask;
193 GX_UBYTE getmask;
194 GX_UBYTE pixel;
195 INT getstride;
196 INT putstride;
197 INT offset;
198 INT pic_width;
199 GX_PIXELMAP *pixelmap = info -> pixelmap;
200
201 pixelmap = info -> pixelmap;
202
203 pic_width = pixelmap -> gx_pixelmap_width;
204 get = info -> current_pixel_ptr;
205 getstride = (pic_width + 3) >> 2;
206
207 if ((info -> draw) && (xstart <= xend))
208 {
209 putstride = (context -> gx_draw_context_pitch + 7) >> 3;
210 put = (GX_UBYTE *)context -> gx_draw_context_memory;
211 put += y * putstride;
212 put += xstart >> 3;
213
214 putmask = (GX_UBYTE)(0x80 >> (xstart & 0x07));
215
216 /* Calculate the map offset in x-axis. */
217 offset = (info -> x_offset % pic_width);
218
219 for (xval = xstart; xval <= xend; xval++)
220 {
221 getmask = (GX_UBYTE)(0x40 >> ((offset & 0x03) << 1));
222 pixel = *(get + (offset >> 2));
223 if (getmask & pixel)
224 {
225 /* If not transparent, draw it. */
226 if ((getmask << 1) & pixel)
227 {
228 *put |= putmask;
229 }
230 else
231 {
232 *put &= (GX_UBYTE)(~putmask);
233 }
234 }
235
236 offset++;
237 if (offset >= pic_width)
238 {
239 offset = 0;
240 }
241
242 putmask >>= 1;
243 if (putmask == 0)
244 {
245 putmask = 0x80;
246 put++;
247 }
248 }
249 }
250
251 /* This line is drawn. Update the pointer position for next row. */
252 info -> current_pixel_ptr += (UINT)getstride * sizeof(GX_UBYTE);
253 }
254
255 /**************************************************************************/
256 /* */
257 /* FUNCTION RELEASE */
258 /* */
259 /* _gx_display_driver_1bpp_horizontal_pixelmap_line_compressed_write */
260 /* PORTABLE C */
261 /* 6.1 */
262 /* AUTHOR */
263 /* */
264 /* Kenneth Maxwell, Microsoft Corporation */
265 /* */
266 /* DESCRIPTION */
267 /* */
268 /* Internal helper function that handles writing of compressed */
269 /* pixlemap file without transparent. */
270 /* */
271 /* INPUT */
272 /* */
273 /* context Drawing context */
274 /* xstart x-coord of line left */
275 /* xend x-coord of line right */
276 /* y y-coord of line top */
277 /* info GX_FILL_PIXELMAP_INFO struct */
278 /* */
279 /* OUTPUT */
280 /* */
281 /* None */
282 /* */
283 /* CALLS */
284 /* */
285 /* None */
286 /* */
287 /* CALLED BY */
288 /* */
289 /* GUIX Internal Code */
290 /* */
291 /* RELEASE HISTORY */
292 /* */
293 /* DATE NAME DESCRIPTION */
294 /* */
295 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
296 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
297 /* resulting in version 6.1 */
298 /* */
299 /**************************************************************************/
_gx_display_driver_1bpp_horizontal_pixelmap_line_compressed_write(GX_DRAW_CONTEXT * context,INT xstart,INT xend,INT y,GX_FILL_PIXELMAP_INFO * info)300 static VOID _gx_display_driver_1bpp_horizontal_pixelmap_line_compressed_write(GX_DRAW_CONTEXT *context,
301 INT xstart, INT xend, INT y, GX_FILL_PIXELMAP_INFO *info)
302 {
303 INT start_pos;
304 INT xval;
305 GX_UBYTE count;
306 GX_CONST GX_UBYTE *get = GX_NULL;
307 GX_UBYTE pixel;
308 GX_UBYTE putmask;
309 GX_UBYTE *put;
310 GX_PIXELMAP *pixelmap;
311
312 pixelmap = info -> pixelmap;
313
314 if ((info -> draw) && (xstart <= xend))
315 {
316 /* Calcualte draw start position. */
317 start_pos = xstart - (info -> x_offset % pixelmap -> gx_pixelmap_width);
318
319 put = (GX_UBYTE *)context -> gx_draw_context_memory;
320 put += y * ((context -> gx_draw_context_pitch + 7) >> 3) + (xstart >> 3);
321
322 putmask = (GX_UBYTE)(0x80 >> (xstart & 0x07));
323
324 /* Repeat the draw operation to fill the whole dirty area.*/
325 while (start_pos <= xend)
326 {
327 xval = start_pos;
328
329 /* Start from where we need to repeat. */
330 get = (GX_CONST GX_UBYTE *)info -> current_pixel_ptr;
331
332 while (xval < start_pos + pixelmap -> gx_pixelmap_width)
333 {
334 count = *get;
335 if (count & 0x80)
336 {
337 count = (GX_UBYTE)(((count & 0x7f) >> 1) + 1);
338 pixel = *get++;
339 while (count--)
340 {
341 if (xval >= xstart && xval <= xend)
342 {
343 if (pixel & 0x01)
344 {
345 *put |= putmask;
346 }
347 else
348 {
349 *put &= (GX_UBYTE)(~putmask);
350 }
351
352 putmask >>= 1;
353 if (putmask == 0)
354 {
355 put++;
356 putmask = 0x80;
357 }
358 }
359 xval++;
360 }
361 }
362 else
363 {
364 count = (GX_UBYTE)((count >> 1) + 1);
365 while (count--)
366 {
367 pixel = *get++;
368 if (xval >= xstart && xval <= xend)
369 {
370 if (pixel & 0x01)
371 {
372 *put |= putmask;
373 }
374 else
375 {
376 *put &= (GX_UBYTE)(~putmask);
377 }
378
379 putmask >>= 1;
380 if (putmask == 0)
381 {
382 put++;
383 putmask = 0x80;
384 }
385 }
386 xval++;
387 }
388 }
389 }
390 start_pos += pixelmap -> gx_pixelmap_width;
391 }
392 }
393 else
394 {
395 xval = 0;
396 get = (GX_CONST GX_UBYTE *)info -> current_pixel_ptr;
397 while (xval < pixelmap -> gx_pixelmap_width)
398 {
399 count = *get;
400 if (count & 0x80)
401 {
402 count = (GX_UBYTE)(((count & 0x7f) >> 1) + 1);
403 get++;
404 }
405 else
406 {
407 count = (GX_UBYTE)((count >> 1) + 1);
408 get += count;
409 }
410 xval += count;
411 }
412 }
413
414 /* This line is drawn. cache the pointer for next line draw. */
415 info -> current_pixel_ptr = (GX_UBYTE *)get;
416 }
417
418 /**************************************************************************/
419 /* */
420 /* FUNCTION RELEASE */
421 /* */
422 /* _gx_display_driver_1bpp_horizontal_pixelmap_line_c_t_write */
423 /* PORTABLE C */
424 /* 6.1 */
425 /* AUTHOR */
426 /* */
427 /* Kenneth Maxwell, Microsoft Corporation */
428 /* */
429 /* DESCRIPTION */
430 /* */
431 /* Internal helper function that handles writing of compressed */
432 /* pixlemap file with alpha channel. */
433 /* */
434 /* INPUT */
435 /* */
436 /* context Drawing context */
437 /* xstart x-coord of line left */
438 /* xend x-coord of line right */
439 /* y y-coord of line top */
440 /* info GX_FILL_PIXELMAP_INFO struct */
441 /* */
442 /* OUTPUT */
443 /* */
444 /* None */
445 /* */
446 /* CALLS */
447 /* */
448 /* None */
449 /* */
450 /* CALLED BY */
451 /* */
452 /* GUIX Internal Code */
453 /* */
454 /* RELEASE HISTORY */
455 /* */
456 /* DATE NAME DESCRIPTION */
457 /* */
458 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
459 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
460 /* resulting in version 6.1 */
461 /* */
462 /**************************************************************************/
_gx_display_driver_1bpp_horizontal_pixelmap_line_compressed_transparent_write(GX_DRAW_CONTEXT * context,INT xstart,INT xend,INT y,GX_FILL_PIXELMAP_INFO * info)463 static VOID _gx_display_driver_1bpp_horizontal_pixelmap_line_compressed_transparent_write(GX_DRAW_CONTEXT *context,
464 INT xstart, INT xend, INT y, GX_FILL_PIXELMAP_INFO *info)
465 {
466 INT start_pos;
467 INT xval;
468 GX_UBYTE count;
469 GX_CONST GX_UBYTE *get = GX_NULL;
470 GX_UBYTE pixel;
471 GX_UBYTE putmask;
472 GX_UBYTE *put;
473 GX_PIXELMAP *pixelmap;
474
475 pixelmap = info -> pixelmap;
476
477 if ((info -> draw) && (xstart <= xend))
478 {
479 /* Calculate draw start position. */
480 start_pos = xstart - (info -> x_offset % pixelmap -> gx_pixelmap_width);
481
482 put = (GX_UBYTE *)context -> gx_draw_context_memory;
483 put += y * ((context -> gx_draw_context_pitch + 7) >> 3) + (xstart >> 3);
484
485 putmask = (GX_UBYTE)(0x80 >> (xstart & 0x07));
486
487 /*Repeat the draw operation to fill the whole dirty area.*/
488 while (start_pos <= xend)
489 {
490 xval = start_pos;
491 /*Start from where we need to repeat.*/
492 get = (GX_CONST GX_UBYTE *)info -> current_pixel_ptr;
493
494 while (xval < start_pos + pixelmap -> gx_pixelmap_width)
495 {
496 count = *get;
497 if (count & 0x80)
498 {
499 count = (GX_UBYTE)(((count & 0x7f) >> 2) + 1);
500 pixel = *get++;
501 while (count--)
502 {
503 if (xval >= xstart && xval <= xend)
504 {
505 if (pixel & 0x01)
506 {
507 if (pixel & 0x02)
508 {
509 *put |= putmask;
510 }
511 else
512 {
513 *put &= (GX_UBYTE)(~putmask);
514 }
515 }
516
517 putmask >>= 1;
518 if (putmask == 0)
519 {
520 put++;
521 putmask = 0x80;
522 }
523 }
524 xval++;
525 }
526 }
527 else
528 {
529 count = (GX_UBYTE)((count >> 2) + 1);
530 while (count--)
531 {
532 pixel = *get++;
533 if (xval >= xstart && xval <= xend)
534 {
535 if (pixel & 0x01)
536 {
537 if (pixel & 0x02)
538 {
539 *put |= putmask;
540 }
541 else
542 {
543 *put &= (GX_UBYTE)(~putmask);
544 }
545 }
546 putmask >>= 1;
547 if (putmask == 0)
548 {
549 put++;
550 putmask = 0x80;
551 }
552 }
553 xval++;
554 }
555 }
556 }
557 start_pos += pixelmap -> gx_pixelmap_width;
558 }
559 }
560 else
561 {
562 xval = 0;
563 get = (GX_CONST GX_UBYTE *)info -> current_pixel_ptr;
564 while (xval < pixelmap -> gx_pixelmap_width)
565 {
566 count = *get;
567 if (count & 0x80)
568 {
569 count = (GX_UBYTE)(((count & 0x7f) >> 2) + 1);
570 get++;
571 }
572 else
573 {
574 count = (GX_UBYTE)((count >> 2) + 1);
575 get += count;
576 }
577 xval += count;
578 }
579 }
580
581 /* This line is drawn. cache the pointer for next line draw. */
582 info -> current_pixel_ptr = (GX_UBYTE *)get;
583 }
584
585 /**************************************************************************/
586 /* */
587 /* FUNCTION RELEASE */
588 /* */
589 /* _gx_display_driver_1bpp_horizontal_pixelmap_line_draw */
590 /* PORTABLE C */
591 /* 6.1 */
592 /* AUTHOR */
593 /* */
594 /* Kenneth Maxwell, Microsoft Corporation */
595 /* */
596 /* DESCRIPTION */
597 /* */
598 /* 1bpp screen driver horizontal pixelmap line drawing function that */
599 /* handles compressed or uncompress, with or without alpha channel. */
600 /* */
601 /* INPUT */
602 /* */
603 /* context Drawing context */
604 /* xstart x-coord of line left */
605 /* xend x-coord of line right */
606 /* y y-coord of line top */
607 /* info GX_FILL_PIXELMAP_INFO struct */
608 /* */
609 /* OUTPUT */
610 /* */
611 /* None */
612 /* */
613 /* CALLS */
614 /* */
615 /* _gx_display_driver_1bpp_horizontal_pixelmap_line_c_t_write */
616 /* Real pixelmap line draw */
617 /* function */
618 /* _gx_display_driver_1bpp_horizontal_pixelmap_line_t_write */
619 /* Real pixelmap line draw */
620 /* function */
621 /* _gx_display_driver_1bpp_horizontal_pixelmap_line_compressed_write */
622 /* Real pixelmap line draw */
623 /* function */
624 /* _gx_display_driver_1bpp_horizontal_pixelmap_line_raw_write */
625 /* Real pixelmap line draw */
626 /* function */
627 /* */
628 /* CALLED BY */
629 /* */
630 /* GUIX Internal Code */
631 /* */
632 /* RELEASE HISTORY */
633 /* */
634 /* DATE NAME DESCRIPTION */
635 /* */
636 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
637 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
638 /* resulting in version 6.1 */
639 /* */
640 /**************************************************************************/
_gx_display_driver_1bpp_horizontal_pixelmap_line_draw(GX_DRAW_CONTEXT * context,INT xstart,INT xend,INT y,GX_FILL_PIXELMAP_INFO * info)641 VOID _gx_display_driver_1bpp_horizontal_pixelmap_line_draw(GX_DRAW_CONTEXT *context, INT xstart, INT xend, INT y, GX_FILL_PIXELMAP_INFO *info)
642 {
643 GX_PIXELMAP *pixelmap = info -> pixelmap;
644
645 if (pixelmap == GX_NULL)
646 {
647 return;
648 }
649
650 if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_TRANSPARENT)
651 {
652 if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_COMPRESSED)
653 {
654 /* has both compression and alpha */
655 _gx_display_driver_1bpp_horizontal_pixelmap_line_compressed_transparent_write(context, xstart, xend, y, info);
656 }
657 else
658 {
659 /* alpha, no compression */
660 _gx_display_driver_1bpp_horizontal_pixelmap_line_transparent_write(context, xstart, xend, y, info);
661 }
662 }
663 else
664 {
665 if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_COMPRESSED)
666 {
667 /* compressed with no alpha */
668 _gx_display_driver_1bpp_horizontal_pixelmap_line_compressed_write(context, xstart, xend, y, info);
669 }
670 else
671 {
672 /* no compression or alpha */
673 _gx_display_driver_1bpp_horizontal_pixelmap_line_raw_write(context, xstart, xend, y, info);
674 }
675 }
676
677 /* Current pixelmap has gone over, so the offset pointer should be reset. */
678 if (info -> current_pixel_ptr >= info -> pixelmap -> gx_pixelmap_data + info -> pixelmap -> gx_pixelmap_data_size)
679 {
680 info -> current_pixel_ptr = (GX_UBYTE *)info -> pixelmap -> gx_pixelmap_data;
681 info -> current_aux_ptr = (GX_UBYTE *)info -> pixelmap -> gx_pixelmap_aux_data;
682 }
683 }
684
685