GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_4bpp_block_move.c Lines: 136 136 100.0 %
Date: 2026-03-06 19:21:09 Branches: 70 70 100.0 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 * Copyright (c) 2026-present Eclipse ThreadX contributors
4
 *
5
 * This program and the accompanying materials are made available under the
6
 * terms of the MIT License which is available at
7
 * https://opensource.org/licenses/MIT.
8
 *
9
 * SPDX-License-Identifier: MIT
10
 **************************************************************************/
11
12
13
/**************************************************************************/
14
/**************************************************************************/
15
/**                                                                       */
16
/** GUIX Component                                                        */
17
/**                                                                       */
18
/**   Display Management (Display)                                        */
19
/**                                                                       */
20
/**************************************************************************/
21
22
#define GX_SOURCE_CODE
23
24
25
/* Include necessary system files.  */
26
27
#include "gx_api.h"
28
#include "gx_display.h"
29
#include "gx_system.h"
30
#include "gx_utility.h"
31
32
/**************************************************************************/
33
/*                                                                        */
34
/*  FUNCTION                                               RELEASE        */
35
/*                                                                        */
36
/*    _gx_display_driver_4bpp_block_move                  PORTABLE C      */
37
/*                                                           6.1          */
38
/*  AUTHOR                                                                */
39
/*                                                                        */
40
/*    Kenneth Maxwell, Microsoft Corporation                              */
41
/*                                                                        */
42
/*  DESCRIPTION                                                           */
43
/*                                                                        */
44
/*    4-bpp display driver block moving function.                         */
45
/*                                                                        */
46
/*  INPUT                                                                 */
47
/*                                                                        */
48
/*    context                               Draw context                  */
49
/*    block                                 The rectangle to be moved     */
50
/*    xshift                                Amount to move on X-axis      */
51
/*    yshift                                Amount to move on Y-axis      */
52
/*                                                                        */
53
/*  OUTPUT                                                                */
54
/*                                                                        */
55
/*    None                                                                */
56
/*                                                                        */
57
/*  CALLS                                                                 */
58
/*                                                                        */
59
/*    memmove                               Move a block of data          */
60
/*                                                                        */
61
/*  CALLED BY                                                             */
62
/*                                                                        */
63
/*    GUIX Internal Code                                                  */
64
/*                                                                        */
65
/**************************************************************************/
66
16
VOID _gx_display_driver_4bpp_block_move(GX_DRAW_CONTEXT *context,
67
                                        GX_RECTANGLE *block, INT xshift, INT yshift)
