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_rotated_glyph_1bit_draw PORTABLE C */
54 /* 6.1.4 */
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 /* 02-02-2021 Kenneth Maxwell Initial Version 6.1.4 */
91 /* */
92 /**************************************************************************/
_gx_display_driver_8bpp_rotated_glyph_1bit_draw(GX_DRAW_CONTEXT * context,GX_RECTANGLE * draw_area,GX_POINT * map_offset,GX_CONST GX_GLYPH * glyph)93 VOID _gx_display_driver_8bpp_rotated_glyph_1bit_draw(GX_DRAW_CONTEXT *context, GX_RECTANGLE *draw_area, GX_POINT *map_offset, GX_CONST GX_GLYPH *glyph)
94 {
95 GX_UBYTE *glyph_row;
96 GX_UBYTE *glyph_data;
97 UINT row;
98 UINT pixel_per_row;
99 UINT pixel_in_first_byte;
100 UINT pixel_in_last_byte = 0;
101 GX_UBYTE text_color;
102 UINT y_height;
103 GX_UBYTE alpha;
104 UINT glyph_width;
105 GX_UBYTE *put;
106 UINT num_bytes;
107 UINT num_bits;
108 GX_UBYTE *line_start;
109 GX_UBYTE mask, init_mask;
110 UINT i;
111 GX_VALUE rotated_map_offset_x;
112 GX_VALUE rotated_map_offset_y;
113 GX_VALUE rotated_draw_left;
114 GX_VALUE rotated_draw_top;
115
116 text_color = (GX_UBYTE)context -> gx_draw_context_brush.gx_brush_line_color;
117 pixel_per_row = (UINT)draw_area -> gx_rectangle_bottom - (UINT)draw_area -> gx_rectangle_top + (UINT)1;
118 y_height = (UINT)(draw_area -> gx_rectangle_right - draw_area -> gx_rectangle_left + 1);
119
120 /* Find the width of the glyph, in terms of bytes */
121 glyph_width = glyph -> gx_glyph_height;
122
123 /* Make it byte-aligned. */
124 glyph_width = (glyph_width + 7) >> 3;
125
126 if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
127 {
128 rotated_draw_left = draw_area -> gx_rectangle_top;
129 rotated_draw_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - draw_area -> gx_rectangle_right - 1);
130
131 rotated_map_offset_x = map_offset -> gx_point_y;
132 rotated_map_offset_y = (GX_VALUE)(glyph -> gx_glyph_width - map_offset -> gx_point_x - (GX_VALUE)y_height);
133 }
134 else
135 {
136 rotated_draw_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_display_offset_y - draw_area -> gx_rectangle_bottom - 1);
137 rotated_draw_top = draw_area -> gx_rectangle_left;
138
139 rotated_map_offset_x = (GX_VALUE)(glyph -> gx_glyph_height - map_offset -> gx_point_y - (GX_VALUE)pixel_per_row);
140 rotated_map_offset_y = map_offset -> gx_point_x;
141 }
142
143 /* Compute the number of useful bytes from the glyph this routine is going to use.
144 Because of map_offset, the first byte may contain pixel bits we don't need to draw;
145 And the width of the draw_area may produce part of the last byte in the row to be ignored. */
146 num_bytes = ((UINT)rotated_map_offset_x + pixel_per_row + 7) >> 3;
147
148 /* Take into account if map_offset specifies the number of bytes to ignore from the beginning of the row. */
149 num_bytes -= (UINT)(rotated_map_offset_x) >> 3;
150
151 /* Compute the number of pixels to draw from the first byte of the glyph data. */
152 pixel_in_first_byte = (UINT)(8 - (rotated_map_offset_x & 0x7));
153 init_mask = (GX_UBYTE)(1 << (pixel_in_first_byte - 1));
154
155 /* Compute the number of pixels to draw from the last byte, if there are more than one byte in a row. */
156 if (num_bytes != 1)
157 {
158 pixel_in_last_byte = (rotated_map_offset_x + (INT)pixel_per_row) & 0x7;
159 if (pixel_in_last_byte == 0)
160 {
161 pixel_in_last_byte = 8;
162 }
163 }
164 else
165 {
166 pixel_in_first_byte = pixel_per_row;
167 }
168
169
170 glyph_row = (GX_UBYTE *)glyph -> gx_glyph_map;
171
172 if (rotated_map_offset_y)
173 {
174 glyph_row = glyph_row + ((INT)glyph_width * rotated_map_offset_y);
175 }
176
177 glyph_row += (rotated_map_offset_x >> 3);
178
179 line_start = (GX_UBYTE *)context -> gx_draw_context_memory;
180 line_start += context -> gx_draw_context_pitch * rotated_draw_top;
181 line_start += rotated_draw_left;
182
183 for (row = 0; row < y_height; row++)
184 {
185 glyph_data = glyph_row;
186 alpha = *(glyph_data);
187 mask = init_mask;
188 num_bits = pixel_in_first_byte;
189 put = line_start;
190
191 for (i = 0; i < num_bytes; i++)
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 DRAW_PIXEL;
201 /* fallthrough */
202 case 7:
203 DRAW_PIXEL;
204 /* fallthrough */
205 case 6:
206 DRAW_PIXEL;
207 /* fallthrough */
208 case 5:
209 DRAW_PIXEL;
210 /* fallthrough */
211 case 4:
212 DRAW_PIXEL;
213 /* fallthrough */
214 case 3:
215 DRAW_PIXEL;
216 /* fallthrough */
217 case 2:
218 DRAW_PIXEL;
219 /* fallthrough */
220
221 default:
222 if (alpha & mask)
223 {
224 *put = text_color;
225 }
226 put++;
227 break;
228 }
229 glyph_data++;
230 alpha = *(glyph_data);
231 num_bits = 8;
232 mask = 0x80;
233 }
234
235 glyph_row += glyph_width;
236 line_start += context -> gx_draw_context_pitch;
237 }
238
239 return;
240 }
241
242