GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_565rgb_horizontal_pixelmap_line_draw.c Lines: 278 278 100.0 %
Date: 2025-09-29 22:21:50 Branches: 176 176 100.0 %

Line Branch Exec Source
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
#if defined(GX_BRUSH_ALPHA_SUPPORT)
31
32
/**************************************************************************/
33
/*                                                                        */
34
/*  FUNCTION                                               RELEASE        */
35
/*                                                                        */
36
/*    _gx_display_driver_565rgb_horizontal_pixelmap_line_raw_blend        */
37
/*                                                        PORTABLE C      */
38
/*                                                           6.1          */
39
/*  AUTHOR                                                                */
40
/*                                                                        */
41
/*    Kenneth Maxwell, Microsoft Corporation                              */
42
/*                                                                        */
43
/*  DESCRIPTION                                                           */
44
/*                                                                        */
45
/*    Internal helper function that handles writing of uncompressed       */
46
/*    pixlemap file without alpha channel with brush alpha.               */
47
/*                                                                        */
48
/*  INPUT                                                                 */
49
/*                                                                        */
50
/*    context                               Drawing context               */
51
/*    xstart                                x-coord of line left          */
52
/*    xend                                  x-coord of line end           */
53
/*    y                                     y-coord of line top           */
54
/*    info                                  GX_FILL_PIXELMAP_INFO struct  */
55
/*    alpha                                 Alpha value                   */
56
/*                                                                        */
57
/*  OUTPUT                                                                */
58
/*                                                                        */
59
/*    None                                                                */
60
/*                                                                        */
61
/*  CALLS                                                                 */
62
/*                                                                        */
63
/*    [gx_display_driver_pixel_blend]       Basic display driver pixel    */
64
/*                                            blend function              */
65
/*                                                                        */
66
/*  CALLED BY                                                             */
67
/*                                                                        */
68
/*    _gx_display_driver_565rgb_horizontal_pixelmap_line_draw             */
69
/*                                                                        */
70
/*  RELEASE HISTORY                                                       */
71
/*                                                                        */
72
/*    DATE              NAME                      DESCRIPTION             */
73
/*                                                                        */
74
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
75
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
76
/*                                            resulting in version 6.1    */
77
/*                                                                        */
78
/**************************************************************************/
79
3803
static VOID _gx_display_driver_565rgb_horizontal_pixelmap_line_raw_blend(GX_DRAW_CONTEXT *context,
80
                                                                         INT xstart, INT xend, INT y,
81
                                                                         GX_FILL_PIXELMAP_INFO *info, GX_UBYTE alpha)
82
{
83
INT              xval;
84
INT              offset;
85
INT              pic_width;
86
GX_CONST USHORT *get;
87
USHORT           pixel;
88
GX_PIXELMAP     *pixelmap;
89
VOID             (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR fcolor, GX_UBYTE balpha);
90
91
3803
    blend_func = context -> gx_draw_context_display -> gx_display_driver_pixel_blend;
92
3803
    if (blend_func == GX_NULL)
93
    {
94
728
        return;
95
    }
96
97
3075
    pixelmap = info -> pixelmap;
98
3075
    pic_width = pixelmap -> gx_pixelmap_width;
99
100
    /* Pick the data pointer to the current row. */
101
3075
    get = (GX_CONST USHORT *)info -> current_pixel_ptr;
102
103

3075
    if ((info -> draw) && (xstart <= xend))
104
    {
105
        /* Calculate the map offset in x-axis. */
106
2081
        offset = (info -> x_offset % pic_width);
107
108
227461
        for (xval = xstart; xval <= xend; xval++)
109
        {
110
225380
            pixel = *(get + offset);
111
225380
            blend_func(context, xval, y, pixel, alpha);
112
225380
            offset++;
113
114
225380
            if (offset >= pic_width)
115
            {
116
6519
                offset -= pic_width;
117
            }
118
        }
119
    }
120
121
    /* Update data pointer for next row.*/
122
3075
    info -> current_pixel_ptr += (UINT)pic_width * sizeof(USHORT);
123
}
124
125
/**************************************************************************/
126
/*                                                                        */
127
/*  FUNCTION                                               RELEASE        */
128
/*                                                                        */
129
/*    _gx_display_driver_565rgb_horizontal_pixelmap_line_alpha_blend      */
130
/*                                                        PORTABLE C      */
131
/*                                                           6.1          */
132
/*  AUTHOR                                                                */
133
/*                                                                        */
134
/*    Kenneth Maxwell, Microsoft Corporation                              */
135
/*                                                                        */
136
/*  DESCRIPTION                                                           */
137
/*                                                                        */
138
/*    Internal helper function that handles writing of uncompressed       */
139
/*    pixlemap file with alpha channel with brush alpha.                  */
140
/*                                                                        */
141
/*  INPUT                                                                 */
142
/*                                                                        */
143
/*    context                               Drawing context               */
144
/*    xstart                                x-coord of line left          */
145
/*    xend                                  x-coord of line end           */
146
/*    y                                     y-coord of line top           */
147
/*    info                                  GX_FILL_PIXELMAP_INFO struct  */
148
/*    alpha                                 Alpha value                   */
149
/*                                                                        */
150
/*  OUTPUT                                                                */
151
/*                                                                        */
152
/*    None                                                                */
153
/*                                                                        */
154
/*  CALLS                                                                 */
155
/*                                                                        */
156
/*    [gx_display_driver_pixel_blend]       Basic display driver pixel    */
157
/*                                            blend function              */
158
/*                                                                        */
159
/*  CALLED BY                                                             */
160
/*                                                                        */
161
/*    _gx_display_driver_565rgb_horizontal_pixelmap_line_draw             */
162
/*                                                                        */
163
/*  RELEASE HISTORY                                                       */
164
/*                                                                        */
165
/*    DATE              NAME                      DESCRIPTION             */
166
/*                                                                        */
167
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
168
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
169
/*                                            resulting in version 6.1    */
170
/*                                                                        */
171
/**************************************************************************/
172
3728
static VOID _gx_display_driver_565rgb_horizontal_pixelmap_line_alpha_blend(GX_DRAW_CONTEXT *context,
173
                                                                           INT xstart, INT xend, INT y,
174
                                                                           GX_FILL_PIXELMAP_INFO *info, GX_UBYTE alpha)
