GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_4bpp_pixelmap_rotate.c Lines: 289 289 100.0 %
Date: 2024-12-05 08:52:37 Branches: 120 120 100.0 %

Line Branch Exec Source
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
#define GX_SOURCE_CODE
21
22
/* Include necessary system files.  */
23
24
#include "gx_api.h"
25
#include "gx_display.h"
26
#include "gx_context.h"
27
#include "gx_utility.h"
28
#include "gx_system.h"
29
30
/**************************************************************************/
31
/*                                                                        */
32
/*  FUNCTION                                               RELEASE        */
33
/*                                                                        */
34
/*    _gx_display_driver_4bpp_pixelmap_raw_rotate         PORTABLE C      */
35
/*                                                           6.1.10       */
36
/*  AUTHOR                                                                */
37
/*                                                                        */
38
/*    Kenneth Maxwell, Microsoft Corporation                              */
39
/*                                                                        */
40
/*  DESCRIPTION                                                           */
41
/*                                                                        */
42
/*    Internal helper function that rotate an uncompressed pixelmap       */
43
/*      without transparent.                                              */
44
/*                                                                        */
45
/*  INPUT                                                                 */
46
/*                                                                        */
47
/*    context                               Drawing context               */
48
/*    xpos                                  x-coord of top-left draw point*/
49
/*    ypos                                  y-coord of top-left draw point*/
50
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
51
/*    angle                                 The angle to rotate           */
52
/*    rot_cx                                x-coord of rotate center      */
53
/*    rot_cy                                y-coord of rotate center      */
54
/*                                                                        */
55
/*  OUTPUT                                                                */
56
/*                                                                        */
57
/*    status                                Completion status             */
58
/*                                                                        */
59
/*  CALLS                                                                 */
60
/*                                                                        */
61
/*    _gx_utility_math_cos                  Compute the cosine value      */
62
/*    _gx_utility_math_sin                  Compute the sine value        */
63
/*                                                                        */
64
/*  CALLED BY                                                             */
65
/*                                                                        */
66
/*    _gx_display_driver_4bpp_pixelmap_rotate                             */
67
/*                                                                        */
68
/*  RELEASE HISTORY                                                       */
69
/*                                                                        */
70
/*    DATE              NAME                      DESCRIPTION             */
71
/*                                                                        */
72
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
73
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
74
/*                                            resulting in version 6.1    */
75
/*  01-31-2022     Ting Zhu                 Modified comment(s),          */
76
/*                                            corrected logic,            */
77
/*                                            resulting in version 6.1.10 */
78
/*                                                                        */
79
/**************************************************************************/
80
1068
static VOID _gx_display_driver_4bpp_pixelmap_raw_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
81
                                                        INT angle, INT cx, INT cy)
