1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
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 #define DRAW_PIXEL if (alpha & mask) \
33 { \
34 *put = text_color; \
35 } \
36 put++; \
37 mask = mask >> 1;
38
39
40 #if defined (GX_BRUSH_ALPHA_SUPPORT)
41 #define BLEND_PIXEL if (alpha & mask) \
42 { \
43 blend_func(context, xval, yval, text_color, brush_alpha); \
44 } \
45 xval++; \
46 mask = mask >> 1;
47 #endif
48
49 /**************************************************************************/
50 /* */
51 /* FUNCTION RELEASE */
52 /* */
53 /* _gx_display_driver_8bpp_glyph_1bit_draw PORTABLE C */
54 /* 6.1.11 */
55 /* AUTHOR */
56 /* */
57 /* Kenneth Maxwell, Microsoft Corporation */
58 /* */
59 /* DESCRIPTION */
60 /* */
61 /* This function draws monochrome font to the 8bpp canvas, clipped */
62 /* to one viweport. */
63 /* */
64 /* INPUT */
65 /* */
66 /* context Draw context */
67 /* draw_area The region bound by the */
68 /* rectangle where the glyph */
69 /* is drawn */
70 /* map_offset X,Y offset into the glyph map */
71 /* glyph Pointer to the glyph */
72 /* */
73 /* OUTPUT */
74 /* */
75 /* None */
76 /* */
77 /* CALLS */
78 /* */
79 /* [gx_display_driver_pixel_blend] Basic display driver pixel */
80 /* blend function */
81 /* */
82 /* CALLED BY */
83 /* */
84 /* GUIX internal code */
85 /* */
86 /* RELEASE HISTORY */
87 /* */
88 /* DATE NAME DESCRIPTION */
89 /* */
90 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
91 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
92 /* resulting in version 6.1 */
93 /* 04-25-2022 Ting Zhu Modified comment(s), */
94 /* fixed access violation bug, */
95 /* resulting in version 6.1.11 */
96 /* */
97 /**************************************************************************/
_gx_display_driver_8bpp_glyph_1bit_draw(GX_DRAW_CONTEXT * context,GX_RECTANGLE * draw_area,GX_POINT * map_offset,GX_CONST GX_GLYPH * glyph)98 VOID _gx_display_driver_8bpp_glyph_1bit_draw(GX_DRAW_CONTEXT *context, GX_RECTANGLE *draw_area, GX_POINT *map_offset, GX_CONST GX_GLYPH *glyph)
99 {
100 /* GX_DISPLAY *display;*/
101 GX_UBYTE *glyph_row;
102 GX_UBYTE *glyph_data;
103 UINT row;
104 UINT pixel_per_row;
105 UINT pixel_in_first_byte;
106 UINT pixel_in_last_byte = 0;
107 GX_UBYTE text_color;
108 UINT y_height;
109 GX_UBYTE alpha;
110 UINT glyph_width;
111 GX_UBYTE *put;
112 UINT num_bytes;
113 UINT num_bits;
114 GX_UBYTE *line_start;
115 GX_UBYTE mask, init_mask;
116 UINT i;
117 GX_UBYTE brush_alpha = 0xff;
118 #if defined (GX_BRUSH_ALPHA_SUPPORT)
119 INT xval, yval;
120 VOID (*blend_func)(GX_DRAW_CONTEXT *, INT, INT, GX_COLOR, GX_UBYTE);
121
122 brush_alpha = context -> gx_draw_context_brush.gx_brush_alpha;
123 blend_func = context -> gx_draw_context_display -> gx_display_driver_pixel_blend;
124
125 if (blend_func == GX_NULL)
126 {
127 /* Pixel blend function is null means alpha isn't supported in this driver.
128 So set alpha value to 0xff to make it draw the original color in case GX_BRUSH_ALPHA_SUPPORT is defined. */
129 brush_alpha = 0xff;
130 }
131 else
132 {
133 if (brush_alpha == 0)
134 return;
135 }
136 #endif
137 text_color = (GX_UBYTE)context -> gx_draw_context_brush.gx_brush_line_color;
138 pixel_per_row = (UINT)draw_area -> gx_rectangle_right - (UINT)draw_area -> gx_rectangle_left + (UINT)1;
139
140 /* pickup pointer to current dispaly driver */
141 /*display = context -> gx_draw_context_display;*/
142
143 /* Find the width of the glyph, in terms of bytes */
144 glyph_width = glyph -> gx_glyph_width;
145 /* Make it byte-aligned. */
146 glyph_width = (glyph_width + 7) >> 3;
147
148 /* Compute the number of useful bytes from the glyph this routine is going to use.
149 Because of map_offset, the first byte may contain pixel bits we don't need to draw;
150 And the width of the draw_area may produce part of the last byte in the row to be ignored. */
151 num_bytes = ((UINT)map_offset -> gx_point_x + pixel_per_row + 7) >> 3;
152 /* Take into account if map_offset specifies the number of bytes to ignore from the beginning of the row. */
153 num_bytes -= (UINT)(map_offset -> gx_point_x) >> 3;
154
155 /* Compute the number of pixels to draw from the first byte of the glyph data. */
156 pixel_in_first_byte = (UINT)(8 - ((map_offset -> gx_point_x) & 0x7));
157 init_mask = (GX_UBYTE)(1 << (pixel_in_first_byte - 1));
158 /* Compute the number of pixels to draw from the last byte, if there are more than one byte in a row. */
159 if (num_bytes != 1)
160 {
161 pixel_in_last_byte = (map_offset -> gx_point_x + (INT)pixel_per_row) & 0x7;
162 if (pixel_in_last_byte == 0)
163 {
164 pixel_in_last_byte = 8;
165 }
166 }
167 else
168 {
169 if ((map_offset -> gx_point_x + (INT)pixel_per_row) < 8)
170 {
171 pixel_in_first_byte = pixel_per_row;
172 }
173 else
174 {
175 pixel_in_last_byte = 0;
176 }
177 }
178
179
180 glyph_row = (GX_UBYTE *)glyph -> gx_glyph_map;
181
182 if (map_offset -> gx_point_y)
183 {
184 glyph_row = glyph_row + ((INT)glyph_width * map_offset -> gx_point_y);
185 }
186
187 glyph_row += (map_offset -> gx_point_x >> 3);
188
189 y_height = (UINT)(draw_area -> gx_rectangle_bottom - draw_area -> gx_rectangle_top + 1);
190
191 if (brush_alpha == 0xff)
192 {
193
194 line_start = (GX_UBYTE *)context -> gx_draw_context_memory;
195 line_start += context -> gx_draw_context_pitch * (draw_area -> gx_rectangle_top);
196 line_start += draw_area -> gx_rectangle_left;
197
198 for (row = 0; row < y_height; row++)
199 {
200 glyph_data = glyph_row;
201 mask = init_mask;
202 num_bits = pixel_in_first_byte;
203 put = line_start;
204
205 for (i = 0; i < num_bytes; i++)
206 {
207 alpha = *(glyph_data++);
208
209 if ((i == (num_bytes - 1)) && (num_bytes > 1))
210 {
211 num_bits = pixel_in_last_byte;
212 }
213 switch (num_bits)
214 {
215 case 8:
216 DRAW_PIXEL;
217 /* fallthrough */
218 case 7:
219 DRAW_PIXEL;
220 /* fallthrough */
221 case 6:
222 DRAW_PIXEL;
223 /* fallthrough */
224 case 5:
225 DRAW_PIXEL;
226 /* fallthrough */
227 case 4:
228 DRAW_PIXEL;
229 /* fallthrough */
230 case 3:
231 DRAW_PIXEL;
232 /* fallthrough */
233 case 2:
234 DRAW_PIXEL;
235 /* fallthrough */
236
237 default:
238 if (alpha & mask)
239 {
240 *put = text_color;
241 }
242 put++;
243 break;
244 }
245 num_bits = 8;
246 mask = 0x80;
247 }
248
249 glyph_row += glyph_width;
250 line_start += context -> gx_draw_context_pitch;
251 }
252 }
253 #if defined (GX_BRUSH_ALPHA_SUPPORT)
254 else
255 {
256 yval = draw_area -> gx_rectangle_top;
257 for (row = 0; row < y_height; row++)
258 {
259 xval = draw_area -> gx_rectangle_left;
260 glyph_data = glyph_row;
261 mask = init_mask;
262 num_bits = pixel_in_first_byte;
263 for (i = 0; i < num_bytes; i++)
264 {
265 alpha = *(glyph_data);
266 if ((i == (num_bytes - 1)) && (num_bytes > 1))
267 {
268 num_bits = pixel_in_last_byte;
269 }
270 switch (num_bits)
271 {
272 case 8:
273 BLEND_PIXEL;
274 /* fallthrough */
275 case 7:
276 BLEND_PIXEL;
277 /* fallthrough */
278 case 6:
279 BLEND_PIXEL;
280 /* fallthrough */
281 case 5:
282 BLEND_PIXEL;
283 /* fallthrough */
284 case 4:
285 BLEND_PIXEL;
286 /* fallthrough */
287 case 3:
288 BLEND_PIXEL;
289 /* fallthrough */
290 case 2:
291 BLEND_PIXEL;
292 /* fallthrough */
293 default:
294 if (alpha & mask)
295 {
296 blend_func(context, xval, yval, text_color, brush_alpha);
297 }
298 xval++;
299 break;
300 }
301 glyph_data++;
302 num_bits = 8;
303 mask = 0x80;
304 }
305
306 glyph_row += glyph_width;
307 yval++;
308 }
309 }
310 #endif
311 return;
312 }
313
314