GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_generic_rotated_glyph_4bit_draw.c Lines: 110 110 100.0 %
Date: 2026-03-06 19:21:09 Branches: 44 44 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
/**************************************************************************/
33
/*                                                                        */
34
/*  FUNCTION                                               RELEASE        */
35
/*                                                                        */
36
/*    _gx_display_driver_generic_rotated_glyph_4bit_draw  PORTABLE C      */
37
/*                                                           6.1.3        */
38
/*  AUTHOR                                                                */
39
/*                                                                        */
40
/*    Kenneth Maxwell, Microsoft Corporation                              */
41
/*                                                                        */
42
/*  DESCRIPTION                                                           */
43
/*                                                                        */
44
/*    This function draws the specified text using the current context,   */
45
/*    clipped to one viewport                                             */
46
/*                                                                        */
47
/*  INPUT                                                                 */
48
/*                                                                        */
49
/*    context                               Draw context                  */
50
/*    draw_area                             The rectangle where the glyph */
51
/*                                            is drawn to                 */
52
/*    map_offset                            Offset from the glyph map     */
53
/*    glyph                                 The glyph structure           */
54
/*                                                                        */
55
/*  OUTPUT                                                                */
56
/*                                                                        */
57
/*    None                                                                */
58
/*                                                                        */
59
/*  CALLS                                                                 */
60
/*                                                                        */
61
/*    [gx_display_driver_pixel_blend]       Call display driver pixel     */
62
/*                                            blend function              */
63
/*                                                                        */
64
/*  CALLED BY                                                             */
65
/*                                                                        */
66
/*    GUIX internal code                                                  */
67
/*                                                                        */
68
/**************************************************************************/
69
439742
VOID _gx_display_driver_generic_rotated_glyph_4bit_draw(GX_DRAW_CONTEXT *context, GX_RECTANGLE *draw_area, GX_POINT *map_offset, GX_CONST GX_GLYPH *glyph)
70
{
71
GX_UBYTE *glyph_row;
72
GX_UBYTE *glyph_data;
73
UINT      row;
74
UINT      col;
75
439742
UINT      pixel_width = 0;
76
UINT      leading_pixel;
77
UINT      trailing_pixel;
78
GX_COLOR  text_color;
79
UINT      y_height;
80
GX_UBYTE  alpha;
81
UINT      pitch;
82
UINT      index;
83
VOID      (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR color, GX_UBYTE alpha);
84
439742
GX_UBYTE  brush_alpha = 0xff;
85
GX_VALUE  rotated_map_offset_x;
86
GX_VALUE  rotated_map_offset_y;
87
GX_VALUE  rotated_left;
88
GX_VALUE  rotated_top;
89
90
#if defined(GX_BRUSH_ALPHA_SUPPORT)
91
INT alpha_sum;
92
439742
    brush_alpha = context -> gx_draw_context_brush.gx_brush_alpha;
93
439742
    if (brush_alpha == 0)
94
    {
95
208
        return;
96
    }
97
#endif
98
99
439534
    text_color = context -> gx_draw_context_brush.gx_brush_line_color;
100
101
439534
    y_height = (UINT)(draw_area -> gx_rectangle_right - draw_area -> gx_rectangle_left + 1);
102
103
    /* Find the width of the glyph */
104
439534
    pitch = glyph -> gx_glyph_height;
105
    /* Make it byte-aligned. */
106
439534
    pitch = (pitch + 1) >> 1;
107
108
439534
    pixel_width = (UINT)(draw_area -> gx_rectangle_bottom - draw_area -> gx_rectangle_top + 1);
109
110
439534
    if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
111
    {
112
269594
        rotated_left = draw_area -> gx_rectangle_top;
113
269594
        rotated_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - draw_area -> gx_rectangle_right - 1);
114
115
269594
        rotated_map_offset_x = map_offset -> gx_point_y;
116
269594
        rotated_map_offset_y = (GX_VALUE)(glyph -> gx_glyph_width - map_offset -> gx_point_x - (GX_VALUE)y_height);
117
    }
118
    else
119
    {
120
169940
        rotated_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_display_offset_y - draw_area -> gx_rectangle_bottom - 1);
121
169940
        rotated_top = draw_area -> gx_rectangle_left;
122
123
169940
        rotated_map_offset_x = (GX_VALUE)(glyph -> gx_glyph_height - map_offset -> gx_point_y - (GX_VALUE)pixel_width);
124
169940
        rotated_map_offset_y = map_offset -> gx_point_x;
125
    }
126
127
439534
    glyph_row = (GX_UBYTE *)glyph -> gx_glyph_map;
128
129
439534
    if (rotated_map_offset_y)
130
    {
131
4469
        glyph_row = glyph_row + ((INT)pitch * rotated_map_offset_y);
132
    }
133
134
439534
    glyph_row += (rotated_map_offset_x >> 1);
135
136

439534
    GX_SET_BLEND_FUNCTION(blend_func, context -> gx_draw_context_display -> gx_display_color_format)
137
138
435955
    leading_pixel = (rotated_map_offset_x & 1);
139
140
435955
    pixel_width -= leading_pixel;
141
142
435955
    trailing_pixel = pixel_width & 1;
143
144
435955
    pixel_width = pixel_width >> 1;
145
146
435955
    if (brush_alpha == 0xff)
