1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** GUIX Component                                                        */
16 /**                                                                       */
17 /**   Display Management (Display)                                        */
18 /**                                                                       */
19 /**************************************************************************/
20 
21 #define GX_SOURCE_CODE
22 
23 
24 /* Include necessary system files.  */
25 
26 #include "gx_api.h"
27 #include "gx_system.h"
28 #include "gx_utility.h"
29 #include "gx_display.h"
30 
31 
32 /**************************************************************************/
33 /*                                                                        */
34 /*  FUNCTION                                               RELEASE        */
35 /*                                                                        */
36 /*    _gx_display_driver_8bpp_rotated_glyph_4bit_draw     PORTABLE C      */
37 /*                                                           6.1.4        */
38 /*  AUTHOR                                                                */
39 /*                                                                        */
40 /*    Kenneth Maxwell, Microsoft Corporation                              */
41 /*                                                                        */
42 /*  DESCRIPTION                                                           */
43 /*                                                                        */
44 /*    This draws the specified text using the current context,            */
45 /*    clipped to one viewport                                             */
46 /*                                                                        */
47 /*  INPUT                                                                 */
48 /*                                                                        */
49 /*    context                               Draw context                  */
50 /*    draw_position                         The X and Y coordinate where  */
51 /*                                            the glyph is drawn to       */
52 /*    string                                String to draw                */
53 /*    count                                 Count of string characters    */
54 /*    view                                  view to clip drawing within   */
55 /*                                                                        */
56 /*  OUTPUT                                                                */
57 /*                                                                        */
58 /*    None                                                                */
59 /*                                                                        */
60 /*  CALLS                                                                 */
61 /*                                                                        */
62 /*    None                                                                */
63 /*                                                                        */
64 /*  CALLED BY                                                             */
65 /*                                                                        */
66 /*    _gx_canvas_text_draw                                                */
67 /*                                                                        */
68 /*  RELEASE HISTORY                                                       */
69 /*                                                                        */
70 /*    DATE              NAME                      DESCRIPTION             */
71 /*                                                                        */
72 /*  02-02-2021     Kenneth Maxwell          Initial Version 6.1.4         */
73 /*                                                                        */
74 /**************************************************************************/
_gx_display_driver_8bpp_rotated_glyph_4bit_draw(GX_DRAW_CONTEXT * context,GX_RECTANGLE * draw_area,GX_POINT * map_offset,GX_CONST GX_GLYPH * glyph)75 VOID _gx_display_driver_8bpp_rotated_glyph_4bit_draw(GX_DRAW_CONTEXT *context, GX_RECTANGLE *draw_area, GX_POINT *map_offset, GX_CONST GX_GLYPH *glyph)
76 {
77 GX_UBYTE *glyph_row;
78 GX_UBYTE *glyph_data;
79 UINT      row;
80 UINT      pixel_width = 0;
81 UINT      leading_pixel;
82 UINT      trailing_pixel;
83 GX_UBYTE  text_color;
84 UINT      y_height;
85 GX_UBYTE  alpha;
86 UINT      pitch;
87 UINT      index;
88 GX_UBYTE *put;
89 GX_UBYTE *draw_start;
90 GX_VALUE  rotated_map_offset_x;
91 GX_VALUE  rotated_map_offset_y;
92 GX_VALUE  rotated_left;
93 GX_VALUE  rotated_top;
94 
95     text_color = (GX_UBYTE)(context -> gx_draw_context_brush.gx_brush_line_color + 15);
96     pixel_width = (UINT)(draw_area -> gx_rectangle_bottom - draw_area -> gx_rectangle_top + 1);
97 
98     y_height = (UINT)(draw_area -> gx_rectangle_right - draw_area -> gx_rectangle_left + 1);
99 
100     if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
101     {
102         rotated_left = draw_area -> gx_rectangle_top;
103         rotated_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - draw_area -> gx_rectangle_right - 1);
104 
105         rotated_map_offset_x = map_offset -> gx_point_y;
106         rotated_map_offset_y = (GX_VALUE)(glyph -> gx_glyph_width - map_offset -> gx_point_x - (GX_VALUE)y_height);
107     }
108     else
109     {
110         rotated_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_display_offset_y - draw_area -> gx_rectangle_bottom - 1);
111         rotated_top = draw_area -> gx_rectangle_left;
112 
113         rotated_map_offset_x = (GX_VALUE)(glyph -> gx_glyph_height - map_offset -> gx_point_y - (GX_VALUE)pixel_width);
114         rotated_map_offset_y = map_offset -> gx_point_x;
115     }
116 
117     leading_pixel = (rotated_map_offset_x & 1);
118 
119     pixel_width -= leading_pixel;
120 
121     trailing_pixel = pixel_width & 1;
122 
123     pixel_width = pixel_width >> 1;
124 
125     /* Find the width of the glyph.  */
126     pitch = glyph -> gx_glyph_height;
127 
128     /* Make it byte-aligned.  */
129     pitch = (pitch + 1) >> 1;
130 
131     glyph_row = (GX_UBYTE *)glyph -> gx_glyph_map;
132 
133     if (rotated_map_offset_y)
134     {
135         glyph_row = glyph_row + ((INT)pitch * rotated_map_offset_y);
136     }
137 
138     glyph_row += (rotated_map_offset_x >> 1);
139 
140     draw_start = (GX_UBYTE *)context -> gx_draw_context_memory;
141     draw_start += context -> gx_draw_context_pitch * rotated_top;
142     draw_start += rotated_left;
143 
144     for (row = 0; row < y_height; row++)
145     {
146         glyph_data = glyph_row;
147 
148         put = draw_start;
149 
150         if (leading_pixel)
151         {
152             alpha = (*glyph_data) & 0x0f;
153 
154             *put = (GX_UBYTE)(text_color - alpha);
155             put++;
156 
157             glyph_data++;
158         }
159         for (index = 0; index < pixel_width; index++)
160         {
161             alpha = (*glyph_data) & 0xf0;
162 
163             *put = (GX_UBYTE)(text_color - (alpha >> 4));
164             put++;
165 
166             alpha = (*glyph_data) & 0x0f;
167             *put = (GX_UBYTE)(text_color - alpha);
168             put++;
169             glyph_data++;
170         }
171 
172         if (trailing_pixel)
173         {
174             alpha = (*glyph_data) & 0xf0;
175             *put = (GX_UBYTE)(text_color - (alpha >> 4));
176             put++;
177         }
178 
179         glyph_row += pitch;
180         draw_start += context -> gx_draw_context_pitch;
181     }
182 }
183 
184