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 /**   Screen Management (Screen)                                          */
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 /*  FUNCTION                                               RELEASE        */
35 /*                                                                        */
36 /*    _gx_canvas_pixelmap_draw                            PORTABLE C      */
37 /*                                                           6.1          */
38 /*  AUTHOR                                                                */
39 /*                                                                        */
40 /*    Kenneth Maxwell, Microsoft Corporation                              */
41 /*                                                                        */
42 /*  DESCRIPTION                                                           */
43 /*                                                                        */
44 /*    This function prepares to draw the specified pixelmap at the        */
45 /*    requested position.                                                 */
46 /*                                                                        */
47 /*  INPUT                                                                 */
48 /*                                                                        */
49 /*    x_position                            Top-left x-coord to place     */
50 /*                                            pixelmap                    */
51 /*    y_position                            Top-left y-coord to place     */
52 /*                                            pixelmap                    */
53 /*    pixelmap                              Pointer to actual pixelmap    */
54 /*                                            to draw                     */
55 /*                                                                        */
56 /*  OUTPUT                                                                */
57 /*                                                                        */
58 /*    status                                Completion status             */
59 /*                                                                        */
60 /*  CALLS                                                                 */
61 /*    _gx_utility_rectangle_define          Define a rectangle            */
62 /*    _gx_utility_rectangle_overlap_detect  Detect rectangle overlap      */
63 /*    [gx_display_driver_pixelmap_draw]     The display driver pixelmap   */
64 /*                                            draw routine                */
65 /*    [gx_display_driver_jpeg_draw]         The display driver JPEG draw  */
66 /*                                            routine                     */
67 /*    [gx_display_driver_png_draw]          The display driver PNG draw   */
68 /*                                            routine                     */
69 /*                                                                        */
70 /*  CALLED BY                                                             */
71 /*                                                                        */
72 /*    _gx_canvas_pixelmap_blend                                           */
73 /*    _gx_canvas_pixelmap_tile                                            */
74 /*    _gx_checkbox_draw                                                   */
75 /*    _gx_icon_button_draw                                                */
76 /*    _gx_icon_draw                                                       */
77 /*    _gx_pixelmap_button_draw                                            */
78 /*    _gx_pixelmap_prompt_draw                                            */
79 /*    _gx_pixelmap_slider_draw                                            */
80 /*    _gx_radio_button_draw                                               */
81 /*    _gx_scroll_thumb_draw                                               */
82 /*    _gx_scrollbar_draw                                                  */
83 /*    _gx_window_draw                                                     */
84 /*    _gx_scroll_thumb_draw                                               */
85 /*                                                                        */
86 /*  RELEASE HISTORY                                                       */
87 /*                                                                        */
88 /*    DATE              NAME                      DESCRIPTION             */
89 /*                                                                        */
90 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
91 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
92 /*                                            resulting in version 6.1    */
93 /*                                                                        */
94 /**************************************************************************/
_gx_canvas_pixelmap_draw(GX_VALUE x_position,GX_VALUE y_position,GX_PIXELMAP * pixelmap)95 UINT  _gx_canvas_pixelmap_draw(GX_VALUE x_position, GX_VALUE y_position, GX_PIXELMAP *pixelmap)
96 {
97 GX_DRAW_CONTEXT *context;
98 GX_DISPLAY      *display;
99 GX_RECTANGLE     clip_rect;
100 GX_RECTANGLE     bound;
101 GX_VIEW         *view;
102 VOID             (*pmp_function)(GX_DRAW_CONTEXT *, INT, INT, GX_PIXELMAP *);
103 
104     /* pick up the current drawing context */
105     context = _gx_system_current_draw_context;
106 
107     /* pick up current display driver */
108     display = context -> gx_draw_context_display;
109 
110     /* calculate rectangle that bounds the pixelmap */
111     _gx_utility_rectangle_define(&bound, x_position, y_position,
112                                  (GX_VALUE)(x_position + pixelmap -> gx_pixelmap_width - 1),
113                                  (GX_VALUE)(y_position + pixelmap -> gx_pixelmap_height - 1));
114 
115     /* clip the line bounding box to the dirty rectangle */
116     if (!_gx_utility_rectangle_overlap_detect(&bound, &context -> gx_draw_context_dirty, &bound))
117     {
118         /* nothing to draw, return */
119         return GX_SUCCESS;
120     }
121 
122     /* pickup pointer to correct pixelmap drawing function */
123     pmp_function = GX_NULL;
124 
125     if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_RAW_FORMAT)
126     {
127 #if defined(GX_SOFTWARE_DECODER_SUPPORT)
128         if ((pixelmap->gx_pixelmap_data[0] == 0xff) && (pixelmap->gx_pixelmap_data[1] == 0xd8))
129         {
130             /* JPEG */
131             pmp_function = display -> gx_display_driver_jpeg_draw;
132         }
133         else
134         {
135             if (pixelmap -> gx_pixelmap_data[1] == 'P')
136             {
137                 /* PNG */
138                 pmp_function = display -> gx_display_driver_png_draw;
139             }
140         }
141 #endif
142     }
143     else
144     {
145         if (pixelmap -> gx_pixelmap_format == GX_COLOR_FORMAT_8BIT_ALPHAMAP)
146         {
147             pmp_function = display -> gx_display_driver_alphamap_draw;
148         }
149         else
150         {
151             pmp_function = display -> gx_display_driver_pixelmap_draw;
152         }
153     }
154 
155     if (!pmp_function)
156     {
157         /* display driver does not support requested action */
158         return GX_FAILURE;
159     }
160 
161     /* test to determine if the bounding rectangle overlaps the region we are allowed to draw
162        into. For each view that overlaps the bounding rectangle, do some drawing.
163      */
164     view = context -> gx_draw_context_view_head;
165 
166     while (view)
167     {
168         if (!_gx_utility_rectangle_overlap_detect(&view -> gx_view_rectangle, &bound, &clip_rect))
169         {
170             view = view -> gx_view_next;
171             continue;
172         }
173 
174         /* we have a view into which we can draw the pixelmap, do it */
175 
176         /* first, set the context clip rectangle */
177         context -> gx_draw_context_clip = &clip_rect;
178 
179         /* now pass the context and drawing params to driver level function */
180         pmp_function(context, x_position, y_position, pixelmap);
181 
182         /* go to the next view */
183         view = view -> gx_view_next;
184     }
185 
186     /* Return successful completion.  */
187     return(GX_SUCCESS);
188 }
189 
190