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 _gx_display_driver_24xrgb_pixel_blend(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_32bpp_glyph_1bit_draw PORTABLE C */
52 /* 6.1.11 */
53 /* AUTHOR */
54 /* */
55 /* Kenneth Maxwell, Microsoft Corporation */
56 /* */
57 /* DESCRIPTION */
58 /* */
59 /* This functions draw monochrome font on 32bpp 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_24xrgb_pixel_blend Display driver basic pixel */
78 /* blend function */
79 /* */
80 /* CALLED BY */
81 /* */
82 /* GUIX internal code */
83 /* */
84 /* RELEASE HISTORY */
85 /* */
86 /* DATE NAME DESCRIPTION */
87 /* */
88 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
89 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
90 /* resulting in version 6.1 */
91 /* 04-25-2022 Ting Zhu Modified comment(s), */
92 /* fixed access violation bug, */
93 /* resulting in version 6.1.11 */
94 /* */
95 /**************************************************************************/
_gx_display_driver_32bpp_glyph_1bit_draw(GX_DRAW_CONTEXT * context,GX_RECTANGLE * draw_area,GX_POINT * map_offset,GX_CONST GX_GLYPH * glyph)96 VOID _gx_display_driver_32bpp_glyph_1bit_draw(GX_DRAW_CONTEXT *context, GX_RECTANGLE *draw_area, GX_POINT *map_offset, GX_CONST GX_GLYPH *glyph)
97 {
98 GX_UBYTE *glyph_row;
99 GX_UBYTE *glyph_data;
100 UINT row;
101 UINT pixel_per_row;
102 UINT pixel_in_first_byte;
103 UINT pixel_in_last_byte = 0;
104 GX_COLOR text_color;
105 UINT y_height;
106 GX_UBYTE alpha;
107 UINT glyph_width;
108 UINT *put;
109 UINT num_bytes;
110 UINT num_bits;
111 UINT *line_start;
112 GX_UBYTE mask, init_mask;
113 UINT i;
114
115 #if defined (GX_BRUSH_ALPHA_SUPPORT)
116 GX_UBYTE brush_alpha;
117 INT xval, yval;
118
119 brush_alpha = context -> gx_draw_context_brush.gx_brush_alpha;
120 if (brush_alpha == 0)
121 {
122 return;
123 }
124 #endif
125
126 text_color = context -> gx_draw_context_brush.gx_brush_line_color;
127 pixel_per_row = (UINT)(draw_area -> gx_rectangle_right - draw_area -> gx_rectangle_left + 1);
128
129 /* pickup pointer to current dispaly driver */
130 /*display = context -> gx_draw_context_display;*/
131
132 /* Find the width of the glyph, in terms of bytes */
133 glyph_width = glyph -> gx_glyph_width;
134 /* Make it byte-aligned. */
135 glyph_width = (glyph_width + 7) >> 3;
136
137 /* Compute the number of useful bytes from the glyph this routine is going to use.
138 Because of map_offset, the first byte may contain pixel bits we don't need to draw;
139 And the width of the draw_area may produce part of the last byte in the row to be ignored. */
140 num_bytes = (UINT)(((UINT)(map_offset -> gx_point_x) + pixel_per_row + 7) >> 3);
141 /* Take into account if map_offset specifies the number of bytes to ignore from the beginning of the row. */
142 num_bytes = num_bytes - (((UINT)(map_offset -> gx_point_x)) >> 3);
143
144 /* Compute the number of pixels to draw from the first byte of the glyph data. */
145 pixel_in_first_byte = 8 - (UINT)((map_offset -> gx_point_x) & 0x7);
146 init_mask = (GX_UBYTE)(1 << (pixel_in_first_byte - 1));
147 /* Compute the number of pixels to draw from the last byte, if there are more than one byte in a row. */
148 if (num_bytes != 1)
149 {
150 pixel_in_last_byte = (((UINT)(map_offset -> gx_point_x) + pixel_per_row) & 0x7);
151 if (pixel_in_last_byte == 0)
152 {
153 pixel_in_last_byte = 8;
154 }
155 }
156 else
157 {
158 if (((UINT)(map_offset -> gx_point_x) + pixel_per_row) < 8)
159 {
160 pixel_in_first_byte = pixel_per_row;
161 }
162 else
163 {
164 pixel_in_last_byte = 0;
165 }
166 }
167
168 glyph_row = (GX_UBYTE *)glyph -> gx_glyph_map;
169
170 if (map_offset -> gx_point_y)
171 {
172 glyph_row = glyph_row + ((INT)glyph_width * (INT)(map_offset -> gx_point_y));
173 }
174
175 glyph_row += (map_offset -> gx_point_x >> 3);
176
177 y_height = (UINT)(draw_area -> gx_rectangle_bottom - draw_area -> gx_rectangle_top + 1);
178
179 #if defined (GX_BRUSH_ALPHA_SUPPORT)
180 if (brush_alpha != 0xff)
181 {
182 yval = draw_area -> gx_rectangle_top;
183 for (row = 0; row < y_height; row++)
184 {
185 xval = draw_area -> gx_rectangle_left;
186 glyph_data = glyph_row;
187 mask = init_mask;
188 num_bits = pixel_in_first_byte;
189 for (i = 0; i < num_bytes; i++)
190 {
191 alpha = *(glyph_data++);
192
193 if ((i == (num_bytes - 1)) && (num_bytes > 1))
194 {
195 num_bits = pixel_in_last_byte;
196 }
197 switch (num_bits)
198 {
199 case 8:
200 BLEND_PIXEL;
201 /* fallthrough */
202 case 7:
203 BLEND_PIXEL;
204 /* fallthrough */
205 case 6:
206 BLEND_PIXEL;
207 /* fallthrough */
208 case 5:
209 BLEND_PIXEL;
210 /* fallthrough */
211 case 4:
212 BLEND_PIXEL;
213 /* fallthrough */
214 case 3:
215 BLEND_PIXEL;
216 /* fallthrough */
217 case 2:
218 BLEND_PIXEL;
219 /* fallthrough */
220 default:
221 if (alpha & mask)
222 {
223 _gx_display_driver_24xrgb_pixel_blend(context, xval, yval, text_color, brush_alpha);
224 }
225 xval++;
226 break;
227 }
228 num_bits = 8;
229 mask = 0x80;
230 }
231
232 glyph_row += glyph_width;
233 yval++;
234 }
235 }
236 else
237 {
238 #endif
239 line_start = (UINT *)context -> gx_draw_context_memory;
240 line_start += context -> gx_draw_context_pitch * (draw_area -> gx_rectangle_top);
241 line_start += draw_area -> gx_rectangle_left;
242
243 for (row = 0; row < y_height; row++)
244 {
245 glyph_data = glyph_row;
246 mask = init_mask;
247 num_bits = pixel_in_first_byte;
248 put = line_start;
249 for (i = 0; i < num_bytes; i++)
250 {
251 alpha = *(glyph_data++);
252
253 if ((i == (num_bytes - 1)) && (num_bytes > 1))
254 {
255 num_bits = pixel_in_last_byte;
256 }
257 switch (num_bits)
258 {
259 case 8:
260 DRAW_PIXEL;
261 /* fallthrough */
262 case 7:
263 DRAW_PIXEL;
264 /* fallthrough */
265 case 6:
266 DRAW_PIXEL;
267 /* fallthrough */
268 case 5:
269 DRAW_PIXEL;
270 /* fallthrough */
271 case 4:
272 DRAW_PIXEL;
273 /* fallthrough */
274 case 3:
275 DRAW_PIXEL;
276 /* fallthrough */
277 case 2:
278 DRAW_PIXEL;
279 /* fallthrough */
280 default:
281 if (alpha & mask)
282 {
283 *put = text_color;
284 }
285 put++;
286 break;
287 }
288 num_bits = 8;
289 mask = 0x80;
290 }
291
292 glyph_row += glyph_width;
293 line_start += context -> gx_draw_context_pitch;
294 }
295 #if defined (GX_BRUSH_ALPHA_SUPPORT)
296 }
297 #endif
298 return;
299 }
300
301