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_utility.h"
29 #include "gx_display.h"
30
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _gx_display_driver_generic_aliased_wide_line_draw PORTABLE C */
37 /* 6.1.3 */
38 /* AUTHOR */
39 /* */
40 /* Kenneth Maxwell, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* Generic display driver function for aliased wide line. */
45 /* */
46 /* INPUT */
47 /* */
48 /* context Drawing context */
49 /* xstart x-coord of endpoint */
50 /* ystart y-coord of endpoint */
51 /* xend x-coord of endpoint */
52 /* yend y-coord of endpoint */
53 /* */
54 /* OUTPUT */
55 /* */
56 /* None */
57 /* */
58 /* CALLS */
59 /* */
60 /* [gx_display_driver_simple_wide_line_draw] */
61 /* Basic display driver wide */
62 /* line draw function */
63 /* _gx_display_driver_generic_wide_line_points_calculate */
64 /* Calculate corners of wide line*/
65 /* _gx_display_driver_generic_aliased_filled_circle_draw */
66 /* Basic display driver aliased */
67 /* circle fill function */
68 /* _gx_display_driver_generic_wide_line_fill */
69 /* Basic display driver wide line*/
70 /* draw function */
71 /* */
72 /* CALLED BY */
73 /* */
74 /* GUIX Internal Code */
75 /* */
76 /* RELEASE HISTORY */
77 /* */
78 /* DATE NAME DESCRIPTION */
79 /* */
80 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
81 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
82 /* resulting in version 6.1 */
83 /* 12-31-2020 Kenneth Maxwell Modified comment(s), */
84 /* supported display rotation, */
85 /* resulting in version 6.1.3 */
86 /* */
87 /**************************************************************************/
_gx_display_driver_generic_aliased_wide_line_draw(GX_DRAW_CONTEXT * context,INT xstart,INT ystart,INT xend,INT yend)88 VOID _gx_display_driver_generic_aliased_wide_line_draw(GX_DRAW_CONTEXT *context, INT xstart,
89 INT ystart, INT xend, INT yend)
90 {
91 GX_DISPLAY *display = context -> gx_draw_context_display;
92 INT brush_width = context -> gx_draw_context_brush.gx_brush_width;
93 GX_FIXED_POINT *line_points;
94 GX_FIXED_VAL sxcenter;
95 GX_FIXED_VAL sycenter;
96 GX_FIXED_VAL excenter;
97 GX_FIXED_VAL eycenter;
98 GX_RECTANGLE clip_rect;
99
100 #if defined(GX_BRUSH_ALPHA_SUPPORT)
101 GX_UBYTE old_alpha;
102 old_alpha = context -> gx_draw_context_brush.gx_brush_alpha;
103 context -> gx_draw_context_brush.gx_brush_alpha = GX_ALPHA_VALUE_OPAQUE;
104 #endif
105 /* calculate the corners of this line, save them
106 to our points array
107 */
108 if (!(context -> gx_draw_context_display -> gx_display_driver_pixel_blend))
109 {
110 display -> gx_display_driver_simple_wide_line_draw(context, xstart, ystart, xend, yend);
111 return;
112 }
113
114 if ((context -> gx_draw_context_brush.gx_brush_style & GX_BRUSH_ROUND) &&
115 (brush_width > 2))
116 {
117 sxcenter = GX_FIXED_VAL_MAKE(xstart);
118 sycenter = GX_FIXED_VAL_MAKE(ystart);
119 excenter = GX_FIXED_VAL_MAKE(xend);
120 eycenter = GX_FIXED_VAL_MAKE(yend);
121
122 if (!(brush_width & 0x01))
123 {
124 if (ystart == yend)
125 {
126 /* Horizontal line. */
127 sycenter -= GX_FIXED_VAL_HALF;
128 eycenter -= GX_FIXED_VAL_HALF;
129 }
130 else if (xstart == xend)
131 {
132 /* Vertical line. */
133 sxcenter -= GX_FIXED_VAL_HALF;
134 excenter -= GX_FIXED_VAL_HALF;
135 }
136 }
137
138 _gx_display_driver_generic_aliased_filled_circle_draw(context, sxcenter, sycenter,
139 GX_FIXED_VAL_MAKE(brush_width) >> 1);
140
141 _gx_display_driver_generic_aliased_filled_circle_draw(context, excenter, eycenter,
142 GX_FIXED_VAL_MAKE(brush_width) >> 1);
143 }
144
145 if (ystart == yend)
146 {
147 /* Horizontal line. */
148
149 if (xstart > xend)
150 {
151 GX_SWAP_VALS(xstart, xend);
152 }
153
154 clip_rect.gx_rectangle_left = (GX_VALUE)xstart;
155 clip_rect.gx_rectangle_right = (GX_VALUE)xend;
156 clip_rect.gx_rectangle_top = (GX_VALUE)(ystart - (brush_width >> 1));
157 clip_rect.gx_rectangle_bottom = (GX_VALUE)(clip_rect.gx_rectangle_top + brush_width - 1);
158
159 if (_gx_utility_rectangle_overlap_detect(&clip_rect, context -> gx_draw_context_clip, &clip_rect))
160 {
161 display -> gx_display_driver_horizontal_line_draw(context,
162 clip_rect.gx_rectangle_left,
163 clip_rect.gx_rectangle_right,
164 clip_rect.gx_rectangle_top,
165 clip_rect.gx_rectangle_bottom - clip_rect.gx_rectangle_top + 1,
166 context -> gx_draw_context_brush.gx_brush_line_color);
167 }
168 }
169 else if (xstart == xend)
170 {
171 /* Vertical line. */
172
173 if (ystart > yend)
174 {
175 GX_SWAP_VALS(ystart, yend);
176 }
177
178 clip_rect.gx_rectangle_left = (GX_VALUE)(xstart - (brush_width >> 1));
179 clip_rect.gx_rectangle_right = (GX_VALUE)(clip_rect.gx_rectangle_left + brush_width - 1);
180 clip_rect.gx_rectangle_top = (GX_VALUE)ystart;
181 clip_rect.gx_rectangle_bottom = (GX_VALUE)yend;
182
183 if (_gx_utility_rectangle_overlap_detect(&clip_rect, context -> gx_draw_context_clip, &clip_rect))
184 {
185 display -> gx_display_driver_vertical_line_draw(context,
186 clip_rect.gx_rectangle_top,
187 clip_rect.gx_rectangle_bottom,
188 clip_rect.gx_rectangle_left,
189 clip_rect.gx_rectangle_right - clip_rect.gx_rectangle_left + 1,
190 context -> gx_draw_context_brush.gx_brush_line_color);
191 }
192 }
193 else
194 {
195 line_points = _gx_display_driver_generic_wide_line_points_calculate(context, xstart, ystart,
196 xend, yend, brush_width, GX_TRUE);
197
198 if (display -> gx_display_rotation_angle)
199 {
200 _gx_display_driver_generic_rotated_wide_line_fill(context, line_points);
201 }
202 else
203 {
204 _gx_display_driver_generic_wide_line_fill(context, line_points);
205 }
206 }
207
208 #if defined(GX_BRUSH_ALPHA_SUPPORT)
209 context -> gx_draw_context_brush.gx_brush_alpha = old_alpha;
210 #endif
211 }
212
213