175
{
176
INT                xval;
177
GX_CONST USHORT   *get;
178
GX_CONST GX_UBYTE *getalpha;
179
USHORT             color;
180
GX_UBYTE           falpha;
181
GX_UBYTE           combined_alpha;
182
GX_PIXELMAP       *pixelmap;
183
INT                pic_width;
184
INT                offset;
185
VOID               (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR color, GX_UBYTE alpha);
186
187
3728
    blend_func = context -> gx_draw_context_display -> gx_display_driver_pixel_blend;
188
3728
    if (blend_func == GX_NULL)
189
    {
190
857
        return;
191
    }
192
193
2871
    pixelmap = info -> pixelmap;
194
2871
    pic_width = pixelmap -> gx_pixelmap_width;
195
196

2871
    if ((info -> draw) && (xstart <= xend))
197
    {
198
        /* Pick the data pointer to the current row. */
199
2068
        get = (GX_CONST USHORT *)info -> current_pixel_ptr;
200
2068
        getalpha = (GX_CONST GX_UBYTE *)info -> current_aux_ptr;
201
202
        /* Calculate the map offset in x-axis. */
203
2068
        offset = (info -> x_offset % pic_width);
204
205
225596
        for (xval = xstart; xval <= xend; xval++)
206
        {
207
223528
            color = *(get + offset);
208
223528
            falpha = *(getalpha + offset);
209
210
223528
            if (falpha)
211
            {
212
123452
                combined_alpha = (GX_UBYTE)(falpha * alpha / 255);
213
214
123452
                blend_func(context, xval, y, color, combined_alpha);
215
            }
216
217
223528
            offset++;
218
223528
            if (offset >= pic_width)
219
            {
220
3276
                offset -= pic_width;
221
            }
222
        }
223
    }
224
225
    /* Update data pointers for next row. */
226
2871
    info -> current_pixel_ptr += (UINT)pic_width * sizeof(USHORT);
227
2871
    info -> current_aux_ptr += (UINT)pic_width * sizeof(GX_UBYTE);
228
}
229
230
231
/**************************************************************************/
232
/*                                                                        */
233
/*  FUNCTION                                               RELEASE        */
234
/*                                                                        */
235
/*    _gx_display_driver_565rgb_horizontal_pixelmap_line_compressed_blend */
236
/*                                                        PORTABLE C      */
237
/*                                                           6.1          */
238
/*  AUTHOR                                                                */
239
/*                                                                        */
240
/*    Kenneth Maxwell, Microsoft Corporation                              */
241
/*                                                                        */
242
/*  DESCRIPTION                                                           */
243
/*                                                                        */
244
/*    Internal helper function that handles writing of compressed         */
245
/*    pixlemap file without alpha channel with brush_alpha.               */
246
/*                                                                        */
247
/*  INPUT                                                                 */
248
/*                                                                        */
249
/*    context                               Drawing context               */
250
/*    xstart                                x-coord of line left          */
251
/*    xend                                  x-coord of line end           */
252
/*    y                                     y-coord of line top           */
253
/*    info                                  GX_FILL_PIXELMAP_INFO struct  */
254
/*    alpha                                 Alpha value                   */
255
/*                                                                        */
256
/*  OUTPUT                                                                */
257
/*                                                                        */
258
/*    None                                                                */
259
/*                                                                        */
260
/*  CALLS                                                                 */
261
/*                                                                        */
262
/*    [gx_display_driver_pixel_blend]       Basic display driver pixel    */
263
/*                                            blend function              */
264
/*                                                                        */
265
/*  CALLED BY                                                             */
266
/*                                                                        */
267
/*    _gx_display_driver_565rgb_horizontal_pixelmap_line_draw             */
268
/*                                                                        */
269
/*  RELEASE HISTORY                                                       */
270
/*                                                                        */
271
/*    DATE              NAME                      DESCRIPTION             */
272
/*                                                                        */
273
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
274
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
275
/*                                            resulting in version 6.1    */
276
/*                                                                        */
277
/**************************************************************************/
278
4919
static VOID _gx_display_driver_565rgb_horizontal_pixelmap_line_compressed_blend(GX_DRAW_CONTEXT *context, INT xstart, INT xend, INT y, GX_FILL_PIXELMAP_INFO *info, GX_UBYTE alpha)
279
{
280
INT              start_pos;
281
INT              xval;
282
USHORT           count;
283
USHORT           pixel;
284
4919
GX_CONST USHORT *get = GX_NULL;
285
GX_PIXELMAP     *pixelmap;
286
VOID             (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR fcolor, GX_UBYTE alpha);
287
288
4919
    blend_func = context -> gx_draw_context_display -> gx_display_driver_pixel_blend;
289
4919
    pixelmap = info -> pixelmap;
290
4919
    if (blend_func == GX_NULL)
291
    {
292
1124
        return;
293
    }
294
295

3795
    if ((info -> draw) && (xstart <= xend))
296
    {
297
        /* Calculate draw start position. */
298
2057
        start_pos = xstart - (info -> x_offset % pixelmap -> gx_pixelmap_width);
299
300
4428
        while (start_pos <= xend)
301
        {
302
2371
            xval = start_pos;
303
304
            /*Start from where we need to repeat.*/
305
2371
            get = (GX_CONST USHORT *)info -> current_pixel_ptr;
306
307
70129
            while (xval < start_pos + pixelmap -> gx_pixelmap_width)
308
            {
309
67758
                count = *get++;
310
67758
                if (count & 0x8000)
311
                {
312
36698
                    count = (USHORT)((count & 0x7fff) + 1);
313
36698
                    pixel = *get++;
314
283557
                    while (count--)
315
                    {
316

246859
                        if (xval >= xstart && xval <= xend)
317
                        {
318
61415
                            blend_func(context, xval, y, pixel, alpha);
319
                        }
320
246859
                        xval++;
321
                    }
322
                }
323
                else
324
                {
325
31060
                    count++;
326
696498
                    while (count--)
327
                    {
328
665438
                        pixel = *get++;
329

665438
                        if (xval >= xstart && xval <= xend)
330
                        {
331
160198
                            blend_func(context, xval, y, pixel, alpha);
332
                        }
333
665438
                        xval++;
334
                    }
335
                }
336
            }
337
2371
            start_pos += pixelmap -> gx_pixelmap_width;
338
        }
339
    }
340
    else
341
    {
342
1738
        xval = 0;
343
1738
        get = (GX_CONST USHORT *)info -> current_pixel_ptr;
344
42192
        while (xval < pixelmap -> gx_pixelmap_width)
345
        {
346
40454
            count = *get++;
347
40454
            if (count & 0x8000)
348
            {
349
21565
                count = (USHORT)((count & 0x7fff) + 1);
350
21565
                get++;
351
            }
352
            else
353
            {
354
18889
                count++;
355
18889
                get += count;
356
            }
357
40454
            xval += count;
358
        }
359
    }
360
361
    /* Update data pointer for next row. */
362
3795
    info -> current_pixel_ptr = (GX_UBYTE *)get;
363
}
364
365
/**************************************************************************/
366
/*                                                                        */
367
/*  FUNCTION                                               RELEASE        */
368
/*                                                                        */
369
/*    _gx_display_driver_565rgb_horizontal_pixelmap_line_c_a_blend        */
370
/*                                                        PORTABLE C      */
371
/*                                                           6.1          */
372
/*  AUTHOR                                                                */
373
/*                                                                        */
374
/*    Kenneth Maxwell, Microsoft Corporation                              */
375
/*                                                                        */
376
/*  DESCRIPTION                                                           */
377
/*                                                                        */
378
/*    Internal helper function that handles writing of compressed         */
379
/*    pixlemap file with alpha channel with brush alpha.                  */
380
/*                                                                        */
381
/*  INPUT                                                                 */
382
/*                                                                        */
383
/*    context                               Drawing context               */
384
/*    xstart                                x-coord of line left          */
385
/*    xend                                  x-coord of line end           */
386
/*    y                                     y-coord of line top           */
387
/*    info                                  GX_FILL_PIXELMAP_INFO struct  */
388
/*    alpha                                 Alpha value                   */
389
/*                                                                        */
390
/*  OUTPUT                                                                */
391
/*                                                                        */
392
/*    None                                                                */
393
/*                                                                        */
394
/*  CALLS                                                                 */
395
/*                                                                        */
396
/*    [gx_display_driver_pixel_blend]       Basic display driver pixel    */
397
/*                                            blend function              */
398
/*                                                                        */
399
/*  CALLED BY                                                             */
400
/*                                                                        */
401
/*    _gx_display_driver_565rgb_horizontal_pixelmap_line_draw             */
402
/*                                                                        */
403
/*  RELEASE HISTORY                                                       */
404
/*                                                                        */
405
/*    DATE              NAME                      DESCRIPTION             */
406
/*                                                                        */
407
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
408
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
409
/*                                            resulting in version 6.1    */
410
/*                                                                        */
411
/**************************************************************************/
412
4092
static VOID _gx_display_driver_565rgb_horizontal_pixelmap_line_compressed_alpha_blend(GX_DRAW_CONTEXT *context,
413
                                                                                      INT xstart, INT xend, INT y,
414
                                                                                      GX_FILL_PIXELMAP_INFO *info, GX_UBYTE alpha)
