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