GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_8bpp_glyph_1bit_draw.c Lines: 102 102 100.0 %
Date: 2024-12-05 08:52:37 Branches: 78 78 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_system.h"
28
#include "gx_utility.h"
29
#include "gx_display.h"
30
31
#define DRAW_PIXEL if (alpha & mask) \
32
    {                                \
33
        *put = text_color;           \
34
    }                                \
35
    put++;                           \
36
    mask = mask >> 1;
37
38
39
#if defined (GX_BRUSH_ALPHA_SUPPORT)
40
#define BLEND_PIXEL if (alpha & mask)                                                        \
41
    {                                                                                        \
42
        blend_func(context, xval, yval, text_color, brush_alpha);                            \
43
    }                                                                                        \
44
    xval++;                                                                                  \
45
    mask = mask >> 1;
46
#endif
47
48
/**************************************************************************/
49
/*                                                                        */
50
/*  FUNCTION                                               RELEASE        */
51
/*                                                                        */
52
/*    _gx_display_driver_8bpp_glyph_1bit_draw             PORTABLE C      */
53
/*                                                           6.1.11       */
54
/*  AUTHOR                                                                */
55
/*                                                                        */
56
/*    Kenneth Maxwell, Microsoft Corporation                              */
57
/*                                                                        */
58
/*  DESCRIPTION                                                           */
59
/*                                                                        */
60
/*    This function draws monochrome font to the 8bpp canvas, clipped     */
61
/*    to one viweport.                                                    */
62
/*                                                                        */
63
/*  INPUT                                                                 */
64
/*                                                                        */
65
/*    context                               Draw context                  */
66
/*    draw_area                             The region bound by the       */
67
/*                                            rectangle where the glyph   */
68
/*                                            is drawn                    */
69
/*    map_offset                            X,Y offset into the glyph map */
70
/*    glyph                                 Pointer to the glyph          */
71
/*                                                                        */
72
/*  OUTPUT                                                                */
73
/*                                                                        */
74
/*    None                                                                */
75
/*                                                                        */
76
/*  CALLS                                                                 */
77
/*                                                                        */
78
/*    [gx_display_driver_pixel_blend]       Basic display driver pixel    */
79
/*                                            blend function              */
80
/*                                                                        */
81
/*  CALLED BY                                                             */
82
/*                                                                        */
83
/*    GUIX internal code                                                  */
84
/*                                                                        */
85
/*  RELEASE HISTORY                                                       */
86
/*                                                                        */
87
/*    DATE              NAME                      DESCRIPTION             */
88
/*                                                                        */
89
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
90
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
91
/*                                            resulting in version 6.1    */
92
/*  04-25-2022     Ting Zhu                 Modified comment(s),          */
93
/*                                            fixed access violation bug, */
94
/*                                            resulting in version 6.1.11 */
95
/*                                                                        */
96
/**************************************************************************/
97
1150498
VOID _gx_display_driver_8bpp_glyph_1bit_draw(GX_DRAW_CONTEXT *context, GX_RECTANGLE *draw_area, GX_POINT *map_offset, GX_CONST GX_GLYPH *glyph)
98
{
99
/* GX_DISPLAY      *display;*/
100
GX_UBYTE *glyph_row;
101
GX_UBYTE *glyph_data;
102
UINT      row;
103
UINT      pixel_per_row;
104
UINT      pixel_in_first_byte;
105
1150498
UINT      pixel_in_last_byte = 0;
106
GX_UBYTE  text_color;
107
UINT      y_height;
108
GX_UBYTE  alpha;
109
UINT      glyph_width;
110
GX_UBYTE *put;
111
UINT      num_bytes;
112
UINT      num_bits;
113
GX_UBYTE *line_start;
114
GX_UBYTE  mask, init_mask;
115
UINT      i;
116
1150498
GX_UBYTE  brush_alpha = 0xff;
117
#if defined (GX_BRUSH_ALPHA_SUPPORT)
118
INT       xval, yval;
119
VOID    (*blend_func)(GX_DRAW_CONTEXT *, INT, INT, GX_COLOR, GX_UBYTE);
120
121
1150498
    brush_alpha = context -> gx_draw_context_brush.gx_brush_alpha;
122
1150498
    blend_func = context -> gx_draw_context_display -> gx_display_driver_pixel_blend;
123
124
1150498
    if (blend_func == GX_NULL)
125
    {
126
        /* Pixel blend function is null means alpha isn't supported in this driver.
127
        So set alpha value to 0xff to make it draw the original color in case GX_BRUSH_ALPHA_SUPPORT is defined. */
128
804583
        brush_alpha = 0xff;
129
    }
130
    else
131
    {
132
345915
        if (brush_alpha == 0)
133
2880
            return;
134
    }
135
#endif
136
1147618
    text_color =  (GX_UBYTE)context -> gx_draw_context_brush.gx_brush_line_color;
137
1147618
    pixel_per_row = (UINT)draw_area -> gx_rectangle_right - (UINT)draw_area -> gx_rectangle_left + (UINT)1;
138
139
    /* pickup pointer to current dispaly driver */
140
    /*display = context -> gx_draw_context_display;*/
141
142
    /* Find the width of the glyph, in terms of bytes */
143
1147618
    glyph_width = glyph -> gx_glyph_width;
144
    /* Make it byte-aligned. */
145
1147618
    glyph_width = (glyph_width + 7) >> 3;
146
147
    /* Compute the number of useful bytes from the glyph this routine is going to use.
148
       Because of map_offset, the first byte may contain pixel bits we don't need to draw;
149
       And the width of the draw_area may produce part of the last byte in the row to be ignored. */
150
1147618
    num_bytes = ((UINT)map_offset -> gx_point_x + pixel_per_row + 7) >> 3;
151
    /* Take into account if map_offset specifies the number of bytes to ignore from the beginning of the row. */
152
1147618
    num_bytes -= (UINT)(map_offset -> gx_point_x) >> 3;
153
154
    /* Compute the number of pixels to draw from the first byte of the glyph data. */
155
1147618
    pixel_in_first_byte = (UINT)(8 - ((map_offset -> gx_point_x) & 0x7));
156
1147618
    init_mask = (GX_UBYTE)(1 << (pixel_in_first_byte - 1));
157
    /* Compute the number of pixels to draw from the last byte, if there are more than one byte in a row. */
158
1147618
    if (num_bytes != 1)
159
    {
160
335105
        pixel_in_last_byte = (map_offset -> gx_point_x + (INT)pixel_per_row) & 0x7;
161
335105
        if (pixel_in_last_byte == 0)
162
        {
163
1
            pixel_in_last_byte = 8;
164
        }
165
    }
166
    else
167
    {
168
812513
        if ((map_offset -> gx_point_x + (INT)pixel_per_row) < 8)
169
        {
170
561609
            pixel_in_first_byte = pixel_per_row;
171
        }
172
        else
173
        {
174
250904
            pixel_in_last_byte = 0;
175
        }
176
    }
177
178
179
1147618
    glyph_row = (GX_UBYTE *)glyph -> gx_glyph_map;
180
181
1147618
    if (map_offset -> gx_point_y)
182
    {
183
3273
        glyph_row = glyph_row + ((INT)glyph_width * map_offset -> gx_point_y);
184
    }
185
186
1147618
    glyph_row += (map_offset -> gx_point_x >> 3);
187
188
1147618
    y_height = (UINT)(draw_area -> gx_rectangle_bottom - draw_area -> gx_rectangle_top + 1);
189
190
1147618
    if (brush_alpha == 0xff)
191
    {
192
193
1144599
        line_start = (GX_UBYTE *)context -> gx_draw_context_memory;
194
1144599
        line_start += context -> gx_draw_context_pitch * (draw_area -> gx_rectangle_top);
195
1144599
        line_start += draw_area -> gx_rectangle_left;
196
197
13561453
        for (row = 0; row < y_height; row++)
198
        {
199
12416854
            glyph_data = glyph_row;
200
12416854
            mask = init_mask;
201
12416854
            num_bits = pixel_in_first_byte;
202
12416854
            put = line_start;
203
204
28771088
            for (i = 0; i < num_bytes; i++)
205
            {
206
16354234
                alpha = *(glyph_data++);
207
208

16354234
                if ((i == (num_bytes - 1)) && (num_bytes > 1))
209
                {
210
3924058
                    num_bits = pixel_in_last_byte;
211
                }
212


16354234
                switch (num_bits)
213
                {
214
6725530
                case 8:
215
6725530
                    DRAW_PIXEL;
216
                    /* fallthrough */
217
8243002
                case 7:
218
8243002
                    DRAW_PIXEL;
219
                    /* fallthrough */
220
9846821
                case 6:
221
9846821
                    DRAW_PIXEL;
222
                    /* fallthrough */
223
10119233
                case 5:
224
10119233
                    DRAW_PIXEL;
225
                    /* fallthrough */
226
10428073
                case 4:
227
10428073
                    DRAW_PIXEL;
228
                    /* fallthrough */
229
10739367
                case 3:
230
10739367
                    DRAW_PIXEL;
231
                    /* fallthrough */
232
14289033
                case 2:
233
14289033
                    DRAW_PIXEL;
234
                    /* fallthrough */
235
236
16354234
                default:
237
16354234
                    if (alpha & mask)
238
                    {
239
9105132
                        *put = text_color;
240
                    }
241
16354234
                    put++;
242
16354234
                    break;
243
                }
244
16354234
                num_bits = 8;
245
16354234
                mask = 0x80;
246
            }
247
248
12416854
            glyph_row += glyph_width;
249
12416854
            line_start += context -> gx_draw_context_pitch;
250
        }
251
    }
252
#if defined (GX_BRUSH_ALPHA_SUPPORT)
253
    else
254
    {
255
3019
        yval = draw_area -> gx_rectangle_top;
256
36627
        for (row = 0; row < y_height; row++)
257
        {
258
33608
            xval = draw_area -> gx_rectangle_left;
259
33608
            glyph_data = glyph_row;
260
33608
            mask = init_mask;
261
33608
            num_bits = pixel_in_first_byte;
262
76382
            for (i = 0; i < num_bytes; i++)
263
            {
264
42774
                alpha = *(glyph_data);
265

42774
                if ((i == (num_bytes - 1)) && (num_bytes > 1))
266
                {
267
9166
                    num_bits = pixel_in_last_byte;
268
                }
269


42774
                switch (num_bits)
270
                {
271
29231
                case 8:
272
29231
                    BLEND_PIXEL;
273
                    /* fallthrough */
274
29257
                case 7:
275
29257
                    BLEND_PIXEL;
276
                    /* fallthrough */
277
33531
                case 6:
278
33531
                    BLEND_PIXEL;
279
                    /* fallthrough */
280
33541
                case 5:
281
33541
                    BLEND_PIXEL;
282
                    /* fallthrough */
283
33853
                case 4:
284
33853
                    BLEND_PIXEL;
285
                    /* fallthrough */
286
34152
                case 3:
287
34152
                    BLEND_PIXEL;
288
                    /* fallthrough */
289
37760
                case 2:
290
37760
                    BLEND_PIXEL;
291
                    /* fallthrough */
292
42774
                default:
293
42774
                    if (alpha & mask)
294
                    {
295
16611
                        blend_func(context, xval, yval, text_color, brush_alpha);
296
                    }
297
42774
                    xval++;
298
42774
                    break;
299
                }
300
42774
                glyph_data++;
301
42774
                num_bits = 8;
302
42774
                mask = 0x80;
303
            }
304
305
33608
            glyph_row += glyph_width;
306
33608
            yval++;
307
        }
308
    }
309
#endif
310
1147618
    return;
311
}
312