415
{
416
INT                xval;
417
GX_UBYTE           count;
418
INT                start_pos;
419
GX_UBYTE           falpha;
420
GX_UBYTE           combined_alpha;
421
USHORT             pixel;
422
4092
GX_CONST GX_UBYTE *get = GX_NULL;
423
GX_CONST USHORT   *getpixel;
424
GX_PIXELMAP       *pixelmap;
425
VOID               (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR color, GX_UBYTE alpha);
426
427
4092
    pixelmap = info -> pixelmap;
428
4092
    blend_func = context -> gx_draw_context_display -> gx_display_driver_pixel_blend;
429
430
4092
    if (blend_func == GX_NULL)
431
    {
432
724
        return;
433
    }
434
435

3368
    if ((info -> draw) && (xstart <= xend))
436
    {
437
        /* Calculate the draw start position. */
438
2038
        start_pos = xstart - (info -> x_offset % pixelmap -> gx_pixelmap_width);
439
440
11414
        while (start_pos <= xend)
441
        {
442
9376
            xval = start_pos;
443
444
            /*Start from where we need to repeat.*/
445
9376
            get = (GX_CONST GX_UBYTE *)info -> current_pixel_ptr;
446
44354
            while (xval < start_pos + pixelmap -> gx_pixelmap_width)
447
            {
448
34978
                count = *get;
449
34978
                if (count & 0x80)
450
                {
451
17410
                    count = (GX_UBYTE)((count & 0x7f) + 1u);
452
17410
                    falpha = *(get + 1);
453
17410
                    combined_alpha = (GX_UBYTE)(falpha * alpha / 255);
454
17410
                    if (combined_alpha)
455
                    {
456
7391
                        get += 2;
457
7391
                        getpixel = (GX_CONST USHORT *)get;
458
7391
                        pixel = *getpixel;
459
7391
                        get += 2;
460
461
165920
                        while (count--)
462
                        {
463

158529
                            if (xval >= xstart && xval <= xend)
464
                            {
465
76559
                                blend_func(context, xval, y, pixel, combined_alpha);
466
                            }
467
158529
                            xval++;
468
                        }
469
                    }
470
                    else
471
                    {
472
10019
                        get += 4;
473
10019
                        xval += count;
474
                    }
475
                }
476
                else
477
                {
478
17568
                    count++;
479
99828
                    while (count--)
480
                    {
481

82260
                        if (xval >= xstart && xval <= xend)
482
                        {
483
65712
                            falpha = *(get + 1);
484
65712
                            combined_alpha = (GX_UBYTE)(falpha * alpha / 255);
485
65712
                            get += 2;
486
65712
                            getpixel = (USHORT *)get;
487
65712
                            pixel = *getpixel;
488
65712
                            get += 2;
489
65712
                            blend_func(context, xval, y, pixel, combined_alpha);
490
                        }
491
                        else
492
                        {
493
16548
                            get += 4;
494
                        }
495
82260
                        xval++;
496
                    }
497
                }
498
            }
499
9376
            start_pos += pixelmap -> gx_pixelmap_width;
500
        }
501
    }
502
    else
503
    {
504
        /* Skip this line. */
505
1330
        xval = 0;
506
1330
        get = (GX_CONST GX_UBYTE *)info -> current_pixel_ptr;
507
11615
        while (xval < pixelmap -> gx_pixelmap_width)
508
        {
509
10285
            count = *get;
510
10285
            if (count & 0x80)
511
            {
512
6508
                count = (GX_UBYTE)((count & 0x7f) + 1);
513
6508
                get += 4;
514
            }
515
            else
516
            {
517
3777
                count++;
518
3777
                get += count * 4;
519
            }
520
10285
            xval += count;
521
        }
522
    }
523
524
    /* Update data pointer for the next line. */
525
3368
    info -> current_pixel_ptr = (GX_UBYTE *)get;
526
}
527
528
#endif /* GX_BRUSH_ALPHA_SUPPORT */
529
530
/**************************************************************************/
531
/*                                                                        */
532
/*  FUNCTION                                               RELEASE        */
533
/*                                                                        */
534
/*    _gx_display_driver_565rgb_horizontal_pixelmap_line_raw_write        */
535
/*                                                        PORTABLE C      */
536
/*                                                           6.X          */
537
/*  AUTHOR                                                                */
538
/*                                                                        */
539
/*    Kenneth Maxwell, Microsoft Corporation                              */
540
/*                                                                        */
541
/*  DESCRIPTION                                                           */
542
/*                                                                        */
543
/*    Internal helper function that handles writing of uncompressed       */
544
/*    pixlemap file without alpha channel.                                */
545
/*                                                                        */
546
/*  INPUT                                                                 */
547
/*                                                                        */
548
/*    context                               Drawing context               */
549
/*    xstart                                x-coord of line left          */
550
/*    xend                                  x-coord of line end           */
551
/*    y                                     y-coord of line top           */
552
/*    info                                  GX_FILL_PIXELMAP_INFO struct  */
553
/*                                                                        */
554
/*  OUTPUT                                                                */
555
/*                                                                        */
556
/*    None                                                                */
557
/*                                                                        */
558
/*  CALLS                                                                 */
559
/*                                                                        */
560
/*    None                                                                */
561
/*                                                                        */
562
/*  CALLED BY                                                             */
563
/*                                                                        */
564
/*    _gx_display_driver_565rgb_horizontal_pixelmap_line_draw             */
565
/*                                                                        */
566
/*  RELEASE HISTORY                                                       */
567
/*                                                                        */
568
/*    DATE              NAME                      DESCRIPTION             */
569
/*                                                                        */
570
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
571
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
572
/*                                            resulting in version 6.1    */
573
/*  10-31-2023     Ting Zhu                 Modified comment(s),          */
574
/*                                            added partial canvas buffer */
575
/*                                            support,                    */
576
/*                                            resulting in version 6.3.0  */
577
/*                                                                        */
578
/**************************************************************************/
579
4122
static VOID _gx_display_driver_565rgb_horizontal_pixelmap_line_raw_write(GX_DRAW_CONTEXT *context,
580
                                                                         INT xstart, INT xend, INT y,
581
                                                                         GX_FILL_PIXELMAP_INFO *info)