147
    {
148
4000082
        for (row = 0; row < y_height; row++)
149
        {
150
3564457
            col = 0;
151
3564457
            glyph_data = glyph_row;
152
153
3564457
            if (leading_pixel)
154
            {
155
264
                alpha = (*glyph_data) & 0x0f;
156
264
                alpha = (GX_UBYTE)(alpha | (GX_UBYTE)(alpha << 4));
157
158
264
                if (alpha > 0)
159
                {
160
90
                    blend_func(context,
161
90
                               rotated_left + (GX_VALUE)col,
162
90
                               rotated_top + (GX_VALUE)row,
163
                               text_color, (GX_UBYTE)alpha);
164
                }
165
264
                col++;
166
264
                glyph_data++;
167
            }
168
169
23758290
            for (index = 0; index < pixel_width; index++)
170
            {
171
20193833
                alpha = (*glyph_data) & 0xf0;
172
20193833
                alpha = (GX_UBYTE)(alpha | (GX_UBYTE)(alpha >> 4));
173
174
20193833
                if (alpha > 0)
175
                {
176
12944637
                    blend_func(context,
177
12944637
                               rotated_left + (GX_VALUE)col,
178
12944637
                               rotated_top + (GX_VALUE)row,
179
                               text_color, (GX_UBYTE)alpha);
180
                }
181
20193833
                col++;
182
183
20193833
                alpha = (*glyph_data) & 0x0f;
184
20193833
                alpha = (GX_UBYTE)(alpha | (GX_UBYTE)(alpha << 4));
185
186
20193833
                if (alpha > 0)
187
                {
188
12974027
                    blend_func(context,
189
12974027
                               rotated_left + (GX_VALUE)col,
190
12974027
                               rotated_top + (GX_VALUE)row,
191
                               text_color, (GX_UBYTE)alpha);
192
                }
193
20193833
                col++;
194
20193833
                glyph_data++;
195
            }
196
197
3564457
            if (trailing_pixel)
198
            {
199
724949
                alpha = (*glyph_data) & 0xf0;
200
724949
                alpha = (GX_UBYTE)(alpha | (GX_UBYTE)(alpha >> 4));
201
202
724949
                if (alpha > 0)
203
                {
204
407244
                    blend_func(context,
205
407244
                               rotated_left + (GX_VALUE)col,
206
407244
                               rotated_top + (GX_VALUE)row,
207
                               text_color, (GX_UBYTE)alpha);
208
                }
209
            }
210
3564457
            glyph_row += pitch;
211
        }
212
    }
213
#if defined(GX_BRUSH_ALPHA_SUPPORT)
214
    else
215
    {
216
4804
        for (row = 0; row < y_height; row++)
217
        {
218
4474
            col = 0;
219
4474
            glyph_data = glyph_row;
220
221
4474
            if (leading_pixel)
222
            {
223
218
                alpha = (*glyph_data) & 0x0f;
224
218
                alpha = (GX_UBYTE)(alpha | (GX_UBYTE)(alpha << 4));
225
226
218
                alpha_sum = alpha * brush_alpha / 255;
227
228
218
                if (alpha_sum > 0)
229
                {
230
77
                    blend_func(context,
231
77
                               rotated_left + (GX_VALUE)col,
232
77
                               rotated_top + (GX_VALUE)row,
233
77
                               text_color, (GX_UBYTE)alpha_sum);
234
                }
235
218
                col++;
236
218
                glyph_data++;
237
            }
238
239
35502
            for (index = 0; index < pixel_width; index++)
240
            {
241
31028
                alpha = (*glyph_data) & 0xf0;
242
31028
                alpha = (GX_UBYTE)(alpha | (GX_UBYTE)(alpha >> 4));
243
31028
                alpha_sum = alpha * brush_alpha / 255;
244
245
31028
                if (alpha_sum > 0)
246
                {
247
13097
                    blend_func(context,
248
13097
                               rotated_left + (GX_VALUE)col,
249
13097
                               rotated_top + (GX_VALUE)row,
250
13097
                               text_color, (GX_UBYTE)alpha_sum);
251
                }
252
31028
                col++;
253
254
31028
                alpha = (*glyph_data) & 0x0f;
255
31028
                alpha = (GX_UBYTE)(alpha | (GX_UBYTE)(alpha << 4));
256
31028
                alpha_sum = alpha * brush_alpha / 255;
257
258
31028
                if (alpha_sum > 0)
259
                {
260
12942
                    blend_func(context,
261
12942
                               rotated_left + (GX_VALUE)col,
262
12942
                               rotated_top + (GX_VALUE)row,
263
12942
                               text_color, (GX_UBYTE)alpha_sum);
264
                }
265
31028
                col++;
266
31028
                glyph_data++;
267
            }
268
269
4474
            if (trailing_pixel)
270
            {
271
2098
                alpha = (*glyph_data) & 0xf0;
272
2098
                alpha = (GX_UBYTE)(alpha | (GX_UBYTE)(alpha >> 4));
273
2098
                alpha_sum = alpha * brush_alpha / 255;
274
275
2098
                if (alpha_sum > 0)
276
                {
277
1144
                    blend_func(context,
278
1144
                               rotated_left + (GX_VALUE)col,
279
1144
                               rotated_top + (GX_VALUE)row,
280
1144
                               text_color, (GX_UBYTE)alpha_sum);
281
                }
282
            }
283
4474
            glyph_row += pitch;
284
        }
285
    }
286
#endif
287
}
288