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 /**   Canvas Management (Canvas)                                          */
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 #include "gx_canvas.h"
31 
32 
33 /**************************************************************************/
34 /*                                                                        */
35 /*  FUNCTION                                               RELEASE        */
36 /*                                                                        */
37 /*    _gx_canvas_polygon_draw                             PORTABLE C      */
38 /*                                                           6.1          */
39 /*  AUTHOR                                                                */
40 /*                                                                        */
41 /*    Kenneth Maxwell, Microsoft Corporation                              */
42 /*                                                                        */
43 /*  DESCRIPTION                                                           */
44 /*                                                                        */
45 /*    This draws a polygon into the current context.                      */
46 /*                                                                        */
47 /*  INPUT                                                                 */
48 /*                                                                        */
49 /*    point_array                           Array of points of the polygon*/
50 /*                                            terminated by NULL entry.   */
51 /*    number_of_points                      Number of points of polygon   */
52 /*                                                                        */
53 /*  OUTPUT                                                                */
54 /*                                                                        */
55 /*    status                                Completion status             */
56 /*                                                                        */
57 /*  CALLS                                                                 */
58 /*                                                                        */
59 /*    _gx_utility_rectangle_define          Define a rectangle            */
60 /*    _gx_utility_rectangle_overlap_detect  Detect rectangle overlap      */
61 /*    [gx_display_driver_polygon_draw]      The display driver basic      */
62 /*                                            polygon drawing routine     */
63 /*    [gx_display_driver_polygon_fill]      The display driver basic      */
64 /*                                            polygon drawing routine     */
65 /*                                                                        */
66 /*  CALLED BY                                                             */
67 /*                                                                        */
68 /*    Application Code                                                    */
69 /*                                                                        */
70 /*  RELEASE HISTORY                                                       */
71 /*                                                                        */
72 /*    DATE              NAME                      DESCRIPTION             */
73 /*                                                                        */
74 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
75 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
76 /*                                            resulting in version 6.1    */
77 /*                                                                        */
78 /**************************************************************************/
_gx_canvas_polygon_draw(GX_POINT * point_array,INT number_of_points)79 UINT  _gx_canvas_polygon_draw(GX_POINT *point_array, INT number_of_points)
80 {
81 GX_DRAW_CONTEXT *context;
82 GX_DISPLAY      *display;
83 GX_RECTANGLE     bound;
84 GX_VIEW         *view;
85 GX_RECTANGLE     clip_rect;
86 INT              i;
87 GX_VALUE         left = point_array[0].gx_point_x;
88 GX_VALUE         right = point_array[0].gx_point_x;
89 GX_VALUE         top = point_array[0].gx_point_y;
90 GX_VALUE         bottom = point_array[0].gx_point_y;
91 GX_VALUE         width;
92 
93     /* Calculate the minumum bounding rectangle. */
94     for (i = 1; i < number_of_points; i++)
95     {
96         if (point_array[i].gx_point_x < left)
97         {
98             left = point_array[i].gx_point_x;
99         }
100         if (point_array[i].gx_point_x > right)
101         {
102             right = point_array[i].gx_point_x;
103         }
104         if (point_array[i].gx_point_y < top)
105         {
106             top = point_array[i].gx_point_y;
107         }
108         if (point_array[i].gx_point_y > bottom)
109         {
110             bottom = point_array[i].gx_point_y;
111         }
112     }
113 
114     /* pick up the current drawing context */
115     context = _gx_system_current_draw_context;
116 
117     width = (GX_VALUE)((context -> gx_draw_context_brush.gx_brush_width + 1) >> 1);
118 
119     _gx_utility_rectangle_define(&bound, (GX_VALUE)(left - width), (GX_VALUE)(top - width), (GX_VALUE)(right + width), (GX_VALUE)(bottom + width));
120 
121     /* clip the polygon bounding box to the dirty rectangle */
122     if (!_gx_utility_rectangle_overlap_detect(&bound, &context -> gx_draw_context_dirty, &bound))
123     {
124         /* nothing to draw, return */
125         return GX_SUCCESS;
126     }
127 
128     /* pick up current display driver */
129     display = context -> gx_draw_context_display;
130 
131     /* test to determine if the bounding rectangle overlaps the region we are allowed to draw
132        into. For each view that overlaps the bounding rectangle, do some drawing.
133      */
134     view = context -> gx_draw_context_view_head;
135 
136     while (view)
137     {
138         if (!_gx_utility_rectangle_overlap_detect(&view -> gx_view_rectangle, &bound, &clip_rect))
139         {
140             view = view -> gx_view_next;
141             continue;
142         }
143 
144         /* we have a view into which we can draw the polygon, do it */
145         context -> gx_draw_context_clip = &clip_rect;
146 
147         if (context -> gx_draw_context_brush.gx_brush_style & (GX_BRUSH_SOLID_FILL | GX_BRUSH_PIXELMAP_FILL))
148         {
149             display -> gx_display_driver_polygon_fill(context, point_array, number_of_points);
150         }
151 
152         if (display -> gx_display_driver_polygon_draw)
153         {
154             /* Draw polygon. */
155             display -> gx_display_driver_polygon_draw(context, point_array, number_of_points);
156         }
157 
158         view = view -> gx_view_next;
159     }
160 
161     /* Return successful completion.  */
162     return(GX_SUCCESS);
163 }
164 
165