582
{
583
INT              xval;
584
INT              offset;
585
INT              pic_width;
586
4122
GX_CONST USHORT *get = GX_NULL;
587
USHORT          *put;
588
GX_PIXELMAP     *pixelmap;
589
590
4122
    pixelmap = info -> pixelmap;
591
592
4122
    pic_width = pixelmap -> gx_pixelmap_width;
593
594
    /* Pickup data pointer for the current line. */
595
4122
    get = (GX_CONST USHORT *)info -> current_pixel_ptr;
596
597

4122
    if ((info -> draw) && (xstart <= xend))
598
    {
599
3054
        put = (USHORT *)context -> gx_draw_context_memory;
600
3054
        GX_CALCULATE_PUTROW(put, xstart, y, context);
601
602
        /*calculate the offset.*/
603
3054
        offset = (info -> x_offset % pic_width);
604
605
423330
        for (xval = xstart; xval <= xend; xval++)
606
        {
607
420276
            *put++ = *(get + offset);
608
420276
            offset++;
609
610
420276
            if (offset >= pic_width)
611
            {
612
13074
                offset -= pic_width;
613
            }
614
        }
615
    }
616
617
    /* Update data pointer for the next line. */
618
4122
    info -> current_pixel_ptr += (UINT)pic_width * sizeof(USHORT);
619
4122
}
620
621
/**************************************************************************/
622
/*                                                                        */
623
/*  FUNCTION                                               RELEASE        */
624
/*                                                                        */
625
/*    _gx_display_driver_565rgb_horizontal_pixelmap_line_alpha_write      */
626
/*                                                        PORTABLE C      */
627
/*                                                           6.1          */
628
/*  AUTHOR                                                                */
629
/*                                                                        */
630
/*    Kenneth Maxwell, Microsoft Corporation                              */
631
/*                                                                        */
632
/*  DESCRIPTION                                                           */
633
/*                                                                        */
634
/*    Internal helper function that handles writing of uncompressed       */
635
/*    pixlemap file with alpha channel.                                   */
636
/*                                                                        */
637
/*  INPUT                                                                 */
638
/*                                                                        */
639
/*    context                               Drawing context               */
640
/*    xstart                                x-coord of line left          */
641
/*    xend                                  x-coord of line end           */
642
/*    y                                     y-coord of line top           */
643
/*    info                                  GX_FILL_PIXELMAP_INFO struct  */
644
/*                                                                        */
645
/*  OUTPUT                                                                */
646
/*                                                                        */
647
/*    None                                                                */
648
/*                                                                        */
649
/*  CALLS                                                                 */
650
/*                                                                        */
651
/*    [gx_display_driver_pixel_blend]       Basic display driver pixel    */
652
/*                                            blend function              */
653
/*    [gx_display_driver_pixel_write]       Basic display driver pixel    */
654
/*                                            write function              */
655
/*                                                                        */
656
/*  CALLED BY                                                             */
657
/*                                                                        */
658
/*    _gx_display_driver_565rgb_horizontal_pixelmap_line_draw             */
659
/*                                                                        */
660
/*  RELEASE HISTORY                                                       */
661
/*                                                                        */
662
/*    DATE              NAME                      DESCRIPTION             */
663
/*                                                                        */
664
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
665
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
666
/*                                            resulting in version 6.1    */
667
/*                                                                        */
668
/**************************************************************************/
669
4047
static VOID _gx_display_driver_565rgb_horizontal_pixelmap_line_alpha_write(GX_DRAW_CONTEXT *context,
670
                                                                           INT xstart, INT xend, INT y, GX_FILL_PIXELMAP_INFO *info)
