GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_32bpp_rotated_glyph_1bit_draw.c Lines: 109 109 100.0 %
Date: 2024-12-05 08:52:37 Branches: 79 79 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_rotated_glyph_1bit_draw    PORTABLE C      */
52
/*                                                           6.1.5        */
53
/*  AUTHOR                                                                */
54
/*                                                                        */
55
/*    Kenneth Maxwell, Microsoft Corporation                              */
56
/*                                                                        */
57
/*  DESCRIPTION                                                           */
58
/*                                                                        */
59
/*    This functions draw monochrome font on 32bpp rotated canvas,        */
60
/*    clipped to 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                               */
78
/*                                                                        */
79
/*  CALLED BY                                                             */
80
/*                                                                        */
81
/*    GUIX Internal code                                                  */
82
/*                                                                        */
83
/*  RELEASE HISTORY                                                       */
84
/*                                                                        */
85
/*    DATE              NAME                      DESCRIPTION             */
86
/*                                                                        */
87
/*  02-02-2021     Kenneth Maxwell          Initial Version 6.1.4         */
88
/*  03-02-2021     Ting Zhu                 Modified comment(s), changed  */
89
/*                                            blend function set macro,   */
90
/*                                            resulting in version 6.1.5  */
91
/*                                                                        */
92
/**************************************************************************/
93
3417
VOID _gx_display_driver_32bpp_rotated_glyph_1bit_draw(GX_DRAW_CONTEXT *context, GX_RECTANGLE *draw_area, GX_POINT *map_offset, GX_CONST GX_GLYPH *glyph)
94
{
95
GX_UBYTE *glyph_row;
96
GX_UBYTE *glyph_data;
97
UINT      row;
98
UINT      pixel_per_row;
99
UINT      pixel_in_first_byte;
100
3417
UINT      pixel_in_last_byte = 0;
101
GX_COLOR  text_color;
102
UINT      y_height;
103
GX_UBYTE  alpha;
104
UINT      glyph_width;
105
UINT     *put;
106
UINT      num_bytes;
107
UINT      num_bits;
108
UINT     *line_start;
109
GX_UBYTE  mask, init_mask;
110
UINT      i;
111
GX_VALUE  rotated_map_offset_x;
112
GX_VALUE  rotated_map_offset_y;
113
GX_VALUE  rotated_draw_left;
114
GX_VALUE  rotated_draw_top;
115
116
#if defined(GX_BRUSH_ALPHA_SUPPORT)
117
GX_UBYTE brush_alpha;
118
INT      xval, yval;
119
VOID   (*blend_func)(GX_DRAW_CONTEXT * context, INT x, INT y, GX_COLOR fcolor, GX_UBYTE alpha);
120
121
3417
    brush_alpha = context -> gx_draw_context_brush.gx_brush_alpha;
122
3417
    if (brush_alpha == 0)
123
    {
124
97
        return;
125
    }
126
127
3320
    GX_SET_32BPP_BLEND_FUNCTION(blend_func, context->gx_draw_context_display->gx_display_color_format);
128
#endif
129
130
2474
    text_color = context -> gx_draw_context_brush.gx_brush_line_color;
131
2474
    pixel_per_row = (UINT)(draw_area -> gx_rectangle_bottom - draw_area -> gx_rectangle_top + 1);
132
2474
    y_height = (UINT)(draw_area -> gx_rectangle_right - draw_area -> gx_rectangle_left + 1);
133
134
    /* Find the width of the glyph, in terms of bytes.  */
135
2474
    glyph_width = glyph -> gx_glyph_height;
136
137
    /* Make it byte-aligned.  */
138
2474
    glyph_width = (glyph_width + 7) >> 3;
139
140
2474
    if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
141
    {
142
1750
        rotated_draw_left = draw_area -> gx_rectangle_top;
143
1750
        rotated_draw_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - draw_area -> gx_rectangle_right - 1);
144
145
1750
        rotated_map_offset_x = map_offset -> gx_point_y;
146
1750
        rotated_map_offset_y = (GX_VALUE)(glyph -> gx_glyph_width - map_offset -> gx_point_x - (GX_VALUE)y_height);
147
    }
148
    else
149
    {
150
724
        rotated_draw_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_display_offset_y - draw_area -> gx_rectangle_bottom - 1);
151
724
        rotated_draw_top = draw_area -> gx_rectangle_left;
152
153
724
        rotated_map_offset_x = (GX_VALUE)(glyph -> gx_glyph_height - map_offset -> gx_point_y - (GX_VALUE)pixel_per_row);
154
724
        rotated_map_offset_y = map_offset -> gx_point_x;
155
    }
156
157
    /* Compute the number of useful bytes from the glyph this routine is going to use.
158
       Because of map_offset, the first byte may contain pixel bits we don't need to draw;
159
       And the width of the draw_area may produce part of the last byte in the row to be ignored.  */
160
2474
    num_bytes = (UINT)(((UINT)rotated_map_offset_x + pixel_per_row + 7) >> 3);
161
162
    /* Take into account if map_offset specifies the number of bytes to ignore from the beginning of the row.  */
163
2474
    num_bytes = num_bytes - (((UINT)rotated_map_offset_x) >> 3);
164
165
    /* Compute the number of pixels to draw from the first byte of the glyph data.  */
