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

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