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_4bpp_glyph_1bit_draw PORTABLE C */
37 /* 6.1 */
38 /* AUTHOR */
39 /* */
40 /* Kenneth Maxwell, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function draws monochrome font to the 4bpp canvas, clipped */
45 /* to one viweport. */
46 /* */
47 /* INPUT */
48 /* */
49 /* context Draw context */
50 /* draw_area The region bound by the */
51 /* rectangle where the glyph */
52 /* is drawn */
53 /* map_offset X,Y offset into the glyph map */
54 /* glyph Pointer to the glyph */
55 /* */
56 /* OUTPUT */
57 /* */
58 /* None */
59 /* */
60 /* CALLS */
61 /* */
62 /* None */
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 /**************************************************************************/
77
78 #define WRITE_PIXEL if (alpha & mask) \
79 { \
80 *put = *put & (GX_UBYTE)(~putmask); \
81 *put = *put | (GX_UBYTE)(text_color & putmask); \
82 } \
83 putmask = putmask >> 4; \
84 if (putmask == 0) \
85 { \
86 putmask = 0xf0; \
87 put++; \
88 }
89
90
_gx_display_driver_4bpp_glyph_1bit_draw(GX_DRAW_CONTEXT * context,GX_RECTANGLE * draw_area,GX_POINT * map_offset,const GX_GLYPH * glyph)91 VOID _gx_display_driver_4bpp_glyph_1bit_draw(GX_DRAW_CONTEXT *context, GX_RECTANGLE *draw_area, GX_POINT *map_offset, const GX_GLYPH *glyph)
92 {
93 GX_UBYTE *glyph_row;
94 GX_UBYTE *glyph_data;
95 UINT row;
96 UINT pixel_per_row;
97 UINT pixel_in_first_byte;
98 UINT pixel_in_last_byte = 0;
99 GX_UBYTE text_color;
100 UINT y_height;
101 GX_UBYTE alpha;
102 UINT glyph_width;
103 GX_UBYTE *put;
104 UINT num_bytes;
105 UINT num_bits;
106 GX_UBYTE *line_start;
107 GX_UBYTE mask, init_mask;
108 UINT i;
109 GX_UBYTE putmask;
110 INT putstride;
111
112 text_color = (GX_UBYTE)context -> gx_draw_context_brush.gx_brush_line_color;
113 text_color |= (GX_UBYTE)(text_color << 4);
114 pixel_per_row = (UINT)draw_area -> gx_rectangle_right - (UINT)draw_area -> gx_rectangle_left + (UINT)1;
115 putstride = (context -> gx_draw_context_pitch + 1) >> 1;
116 /* pickup pointer to current dispaly driver */
117 /*display = context -> gx_draw_context_display;*/
118
119 /* Find the width of the glyph, in terms of bytes */
120 glyph_width = glyph -> gx_glyph_width;
121 /* Make it byte-aligned. */
122 glyph_width = (glyph_width + 7) >> 3;
123
124 /* Compute the number of useful bytes from the glyph this routine is going to use.
125 Because of map_offset, the first byte may contain pixel bits we don't need to draw;
126 And the width of the draw_area may produce part of the last byte in the row to be ignored. */
127 num_bytes = ((UINT)map_offset -> gx_point_x + pixel_per_row + 7) >> 3;
128 /* Take into account if map_offset specifies the number of bytes to ignore from the beginning of the row. */
129 num_bytes -= (UINT)(map_offset -> gx_point_x) >> 3;
130
131 /* Compute the number of pixels to draw from the first byte of the glyph data. */
132 pixel_in_first_byte = (UINT)(8 - ((map_offset -> gx_point_x) & 0x7));
133 init_mask = (GX_UBYTE)(1 << (pixel_in_first_byte - 1));
134 /* Compute the number of pixels to draw from the last byte, if there are more than one byte in a row. */
135 if (num_bytes != 1)
136 {
137 pixel_in_last_byte = (map_offset -> gx_point_x + (INT)pixel_per_row) & 0x7;
138 if (pixel_in_last_byte == 0)
139 {
140 pixel_in_last_byte = 8;
141 }
142 }
143 else
144 {
145 if ((map_offset -> gx_point_x + (INT)pixel_per_row) < 8)
146 {
147 pixel_in_first_byte = pixel_per_row;
148 }
149 else
150 {
151 pixel_in_last_byte = 0;
152 }
153 }
154
155
156 glyph_row = (GX_UBYTE *)glyph -> gx_glyph_map;
157
158 if (map_offset -> gx_point_y)
159 {
160 glyph_row = glyph_row + ((INT)glyph_width * map_offset -> gx_point_y);
161 }
162
163 glyph_row += (map_offset -> gx_point_x >> 3);
164
165 y_height = (UINT)(draw_area -> gx_rectangle_bottom - draw_area -> gx_rectangle_top + 1);
166
167 line_start = (GX_UBYTE *)context -> gx_draw_context_memory;
168 line_start += putstride * (draw_area -> gx_rectangle_top);
169 line_start += draw_area -> gx_rectangle_left >> 1;
170
171
172 for (row = 0; row < y_height; row++)
173 {
174 if (draw_area -> gx_rectangle_left & 0x01)
175 {
176 putmask = 0x0f;
177 }
178 else
179 {
180 putmask = 0xf0;
181 }
182 glyph_data = glyph_row;
183 alpha = *(glyph_data);
184 mask = init_mask;
185 num_bits = pixel_in_first_byte;
186 put = line_start;
187 for (i = 0; i < num_bytes; i++)
188 {
189 if ((i == (num_bytes - 1)) && (num_bytes > 1))
190 {
191 num_bits = pixel_in_last_byte;
192 }
193 switch (num_bits)
194 {
195 case 8:
196 WRITE_PIXEL;
197 mask >>= 1;
198 /* fallthrough */
199 case 7:
200 WRITE_PIXEL;
201 mask >>= 1;
202 /* fallthrough */
203 case 6:
204 WRITE_PIXEL;
205 mask >>= 1;
206 /* fallthrough */
207 case 5:
208 WRITE_PIXEL;
209 mask >>= 1;
210 /* fallthrough */
211 case 4:
212 WRITE_PIXEL;
213 mask >>= 1;
214 /* fallthrough */
215 case 3:
216 WRITE_PIXEL;
217 mask >>= 1;
218 /* fallthrough */
219 case 2:
220 WRITE_PIXEL;
221 mask >>= 1;
222 /* fallthrough */
223 default:
224 WRITE_PIXEL;
225 }
226 glyph_data++;
227 alpha = *(glyph_data);
228 num_bits = 8;
229 mask = 0x80;
230 }
231
232 glyph_row += glyph_width;
233 line_start += putstride;
234 }
235
236 return;
237 }
238
239