82
{
83
GX_UBYTE     *putrow;
84
GX_UBYTE     *put;
85
GX_UBYTE     *get;
86
INT           srcxres;
87
INT           srcyres;
88
INT           cosv;
89
INT           sinv;
90
INT           idxminx;
91
INT           idxmaxx;
92
INT           idxmaxy;
93
1068
INT           mx[] = {-1, 1, 1, -1};
94
1068
INT           my[] = {1, 1, -1, -1};
95
INT           xres;
96
INT           yres;
97
INT           x;
98
INT           y;
99
INT           xx;
100
INT           yy;
101
GX_RECTANGLE *clip;
102
INT           newxpos;
103
INT           newypos;
104
GX_UBYTE      putmask;
105
INT           putstride;
106
INT           getstride;
107
GX_UBYTE      color;
108
109
1068
    clip = context -> gx_draw_context_clip;
110
111
    /* Set transparent color.  */
112
1068
    idxminx = (angle / 90) & 0x3;
113
1068
    idxmaxx = (idxminx + 2) & 0x3;
114
1068
    idxmaxy = (idxminx + 1) & 0x3;
115
116
    /* Calculate the source x and y center. */
117
1068
    srcxres = pixelmap -> gx_pixelmap_width >> 1;
118
1068
    srcyres = pixelmap -> gx_pixelmap_height >> 1;
119
120
1068
    cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
121
1068
    sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
122
123
1068
    xres = GX_FIXED_VAL_TO_INT((mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv));
124
1068
    yres = GX_FIXED_VAL_TO_INT((my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv));
125
126
1068
    getstride = (pixelmap -> gx_pixelmap_width + 1) >> 1;
127
1068
    putstride = (context -> gx_draw_context_pitch + 1) >> 1;
128
1068
    putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
129
1068
    putrow += clip -> gx_rectangle_top * putstride;
130
1068
    putrow += clip -> gx_rectangle_left >> 1;
131
132
    /* Calculate the new rotation axis. */
133
1068
    xres = GX_FIXED_VAL_TO_INT((cx - srcxres) * cosv - (cy - srcyres) * sinv) + xres;
134
1068
    yres = GX_FIXED_VAL_TO_INT((cy - srcyres) * cosv + (cx - srcxres) * sinv) + yres;
135
136
1068
    newxpos = xpos + cx - xres;
137
1068
    newypos = ypos + cy - yres;
138
139
    /* For every pixel in destination bitmap, find its position in source bitmap,
140
       and set the pixel with the value in source bitmap.  */
141
211263
    for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
142
    {
143
210195
        if (clip -> gx_rectangle_left & 1)
144
        {
145
109158
            putmask = 0x0f;
146
        }
147
        else
148
        {
149
101037
            putmask = 0xf0;
150
        }
151
210195
        put = putrow;
152
153
47481279
        for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
154
        {
155
47271084
            xx = GX_FIXED_VAL_TO_INT((x - xres) * cosv + (y - yres) * sinv) + cx;
156
47271084
            yy = GX_FIXED_VAL_TO_INT((y - yres) * cosv - (x - xres) * sinv) + cy;
157
158

47271084
            if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_width) &&
159
35086005
                (yy >= 0) && (yy < pixelmap -> gx_pixelmap_height))
160
            {
161
26972906
                get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
162
26972906
                get += yy * getstride;
163
26972906
                get += xx >> 1;
164
165
26972906
                if (xx & 1)
166
                {
167
13496587
                    color = *get & 0x0f;
168
                }
169
                else
170
                {
171
13476319
                    color = (*get & 0xf0) >> 4;
172
                }
173
26972906
                color |= (GX_UBYTE)(color << 4);
174
175
26972906
                *put &= (GX_UBYTE)(~putmask);
176
26972906
                *put |= color & putmask;
177
            }
178
179
47271084
            putmask >>= 4;
180
47271084
            if (putmask == 0)
181
            {
182
23639588
                put++;
183
23639588
                putmask = 0xf0;
184
            }
185
        }
186
210195
        putrow += putstride;
187
    }
188
1068
}
189
190
/**************************************************************************/
191
/*                                                                        */
192
/*  FUNCTION                                               RELEASE        */
193
/*                                                                        */
194
/*    _gx_display_driver_4bpp_pixelmap_transparent_rotate PORTABLE C      */
195
/*                                                           6.1.10       */
196
/*  AUTHOR                                                                */
197
/*                                                                        */
198
/*    Kenneth Maxwell, Microsoft Corporation                              */
199
/*                                                                        */
200
/*  DESCRIPTION                                                           */
201
/*                                                                        */
202
/*    Internal helper function that rotate an uncompressed pixelmap       */
203
/*      with transparent info.                                            */
204
/*                                                                        */
205
/*  INPUT                                                                 */
206
/*                                                                        */
207
/*    context                               Drawing context               */
208
/*    xpos                                  x-coord of top-left draw point*/
209
/*    ypos                                  y-coord of top-left draw point*/
210
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
211
/*    angle                                 The angle to rotate           */
212
/*    rot_cx                                x-coord of rotate center      */
213
/*    rot_cy                                y-coord of rotate center      */
214
/*                                                                        */
215
/*  OUTPUT                                                                */
216
/*                                                                        */
217
/*    status                                Completion status             */
218
/*                                                                        */
219
/*  CALLS                                                                 */
220
/*                                                                        */
221
/*    _gx_utility_math_cos                  Compute the cosine value      */
222
/*    _gx_utility_math_sin                  Compute the sine value        */
223
/*                                                                        */
224
/*  CALLED BY                                                             */
225
/*                                                                        */
226
/*    _gx_display_driver_4bpp_pixelmap_rotate                             */
227
/*                                                                        */
228
/*  RELEASE HISTORY                                                       */
229
/*                                                                        */
230
/*    DATE              NAME                      DESCRIPTION             */
231
/*                                                                        */
232
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
233
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
234
/*                                            resulting in version 6.1    */
235
/*  01-31-2022     Ting Zhu                 Modified comment(s),          */
236
/*                                            corrected logic,            */
237
/*                                            resulting in version 6.1.10 */
238
/*                                                                        */
239
/**************************************************************************/
240
712
static VOID _gx_display_driver_4bpp_pixelmap_transparent_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
241
                                                                INT angle, INT cx, INT cy)
