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_1bpp_block_move PORTABLE C */
36 /* 6.1 */
37 /* AUTHOR */
38 /* */
39 /* Kenneth Maxwell, Microsoft Corporation */
40 /* */
41 /* DESCRIPTION */
42 /* */
43 /* 1-bit color palette 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 /* */
72 /**************************************************************************/
_gx_display_driver_1bpp_block_move(GX_DRAW_CONTEXT * context,GX_RECTANGLE * block,INT xshift,INT yshift)73 VOID _gx_display_driver_1bpp_block_move(GX_DRAW_CONTEXT *context,
74 GX_RECTANGLE *block, INT xshift, INT yshift)
75 {
76 GX_UBYTE *putrow;
77 GX_UBYTE *getrow;
78 GX_UBYTE *pGet;
79 GX_UBYTE *pPut;
80 INT width;
81 INT column;
82 INT y;
83 INT height;
84 INT stride;
85 GX_UBYTE putmask;
86 GX_UBYTE getmask;
87 INT move_width;
88
89 putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
90
91 stride = (context -> gx_draw_context_pitch + 7) >> 3;
92
93 if (xshift)
94 {
95 if (xshift > 0)
96 {
97 /* Copy from left to right. */
98 width = block -> gx_rectangle_right - block -> gx_rectangle_left + 1;
99 width -= xshift;
100
101 putrow += block -> gx_rectangle_top * stride;
102 getrow = putrow;
103
104 putrow += block -> gx_rectangle_right >> 3;
105 getrow += (block -> gx_rectangle_left + width - 1) >> 3;
106
107 for (y = block -> gx_rectangle_top; y <= block -> gx_rectangle_bottom; y++)
108 {
109 pPut = putrow;
110 pGet = getrow;
111
112 putmask = (GX_UBYTE)(0x80 >> (block -> gx_rectangle_right & 0x07));
113 getmask = (GX_UBYTE)(0x80 >> ((block -> gx_rectangle_left + width - 1) & 0x07));
114
115 for (column = 0; column < width; column++)
116 {
117 if ((*pGet) & getmask)
118 {
119 *pPut |= putmask;
120 }
121 else
122 {
123 *pPut = (GX_UBYTE)((*pPut) & (~putmask));
124 }
125
126 if (getmask == 0x80)
127 {
128 getmask = 0x01;
129 pGet--;
130 }
131 else
132 {
133 getmask = (GX_UBYTE)(getmask << 1);
134 }
135
136 if (putmask == 0x80)
137 {
138 putmask = 0x01;
139 pPut--;
140 }
141 else
142 {
143 putmask = (GX_UBYTE)(putmask << 1);
144 }
145 }
146
147 putrow += stride;
148 getrow += stride;
149 }
150 }
151 else
152 {
153 /* Copy from right to left. */
154 width = block -> gx_rectangle_right - block -> gx_rectangle_left + 1;
155 width += xshift;
156
157 putrow += block -> gx_rectangle_top * stride;
158 getrow = putrow;
159
160 putrow += block -> gx_rectangle_left >> 3;
161 getrow += (block -> gx_rectangle_left - xshift) >> 3;
162
163 for (y = block -> gx_rectangle_top; y <= block -> gx_rectangle_bottom; y++)
164 {
165 pPut = putrow;
166 pGet = getrow;
167
168 putmask = (GX_UBYTE)(0x80 >> (block -> gx_rectangle_left & 0x07));
169 getmask = (GX_UBYTE)(0x80 >> ((block -> gx_rectangle_left - xshift) & 0x07));
170
171 for (column = 0; column < width; column++)
172 {
173 if ((*pGet) & getmask)
174 {
175 *pPut |= putmask;
176 }
177 else
178 {
179 *pPut &= (GX_UBYTE)(~putmask);
180 }
181
182 getmask >>= 1;
183 putmask >>= 1;
184
185 if (!getmask)
186 {
187 getmask = 0x80;
188 pGet++;
189 }
190 if (!putmask)
191 {
192 putmask = 0x80;
193 pPut++;
194 }
195 }
196
197 putrow += stride;
198 getrow += stride;
199 }
200 }
201 }
202 else
203 {
204 width = block -> gx_rectangle_right - block -> gx_rectangle_left + 1;
205
206 if (yshift > 0)
207 {
208 /* Copy from top to bottom. */
209 putrow += (block -> gx_rectangle_bottom * stride);
210 putrow += (block -> gx_rectangle_left >> 3);
211
212 getrow = putrow;
213 getrow -= yshift * stride;
214
215 height = block -> gx_rectangle_bottom - block -> gx_rectangle_top + 1;
216 height -= yshift;
217
218 for (y = 0; y < height; y++)
219 {
220 pPut = putrow;
221 pGet = getrow;
222
223 putmask = (GX_UBYTE)(0x80 >> (block -> gx_rectangle_left & 0x07));
224
225 column = 0;
226 while (column < width)
227 {
228 if ((putmask == 0x80) && (width - column >= 8))
229 {
230 move_width = (width - column) >> 3;
231 memmove(pPut, pGet, (size_t)move_width);
232 pPut += move_width;
233 pGet += move_width;
234 column += (move_width << 3);
235 }
236 else
237 {
238 if ((*pGet) & putmask)
239 {
240 *pPut |= putmask;
241 }
242 else
243 {
244 *pPut &= (GX_UBYTE)(~putmask);
245 }
246
247 putmask >>= 1;
248
249 if (!putmask)
250 {
251 putmask = 0x80;
252 pPut++;
253 pGet++;
254 }
255
256 column++;
257 }
258 }
259
260 putrow -= stride;
261 getrow -= stride;
262 }
263 }
264 else
265 {
266 /* Copy from bottom to top. */
267 putrow += (block -> gx_rectangle_top * stride);
268 putrow += (block -> gx_rectangle_left >> 3);
269
270 getrow = putrow;
271 getrow -= yshift * stride;
272
273 height = block -> gx_rectangle_bottom - block -> gx_rectangle_top + 1;
274 height += yshift;
275
276 for (y = 0; y < height; y++)
277 {
278 pPut = putrow;
279 pGet = getrow;
280
281 putmask = (GX_UBYTE)(0x80 >> (block -> gx_rectangle_left & 0x07));
282
283 column = 0;
284
285 while (column < width)
286 {
287 if ((putmask == 0x80) && (width - column >= 8))
288 {
289 move_width = (width - column) >> 3;
290 memmove(pPut, pGet, (size_t)move_width);
291 pPut += move_width;
292 pGet += move_width;
293 column += (move_width << 3);
294 }
295 else
296 {
297 if ((*pGet) & putmask)
298 {
299 *pPut |= putmask;
300 }
301 else
302 {
303 *pPut &= (GX_UBYTE)(~putmask);
304 }
305
306 putmask >>= 1;
307
308 if (!putmask)
309 {
310 putmask = 0x80;
311 pPut++;
312 pGet++;
313 }
314
315 column++;
316 }
317 }
318
319 putrow += stride;
320 getrow += stride;
321 }
322 }
323 }
324 }
325
326