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