242
{
243
GX_UBYTE     *putrow;
244
GX_UBYTE     *put;
245
GX_UBYTE     *get;
246
GX_UBYTE     *getaux;
247
GX_UBYTE      putmask;
248
GX_UBYTE      transmask;
249
GX_UBYTE      pixel;
250
INT           putstride;
251
INT           getauxstride;
252
INT           getstride;
253
INT           srcxres;
254
INT           srcyres;
255
INT           cosv;
256
INT           sinv;
257
INT           idxminx;
258
INT           idxmaxx;
259
INT           idxmaxy;
260
712
INT           mx[] = {-1, 1, 1, -1};
261
712
INT           my[] = {1, 1, -1, -1};
262
INT           xres;
263
INT           yres;
264
INT           x;
265
INT           y;
266
INT           xx;
267
INT           yy;
268
GX_RECTANGLE *clip;
269
INT           newxpos;
270
INT           newypos;
271
272
712
    clip = context -> gx_draw_context_clip;
273
712
    putstride = (context -> gx_draw_context_pitch + 1) >> 1;
274
712
    getstride = (pixelmap -> gx_pixelmap_width + 1) >> 1;
275
712
    getauxstride = (pixelmap -> gx_pixelmap_width + 7) >> 3;
276
277
    /* Set transparent color.  */
278
712
    idxminx = (angle / 90) & 0x3;
279
712
    idxmaxx = (idxminx + 2) & 0x3;
280
712
    idxmaxy = (idxminx + 1) & 0x3;
281
282
    /* Calculate the source x and y center. */
283
712
    srcxres = pixelmap -> gx_pixelmap_width >> 1;
284
712
    srcyres = pixelmap -> gx_pixelmap_height >> 1;
285
286
712
    cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
287
712
    sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
288
289
712
    xres = GX_FIXED_VAL_TO_INT((mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv));
290
712
    yres = GX_FIXED_VAL_TO_INT((my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv));
291
292
712
    putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
293
712
    putrow += clip -> gx_rectangle_top * putstride;
294
712
    putrow += clip -> gx_rectangle_left >> 1;
295
296
    /* Calculate the new rotation axis. */
297
712
    x = (cx - srcxres) * cosv - (cy - srcyres) * sinv;
298
712
    y = (cy - srcyres) * cosv + (cx - srcxres) * sinv;
299
300
712
    xres = GX_FIXED_VAL_TO_INT(x) + xres;
301
712
    yres = GX_FIXED_VAL_TO_INT(y) + yres;
302
303
712
    newxpos = xpos + cx - xres;
304
712
    newypos = ypos + cy - yres;
305
306
    /* For every pixel in destination bitmap, find its position in source bitmap,
307
       and set the pixel with the value in source bitmap.  */
308
167899
    for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
309
    {
310
167187
        put = putrow;
311
167187
        if (clip -> gx_rectangle_left & 1)
312
        {
313
92123
            putmask = 0x0f;
314
        }
315
        else
316
        {
317
75064
            putmask = 0xf0;
318
        }
319
320
48499009
        for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
321
        {
322
48331822
            xx = GX_FIXED_VAL_TO_INT((x - xres) * cosv + (y - yres) * sinv) + cx;
323
48331822
            yy = GX_FIXED_VAL_TO_INT((y - yres) * cosv - (x - xres) * sinv) + cy;
324
325

48331822
            if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_width) &&
326
32737301
                (yy >= 0) && (yy < pixelmap -> gx_pixelmap_height))
327
            {
328
28998345
                getaux = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
329
28998345
                getaux += yy * getauxstride;
330
28998345
                getaux += xx >> 3;
331
332
28998345
                transmask = (GX_UBYTE)(0x80 >> (xx & 0x07));
333
28998345
                if (!(transmask & (*getaux)))
334
                {
335
20386958
                    get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
336
20386958
                    get += yy * getstride;
337
20386958
                    get += xx >> 1;
338
339
20386958
                    if (xx & 1)
340
                    {
341
10190126
                        pixel = *get & 0x0f;
342
                    }
343
                    else
344
                    {
345
10196832
                        pixel = *get >> 4;
346
                    }
347
20386958
                    pixel |= (GX_UBYTE)(pixel << 4);
348
349
20386958
                    *put &= (GX_UBYTE)(~putmask);
350
20386958
                    *put |= pixel & putmask;
351
                }
352
            }
353
354
48331822
            putmask >>= 4;
355
48331822
            if (putmask == 0)
356
            {
357
24170623
                put++;
358
24170623
                putmask = 0xf0;
359
            }
360
        }
