GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_565rgb_rotated_glyph_1bit_draw.c Lines: 109 109 100.0 %
Date: 2026-03-06 19:21:09 Branches: 76 76 100.0 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 * Copyright (c) 2026-present Eclipse ThreadX contributors
4
 *
5
 * This program and the accompanying materials are made available under the
6
 * terms of the MIT License which is available at
7
 * https://opensource.org/licenses/MIT.
8
 *
9
 * SPDX-License-Identifier: MIT
10
 **************************************************************************/
11
12
13
/**************************************************************************/
14
/**************************************************************************/
15
/**                                                                       */
16
/** GUIX Component                                                        */
17
/**                                                                       */
18
/**   Display Management (Display)                                        */
19
/**                                                                       */
20
/**************************************************************************/
21
22
#define GX_SOURCE_CODE
23
24
25
/* Include necessary system files.  */
26
27
#include "gx_api.h"
28
#include "gx_system.h"
29
#include "gx_utility.h"
30
#include "gx_display.h"
31
32
#define DRAW_PIXEL  if (alpha & mask) \
33
    {                                 \
34
        *put = text_color;            \
35
    }                                 \
36
    put++;                            \
37
    mask = mask >> 1;
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_565rgb_rotated_glyph_1bit_draw   PORTABLE C      */
53
/*                                                           6.1.3        */
54
/*  AUTHOR                                                                */
55
/*                                                                        */
56
/*    Kenneth Maxwell, Microsoft Corporation                              */
57
/*                                                                        */
58
/*  DESCRIPTION                                                           */
59
/*                                                                        */
60
/*    This functions draw monochrome font on 16bpp canvas, clipped to     */
61
/*    one viewport.                                                       */
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
/**************************************************************************/
86
2178
VOID _gx_display_driver_565rgb_rotated_glyph_1bit_draw(GX_DRAW_CONTEXT *context, GX_RECTANGLE *draw_area, GX_POINT *map_offset, GX_CONST GX_GLYPH *glyph)
87
{
88
/* GX_DISPLAY      *display;*/
89
GX_UBYTE *glyph_row;
90
GX_UBYTE *glyph_data;
91
UINT      row;
92
UINT      pixel_per_row;
93
UINT      pixel_in_first_byte;
94
2178
UINT      pixel_in_last_byte = 0;
95
USHORT    text_color;
96
UINT      y_height;
97
GX_UBYTE  alpha;
98
UINT      glyph_width;
99
USHORT   *put;
100
UINT      num_bytes;
101
UINT      num_bits;
102
USHORT   *line_start;
103
GX_UBYTE  mask, init_mask;
104
UINT      i;
105
GX_VALUE  rotated_map_offset_x;
106
GX_VALUE  rotated_map_offset_y;
107
GX_VALUE  rotated_draw_left;
108
GX_VALUE  rotated_draw_top;
109
110
#if defined(GX_BRUSH_ALPHA_SUPPORT)
111
GX_UBYTE brush_alpha;
112
INT      xval, yval;
113
VOID     (*blend_func)(GX_DRAW_CONTEXT *, INT, INT, GX_COLOR, GX_UBYTE);
114
115
2178
    brush_alpha = context -> gx_draw_context_brush.gx_brush_alpha;
116
117
2178
    if (brush_alpha == 0)
118
    {
119
97
        return;
120
    }
121
122
2081
    blend_func = _gx_display_driver_565rgb_pixel_blend;
123
#endif
124
2081
    text_color = (USHORT)context -> gx_draw_context_brush.gx_brush_line_color;
125
2081
    pixel_per_row = (UINT)(draw_area -> gx_rectangle_bottom - draw_area -> gx_rectangle_top + 1);
126
2081
    y_height = (UINT)(draw_area -> gx_rectangle_right - draw_area -> gx_rectangle_left + 1);
127
128
    /* Find the width of the glyph, in terms of bytes */
129
2081
    glyph_width = glyph -> gx_glyph_height;
130
131
    /* Make it byte-aligned. */
132
2081
    glyph_width = (glyph_width + 7) >> 3;
133
134
2081
    if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
135
    {
136
1579
        rotated_draw_left = draw_area -> gx_rectangle_top;
137
1579
        rotated_draw_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - draw_area -> gx_rectangle_right - 1);
138
139
1579
        rotated_map_offset_x = map_offset -> gx_point_y;
140
1579
        rotated_map_offset_y = (GX_VALUE)(glyph -> gx_glyph_width - map_offset -> gx_point_x - (GX_VALUE)y_height);
141
    }
142
    else
143
    {
144
502
        rotated_draw_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_display_offset_y - draw_area -> gx_rectangle_bottom - 1);
145
502
        rotated_draw_top = draw_area -> gx_rectangle_left;
146
147
502
        rotated_map_offset_x = (GX_VALUE)(glyph -> gx_glyph_height - map_offset -> gx_point_y - (GX_VALUE)pixel_per_row);
148
502
        rotated_map_offset_y = map_offset -> gx_point_x;
149
    }
150
151
    /* Compute the number of useful bytes from the glyph this routine is going to use.
152
       Because of map_offset, the first byte may contain pixel bits we don't need to draw;
153
       And the width of the draw_area may produce part of the last byte in the row to be ignored. */
154
2081
    num_bytes = (UINT)(((INT)rotated_map_offset_x + (INT)pixel_per_row + 7) >> 3);
155
156
    /* Take into account if map_offset specifies the number of bytes to ignore from the beginning of the row. */
157
2081
    num_bytes -= ((UINT)(rotated_map_offset_x)) >> 3;
