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 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _gx_display_driver_generic_glyph_4bit_draw PORTABLE C */
37 /* 6.1 */
38 /* AUTHOR */
39 /* */
40 /* Kenneth Maxwell, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function draws the specified text using the current context, */
45 /* clipped to one viewport */
46 /* */
47 /* INPUT */
48 /* */
49 /* context Draw context */
50 /* draw_area The rectangle where the glyph */
51 /* is drawn to */
52 /* map_offset Offset from the glyph map */
53 /* glyph The glyph structure */
54 /* */
55 /* OUTPUT */
56 /* */
57 /* None */
58 /* */
59 /* CALLS */
60 /* */
61 /* [gx_display_driver_pixel_blend] Call display driver pixel */
62 /* blend function */
63 /* */
64 /* CALLED BY */
65 /* */
66 /* GUIX internal code */
67 /* */
68 /* RELEASE HISTORY */
69 /* */
70 /* DATE NAME DESCRIPTION */
71 /* */
72 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
73 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
74 /* resulting in version 6.1 */
75 /* */
76 /**************************************************************************/
_gx_display_driver_generic_glyph_4bit_draw(GX_DRAW_CONTEXT * context,GX_RECTANGLE * draw_area,GX_POINT * map_offset,GX_CONST GX_GLYPH * glyph)77 VOID _gx_display_driver_generic_glyph_4bit_draw(GX_DRAW_CONTEXT *context, GX_RECTANGLE *draw_area, GX_POINT *map_offset, GX_CONST GX_GLYPH *glyph)
78 {
79 GX_DISPLAY *display;
80 GX_UBYTE *glyph_row;
81 GX_UBYTE *glyph_data;
82 UINT row;
83 UINT col;
84 UINT pixel_width = 0;
85 UINT leading_pixel;
86 UINT trailing_pixel;
87 GX_COLOR text_color;
88 UINT y_height;
89 GX_UBYTE alpha;
90 UINT pitch;
91 UINT index;
92 VOID (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR color, GX_UBYTE alpha);
93 GX_UBYTE brush_alpha = 0xff;
94
95 #if defined (GX_BRUSH_ALPHA_SUPPORT)
96 INT alpha_sum;
97 brush_alpha = context -> gx_draw_context_brush.gx_brush_alpha;
98 if (brush_alpha == 0)
99 {
100 return;
101 }
102 #endif
103
104 text_color = context -> gx_draw_context_brush.gx_brush_line_color;
105 pixel_width = (UINT)(draw_area -> gx_rectangle_right - draw_area -> gx_rectangle_left + 1);
106
107 /* pickup pointer to current dispaly driver */
108 display = context -> gx_draw_context_display;
109
110 if (display -> gx_display_driver_pixel_blend == GX_NULL)
111 {
112 return;
113 }
114
115 /* Find the width of the glyph */
116 pitch = glyph -> gx_glyph_width;
117 /* Make it byte-aligned. */
118 pitch = (pitch + 1) >> 1;
119
120 glyph_row = (GX_UBYTE *)glyph -> gx_glyph_map;
121
122 if (map_offset -> gx_point_y)
123 {
124 glyph_row = glyph_row + ((INT)pitch * map_offset -> gx_point_y);
125 }
126
127 glyph_row += (map_offset -> gx_point_x >> 1);
128
129 y_height = (UINT)(draw_area -> gx_rectangle_bottom - draw_area -> gx_rectangle_top + 1);
130
131 blend_func = display -> gx_display_driver_pixel_blend;
132
133 leading_pixel = (map_offset -> gx_point_x & 1);
134
135 pixel_width -= leading_pixel;
136
137 trailing_pixel = pixel_width & 1;
138
139 pixel_width = pixel_width >> 1;
140
141 if (brush_alpha == 0xff)
142 {
143 for (row = 0; row < y_height; row++)
144 {
145 col = 0;
146 glyph_data = glyph_row;
147
148 if (leading_pixel)
149 {
150 alpha = (*glyph_data) & 0x0f;
151 alpha = (GX_UBYTE)(alpha | (GX_UBYTE)(alpha << 4));
152
153 if (alpha > 0)
154 {
155 blend_func(context,
156 draw_area -> gx_rectangle_left + (GX_VALUE)col,
157 draw_area -> gx_rectangle_top + (GX_VALUE)row,
158 text_color, (GX_UBYTE)alpha);
159 }
160 col++;
161 glyph_data++;
162 }
163
164 for (index = 0; index < pixel_width; index++)
165 {
166 alpha = (*glyph_data) & 0xf0;
167 alpha = (GX_UBYTE)(alpha | (GX_UBYTE)(alpha >> 4));
168
169 if (alpha > 0)
170 {
171 blend_func(context,
172 draw_area -> gx_rectangle_left + (GX_VALUE)col,
173 draw_area -> gx_rectangle_top + (GX_VALUE)row,
174 text_color, (GX_UBYTE)alpha);
175 }
176 col++;
177
178 alpha = (*glyph_data) & 0x0f;
179 alpha = (GX_UBYTE)(alpha | (GX_UBYTE)(alpha << 4));
180
181 if (alpha > 0)
182 {
183 blend_func(context,
184 draw_area -> gx_rectangle_left + (GX_VALUE)col,
185 draw_area -> gx_rectangle_top + (GX_VALUE)row,
186 text_color, (GX_UBYTE)alpha);
187 }
188 col++;
189 glyph_data++;
190 }
191
192 if (trailing_pixel)
193 {
194 alpha = (*glyph_data) & 0xf0;
195 alpha = (GX_UBYTE)(alpha | (GX_UBYTE)(alpha >> 4));
196
197 if (alpha > 0)
198 {
199 blend_func(context,
200 draw_area -> gx_rectangle_left + (GX_VALUE)col,
201 draw_area -> gx_rectangle_top + (GX_VALUE)row,
202 text_color, (GX_UBYTE)alpha);
203 }
204 }
205 glyph_row += pitch;
206 }
207 }
208 #if defined (GX_BRUSH_ALPHA_SUPPORT)
209 else
210 {
211 for (row = 0; row < y_height; row++)
212 {
213 col = 0;
214 glyph_data = glyph_row;
215
216 if (leading_pixel)
217 {
218 alpha = (*glyph_data) & 0x0f;
219 alpha = (GX_UBYTE)(alpha | (GX_UBYTE)(alpha << 4));
220
221 alpha_sum = alpha * brush_alpha / 255;
222
223 if (alpha_sum > 0)
224 {
225 blend_func(context,
226 draw_area->gx_rectangle_left + (GX_VALUE)col,
227 draw_area->gx_rectangle_top + (GX_VALUE)row,
228 text_color, (GX_UBYTE)alpha_sum);
229 }
230 col++;
231 glyph_data++;
232 }
233
234 for (index = 0; index < pixel_width; index++)
235 {
236 alpha = (*glyph_data) & 0xf0;
237 alpha = (GX_UBYTE)(alpha | (GX_UBYTE)(alpha >> 4));
238 alpha_sum = alpha * brush_alpha / 255;
239
240 if (alpha_sum > 0)
241 {
242 blend_func(context,
243 draw_area -> gx_rectangle_left + (GX_VALUE)col,
244 draw_area -> gx_rectangle_top + (GX_VALUE)row,
245 text_color, (GX_UBYTE)alpha_sum);
246 }
247 col++;
248
249 alpha = (*glyph_data) & 0x0f;
250 alpha = (GX_UBYTE)(alpha | (GX_UBYTE)(alpha << 4));
251 alpha_sum = alpha * brush_alpha / 255;
252
253 if (alpha_sum > 0)
254 {
255 blend_func(context,
256 draw_area -> gx_rectangle_left + (GX_VALUE)col,
257 draw_area -> gx_rectangle_top + (GX_VALUE)row,
258 text_color, (GX_UBYTE)alpha_sum);
259 }
260 col++;
261 glyph_data++;
262 }
263
264 if (trailing_pixel)
265 {
266 alpha = (*glyph_data) & 0xf0;
267 alpha = (GX_UBYTE)(alpha | (GX_UBYTE)(alpha >> 4));
268 alpha_sum = alpha * brush_alpha / 255;
269
270 if (alpha_sum > 0)
271 {
272 blend_func(context,
273 draw_area -> gx_rectangle_left + (GX_VALUE)col,
274 draw_area -> gx_rectangle_top + (GX_VALUE)row,
275 text_color, (GX_UBYTE)alpha_sum);
276 }
277 }
278 glyph_row += pitch;
279 }
280 }
281 #endif
282
283 }
284
285