68
{
69
GX_UBYTE *putrow;
70
GX_UBYTE *getrow;
71
GX_UBYTE *pGet;
72
GX_UBYTE *pPut;
73
INT       width;
74
INT       column;
75
INT       y;
76
INT       height;
77
INT       stride;
78
GX_UBYTE  putmask;
79
GX_UBYTE  getmask;
80
INT       move_width;
81
82
16
    putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
83
84
16
    stride = (context -> gx_draw_context_pitch + 1) >> 1;
85
86
16
    if (xshift)
87
    {
88
9
        if (xshift > 0)
89
        {
90
            /* Copy from right to left.  */
91
5
            width = block -> gx_rectangle_right - block -> gx_rectangle_left + 1;
92
5
            width -= xshift;
93
94
5
            putrow += block -> gx_rectangle_top * stride;
95
5
            getrow = putrow;
96
97
5
            putrow += block -> gx_rectangle_right >> 1;
98
5
            getrow += (block -> gx_rectangle_left + width - 1) >> 1;
99
100
546
            for (y = block -> gx_rectangle_top; y <= block -> gx_rectangle_bottom; y++)
101
            {
102
541
                pPut = putrow;
103
541
                pGet = getrow;
104
105
541
                if (block -> gx_rectangle_right & 0x01)
106
                {
107
456
                    putmask = 0x0f;
108
                }
109
                else
110
                {
111
85
                    putmask = 0xf0;
112
                }
113
114
541
                if ((block -> gx_rectangle_left + width - 1) & 0x01)
115
                {
116
114
                    getmask = 0x0f;
117
                }
118
                else
119
                {
120
427
                    getmask = 0xf0;
121
                }
122
123
77645
                for (column = 0; column < width; column++)
124
                {
125
                    /* Set bits to 0. */
126
77104
                    *pPut &= (GX_UBYTE)(~putmask);
127
128
77104
                    if ((*pGet) & getmask)
129
                    {
130
75695
                        if (getmask == putmask)
131
                        {
132
11609
                            *pPut |= ((*pGet) & getmask);
133
                        }
134
                        else
135
                        {
136
64086
                            if (getmask == 0xf0)
137
                            {
138
32208
                                *pPut |= (GX_UBYTE)((((*pGet) & getmask) >> 4) & 0x0f);
139
                            }
140
                            else
141
                            {
142
31878
                                *pPut |= (GX_UBYTE)((GX_UBYTE)(((*pGet) & getmask) << 4) & 0xf0);
143
                            }
144
                        }
145
                    }
146
147
77104
                    if (getmask == 0xf0)
148
                    {
149
38723
                        getmask = 0x0f;
150
38723
                        pGet--;
151
                    }
152
                    else
153
                    {
154
38381
                        getmask = 0xf0;
155
                    }
156
157
77104
                    if (putmask == 0xf0)
158
                    {
159
38381
                        putmask = 0x0f;
160
38381
                        pPut--;
161
                    }
162
                    else
163
                    {
164
38723
                        putmask = 0xf0;
165
                    }
166
                }
167
168
541
                putrow += stride;
169
541
                getrow += stride;
170
            }
171
        }
172
        else
173
        {
174
            /* Copy from right to left.  */
175
4
            width = block -> gx_rectangle_right - block -> gx_rectangle_left + 1;
176
4
            width += xshift;
177
178
4
            putrow += block -> gx_rectangle_top * stride;
179
4
            getrow = putrow;
180
181
4
            putrow += block -> gx_rectangle_left >> 1;
182
4
            getrow += (block -> gx_rectangle_left - xshift) >> 1;
183
184
431
            for (y = block -> gx_rectangle_top; y <= block -> gx_rectangle_bottom; y++)
185
            {
186
427
                pPut = putrow;
187
427
                pGet = getrow;
188
189
427
                if (block -> gx_rectangle_left & 0x01)
190
                {
191
85
                    putmask = 0x0f;
192
                }
193
                else
194
                {
195
342
                    putmask = 0xf0;
196
                }
197
198
427
                if ((block -> gx_rectangle_left - xshift) & 0x01)
199
                {
200
313
                    getmask = 0x0f;
201
                }
202
                else
203
                {
204
114
                    getmask = 0xf0;
205
                }
206
207
47321
                for (column = 0; column < width; column++)
208
                {
209
                    /* Set bits to 0. */
210
46894
                    *pPut &= (GX_UBYTE)(~putmask);
211
212
46894
                    if ((*pGet) & getmask)
213
                    {
214
45329
                        if (getmask == putmask)
215
                        {
216
11609
                            *pPut |= ((*pGet) & getmask);
217
                        }
218
                        else
219
                        {
220
33720
                            if (getmask == 0xf0)
221
                            {
222
16749
                                *pPut |= (GX_UBYTE)((((*pGet) & getmask) >> 4) & 0x0f);
223
                            }
224
                            else
225
                            {
226
16971
                                *pPut |= (GX_UBYTE)((GX_UBYTE)(((*pGet) & getmask) << 4) & 0xf0);
227
                            }
228
                        }
229
                    }
230
231
46894
                    getmask >>= 4;
232
46894
                    if (getmask == 0)
233
                    {
234
23561
                        getmask = 0xf0;
235
23561
                        pGet++;
236
                    }
237
238
46894
                    putmask >>= 4;
239
46894
                    if (putmask == 0)
240
                    {
241
23333
                        putmask = 0xf0;
242
23333
                        pPut++;
243
                    }
244
                }
245
246
427
                putrow += stride;
247
427
                getrow += stride;
248
            }
249
        }
250
    }
251
    else
252
    {
253
7
        width = block -> gx_rectangle_right - block -> gx_rectangle_left + 1;
254
255
7
        if (yshift > 0)
256
        {
257
            /* Copy from top to bottom.  */
258
4
            putrow += (block -> gx_rectangle_bottom * stride);
259
4
            putrow += (block -> gx_rectangle_left >> 1);
260
261
4
            getrow = putrow;
262
4
            getrow -= yshift * stride;
263
264
4
            height = block -> gx_rectangle_bottom - block -> gx_rectangle_top + 1;
265
4
            height -= yshift;
266
267
411
            for (y = 0; y < height; y++)
268
            {
269
407
                pPut = putrow;
270
407
                pGet = getrow;
271
272
407
                if (block -> gx_rectangle_left & 0x01)
273
                {
274
68
                    putmask = 0x0f;
275
                }
276
                else
277
                {
278
339
                    putmask = 0xf0;
279
                }
280
281
407
                column = 0;
282
950
                while (column < width)
283
                {
284

543
                    if ((putmask == 0xf0) && (width - column >= 2))
285
                    {
286
407
                        move_width = (width - column) >> 1;
287
407
                        memmove(pPut, pGet, (size_t)move_width);
288
407
                        pPut += move_width;
289
407
                        pGet += move_width;
290
407
                        column += (move_width << 1);
291
                    }
292
                    else
293
                    {
294
136
                        *pPut &= (GX_UBYTE)(~putmask);
295
136
                        if ((*pGet) & putmask)
296
                        {
297
12
                            *pPut |= (GX_UBYTE)((*pGet) & putmask);
298
                        }
299
300
301
136
                        putmask >>= 4;
302
303
136
                        if (putmask == 0)
304
                        {
305
68
                            putmask = 0xf0;
306
68
                            pPut++;
307
68
                            pGet++;
308
                        }
309
310
136
                        column++;
311
                    }
312
                }
313
314
407
                putrow -= stride;
315
407
                getrow -= stride;
316
            }
317
        }
318
        else
319
        {
320
            /* Copy from bottom to top.  */
321
3
            putrow += (block -> gx_rectangle_top * stride);
322
3
            putrow += (block -> gx_rectangle_left >> 1);
323
324
3
            getrow = putrow;
325
3
            getrow -= yshift * stride;
326
327
3
            height = block -> gx_rectangle_bottom - block -> gx_rectangle_top + 1;
328
3
            height += yshift;
329
330
221
            for (y = 0; y < height; y++)
331
            {
332
218
                pPut = putrow;
333
218
                pGet = getrow;
334
335
218
                if (block -> gx_rectangle_left & 0x01)
336
                {
337
68
                    putmask = 0x0f;
338
                }
339
                else
340
                {
341
150
                    putmask = 0xf0;
342
                }
343
344
218
                column = 0;
345
346
572
                while (column < width)
347
                {
348

354
                    if ((putmask == 0xf0) && (width - column >= 2))
349
                    {
350
218
                        move_width = (width - column) >> 1;
351
218
                        memmove(pPut, pGet, (size_t)move_width);
352
218
                        pPut += move_width;
353
218
                        pGet += move_width;
354
218
                        column += (move_width << 1);
355
                    }
356
                    else
357
                    {
358
136
                        *pPut &= (GX_UBYTE)(~putmask);
359
136
                        if ((*pGet) & putmask)
360
                        {
361
12
                            *pPut |= (GX_UBYTE)((*pGet) & putmask);
362
                        }
363
364
136
                        putmask >>= 4;
365
366
136
                        if (putmask == 0)
367
                        {
368
68
                            putmask = 0xf0;
369
68
                            pPut++;
370
68
                            pGet++;
371
                        }
372
373
136
                        column++;
374
                    }
375
                }
376
377
218
                putrow += stride;
378
218
                getrow += stride;
379
            }
380
        }
381
    }
382
16
}
383