671
{
672
INT                xval;
673
GX_CONST USHORT   *get;
674
GX_CONST GX_UBYTE *getalpha;
675
USHORT             color;
676
GX_UBYTE           alpha;
677
GX_PIXELMAP       *pixelmap;
678
INT                pic_width;
679
INT                offset;
680
VOID               (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR color, GX_UBYTE alpha);
681
682
4047
    blend_func = context -> gx_draw_context_display -> gx_display_driver_pixel_blend;
683
4047
    pixelmap = info -> pixelmap;
684
685
4047
    if (blend_func == GX_NULL)
686
    {
687
857
        return;
688
    }
689
690
3190
    pic_width = pixelmap -> gx_pixelmap_width;
691

3190
    if ((info -> draw) && (xstart <= xend))
692
    {
693
        /* Pick up data pointers to the current line. */
694
2387
        get = (GX_CONST USHORT *)info -> current_pixel_ptr;
695
2387
        getalpha = (GX_CONST GX_UBYTE *)info -> current_aux_ptr;
696
697
        /* calculate map offset in x-axis. */
698
2387
        offset = (info -> x_offset % pic_width);
699
700
306284
        for (xval = xstart; xval <= xend; xval++)
701
        {
702
303897
            color = *(get + offset);
703
303897
            alpha = *(getalpha + offset);
704
705
303897
            blend_func(context, xval, y, color, alpha);
706
707
303897
            offset++;
708
303897
            if (offset >= pic_width)
709
            {
710
5366
                offset -= pic_width;
711
            }
712
        }
713
    }
714
715
    /* Update data pointers for the next line. */
716
3190
    info -> current_pixel_ptr += (UINT)pic_width * sizeof(USHORT);
717
3190
    info -> current_aux_ptr += (UINT)pic_width * sizeof(GX_UBYTE);
718
}
719
720
/**************************************************************************/
721
/*                                                                        */
722
/*  FUNCTION                                               RELEASE        */
723
/*                                                                        */
724
/*    _gx_display_driver_565rgb_horizontal_pixelmap_line_compressed_write */
725
/*                                                        PORTABLE C      */
726
/*                                                           6.3.0        */
727
/*  AUTHOR                                                                */
728
/*                                                                        */
729
/*    Kenneth Maxwell, Microsoft Corporation                              */
730
/*                                                                        */
731
/*  DESCRIPTION                                                           */
732
/*                                                                        */
733
/*    Internal helper function that handles writing of compressed         */
734
/*    pixlemap file without alpha channel.                                */
735
/*                                                                        */
736
/*  INPUT                                                                 */
737
/*                                                                        */
738
/*    context                               Drawing context               */
739
/*    xstart                                x-coord of line left          */
740
/*    xend                                  x-coord of line end           */
741
/*    y                                     y-coord of line top           */
742
/*    info                                  GX_FILL_PIXELMAP_INFO struct  */
743
/*                                                                        */
744
/*  OUTPUT                                                                */
745
/*                                                                        */
746
/*    None                                                                */
747
/*                                                                        */
748
/*  CALLS                                                                 */
749
/*                                                                        */
750
/*    None                                                                */
751
/*                                                                        */
752
/*  CALLED BY                                                             */
753
/*                                                                        */
754
/*    _gx_display_driver_565rgb_horizontal_pixelmap_line_draw             */
755
/*                                                                        */
756
/*  RELEASE HISTORY                                                       */
757
/*                                                                        */
758
/*    DATE              NAME                      DESCRIPTION             */
759
/*                                                                        */
760
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
761
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
762
/*                                            resulting in version 6.1    */
763
/*  10-31-2023     Ting Zhu                 Modified comment(s),          */
764
/*                                            added partial canvas buffer */
765
/*                                            support,                    */
766
/*                                            resulting in version 6.3.0  */
767
/*                                                                        */
768
/**************************************************************************/
769
5238
static VOID _gx_display_driver_565rgb_horizontal_pixelmap_line_compressed_write(GX_DRAW_CONTEXT *context,
770
                                                                                INT xstart, INT xend, INT y, GX_FILL_PIXELMAP_INFO *info)
