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