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