771
{
772
INT              start_pos;
773
INT              xval;
774
USHORT           count;
775
USHORT           pixel;
776
5238
GX_CONST USHORT *get = GX_NULL;
777
USHORT          *put;
778
GX_PIXELMAP     *pixelmap;
779
780
5238
    pixelmap = info -> pixelmap;
781
782

5238
    if ((info -> draw) && (xstart <= xend))
783
    {
784
        /* Calculate draw start position. */
785
3030
        start_pos = xstart - (info -> x_offset % pixelmap -> gx_pixelmap_width);
786
787
3030
        put = (USHORT *)context -> gx_draw_context_memory;
788
3030
        GX_CALCULATE_PUTROW(put, start_pos, y, context);
789
790
        /*Repeat the draw operation to fill the whole dirty area.*/
791
6687
        while (start_pos <= xend)
792
        {
793
3657
            xval = start_pos;
794
795
            /*Start from where we need to repeat.*/
796
3657
            get = (GX_CONST USHORT *)info -> current_pixel_ptr;
797
798
127632
            while (xval < start_pos + pixelmap -> gx_pixelmap_width)
799
            {
800
123975
                count = *get++;
801
123975
                if (count & 0x8000)
802
                {
803
67179
                    count = (USHORT)((count & 0x7fff) + 1);
804
67179
                    pixel = *get++;
805
478354
                    while (count--)
806
                    {
807

411175
                        if (xval >= xstart && xval <= xend)
808
                        {
809
118668
                            *put = pixel;
810
                        }
811
411175
                        xval++;
812
411175
                        put++;
813
                    }
814
                }
815
                else
816
                {
817
56796
                    count++;
818
1258640
                    while (count--)
819
                    {
820
1201844
                        pixel = *get++;
821

1201844
                        if (xval >= xstart && xval <= xend)
822
                        {
823
297841
                            *put = pixel;
824
                        }
825
1201844
                        xval++;
826
1201844
                        put++;
827
                    }
828
                }
829
            }
830
3657
            start_pos += pixelmap -> gx_pixelmap_width;
831
        }
832
    }
833
    else
834
    {
835
2208
        xval = 0;
836
2208
        get = (GX_CONST USHORT *)info -> current_pixel_ptr;
837
67516
        while (xval < pixelmap -> gx_pixelmap_width)
838
        {
839
65308
            count = *get++;
840
65308
            if (count & 0x8000)
841
            {
842
34365
                count = (USHORT)((count & 0x7fff) + 1);
843
34365
                get++;
844
            }
845
            else
846
            {
847
30943
                count++;
848
30943
                get += count;
849
            }
850
65308
            xval += count;
851
        }
852
    }
853
854
    /* Update data pointer for the next line. */
855
5238
    info -> current_pixel_ptr = (GX_UBYTE *)get;
856
5238
}
857
858
/**************************************************************************/
859
/*                                                                        */
860
/*  FUNCTION                                               RELEASE        */
861
/*                                                                        */
862
/*    _gx_display_driver_565rgb_horizontal_pixelmap_line_c_a_write        */
863
/*                                                        PORTABLE C      */
864
/*                                                           6.1          */
865
/*  AUTHOR                                                                */
866
/*                                                                        */
867
/*    Kenneth Maxwell, Microsoft Corporation                              */
868
/*                                                                        */
869
/*  DESCRIPTION                                                           */
870
/*                                                                        */
871
/*    Internal helper function that handles writing of compressed         */
872
/*    pixlemap file with alpha channel.                                   */
873
/*                                                                        */
874
/*  INPUT                                                                 */
875
/*                                                                        */
876
/*    context                               Drawing context               */
877
/*    xstart                                x-coord of line left          */
878
/*    xend                                  x-coord of line end           */
879
/*    y                                     y-coord of line top           */
880
/*    info                                  GX_FILL_PIXELMAP_INFO struct  */
881
/*                                                                        */
882
/*  OUTPUT                                                                */
883
/*                                                                        */
884
/*    None                                                                */
885
/*                                                                        */
886
/*  CALLS                                                                 */
887
/*                                                                        */
888
/*    [gx_display_driver_pixel_blend]       Basic display driver pixel    */
889
/*                                            blend function              */
890
/*                                                                        */
891
/*  CALLED BY                                                             */
892
/*                                                                        */
893
/*    _gx_display_driver_565rgb_horizontal_pixelmap_line_draw             */
894
/*                                                                        */
895
/*  RELEASE HISTORY                                                       */
896
/*                                                                        */
897
/*    DATE              NAME                      DESCRIPTION             */
898
/*                                                                        */
899
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
900
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
901
/*                                            resulting in version 6.1    */
902
/*                                                                        */
903
/**************************************************************************/
904
4411
static VOID _gx_display_driver_565rgb_horizontal_pixelmap_line_compressed_alpha_write(GX_DRAW_CONTEXT *context,
905
                                                                                      INT xstart, INT xend, INT y, GX_FILL_PIXELMAP_INFO *info)
