GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_4bpp_glyph_1bit_draw.c Lines: 70 70 100.0 %
Date: 2024-12-05 08:52:37 Branches: 58 58 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_4bpp_glyph_1bit_draw             PORTABLE C      */
36
/*                                                           6.1          */
37
/*  AUTHOR                                                                */
38
/*                                                                        */
39
/*    Kenneth Maxwell, Microsoft Corporation                              */
40
/*                                                                        */
41
/*  DESCRIPTION                                                           */
42
/*                                                                        */
43
/*    This function draws monochrome font to the 4bpp canvas, clipped     */
44
/*    to one viweport.                                                    */
45
/*                                                                        */
46
/*  INPUT                                                                 */
47
/*                                                                        */
48
/*    context                               Draw context                  */
49
/*    draw_area                             The region bound by the       */
50
/*                                            rectangle where the glyph   */
51
/*                                            is drawn                    */
52
/*    map_offset                            X,Y offset into the glyph map */
53
/*    glyph                                 Pointer to the glyph          */
54
/*                                                                        */
55
/*  OUTPUT                                                                */
56
/*                                                                        */
57
/*    None                                                                */
58
/*                                                                        */
59
/*  CALLS                                                                 */
60
/*                                                                        */
61
/*    None                                                                */
62
/*                                                                        */
63
/*  CALLED BY                                                             */
64
/*                                                                        */
65
/*    GUIX internal code                                                  */
66
/*                                                                        */
67
/*  RELEASE HISTORY                                                       */
68
/*                                                                        */
69
/*    DATE              NAME                      DESCRIPTION             */
70
/*                                                                        */
71
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
72
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
73
/*                                            resulting in version 6.1    */
74
/*                                                                        */
75
/**************************************************************************/
76
77
#define WRITE_PIXEL if (alpha & mask)                      \
78
    {                                                      \
79
        *put = *put & (GX_UBYTE)(~putmask);                \
80
        *put = *put | (GX_UBYTE)(text_color & putmask);    \
81
    }                                                      \
82
    putmask = putmask >> 4;                                \
83
    if (putmask == 0)                                      \
84
    {                                                      \
85
        putmask = 0xf0;                                    \
86
        put++;                                             \
87
    }