361
167187
        putrow += putstride;
362
    }
363
712
}
364
365
/**************************************************************************/
366
/*                                                                        */
367
/*  FUNCTION                                               RELEASE        */
368
/*                                                                        */
369
/*    _gx_display_driver_4bpp_pixelmap_simple_rotate      PORTABLE C      */
370
/*                                                           6.1.7        */
371
/*  AUTHOR                                                                */
372
/*                                                                        */
373
/*    Kenneth Maxwell, Microsoft Corporation                              */
374
/*                                                                        */
375
/*  DESCRIPTION                                                           */
376
/*                                                                        */
377
/*    Internal help function that hangles 90, 180 and 270 degree pixelmap */
378
/*    rotation.                                                           */
379
/*                                                                        */
380
/*  INPUT                                                                 */
381
/*                                                                        */
382
/*    context                               Drawing context               */
383
/*    xpos                                  x-coord of top-left draw point*/
384
/*    ypos                                  y-coord of top-left draw point*/
385
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
386
/*    angle                                 The angle to rotate           */
387
/*    rot_cx                                x-coord of rotate center      */
388
/*    rot_cy                                y-coord of rotate center      */
389
/*                                                                        */
390
/*  OUTPUT                                                                */
391
/*                                                                        */
392
/*    status                                Completion status             */
393
/*                                                                        */
394
/*  CALLS                                                                 */
395
/*                                                                        */
396
/*    None                                                                */
397
/*                                                                        */
398
/*  CALLED BY                                                             */
399
/*                                                                        */
400
/*    _gx_display_driver_4bpp_pixelmap_rotate                             */
401
/*                                                                        */
402
/*  RELEASE HISTORY                                                       */
403
/*                                                                        */
404
/*    DATE              NAME                      DESCRIPTION             */
405
/*                                                                        */
406
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
407
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
408
/*                                            resulting in version 6.1    */
409
/*  06-02-2021     Kenneth Maxwell          Modified comment(s),          */
410
/*                                            removed unused variable     */
411
/*                                            assignment,                 */
412
/*                                            resulting in version 6.1.7  */
413
/*                                                                        */
414
/**************************************************************************/
415
15
static VOID _gx_display_driver_4bpp_pixelmap_simple_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
416
                                                           INT angle, INT cx, INT cy)