166
2474
    pixel_in_first_byte = 8 - (UINT)(rotated_map_offset_x & 0x7);
167
2474
    init_mask = (GX_UBYTE)(1 << (pixel_in_first_byte - 1));
168
169
    /* Compute the number of pixels to draw from the last byte, if there are more than one byte in a row.  */
170
2474
    if (num_bytes != 1)
171
    {
172
1773
        pixel_in_last_byte = (((UINT)rotated_map_offset_x + pixel_per_row) & 0x7);
173
1773
        if (pixel_in_last_byte == 0)
174
        {
175
2
            pixel_in_last_byte = 8;
176
        }
177
    }
178
    else
179
    {
180
701
        pixel_in_first_byte = pixel_per_row;
181
    }
182
183
2474
    glyph_row = (GX_UBYTE *)glyph -> gx_glyph_map;
184
185
2474
    if (rotated_map_offset_y)
186
    {
187
26
        glyph_row = glyph_row + ((INT)glyph_width * (INT)rotated_map_offset_y);
188
    }
189
190
2474
    glyph_row += (rotated_map_offset_x >> 3);
191
192
#if defined(GX_BRUSH_ALPHA_SUPPORT)
193
2474
    if (brush_alpha != 0xff)
194
    {
195
115
        yval = rotated_draw_top;
196
1657
        for (row = 0; row < y_height; row++)
197
        {
198
1542
            xval = rotated_draw_left;
199
1542
            glyph_data = glyph_row;
200
1542
            alpha = *(glyph_data);
201
1542
            mask = init_mask;
202
1542
            num_bits = pixel_in_first_byte;
203
5013
            for (i = 0; i < num_bytes; i++)
204
            {
205

3471
                if ((i == (num_bytes - 1)) && (num_bytes > 1))
206
                {
207
1332
                    num_bits = pixel_in_last_byte;
208
                }
209


3471
                switch (num_bits)
210
                {
211
1849
                case 8:
212
1849
                    BLEND_PIXEL;
213
                /* fallthrough */
214
2306
                case 7:
215
2306
                    BLEND_PIXEL;
216
                /* fallthrough */
217
2368
                case 6:
218
2368
                    BLEND_PIXEL;
219
                /* fallthrough */
220
2622
                case 5:
221
2622
                    BLEND_PIXEL;
222
                /* fallthrough */
223
3273
                case 4:
224
3273
                    BLEND_PIXEL;
225
                /* fallthrough */
226
3333
                case 3:
227
3333
                    BLEND_PIXEL;
228
                /* fallthrough */
229
3411
                case 2:
230
3411
                    BLEND_PIXEL;
231
                /* fallthrough */
232
3471
                default:
233
3471
                    if (alpha & mask)
234
                    {
235
1318
                        blend_func(context, xval, yval, text_color, brush_alpha);
236
                    }
237
3471
                    xval++;
238
3471
                    break;
239
                }
240
3471
                glyph_data++;
241
3471
                alpha = *(glyph_data);
242
3471
                num_bits = 8;
243
3471
                mask = 0x80;
244
            }
245
246
1542
            glyph_row += glyph_width;
247
1542
            yval++;
248
        }
249
    }
250
    else
251
    {
252
#endif
253
2359
        line_start = (UINT *)context -> gx_draw_context_memory;
254
2359
        line_start += context -> gx_draw_context_pitch * (rotated_draw_top);
255
2359
        line_start += rotated_draw_left;
256
257
27740
        for (row = 0; row < y_height; row++)
258
        {
259
25381
            glyph_data = glyph_row;
260
25381
            alpha = *(glyph_data);
261
25381
            mask = init_mask;
262
25381
            num_bits = pixel_in_first_byte;
263
25381
            put = line_start;
264
70674
            for (i = 0; i < num_bytes; i++)
265
            {
266

45293
                if ((i == (num_bytes - 1)) && (num_bytes > 1))
267
                {
268
18184
                    num_bits = pixel_in_last_byte;
269
                }
270


45293
                switch (num_bits)
271
                {
272
19513
                case 8:
273
19513
                    DRAW_PIXEL;
274
                /* fallthrough */
275
20290
                case 7:
276
20290
                    DRAW_PIXEL;
277
                /* fallthrough */
278
20367
                case 6:
279
20367
                    DRAW_PIXEL;
280
                /* fallthrough */
281
36225
                case 5:
282
36225
                    DRAW_PIXEL;
283
                /* fallthrough */
284
37547
                case 4:
285
37547
                    DRAW_PIXEL;
286
                /* fallthrough */
287
38172
                case 3:
288
38172
                    DRAW_PIXEL;
289
                /* fallthrough */
290
41448
                case 2:
291
41448
                    DRAW_PIXEL;
292
                /* fallthrough */
293
45293
                default:
294
45293
                    if (alpha & mask)
295
                    {
296
18010
                        *put = text_color;
297
                    }
298
45293
                    put++;
299
45293
                    break;
300
                }
301
45293
                glyph_data++;
302
45293
                alpha = *(glyph_data);
303
45293
                num_bits = 8;
304
45293
                mask = 0x80;
305
            }
306
307
25381
            glyph_row += glyph_width;
308
25381
            line_start += context -> gx_draw_context_pitch;
309
        }
310
#if defined(GX_BRUSH_ALPHA_SUPPORT)
311
    }
312
#endif
313
2474
    return;
314
}
315