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