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

1451592
                if ((i == (num_bytes - 1)) && (num_bytes > 1))
194
                {
195
219201
                    num_bits = pixel_in_last_byte;
196
                }
197


1451592
                switch (num_bits)
198
                {
199
485217
                case 8:
200
485217
                    BLEND_PIXEL;
201
                    /* fallthrough */
202
787293
                case 7:
203
787293
                    BLEND_PIXEL;
204
                    /* fallthrough */
205
916077
                case 6:
206
916077
                    BLEND_PIXEL;
207
                    /* fallthrough */
208
984654
                case 5:
209
984654
                    BLEND_PIXEL;
210
                    /* fallthrough */
211
1085868
                case 4:
212
1085868
                    BLEND_PIXEL;
213
                    /* fallthrough */
214
1175097
                case 3:
215
1175097
                    BLEND_PIXEL;
216
                    /* fallthrough */
217
1282077
                case 2:
218
1282077
                    BLEND_PIXEL;
219
                    /* fallthrough */
220
1451592
                default:
221
1451592
                    if (alpha & mask)
222
                    {
223
514418
                        _gx_display_driver_24xrgb_pixel_blend(context, xval, yval, text_color, brush_alpha);
224
                    }
225
1451592
                    xval++;
226
1451592
                    break;
227
                }
228
1451592
                num_bits = 8;
229
1451592
                mask = 0x80;
230
            }
231
232
1232391
            glyph_row += glyph_width;
233
1232391
            yval++;
234
        }
235
    }
236
    else
237
    {
238
#endif
239
152537
        line_start = (UINT *)context -> gx_draw_context_memory;
240
152537
        line_start += context -> gx_draw_context_pitch * (draw_area -> gx_rectangle_top);
241
152537
        line_start += draw_area -> gx_rectangle_left;
242
243
1469944
        for (row = 0; row < y_height; row++)
244
        {
245
1317407
            glyph_data = glyph_row;
246
1317407
            mask = init_mask;
247
1317407
            num_bits = pixel_in_first_byte;
248
1317407
            put = line_start;
249
2865400
            for (i = 0; i < num_bytes; i++)
250
            {
251
1547993
                alpha = *(glyph_data++);
252
253

1547993
                if ((i == (num_bytes - 1)) && (num_bytes > 1))
254
                {
255
228874
                    num_bits = pixel_in_last_byte;
256
                }
257


1547993
                switch (num_bits)
258
                {
259
526841
                case 8:
260
526841
                    DRAW_PIXEL;
261
                    /* fallthrough */
262
860691
                case 7:
263
860691
                    DRAW_PIXEL;
264
                    /* fallthrough */
265
991867
                case 6:
266
991867
                    DRAW_PIXEL;
267
                    /* fallthrough */
268
1066358
                case 5:
269
1066358
                    DRAW_PIXEL;
270
                    /* fallthrough */
271
1168745
                case 4:
272
1168745
                    DRAW_PIXEL;
273
                    /* fallthrough */
274
1258658
                case 3:
275
1258658
                    DRAW_PIXEL;
276
                    /* fallthrough */
277
1377185
                case 2:
278
1377185
                    DRAW_PIXEL;
279
                    /* fallthrough */
280
1547993
                default:
281
1547993
                    if (alpha & mask)
282
                    {
283
550862
                        *put = text_color;
284
                    }
285
1547993
                    put++;
286
1547993
                    break;
287
                }
288
1547993
                num_bits = 8;
289
1547993
                mask = 0x80;
290
            }
291
292
1317407
            glyph_row += glyph_width;
293
1317407
            line_start += context -> gx_draw_context_pitch;
294
        }
295
#if defined (GX_BRUSH_ALPHA_SUPPORT)
296
    }
297
#endif
298
297799
    return;
299
}
300