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 /** Display Management (Display) */
18 /** */
19 /**************************************************************************/
20
21 #define GX_SOURCE_CODE
22
23
24 /* Include necessary system files. */
25
26 #include "gx_api.h"
27 #include "gx_display.h"
28 #include "gx_system.h"
29 #include "gx_utility.h"
30
31 /**************************************************************************/
32 /* */
33 /* FUNCTION RELEASE */
34 /* */
35 /* _gx_display_driver_16bpp_block_move PORTABLE C */
36 /* 6.3.0 */
37 /* AUTHOR */
38 /* */
39 /* Kenneth Maxwell, Microsoft Corporation */
40 /* */
41 /* DESCRIPTION */
42 /* */
43 /* Generic 16bpp color format display driver block moving function. */
44 /* */
45 /* INPUT */
46 /* */
47 /* context Draw context */
48 /* block The rectangle to be moved */
49 /* xshift Amount to move on X-axis */
50 /* yshift Amount to move on Y-axis */
51 /* */
52 /* OUTPUT */
53 /* */
54 /* None */
55 /* */
56 /* CALLS */
57 /* */
58 /* memmove Move a block of data */
59 /* */
60 /* CALLED BY */
61 /* */
62 /* GUIX Internal Code */
63 /* */
64 /* RELEASE HISTORY */
65 /* */
66 /* DATE NAME DESCRIPTION */
67 /* */
68 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
69 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
70 /* resulting in version 6.1 */
71 /* 10-31-2023 Ting Zhu Modified comment(s), */
72 /* added canvas status check, */
73 /* resulting in version 6.3.0 */
74 /* */
75 /**************************************************************************/
_gx_display_driver_16bpp_block_move(GX_DRAW_CONTEXT * context,GX_RECTANGLE * block,INT xshift,INT yshift)76 VOID _gx_display_driver_16bpp_block_move(GX_DRAW_CONTEXT *context,
77 GX_RECTANGLE *block, INT xshift, INT yshift)
78 {
79 USHORT *pGet;
80 USHORT *pPut;
81 INT width;
82 INT width_in_bytes;
83 INT y;
84 INT height;
85
86 #ifdef GX_ENABLE_CANVAS_PARTIAL_FRAME_BUFFER
87 if (context -> gx_draw_context_canvas -> gx_canvas_status & GX_CANVAS_PARTIAL_FRAME_BUFFER)
88 {
89 /* Not supported. */
90 return;
91 }
92 #endif
93
94 if (xshift)
95 {
96 if (xshift > 0)
97 {
98 /* have to copy from left to right. */
99 pPut = (USHORT *)context -> gx_draw_context_memory;
100 pPut += block -> gx_rectangle_top * context -> gx_draw_context_pitch;
101 pPut += block -> gx_rectangle_left + xshift;
102
103 pGet = (USHORT *)context -> gx_draw_context_memory;
104 pGet += block -> gx_rectangle_top * context -> gx_draw_context_pitch;
105 pGet += block -> gx_rectangle_left;
106
107 width = block -> gx_rectangle_right - block -> gx_rectangle_left + 1 - xshift;
108 width_in_bytes = width * (int)sizeof(USHORT);
109
110 if (width_in_bytes <= 0)
111 {
112 return;
113 }
114
115 for (y = block -> gx_rectangle_top; y <= block -> gx_rectangle_bottom; y++)
116 {
117 memmove(pPut, pGet, (size_t)width_in_bytes);
118
119 pPut += context -> gx_draw_context_pitch;
120 pGet += context -> gx_draw_context_pitch;
121 }
122 }
123 else
124 {
125 /* have to copy from right to left */
126 pPut = (USHORT *)context -> gx_draw_context_memory;
127 pPut += block -> gx_rectangle_top * context -> gx_draw_context_pitch;
128 pPut += block -> gx_rectangle_left;
129
130 pGet = (USHORT *)context -> gx_draw_context_memory;
131 pGet += block -> gx_rectangle_top * context -> gx_draw_context_pitch;
132 pGet += block -> gx_rectangle_left - xshift;
133
134 width = block -> gx_rectangle_right - block -> gx_rectangle_left + 1 + xshift;
135 width_in_bytes = width * (int)sizeof(USHORT);
136
137 if (width_in_bytes <= 0)
138 {
139 return;
140 }
141
142 for (y = block -> gx_rectangle_top; y <= block -> gx_rectangle_bottom; y++)
143 {
144 memmove(pPut, pGet, (size_t)width_in_bytes);
145
146 pPut += context -> gx_draw_context_pitch;
147 pGet += context -> gx_draw_context_pitch;
148 }
149 }
150 }
151 else
152 {
153 width = block -> gx_rectangle_right - block -> gx_rectangle_left + 1;
154 width_in_bytes = width * (int)sizeof(USHORT);
155
156 if (yshift > 0)
157 {
158 /* have to copy from top to bottom */
159 pPut = (USHORT *)context -> gx_draw_context_memory;
160 pPut += block -> gx_rectangle_bottom * context -> gx_draw_context_pitch;
161 pPut += block -> gx_rectangle_left;
162
163 pGet = (USHORT *)context -> gx_draw_context_memory;
164 pGet += (block -> gx_rectangle_bottom - yshift) * context -> gx_draw_context_pitch;
165 pGet += block -> gx_rectangle_left;
166
167 height = block -> gx_rectangle_bottom - block -> gx_rectangle_top + 1 - yshift;
168
169 for (y = 0; y < height; y++)
170 {
171 memmove(pPut, pGet, (size_t)width_in_bytes);
172
173 pPut -= context -> gx_draw_context_pitch;
174 pGet -= context -> gx_draw_context_pitch;
175 }
176 }
177 else
178 {
179 /* have to copy from bottom to top */
180 pPut = (USHORT *)context -> gx_draw_context_memory;
181 pPut += block -> gx_rectangle_top * context -> gx_draw_context_pitch;
182 pPut += block -> gx_rectangle_left;
183
184 pGet = (USHORT *)context -> gx_draw_context_memory;
185 pGet += (block -> gx_rectangle_top - yshift) * context -> gx_draw_context_pitch;
186 pGet += block -> gx_rectangle_left;
187
188 height = block -> gx_rectangle_bottom - block -> gx_rectangle_top + 1 + yshift;
189
190 for (y = 0; y < height; y++)
191 {
192 memmove(pPut, pGet, (size_t)width_in_bytes);
193
194 pPut += context -> gx_draw_context_pitch;
195 pGet += context -> gx_draw_context_pitch;
196 }
197 }
198 }
199 }
200
201