417
{
418
GX_UBYTE     *putrow;
419
GX_UBYTE     *put;
420
GX_UBYTE      putmask;
421
GX_UBYTE     *get;
422
INT           putstride;
423
INT           width;
424
INT           height;
425
INT           x;
426
INT           y;
427
GX_RECTANGLE *clip;
428
INT           newxpos;
429
INT           newypos;
430
GX_UBYTE      color;
431
432
15
    clip = context -> gx_draw_context_clip;
433
15
    putstride = (context -> gx_draw_context_pitch + 1) >> 1;
434
435
15
    putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
436
15
    putrow += clip -> gx_rectangle_top * putstride;
437
15
    putrow += clip -> gx_rectangle_left >> 1;
438
439
15
    if (angle == 90)
440
    {
441
5
        width = pixelmap -> gx_pixelmap_height;
442
5
        height = (pixelmap -> gx_pixelmap_width + 1) >> 1;
443
444
5
        newxpos = xpos + cx - (width - 1 - cy);
445
5
        newypos = ypos + cy - cx;
446
447
1136
        for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
448
        {
449
1131
            if (clip -> gx_rectangle_left & 1)
450
            {
451
651
                putmask = 0x0f;
452
            }
453
            else
454
            {
455
480
                putmask = 0xf0;
456
            }
457
458
1131
            put = putrow;
459
460
147777
            for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
461
            {
462
146646
                get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
463
146646
                get += (width - 1 - x) * height;
464
146646
                get += y >> 1;
465
466
146646
                if (y & 1)
467
                {
468
73386
                    color = *get & 0x0f;
469
                }
470
                else
471
                {
472
73260
                    color = (*get & 0xf0) >> 4;
473
                }
474
146646
                color |= (GX_UBYTE)(color << 4);
475
476
146646
                *put &= (GX_UBYTE)(~putmask);
477
146646
                *put |= color & putmask;
478
479
146646
                putmask >>= 4;
480
146646
                if (putmask == 0)
481
                {
482
73413
                    putmask = 0xf0;
483
73413
                    put++;
484
                }
485
            }
486
487
1131
            putrow += putstride;
488
        }
489
    }
490
10
    else if (angle == 180)
491
    {
492
493
5
        width = pixelmap -> gx_pixelmap_width;
494
5
        height = pixelmap -> gx_pixelmap_height;
495
496
5
        newxpos = xpos + cx - (width - 1 - cx);
497
5
        newypos = ypos + cy - (height - 1 - cy);
498
499
586
        for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
500
        {
501
581
            if (clip -> gx_rectangle_left & 1)
502
            {
503
455
                putmask = 0x0f;
504
            }
505
            else
506
            {
507
126
                putmask = 0xf0;
508
            }
509
581
            put = putrow;
510
511
129660
            for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
512
            {
513
129079
                get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
514
129079
                get += (height - 1 - y) * ((width + 1) >> 1);
515
129079
                get += (width - 1 - x) >> 1;
516
517
129079
                if ((pixelmap -> gx_pixelmap_width - 1 - x) & 1)
518
                {
519
64593
                    color = *get & 0x0f;
520
                }
521
                else
522
                {
523
64486
                    color = (*get & 0xf0) >> 4;
524
                }
525
129079
                color |= (GX_UBYTE)(color << 4);
526
129079
                *put &= (GX_UBYTE)(~putmask);
527
129079
                *put |= color & putmask;
528
529
129079
                putmask >>= 4;
530
129079
                if (putmask == 0)
531
                {
532
64593
                    putmask = 0xf0;
533
64593
                    put++;
534
                }
535
            }
536
581
            putrow += putstride;
537
        }
538
    }
539
    else
540
    {
541
5
        height = pixelmap -> gx_pixelmap_width;
542
543
5
        newxpos = xpos + cx - cy;
544
5
        newypos = ypos + cx - (height - 1 - cy);
545
546
928
        for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
547
        {
548
923
            if (clip -> gx_rectangle_left & 1)
549
            {
550
576
                putmask = 0x0f;
551
            }
552
            else
553
            {
554
347
                putmask = 0xf0;
555
            }
556
923
            put = putrow;
557
558
119429
            for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
559
            {
560
118506
                get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
561
118506
                get += x * ((height + 1) >> 1);
562
118506
                get += (height - 1 - y) >> 1;
563
564
118506
                if ((height - 1 - y) & 1)
565
                {
566
59316
                    color = *get & 0x0f;
567
                }
568
                else
569
                {
570
59190
                    color = (*get & 0xf0) >> 4;
571
                }
572
118506
                color |= (GX_UBYTE)(color << 4);
573
574
118506
                *put &= (GX_UBYTE)(~putmask);
575
118506
                *put |= color & putmask;
576
577
118506
                putmask >>= 4;
578
118506
                if (putmask == 0)
579
                {
580
59301
                    putmask = 0xf0;
581
59301
                    put++;
582
                }
583
            }
584
585
923
            putrow += putstride;
586
        }
587
    }
588
15
}
589
/**************************************************************************/
590
/*                                                                        */
591
/*  FUNCTION                                               RELEASE        */
592
/*                                                                        */
593
/*    _gx_display_driver_4bpp_pixelmap_simple_transparent_rotate          */
594
/*                                                        PORTABLE C      */
595
/*                                                           6.1.7        */
596
/*  AUTHOR                                                                */
597
/*                                                                        */
598
/*    Kenneth Maxwell, Microsoft Corporation                              */
599
/*                                                                        */
600
/*  DESCRIPTION                                                           */
601
/*                                                                        */
602
/*    Internal help function that hangles 90, 180 and 270 degree pixelmap */
603
/*    rotation.                                                           */
604
/*                                                                        */
605
/*  INPUT                                                                 */
606
/*                                                                        */
607
/*    context                               Drawing context               */
608
/*    xpos                                  x-coord of top-left draw point*/
609
/*    ypos                                  y-coord of top-left draw point*/
610
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
611
/*    angle                                 The angle to rotate           */
612
/*    rot_cx                                x-coord of rotate center      */
613
/*    rot_cy                                y-coord of rotate center      */
614
/*                                                                        */
615
/*  OUTPUT                                                                */
616
/*                                                                        */
617
/*    status                                Completion status             */
618
/*                                                                        */
619
/*  CALLS                                                                 */
620
/*                                                                        */
621
/*    None                                                                */
622
/*                                                                        */
623
/*  CALLED BY                                                             */
624
/*                                                                        */
625
/*    _gx_display_driver_4bpp_pixelmap_rotate                             */
626
/*                                                                        */
627
/*  RELEASE HISTORY                                                       */
628
/*                                                                        */
629
/*    DATE              NAME                      DESCRIPTION             */
630
/*                                                                        */
631
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
632
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
633
/*                                            resulting in version 6.1    */
634
/*  06-02-2021     Kenneth Maxwell          Modified comment(s),          */
635
/*                                            removed unused variable     */
636
/*                                            assignment,                 */
637
/*                                            resulting in version 6.1.7  */
638
/*                                                                        */
639
/**************************************************************************/
640
13
static VOID _gx_display_driver_4bpp_pixelmap_simple_transparent_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
641
                                                                       INT angle, INT cx, INT cy)
