GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_565rgb_rotated_glyph_1bit_draw.c Lines: 109 109 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
        blend_func(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_565rgb_rotated_glyph_1bit_draw   PORTABLE C      */
52
/*                                                           6.1.3        */
53
/*  AUTHOR                                                                */
54
/*                                                                        */
55
/*    Kenneth Maxwell, Microsoft Corporation                              */
56
/*                                                                        */
57
/*  DESCRIPTION                                                           */
58
/*                                                                        */
59
/*    This functions draw monochrome font on 16bpp 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_pixel_blend]       Basic display driver pixel    */
78
/*                                            blend function              */
79
/*                                                                        */
80
/*  CALLED BY                                                             */
81
/*                                                                        */
82
/*    GUIX internal code                                                  */
83
/*                                                                        */
84
/*  RELEASE HISTORY                                                       */
85
/*                                                                        */
86
/*    DATE              NAME                      DESCRIPTION             */
87
/*                                                                        */
88
/*  12-31-2020     Kenneth Maxwell          Initial Version 6.1.3         */
89
/*                                                                        */
90
/**************************************************************************/
91
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)
92
{
93
/* GX_DISPLAY      *display;*/
94
GX_UBYTE *glyph_row;
95
GX_UBYTE *glyph_data;
96
UINT      row;
97
UINT      pixel_per_row;
98
UINT      pixel_in_first_byte;
99
2178
UINT      pixel_in_last_byte = 0;
100
USHORT    text_color;
101
UINT      y_height;
102
GX_UBYTE  alpha;
103
UINT      glyph_width;
104
USHORT   *put;
105
UINT      num_bytes;
106
UINT      num_bits;
107
USHORT   *line_start;
108
GX_UBYTE  mask, init_mask;
109
UINT      i;
110
GX_VALUE  rotated_map_offset_x;
111
GX_VALUE  rotated_map_offset_y;
112
GX_VALUE  rotated_draw_left;
113
GX_VALUE  rotated_draw_top;
114
115
#if defined(GX_BRUSH_ALPHA_SUPPORT)
116
GX_UBYTE brush_alpha;
117
INT      xval, yval;
118
VOID     (*blend_func)(GX_DRAW_CONTEXT *, INT, INT, GX_COLOR, GX_UBYTE);
119
120
2178
    brush_alpha = context -> gx_draw_context_brush.gx_brush_alpha;
121
122
2178
    if (brush_alpha == 0)
123
    {
124
97
        return;
125
    }
126
127
2081
    blend_func = _gx_display_driver_565rgb_pixel_blend;
128
#endif
129
2081
    text_color = (USHORT)context -> gx_draw_context_brush.gx_brush_line_color;
130
2081
    pixel_per_row = (UINT)(draw_area -> gx_rectangle_bottom - draw_area -> gx_rectangle_top + 1);
131
2081
    y_height = (UINT)(draw_area -> gx_rectangle_right - draw_area -> gx_rectangle_left + 1);
132
133
    /* Find the width of the glyph, in terms of bytes */
134
2081
    glyph_width = glyph -> gx_glyph_height;
135
136
    /* Make it byte-aligned. */
137
2081
    glyph_width = (glyph_width + 7) >> 3;
138
139
2081
    if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
140
    {
141
1579
        rotated_draw_left = draw_area -> gx_rectangle_top;
142
1579
        rotated_draw_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - draw_area -> gx_rectangle_right - 1);
143
144
1579
        rotated_map_offset_x = map_offset -> gx_point_y;
145
1579
        rotated_map_offset_y = (GX_VALUE)(glyph -> gx_glyph_width - map_offset -> gx_point_x - (GX_VALUE)y_height);
146
    }
147
    else
148
    {
149
502
        rotated_draw_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_display_offset_y - draw_area -> gx_rectangle_bottom - 1);
150
502
        rotated_draw_top = draw_area -> gx_rectangle_left;
151
152
502
        rotated_map_offset_x = (GX_VALUE)(glyph -> gx_glyph_height - map_offset -> gx_point_y - (GX_VALUE)pixel_per_row);
153
502
        rotated_map_offset_y = map_offset -> gx_point_x;
154
    }
155
156
    /* Compute the number of useful bytes from the glyph this routine is going to use.
157
       Because of map_offset, the first byte may contain pixel bits we don't need to draw;
158
       And the width of the draw_area may produce part of the last byte in the row to be ignored. */
159
2081
    num_bytes = (UINT)(((INT)rotated_map_offset_x + (INT)pixel_per_row + 7) >> 3);
160
161
    /* Take into account if map_offset specifies the number of bytes to ignore from the beginning of the row. */
162
2081
    num_bytes -= ((UINT)(rotated_map_offset_x)) >> 3;
163
164
    /* Compute the number of pixels to draw from the first byte of the glyph data. */
165
2081
    pixel_in_first_byte = (UINT)(8 - ((rotated_map_offset_x) & 0x7));
166
2081
    init_mask = (GX_UBYTE)(1 << (pixel_in_first_byte - 1));
167
168
    /* Compute the number of pixels to draw from the last byte, if there are more than one byte in a row. */
169
2081
    if (num_bytes != 1)
170
    {
171
1624
        pixel_in_last_byte = ((UINT)rotated_map_offset_x + pixel_per_row) & 0x7;
172
1624
        if (pixel_in_last_byte == 0)
173
        {
174
3
            pixel_in_last_byte = 8;
175
        }
176
    }
177
    else
178
    {
179
457
        pixel_in_first_byte = pixel_per_row;
180
    }
181
182
183
2081
    glyph_row = (GX_UBYTE *)glyph -> gx_glyph_map;
184
185
2081
    if (rotated_map_offset_y)
186
    {
187
146
        glyph_row = (GX_UBYTE *)(glyph_row + ((INT)glyph_width * (INT)(rotated_map_offset_y)));
188
    }
189
190
2081
    glyph_row += (rotated_map_offset_x >> 3);
191
192
2081
    line_start = (USHORT *)context -> gx_draw_context_memory;
193
2081
    line_start += context -> gx_draw_context_pitch * (rotated_draw_top);
194
2081
    line_start += rotated_draw_left;
195
196
#if defined(GX_BRUSH_ALPHA_SUPPORT)
197
2081
    if (brush_alpha != 0xff)
198
    {
199
97
        yval = rotated_draw_top;
200
1451
        for (row = 0; row < y_height; row++)
201
        {
202
1354
            xval = rotated_draw_left;
203
1354
            glyph_data = glyph_row;
204
1354
            alpha = *(glyph_data);
205
1354
            mask = init_mask;
206
1354
            num_bits = pixel_in_first_byte;
207
4467
            for (i = 0; i < num_bytes; i++)
208
            {
209

3113
                if ((i == (num_bytes - 1)) && (num_bytes > 1))
210
                {
211
1162
                    num_bits = pixel_in_last_byte;
212
                }
213


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

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


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