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_blend PORTABLE C */
37 /* 6.1 */
38 /* AUTHOR */
39 /* */
40 /* Kenneth Maxwell, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function prepares to blend the specified pixelmap with */
45 /* background at the 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 /* alpha blending value 0-255 */
56 /* */
57 /* OUTPUT */
58 /* */
59 /* status Completion status */
60 /* */
61 /* CALLS */
62 /* */
63 /* _gx_utility_rectangle_define Define a rectangle */
64 /* _gx_utility_rectangle_overlap_detect Detect rectangle overlap */
65 /* [gx_display_driver_pixelmap_draw] Driver level pixelmap blend */
66 /* function */
67 /* */
68 /* CALLED BY */
69 /* */
70 /* Application Code */
71 /* _gx_sprite_draw */
72 /* */
73 /* RELEASE HISTORY */
74 /* */
75 /* DATE NAME DESCRIPTION */
76 /* */
77 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
78 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
79 /* resulting in version 6.1 */
80 /* */
81 /**************************************************************************/
_gx_canvas_pixelmap_blend(GX_VALUE x_position,GX_VALUE y_position,GX_PIXELMAP * pixelmap,GX_UBYTE alpha)82 UINT _gx_canvas_pixelmap_blend(GX_VALUE x_position, GX_VALUE y_position,
83 GX_PIXELMAP *pixelmap, GX_UBYTE alpha)
84 {
85 GX_DRAW_CONTEXT *context;
86 GX_DISPLAY *display;
87 GX_RECTANGLE clip_rect;
88 GX_RECTANGLE bound;
89 GX_VIEW *view;
90 GX_UBYTE old_alpha;
91 VOID (*pmp_function)(GX_DRAW_CONTEXT *, INT, INT, GX_PIXELMAP *);
92
93 if (alpha == 0)
94 {
95 return GX_SUCCESS;
96 }
97
98 /* pick up the current drawing context */
99 context = _gx_system_current_draw_context;
100
101 /* calculate rectangle that bounds the pixelmap */
102 _gx_utility_rectangle_define(&bound, x_position, y_position,
103 (GX_VALUE)(x_position + pixelmap -> gx_pixelmap_width - 1),
104 (GX_VALUE)(y_position + pixelmap -> gx_pixelmap_height - 1));
105
106 /* clip the line bounding box to the dirty rectangle */
107 if (!_gx_utility_rectangle_overlap_detect(&bound, &context -> gx_draw_context_dirty, &bound))
108 {
109 /* nothing to draw, return */
110 return GX_SUCCESS;
111 }
112
113 /* pick up current display driver */
114 display = context -> gx_draw_context_display;
115
116 /* pickup pointer to correct pixelmap blending function */
117 if (pixelmap -> gx_pixelmap_format == GX_COLOR_FORMAT_8BIT_ALPHAMAP)
118 {
119 pmp_function = display -> gx_display_driver_alphamap_draw;
120 }
121 else
122 {
123 pmp_function = display -> gx_display_driver_pixelmap_draw;
124 }
125
126 if (pmp_function == GX_NULL)
127 {
128 return GX_NOT_SUPPORTED;
129 }
130
131 /* Set the parameter alpha to brush alpha value. */
132 old_alpha = context -> gx_draw_context_brush.gx_brush_alpha;
133 context -> gx_draw_context_brush.gx_brush_alpha = alpha;
134
135 /* test to determine if the bounding rectangle overlaps the region we are allowed to draw
136 into. For each view that overlaps the bounding rectangle, do some drawing.
137 */
138 view = context -> gx_draw_context_view_head;
139
140 while (view)
141 {
142 if (!_gx_utility_rectangle_overlap_detect(&view -> gx_view_rectangle, &bound, &clip_rect))
143 {
144 view = view -> gx_view_next;
145 continue;
146 }
147
148 /* we have a view into which we can draw the pixelmap, do it */
149 /* first, set the context clip rectangle */
150 context -> gx_draw_context_clip = &clip_rect;
151
152 /* now pass the context and drawing params to driver level function */
153 pmp_function(context, x_position, y_position, pixelmap);
154
155 /* go to the next view */
156 view = view -> gx_view_next;
157 }
158
159 context -> gx_draw_context_brush.gx_brush_alpha = old_alpha;
160
161 /* Return successful completion. */
162 return(GX_SUCCESS);
163 }
164
165