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_8bpp_block_move PORTABLE C */
36 /* 6.1 */
37 /* AUTHOR */
38 /* */
39 /* Kenneth Maxwell, Microsoft Corporation */
40 /* */
41 /* DESCRIPTION */
42 /* */
43 /* 8-bit 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 /* */
72 /**************************************************************************/
_gx_display_driver_8bpp_block_move(GX_DRAW_CONTEXT * context,GX_RECTANGLE * block,INT xshift,INT yshift)73 VOID _gx_display_driver_8bpp_block_move(GX_DRAW_CONTEXT *context,
74 GX_RECTANGLE *block, INT xshift, INT yshift)
75 {
76 GX_UBYTE *pGet;
77 GX_UBYTE *pPut;
78 int width;
79 int y;
80 int height;
81
82 if (xshift)
83 {
84 if (xshift > 0)
85 {
86 pPut = (GX_UBYTE *)context -> gx_draw_context_memory;
87 pPut += block -> gx_rectangle_top * context -> gx_draw_context_pitch;
88 pPut += block -> gx_rectangle_left + xshift;
89
90 pGet = (GX_UBYTE *)context -> gx_draw_context_memory;
91 pGet += block -> gx_rectangle_top * context -> gx_draw_context_pitch;
92 pGet += block -> gx_rectangle_left;
93
94 width = block -> gx_rectangle_right - block -> gx_rectangle_left + 1 - xshift;
95
96 if (width <= 0)
97 {
98 /* Shift distance is bigger than block with. */
99 return;
100 }
101
102 for (y = block -> gx_rectangle_top; y <= block -> gx_rectangle_bottom; y++)
103 {
104 memmove(pPut, pGet, (size_t)width);
105
106 pPut += context -> gx_draw_context_pitch;
107 pGet += context -> gx_draw_context_pitch;
108 }
109 }
110 else
111 {
112 /* have to copy from left to right */
113 pPut = (GX_UBYTE *)context -> gx_draw_context_memory;
114 pPut += block -> gx_rectangle_top * context -> gx_draw_context_pitch;
115 pPut += block -> gx_rectangle_left;
116
117 pGet = (GX_UBYTE *)context -> gx_draw_context_memory;
118 pGet += block -> gx_rectangle_top * context -> gx_draw_context_pitch;
119 pGet += block -> gx_rectangle_left - xshift;
120
121 width = block -> gx_rectangle_right - block -> gx_rectangle_left + 1 + xshift;
122
123 if (width <= 0)
124 {
125 return;
126 }
127
128 for (y = block -> gx_rectangle_top; y <= block -> gx_rectangle_bottom; y++)
129 {
130 memmove(pPut, pGet, (size_t)width);
131
132 pPut += context -> gx_draw_context_pitch;
133 pGet += context -> gx_draw_context_pitch;
134 }
135 }
136 }
137 else
138 {
139 width = block -> gx_rectangle_right - block -> gx_rectangle_left + 1;
140
141 if (yshift > 0)
142 {
143 /* have to copy from bottom to top */
144 pPut = (GX_UBYTE *)context -> gx_draw_context_memory;
145 pPut += block -> gx_rectangle_bottom * context -> gx_draw_context_pitch;
146 pPut += block -> gx_rectangle_left;
147
148 pGet = (GX_UBYTE *)context -> gx_draw_context_memory;
149 pGet += (block -> gx_rectangle_bottom - yshift) * context -> gx_draw_context_pitch;
150 pGet += block -> gx_rectangle_left;
151
152 height = block -> gx_rectangle_bottom - block -> gx_rectangle_top + 1 - yshift;
153
154 for (y = 0; y < height; y++)
155 {
156 memmove(pPut, pGet, (size_t)width);
157
158 pPut -= context -> gx_draw_context_pitch;
159 pGet -= context -> gx_draw_context_pitch;
160 }
161 }
162 else
163 {
164 /* have to copy from top to bottom */
165 pPut = (GX_UBYTE *)context -> gx_draw_context_memory;
166 pPut += block -> gx_rectangle_top * context -> gx_draw_context_pitch;
167 pPut += block -> gx_rectangle_left;
168
169 pGet = (GX_UBYTE *)context -> gx_draw_context_memory;
170 pGet += (block -> gx_rectangle_top - yshift) * context -> gx_draw_context_pitch;
171 pGet += block -> gx_rectangle_left;
172
173 height = block -> gx_rectangle_bottom - block -> gx_rectangle_top + 1 + yshift;
174
175 for (y = 0; y < height; y++)
176 {
177 memmove(pPut, pGet, (size_t)width);
178
179 pPut += context -> gx_draw_context_pitch;
180 pGet += context -> gx_draw_context_pitch;
181 }
182 }
183 }
184 }
185
186