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 /* Internal scratch area. */
33 static GX_FIXED_POINT LinePoints[5];
34
35 /**************************************************************************/
36 /* */
37 /* FUNCTION RELEASE */
38 /* */
39 /* _gx_display_driver_generic_wide_line_points_calculate */
40 /* PORTABLE C */
41 /* 6.1 */
42 /* */
43 /* AUTHOR */
44 /* */
45 /* Kenneth Maxwell, Microsoft Corporation */
46 /* */
47 /* DESCRIPTION */
48 /* */
49 /* Calculate corners of wide line. Used by all versions (anti-aliased */
50 /* or not, square or round ends) of wide line drawinggeneric display */
51 /* driver wide line drawing function. */
52 /* */
53 /* INPUT */
54 /* */
55 /* context Drawing context */
56 /* xStart x-coord of endpoint */
57 /* yStart y-coord of endpoint */
58 /* xEnd x-coord of endpoint */
59 /* yEnd y-coord of endpoint */
60 /* outline Whether or not to draw */
61 /* outline */
62 /* */
63 /* OUTPUT */
64 /* */
65 /* GX_POINT* Calculated end points */
66 /* */
67 /* CALLS */
68 /* */
69 /* GX_ABS Compute the absolute value */
70 /* GX_SWAP_VALS Swap two values */
71 /* GX_FIXED_VAL_MAKE */
72 /* GX_FIXED_VAL_RND */
73 /* _gx_utility_math_sqrt Compute the square root value */
74 /* [gx_display_driver_anti_aliased_line_draw */
75 /* Driver function that draws */
76 /* anti-aliased lines. */
77 /* */
78 /* CALLED BY */
79 /* */
80 /* _gx_display_driver_generic_simple_wide_line_draw */
81 /* _gx_display_driver_generic_aliased_wide_line_draw */
82 /* */
83 /* RELEASE HISTORY */
84 /* */
85 /* DATE NAME DESCRIPTION */
86 /* */
87 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
88 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
89 /* resulting in version 6.1 */
90 /* */
91 /**************************************************************************/
_gx_display_driver_generic_wide_line_points_calculate(GX_DRAW_CONTEXT * context,INT xStart,INT yStart,INT xEnd,INT yEnd,INT brush_width,GX_BOOL outline)92 GX_FIXED_POINT *_gx_display_driver_generic_wide_line_points_calculate(GX_DRAW_CONTEXT *context, INT xStart, INT yStart,
93 INT xEnd, INT yEnd, INT brush_width, GX_BOOL outline)
94 {
95 GX_FIXED_VAL distance;
96 GX_FIXED_VAL brush_distance;
97 GX_FIXED_POINT FixedPoints[5];
98 INT LineDirection[4];
99 int xsign;
100 int ysign;
101 int xside;
102 int yside;
103 VOID (*aliased_line)(GX_DRAW_CONTEXT *context, GX_FIXED_VAL x1, GX_FIXED_VAL y1, GX_FIXED_VAL x2, GX_FIXED_VAL y2);
104
105 int dx = GX_ABS(xEnd - xStart);
106 int dy = GX_ABS(yEnd - yStart);
107
108 if (((dx >= dy && (xStart > xEnd)) || ((dy > dx) && yStart > yEnd)))
109 {
110 GX_SWAP_VALS(xEnd, xStart);
111 GX_SWAP_VALS(yEnd, yStart);
112 }
113
114 distance = (GX_FIXED_VAL)_gx_utility_math_sqrt((UINT)(GX_FIXED_VAL_MAKE(dx * dx) + GX_FIXED_VAL_MAKE(dy * dy)));
115 distance <<= (GX_FIXED_VAL_SHIFT >> 1);
116 brush_distance = GX_FIXED_VAL_MAKE(brush_width - 1);
117 brush_distance >>= 1;
118 xsign = ysign = 1;
119
120 if (dx)
121 {
122 xsign = (xEnd - xStart) / dx;
123 }
124 if (dy)
125 {
126 ysign = (yEnd - yStart) / dy;
127 }
128
129 xside = dy;
130 xside *= brush_distance;
131 xside /= (distance >> GX_FIXED_VAL_SHIFT);
132 xside *= xsign;
133
134 yside = dx;
135 yside *= brush_distance;
136 yside /= (distance >> GX_FIXED_VAL_SHIFT);
137 yside *= ysign;
138
139 LineDirection[0] = 0;
140 LineDirection[1] = 1;
141 LineDirection[2] = 2;
142 LineDirection[3] = 3;
143
144 if (yEnd < yStart)
145 {
146 LineDirection[1] = 3;
147 LineDirection[3] = 1;
148 }
149
150 if (xEnd < xStart)
151 {
152 LineDirection[0] = 2;
153 LineDirection[2] = 0;
154 }
155
156 FixedPoints[LineDirection[0]].x = GX_FIXED_VAL_MAKE(xStart) - xside;
157 FixedPoints[LineDirection[0]].y = GX_FIXED_VAL_MAKE(yStart) + yside;
158 FixedPoints[LineDirection[1]].x = GX_FIXED_VAL_MAKE(xStart) + xside;
159 FixedPoints[LineDirection[1]].y = GX_FIXED_VAL_MAKE(yStart) - yside;
160 FixedPoints[LineDirection[2]].x = GX_FIXED_VAL_MAKE(xEnd) + xside;
161 FixedPoints[LineDirection[2]].y = GX_FIXED_VAL_MAKE(yEnd) - yside;
162 FixedPoints[LineDirection[3]].x = GX_FIXED_VAL_MAKE(xEnd) - xside;
163 FixedPoints[LineDirection[3]].y = GX_FIXED_VAL_MAKE(yEnd) + yside;
164
165 LinePoints[0] = FixedPoints[0];
166 LinePoints[1] = FixedPoints[1];
167 LinePoints[2] = FixedPoints[2];
168 LinePoints[3] = FixedPoints[3];
169
170 if (outline)
171 {
172 aliased_line = _gx_display_driver_generic_aliased_fixed_point_line_draw;
173
174 aliased_line(context, FixedPoints[0].x,
175 FixedPoints[0].y,
176 FixedPoints[1].x,
177 FixedPoints[1].y);
178
179 aliased_line(context, FixedPoints[1].x,
180 FixedPoints[1].y,
181 FixedPoints[2].x,
182 FixedPoints[2].y);
183
184 aliased_line(context, FixedPoints[2].x,
185 FixedPoints[2].y,
186 FixedPoints[3].x,
187 FixedPoints[3].y);
188
189 aliased_line(context, FixedPoints[3].x,
190 FixedPoints[3].y,
191 FixedPoints[0].x,
192 FixedPoints[0].y);
193 }
194
195 /* close the polygon */
196 LinePoints[4] = LinePoints[0];
197
198 return(LinePoints);
199 }
200
201