158
159
    /* Compute the number of pixels to draw from the first byte of the glyph data. */
160
2081
    pixel_in_first_byte = (UINT)(8 - ((rotated_map_offset_x) & 0x7));
161
2081
    init_mask = (GX_UBYTE)(1 << (pixel_in_first_byte - 1));
162
163
    /* Compute the number of pixels to draw from the last byte, if there are more than one byte in a row. */
164
2081
    if (num_bytes != 1)
165
    {
166
1624
        pixel_in_last_byte = ((UINT)rotated_map_offset_x + pixel_per_row) & 0x7;
167
1624
        if (pixel_in_last_byte == 0)
168
        {
169
3
            pixel_in_last_byte = 8;
170
        }
171
    }
172
    else
173
    {
174
457
        pixel_in_first_byte = pixel_per_row;
175
    }
176
177
178
2081
    glyph_row = (GX_UBYTE *)glyph -> gx_glyph_map;
179
180
2081
    if (rotated_map_offset_y)
181
    {
182
146
        glyph_row = (GX_UBYTE *)(glyph_row + ((INT)glyph_width * (INT)(rotated_map_offset_y)));
183
    }
184
185
2081
    glyph_row += (rotated_map_offset_x >> 3);
186
187
2081
    line_start = (USHORT *)context -> gx_draw_context_memory;
188
2081
    line_start += context -> gx_draw_context_pitch * (rotated_draw_top);
189
2081
    line_start += rotated_draw_left;
190
191
#if defined(GX_BRUSH_ALPHA_SUPPORT)
192
2081
    if (brush_alpha != 0xff)
193
    {
194
97
        yval = rotated_draw_top;
195
1451
        for (row = 0; row < y_height; row++)
196
        {
197
1354
            xval = rotated_draw_left;
198
1354
            glyph_data = glyph_row;
199
1354
            alpha = *(glyph_data);
200
1354
            mask = init_mask;
201
1354
            num_bits = pixel_in_first_byte;
202
4467
            for (i = 0; i < num_bytes; i++)
203
            {
204

3113
                if ((i == (num_bytes - 1)) && (num_bytes > 1))
205
                {
206
1162
                    num_bits = pixel_in_last_byte;
207
                }
208


3113
                switch (num_bits)
209
                {
210
1679
                case 8:
211
1679
                    BLEND_PIXEL;
212
                /* fallthrough */
213
2136
                case 7:
214
2136
                    BLEND_PIXEL;
215
                /* fallthrough */
216
2198
                case 6:
217
2198
                    BLEND_PIXEL;
218
                /* fallthrough */
219
2282
                case 5:
220
2282
                    BLEND_PIXEL;
221
                /* fallthrough */
222
2933
                case 4:
223
2933
                    BLEND_PIXEL;
224
                /* fallthrough */
225
2993
                case 3:
226
2993
                    BLEND_PIXEL;
227
                /* fallthrough */
228
3053
                case 2:
229
3053
                    BLEND_PIXEL;
230
                /* fallthrough */
231
3113
                default:
232
3113
                    if (alpha & mask)
233
                    {
234
1161
                        blend_func(context, xval, yval, text_color, brush_alpha);
235
                    }
236
3113
                    xval++;
237
3113
                    break;
238
                }
239
3113
                glyph_data++;
240
3113
                alpha = *(glyph_data);
241
3113
                num_bits = 8;
242
3113
                mask = 0x80;
243
            }
244
245
1354
            glyph_row += glyph_width;
246
1354
            yval++;
247
        }
248
    }
249
    else
250
    {
251
#endif
252
22650
        for (row = 0; row < y_height; row++)
253
        {
254
20666
            glyph_data = glyph_row;
255
20666
            alpha = *(glyph_data);
256
20666
            mask = init_mask;
257
20666
            num_bits = pixel_in_first_byte;
258
20666
            put = line_start;
259
59018
            for (i = 0; i < num_bytes; i++)
260
            {
261

38352
                if ((i == (num_bytes - 1)) && (num_bytes > 1))
262
                {
263
16034
                    num_bits = pixel_in_last_byte;
264
                }
265


38352
                switch (num_bits)
266
                {
267
17410
                case 8:
268
17410
                    DRAW_PIXEL;
269
                /* fallthrough */
270
18484
                case 7:
271
18484
                    DRAW_PIXEL;
272
                /* fallthrough */
273
18623
                case 6:
274
18623
                    DRAW_PIXEL;
275
                /* fallthrough */
276
32000
                case 5:
277
32000
                    DRAW_PIXEL;
278
                /* fallthrough */
279
33549
                case 4:
280
33549
                    DRAW_PIXEL;
281
                /* fallthrough */
282
33935
                case 3:
283
33935
                    DRAW_PIXEL;
284
                /* fallthrough */
285
36459
                case 2:
286
36459
                    DRAW_PIXEL;
287
                /* fallthrough */
288
38352
                default:
289
38352
                    if (alpha & mask)
290
                    {
291
15653
                        *put = text_color;
292
                    }
293
38352
                    put++;
294
38352
                    break;
295
                }
296
38352
                glyph_data++;
297
38352
                alpha = *(glyph_data);
298
38352
                num_bits = 8;
299
38352
                mask = 0x80;
300
            }
301
302
20666
            glyph_row += glyph_width;
303
20666
            line_start += context -> gx_draw_context_pitch;
304
        }
305
#if defined(GX_BRUSH_ALPHA_SUPPORT)
306
    }
307
#endif
308
2081
    return;
309
}
310