906
{
907
INT                xval;
908
GX_UBYTE           count;
909
INT                start_pos;
910
GX_UBYTE           alpha;
911
USHORT             pixel;
912
4411
GX_CONST GX_UBYTE *get = GX_NULL;
913
GX_CONST USHORT   *getpixel;
914
GX_PIXELMAP       *pixelmap;
915
VOID               (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR color, GX_UBYTE alpha);
916
917
4411
    pixelmap = info -> pixelmap;
918
4411
    blend_func = context -> gx_draw_context_display -> gx_display_driver_pixel_blend;
919
920
4411
    if (blend_func == GX_NULL)
921
    {
922
724
        return;
923
    }
924
925

3687
    if ((info -> draw) && (xstart <= xend))
926
    {
927
        /* Calculate draw start position. */
928
2357
        start_pos = xstart - (info -> x_offset % pixelmap -> gx_pixelmap_width);
929
930
        /* Repeat the draw operation to fill the whole dirty area. */
931
12369
        while (start_pos <= xend)
932
        {
933
10012
            xval = start_pos;
934
935
            /* Start from where we need to repeat. */
936
10012
            get = (GX_CONST GX_UBYTE *)info -> current_pixel_ptr;
937
49915
            while (xval < start_pos + pixelmap -> gx_pixelmap_width)
938
            {
939
39903
                count = *get;
940
39903
                if (count & 0x80)
941
                {
942
20544
                    count = (GX_UBYTE)((count & 0x7f) + 1u);
943
20544
                    alpha = *(get + 1);
944
20544
                    if (alpha)
945
                    {
946
8323
                        get += 2;
947
948
8323
                        getpixel = (GX_CONST USHORT *)get;
949
8323
                        pixel = *getpixel;
950
8323
                        get += 2;
951
952
207073
                        while (count--)
953
                        {
954

198750
                            if (xval >= xstart && xval <= xend)
955
                            {
956
107607
                                blend_func(context, xval, y, pixel, alpha);
957
                            }
958
198750
                            xval++;
959
                        }
960
                    }
961
                    else
962
                    {
963
12221
                        get += 4;
964
12221
                        xval += count;
965
                    }
966
                }
967
                else
968
                {
969
19359
                    count++;
970
107749
                    while (count--)
971
                    {
972

88390
                        if (xval >= xstart && xval <= xend)
973
                        {
974
69676
                            alpha = *(get + 1);
975
69676
                            get += 2;
976
69676
                            getpixel = (USHORT *)get;
977
69676
                            pixel = *getpixel;
978
69676
                            get += 2;
979
69676
                            blend_func(context, xval, y, pixel, alpha);
980
                        }
981
                        else
982
                        {
983
18714
                            get += 4;
984
                        }
985
88390
                        xval++;
986
                    }
987
                }
988
            }
989
10012
            start_pos += pixelmap -> gx_pixelmap_width;
990
        }
991
    }
992
    else
993
    {
994
        /* Just do skip operation here. */
995
1330
        xval = 0;
996
1330
        get = (GX_CONST GX_UBYTE *)info -> current_pixel_ptr;
997
11615
        while (xval < pixelmap -> gx_pixelmap_width)
998
        {
999
10285
            count = *get;
1000
10285
            if (count & 0x80)
1001
            {
1002
6508
                count = (GX_UBYTE)((count & 0x7f) + 1);
1003
6508
                get += 4;
1004
            }
1005
            else
1006
            {
1007
3777
                count++;
1008
3777
                get += count * 4;
1009
            }
1010
10285
            xval += count;
1011
        }
1012
    }
1013
1014
    /* Update data pinter for the next line. */
1015
3687
    info -> current_pixel_ptr = (GX_UBYTE *)get;
1016
}
1017
1018
/**************************************************************************/
1019
/*                                                                        */
1020
/*  FUNCTION                                               RELEASE        */
1021
/*                                                                        */
1022
/*    _gx_display_driver_565rgb_horizontal_pixelmap_line_draw             */
1023
/*                                                        PORTABLE C      */
1024
/*                                                           6.1          */
1025
/*  AUTHOR                                                                */
1026
/*                                                                        */
1027
/*    Kenneth Maxwell, Microsoft Corporation                              */
1028
/*                                                                        */
1029
/*  DESCRIPTION                                                           */
1030
/*                                                                        */
1031
/*    565rgb screen driver pixelmap drawing function that handles         */
1032
/*    compressed or uncompress, with or without alpha channel.            */
1033
/*                                                                        */
1034
/*  INPUT                                                                 */
1035
/*                                                                        */
1036
/*    context                               Drawing context               */
1037
/*    xstart                                x-coord of line left          */
1038
/*    xend                                  x-coord of line right         */
1039
/*    y                                     y-coord of line top           */
1040
/*    info                                  GX_FILL_PIXELMAP_INFO struct  */
1041
/*                                                                        */
1042
/*  OUTPUT                                                                */
1043
/*                                                                        */
1044
/*    None                                                                */
1045
/*                                                                        */
1046
/*  CALLS                                                                 */
1047
/*                                                                        */
1048
/*     _gx_display_driver_565rgb_horizontal_pixelmap_line_c_a_blend       */
1049
/*                                          Real pixelmap blend function  */
1050
/*     _gx_display_driver_565rgb_horizontal_pixelmap_line_alpha_blend     */
1051
/*                                          Real pixelmap blend function  */
1052
/*     _gx_display_driver_565rgb_horizontal_pixelmap_line_c_blend         */
1053
/*                                          Real pixelmap blend function  */
1054
/*     _gx_display_driver_565rgb_horizontal_pixelmap_line_raw_blend       */
1055
/*                                          Real pixelmap blend function  */
1056
/*     _gx_display_driver_565rgb_horizontal_pixelmap_line_c_a_write       */
1057
/*                                          Real pixelmap write function  */
1058
/*     _gx_display_driver_565rgb_horizontal_pixelmap_line_alpha_write     */
1059
/*                                          Real pixelmap write function  */
1060
/*     _gx_display_driver_565rgb_horizontal_pixelmap_line_c_write         */
1061
/*                                          Real pixelmap write function  */
1062
/*     _gx_display_driver_565rgb_horizontal_pixelmap_line_raw_write       */
1063
/*                                          Real pixelmap write function  */
1064
/*                                                                        */
1065
/*  CALLED BY                                                             */
1066
/*                                                                        */
1067
/*    GUIX Internal Code                                                  */
1068
/*                                                                        */
1069
/*  RELEASE HISTORY                                                       */
1070
/*                                                                        */
1071
/*    DATE              NAME                      DESCRIPTION             */
1072
/*                                                                        */
1073
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
1074
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
1075
/*                                            resulting in version 6.1    */
1076
/*                                                                        */
1077
/**************************************************************************/
1078
44037
VOID _gx_display_driver_565rgb_horizontal_pixelmap_line_draw(GX_DRAW_CONTEXT *context,
1079
                                                             INT xstart, INT xend, INT y, GX_FILL_PIXELMAP_INFO *info)
