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