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

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

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