1080
{
1081
#if defined GX_BRUSH_ALPHA_SUPPORT
1082
GX_UBYTE alpha;
1083
1084
44037
    alpha = context -> gx_draw_context_brush.gx_brush_alpha;
1085

44037
    if ((alpha == 0) || (info -> pixelmap == GX_NULL))
1086
    {
1087
        /* Nothing to drawn. Just return. */
1088
9677
        return;
1089
    }
1090
1091
34360
    if (alpha != 0xff)
1092
    {
1093
1094
16542
        if (info -> pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
1095
        {
1096
7820
            if (info -> pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_COMPRESSED)
1097
            {
1098
                /* has both compression and alpha */
1099
4092
                _gx_display_driver_565rgb_horizontal_pixelmap_line_compressed_alpha_blend(context, xstart, xend, y, info, alpha);
1100
            }
1101
            else
1102
            {
1103
                /* alpha, no compression */
1104
3728
                _gx_display_driver_565rgb_horizontal_pixelmap_line_alpha_blend(context, xstart, xend, y, info, alpha);
1105
            }
1106
        }
1107
        else
1108
        {
1109
8722
            if (info -> pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_COMPRESSED)
1110
            {
1111
                /* compressed with no alpha */
1112
4919
                _gx_display_driver_565rgb_horizontal_pixelmap_line_compressed_blend(context, xstart, xend, y, info, alpha);
1113
            }
1114
            else
1115
            {
1116
                /* no compression or alpha */
1117
3803
                _gx_display_driver_565rgb_horizontal_pixelmap_line_raw_blend(context, xstart, xend, y, info, alpha);
1118
            }
1119
        }
1120
1121
        /* Data pointer goes to the end of the fill map, move it to the start again. */
1122
16542
        if (info -> current_pixel_ptr >= info -> pixelmap -> gx_pixelmap_data + info -> pixelmap -> gx_pixelmap_data_size)
1123
        {
1124
144
            info -> current_pixel_ptr = (GX_UBYTE *)info -> pixelmap -> gx_pixelmap_data;
1125
144
            info -> current_aux_ptr = (GX_UBYTE *)info -> pixelmap -> gx_pixelmap_aux_data;
1126
        }
1127
16542
        return;
1128
    }
1129
#endif
1130
1131
17818
    if (info -> pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
1132
    {
1133
8458
        if (info -> pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_COMPRESSED)
1134
        {
1135
            /* has both compression and alpha */
1136
4411
            _gx_display_driver_565rgb_horizontal_pixelmap_line_compressed_alpha_write(context, xstart, xend, y, info);
1137
        }
1138
        else
1139
        {
1140
            /* alpha, no compression */
1141
4047
            _gx_display_driver_565rgb_horizontal_pixelmap_line_alpha_write(context, xstart, xend, y, info);
1142
        }
1143
    }
1144
    else
1145
    {
1146
9360
        if (info -> pixelmap ->  gx_pixelmap_flags & GX_PIXELMAP_COMPRESSED)
1147
        {
1148
            /* compressed with no alpha */
1149
5238
            _gx_display_driver_565rgb_horizontal_pixelmap_line_compressed_write(context, xstart, xend, y, info);
1150
        }
1151
        else
1152
        {
1153
            /* no compression or alpha */
1154
4122
            _gx_display_driver_565rgb_horizontal_pixelmap_line_raw_write(context, xstart, xend, y, info);
1155
        }
1156
    }
1157
1158
    /* Data pointers goes to the end of full map, move it to the start again. */
1159
17818
    if (info -> current_pixel_ptr >= info -> pixelmap -> gx_pixelmap_data + info -> pixelmap -> gx_pixelmap_data_size)
1160
    {
1161
196
        info -> current_pixel_ptr = (GX_UBYTE *)info ->  pixelmap -> gx_pixelmap_data;
1162
196
        info -> current_aux_ptr = (GX_UBYTE *)info ->  pixelmap -> gx_pixelmap_aux_data;
1163
    }
1164
}