642
{
643
GX_UBYTE     *get;
644
GX_UBYTE     *gettransmask;
645
INT           width;
646
INT           height;
647
INT           x;
648
INT           y;
649
GX_RECTANGLE *clip;
650
INT           newxpos;
651
INT           newypos;
652
GX_UBYTE     *put;
653
GX_UBYTE     *putrow;
654
INT           putstride;
655
GX_UBYTE      putmask;
656
INT           getstride;
657
INT           getauxstride;
658
GX_UBYTE      transmask;
659
GX_UBYTE      pixel;
660
661
13
    if (pixelmap -> gx_pixelmap_aux_data == GX_NULL)
662
    {
663
        /* 4bpp transparent pixelmap must have aux data to store the transparent mask info. */
664
1
        return;
665
    }
666
667
12
    clip = context -> gx_draw_context_clip;
668
    /* 4bpp pixelmap is stored as half byte. And it's transparent info is stored in aux data by one bit */
669
12
    getstride = (pixelmap -> gx_pixelmap_width + 1) >> 1;
670
12
    getauxstride = (pixelmap -> gx_pixelmap_width + 7) >> 3;
671
12
    putstride = (context -> gx_draw_context_pitch + 1) >> 1;
672
12
    putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
673
12
    putrow += clip -> gx_rectangle_top * putstride;
674
12
    putrow += clip -> gx_rectangle_left >> 1;
675
676
12
    clip = context -> gx_draw_context_clip;
677
678
12
    if (angle == 90)
679
    {
680
4
        width = pixelmap -> gx_pixelmap_height;
681
682
4
        newxpos = xpos + cx - (width - 1 - cy);
683
4
        newypos = ypos + cy - cx;
684
685
784
        for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
686
        {
687
780
            put = putrow;
688
780
            if (clip -> gx_rectangle_left & 1)
689
            {
690
195
                putmask = 0x0f;
691
            }
692
            else
693
            {
694
585
                putmask = 0xf0;
695
            }
696
697
199875
            for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
698
            {
699
199095
                gettransmask = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
700
199095
                gettransmask += (width - 1 - x) * getauxstride;
701
199095
                gettransmask += y >> 3;
702
703
199095
                transmask = (GX_UBYTE)(0x80 >> (y & 0x07));
704
705
                /* if not transparent, draw pixel. else skip. */
706
199095
                if (!(transmask & (*gettransmask)))
707
                {
708
141237
                    get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
709
141237
                    get += (width - 1 - x) * getstride;
710
141237
                    get += y >> 1;
711
712
141237
                    if (y & 1)
713
                    {
714
70595
                        pixel = *get & 0x0f;
715
                    }
716
                    else
717
                    {
718
70642
                        pixel = *get >> 4;
719
                    }
720
141237
                    pixel |= (GX_UBYTE)(pixel << 4);
721
722
141237
                    *put &= (GX_UBYTE)(~putmask);
723
141237
                    *put |= pixel & putmask;
724
                }
725
726
199095
                putmask >>= 4;
727
199095
                if (putmask == 0)
728
                {
729
99450
                    putmask = 0xf0;
730
99450
                    put++;
731
                }
732
            }
733
780
            putrow += putstride;
734
        }
735
    }
736
8
    else if (angle == 180)
737
    {
738
4
        width = pixelmap -> gx_pixelmap_width;
739
4
        height = pixelmap -> gx_pixelmap_height;
740
741
4
        newxpos = xpos + cx - (width - 1 - cx);
742
4
        newypos = ypos + cy - (height - 1 - cy);
743
744
796
        for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
745
        {
746
792
            put = putrow;
747
792
            if (clip -> gx_rectangle_left & 1)
748
            {
749
244
                putmask = 0x0f;
750
            }
751
            else
752
            {
753
548
                putmask = 0xf0;
754
            }
755
155232
            for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
756
            {
757
154440
                gettransmask = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
758
154440
                gettransmask += (height - 1 - y) * getauxstride;
759
154440
                gettransmask += (width - 1 - x) >> 3;
760
761
                /* Calculate and go ot the transmask bit.*/
762
154440
                transmask = (GX_UBYTE)(0x80 >> ((width - 1 - x) & 0x07));
763
                /* if not transparent, draw pixel. else skip. */
764
154440
                if (!(transmask & (*gettransmask)))
765
                {
766
110800
                    get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
767
110800
                    get += (height - 1 - y) * getstride;
768
110800
                    get += (width - 1 - x) >> 1;
769
770
110800
                    if ((width - 1 - x) & 1)
771
                    {
772
55384
                        pixel = *get & 0x0f;
773
                    }
774
                    else
775
                    {
776
55416
                        pixel = *get >> 4;
777
                    }
778
110800
                    pixel |= (GX_UBYTE)(pixel << 4);
779
780
110800
                    *put &= (GX_UBYTE)(~putmask);
781
110800
                    *put |= pixel & putmask;
782
                }
783
784
154440
                putmask >>= 4;
785
154440
                if (putmask == 0)
786
                {
787
77068
                    putmask = 0xf0;
788
77068
                    put++;
789
                }
790
            }
791
792
            putrow += putstride;
792
        }
793
    }
794
    else
795
    {
796
4
        height = pixelmap -> gx_pixelmap_width;
797
798
4
        newxpos = xpos + cx - cy;
799
4
        newypos = ypos + cx - (height - 1 - cy);
800
801
626
        for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
802
        {
803
622
            put = putrow;
804
622
            if (clip -> gx_rectangle_left & 1)
805
            {
806
195
                putmask = 0x0f;
807
            }
808
            else
809
            {
810
427
                putmask = 0xf0;
811
            }
812
813
166696
            for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
814
            {
815
166074
                gettransmask = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
816
166074
                gettransmask += x * getauxstride;
817
166074
                gettransmask += (height - 1 - y) >> 3;
818
819
166074
                transmask = (GX_UBYTE)(0x80 >> ((height - 1 - y) & 0x07));
820
                /* if not transparent, draw pixel. else skip. */
821
166074
                if (!(transmask & (*gettransmask)))
822
                {
823
113735
                    get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
824
113735
                    get += x * getstride;
825
113735
                    get += (height - 1 - y) >> 1;
826
827
113735
                    if ((height - 1 - y) & 1)
828
                    {
829
56789
                        pixel = *get & 0x0f;
830
                    }
831
                    else
832
                    {
833
56946
                        pixel = *get >> 4;
834
                    }
835
113735
                    pixel |= (GX_UBYTE)(pixel << 4);
836
837
113735
                    *put &= (GX_UBYTE)(~putmask);
838
113735
                    *put |= pixel & putmask;
839
                }
840
841
166074
                putmask >>= 4;
842
166074
                if (putmask == 0)
843
                {
844
82921
                    putmask = 0xf0;
845
82921
                    put++;
846
                }
847
            }
848
622
            putrow += putstride;
849
        }
850
    }
851
}
852
853
/**************************************************************************/
854
/*                                                                        */
855
/*  FUNCTION                                               RELEASE        */
856
/*                                                                        */
857
/*    _gx_display_driver_4bpp_pixelmap_rotate             PORTABLE C      */
858
/*                                                           6.1          */
859
/*  AUTHOR                                                                */
860
/*                                                                        */
861
/*    Kenneth Maxwell, Microsoft Corporation                              */
862
/*                                                                        */
863
/*  DESCRIPTION                                                           */
864
/*                                                                        */
865
/*    This service rotate a pixelmap directly to canvas memory.           */
866
/*                                                                        */
867
/*  INPUT                                                                 */
868
/*                                                                        */
869
/*    context                               Drawing context               */
870
/*    xpos                                  x-coord of top-left draw point*/
871
/*    ypos                                  y-coord of top-left draw point*/
872
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
873
/*    angle                                 The angle to rotate           */
874
/*    rot_cx                                x-coord of rotating center.   */
875
/*    rot_cy                                y-coord of rotationg center.  */
876
/*                                                                        */
877
/*  OUTPUT                                                                */
878
/*                                                                        */
879
/*    status                                Completion status             */
880
/*                                                                        */
881
/*  CALLS                                                                 */
882
/*                                                                        */
883
/*    _gx_display_driver_4bpp_pixelmap_simple_transparent_rotate          */
884
/*                                          Real pixelmap rotate routine  */
885
/*    _gx_display_driver_4bpp_pixelmap_simple_rotate                      */
886
/*                                          Real pixelmap rotate routine  */
887
/*    _gx_display_driver_4bpp_pixelmap_transparent_rotate                 */
888
/*                                          Real pixelmap rotate routine  */
889
/*    _gx_display_driver_4bpp_pixelmap_raw_rotate                         */
890
/*                                          Real pixelmap rotate routine  */
891
/*                                                                        */
892
/*  CALLED BY                                                             */
893
/*                                                                        */
894
/*    Application Code                                                    */
895
/*    GUIX Internal Code                                                  */
896
/*                                                                        */
897
/*  RELEASE HISTORY                                                       */
898
/*                                                                        */
899
/*    DATE              NAME                      DESCRIPTION             */
900
/*                                                                        */
901
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
902
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
903
/*                                            resulting in version 6.1    */
904
/*                                                                        */
905
/**************************************************************************/
906
1808
VOID _gx_display_driver_4bpp_pixelmap_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
907
                                             INT angle, INT rot_cx, INT rot_cy)
908
{
909
1808
    if (angle % 90 == 0)
910
    {
911
        /* Simple angle rotate: 90 degree, 180 degree and 270 degree.  */
912
28
        if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_TRANSPARENT)
913
        {
914
13
            _gx_display_driver_4bpp_pixelmap_simple_transparent_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
915
        }
916
        else
917
        {
918
15
            _gx_display_driver_4bpp_pixelmap_simple_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
919
        }
920
    }
921
    else
922
    {
923
1780
        if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_TRANSPARENT)
924
        {
925
            /* no compression or alpha */
926
712
            _gx_display_driver_4bpp_pixelmap_transparent_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
927
        }
928
        else
929
        {
930
            /* no compression or alpha */
931
1068
            _gx_display_driver_4bpp_pixelmap_raw_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
932
        }
933
    }
934
935
1808
    return;
936
}
937