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