88
89
90
163700
VOID _gx_display_driver_4bpp_glyph_1bit_draw(GX_DRAW_CONTEXT *context, GX_RECTANGLE *draw_area, GX_POINT *map_offset, const GX_GLYPH *glyph)
91
{
92
GX_UBYTE *glyph_row;
93
GX_UBYTE *glyph_data;
94
UINT      row;
95
UINT      pixel_per_row;
96
UINT      pixel_in_first_byte;
97
163700
UINT      pixel_in_last_byte = 0;
98
GX_UBYTE  text_color;
99
UINT      y_height;
100
GX_UBYTE  alpha;
101
UINT      glyph_width;
102
GX_UBYTE *put;
103
UINT      num_bytes;
104
UINT      num_bits;
105
GX_UBYTE *line_start;
106
GX_UBYTE  mask, init_mask;
107
UINT      i;
108
GX_UBYTE  putmask;
109
INT       putstride;
110
111
163700
    text_color =  (GX_UBYTE)context -> gx_draw_context_brush.gx_brush_line_color;
112
163700
    text_color |= (GX_UBYTE)(text_color << 4);
113
163700
    pixel_per_row = (UINT)draw_area -> gx_rectangle_right - (UINT)draw_area -> gx_rectangle_left + (UINT)1;
114
163700
    putstride = (context -> gx_draw_context_pitch + 1) >> 1;
115
    /* pickup pointer to current dispaly driver */
116
    /*display = context -> gx_draw_context_display;*/
117
118
    /* Find the width of the glyph, in terms of bytes */
119
163700
    glyph_width = glyph -> gx_glyph_width;
120
    /* Make it byte-aligned. */
121
163700
    glyph_width = (glyph_width + 7) >> 3;
122
123
    /* Compute the number of useful bytes from the glyph this routine is going to use.
124
       Because of map_offset, the first byte may contain pixel bits we don't need to draw;
125
       And the width of the draw_area may produce part of the last byte in the row to be ignored. */
126
163700
    num_bytes = ((UINT)map_offset -> gx_point_x + pixel_per_row + 7) >> 3;
127
    /* Take into account if map_offset specifies the number of bytes to ignore from the beginning of the row. */
128
163700
    num_bytes -= (UINT)(map_offset -> gx_point_x) >> 3;
129
130
    /* Compute the number of pixels to draw from the first byte of the glyph data. */
131
163700
    pixel_in_first_byte = (UINT)(8 - ((map_offset -> gx_point_x) & 0x7));
132
163700
    init_mask = (GX_UBYTE)(1 << (pixel_in_first_byte - 1));
133
    /* Compute the number of pixels to draw from the last byte, if there are more than one byte in a row. */
134
163700
    if (num_bytes != 1)
135
    {
136
65149
        pixel_in_last_byte = (map_offset -> gx_point_x + (INT)pixel_per_row) & 0x7;
137
65149
        if (pixel_in_last_byte == 0)
138
        {
139
2
            pixel_in_last_byte = 8;
140
        }
141
    }
142
    else
143
    {
144
98551
        if ((map_offset -> gx_point_x + (INT)pixel_per_row) < 8)
145
        {
146
65679
            pixel_in_first_byte = pixel_per_row;
147
        }
148
        else
149
        {
150
32872
            pixel_in_last_byte = 0;
151
        }
152
    }
153
154
155
163700
    glyph_row = (GX_UBYTE *)glyph -> gx_glyph_map;
156
157
163700
    if (map_offset -> gx_point_y)
158
    {
159
11
        glyph_row = glyph_row + ((INT)glyph_width * map_offset -> gx_point_y);
160
    }
161
162
163700
    glyph_row += (map_offset -> gx_point_x >> 3);
163
164
163700
    y_height = (UINT)(draw_area -> gx_rectangle_bottom - draw_area -> gx_rectangle_top + 1);
165
166
163700
    line_start = (GX_UBYTE *)context -> gx_draw_context_memory;
167
163700
    line_start += putstride * (draw_area -> gx_rectangle_top);
168
163700
    line_start += draw_area -> gx_rectangle_left >> 1;
169
170
171
2100382
    for (row = 0; row < y_height; row++)
172
    {
173
1936682
        if (draw_area -> gx_rectangle_left & 0x01)
174
        {
175
936376
            putmask = 0x0f;
176
        }
177
        else
178
        {
179
1000306
            putmask = 0xf0;
180
        }
181
1936682
        glyph_data = glyph_row;
182
1936682
        alpha = *(glyph_data);
183
1936682
        mask = init_mask;
184
1936682
        num_bits = pixel_in_first_byte;
185
1936682
        put = line_start;
186
4628610
        for (i = 0; i < num_bytes; i++)
187
        {
188

2691928
            if ((i == (num_bytes - 1)) && (num_bytes > 1))
189
            {
190
755192
                num_bits = pixel_in_last_byte;
191
            }
192


2691928
            switch (num_bits)
193
            {
194
1114030
            case 8:
195

1114030
                WRITE_PIXEL;
196
1114030
                mask >>= 1;
197
                /* fallthrough */
198
1256791
            case 7:
199

1256791
                WRITE_PIXEL;
200
1256791
                mask >>= 1;
201
                /* fallthrough */
202
1595866
            case 6:
203

1595866
                WRITE_PIXEL;
204
1595866
                mask >>= 1;
205
                /* fallthrough */
206
1666250
            case 5:
207

1666250
                WRITE_PIXEL;
208
1666250
                mask >>= 1;
209
                /* fallthrough */
210
1678393
            case 4:
211

1678393
                WRITE_PIXEL;
212
1678393
                mask >>= 1;
213
                /* fallthrough */
214
1688733
            case 3:
215

1688733
                WRITE_PIXEL;
216
1688733
                mask >>= 1;
217
                /* fallthrough */
218
2378685
            case 2:
219

2378685
                WRITE_PIXEL;
220
2378685
                mask >>= 1;
221
                /* fallthrough */
222
2691928
            default:
223

2691928
                WRITE_PIXEL;
224
            }
225
2691928
            glyph_data++;
226
2691928
            alpha = *(glyph_data);
227
2691928
            num_bits = 8;
228
2691928
            mask = 0x80;
229
        }
230
231
1936682
        glyph_row +=  glyph_width;
232
1936682
        line_start += putstride;
233
    }
234
235
163700
    return;
236
}
237