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