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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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