GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_332rgb_pixelmap_rotate.c Lines: 266 266 100.0 %
Date: 2026-03-06 19:21:09 Branches: 112 112 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
#define REDVAL_332(_c)   (USHORT)(((_c) >> 5) & 0x07)
24
#define GREENVAL_332(_c) (USHORT)(((_c) >> 2) & 0x07)
25
#define BLUEVAL_332(_c)  (USHORT)((_c) & 0x03)
26
27
#define ASSEMBLECOLOR_332(_r, _g, _b) \
28
    ((((_r) & 0x07) << 5) |           \
29
     (((_g) & 0x07) << 2) |           \
30
     ((_b) & 0x03))
31
32
/* Include necessary system files.  */
33
34
#include "gx_api.h"
35
#include "gx_display.h"
36
#include "gx_context.h"
37
#include "gx_utility.h"
38
#include "gx_system.h"
39
40
/**************************************************************************/
41
/*                                                                        */
42
/*  FUNCTION                                               RELEASE        */
43
/*                                                                        */
44
/*    _gx_display_driver_332rgb_pixelmap_simple_alpha_rotate              */
45
/*                                                        PORTABLE C      */
46
/*                                                           6.1.7        */
47
/*  AUTHOR                                                                */
48
/*                                                                        */
49
/*    Kenneth Maxwell, Microsoft Corporation                              */
50
/*                                                                        */
51
/*  DESCRIPTION                                                           */
52
/*                                                                        */
53
/*    Internal helper function that rotates 332rgb format pixelmap with   */
54
/*    alpha in 90, 180 or 270 degree.                                     */
55
/*                                                                        */
56
/*  INPUT                                                                 */
57
/*                                                                        */
58
/*    context                               Drawing context               */
59
/*    xpos                                  x-coord of top-left draw point*/
60
/*    ypos                                  y-coord of top-left draw point*/
61
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
62
/*    angle                                 The angle to rotate           */
63
/*    cx                                    x-coord of rotate center      */
64
/*    cy                                    y-coord of rotate center      */
65
/*                                                                        */
66
/*  OUTPUT                                                                */
67
/*                                                                        */
68
/*    None                                                                */
69
/*                                                                        */
70
/*  CALLS                                                                 */
71
/*                                                                        */
72
/*    [gx_display_driver_pixel_blend]       Basic display driver pixel    */
73
/*                                            blend function              */
74
/*                                                                        */
75
/*  CALLED BY                                                             */
76
/*                                                                        */
77
/*    _gx_display_driver_332rgb_pixelmap_rotate                           */
78
/*                                                                        */
79
/**************************************************************************/
80
10
static VOID _gx_display_driver_332rgb_pixelmap_simple_alpha_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
81
                                                                   INT angle, INT cx, INT cy)
82
{
83
GX_UBYTE     *get;
84
GX_UBYTE     *getalpha;
85
INT           width;
86
INT           height;
87
INT           x;
88
INT           y;
89
GX_RECTANGLE *clip;
90
INT           newxpos;
91
INT           newypos;
92
VOID          (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR color, GX_UBYTE alpha);
93
94
10
    clip = context -> gx_draw_context_clip;
95
10
    blend_func = context -> gx_draw_context_display -> gx_display_driver_pixel_blend;
96
97
10
    if (GX_NULL == blend_func)
98
    {
99
1
        return;
100
    }
101
102
9
    if (angle == 90)
103
    {
104
3
        width = pixelmap -> gx_pixelmap_height;
105
3
        height = pixelmap -> gx_pixelmap_width;
106
107
3
        newxpos = xpos + cx - (width - 1 - cy);
108
3
        newypos = ypos + cy - cx;
109
110
573
        for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
111
        {
112
114750
            for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
113
            {
114
114180
                get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
115
114180
                getalpha = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
116
114180
                get += (width - 1 - x) * height;
117
114180
                get += y;
118
114180
                getalpha += (width - 1 - x) * height;
119
114180
                getalpha += y;
120
114180
                blend_func(context, x + newxpos, y + newypos, *get, *getalpha);
121
            }
122
        }
123
    }
124
6
    else if (angle == 180)
125
    {
126
127
3
        width = pixelmap -> gx_pixelmap_width;
128
3
        height = pixelmap -> gx_pixelmap_height;
129
130
3
        newxpos = xpos + cx - (width - 1 - cx);
131
3
        newypos = ypos + cy - (height - 1 - cy);
132
133
134
403
        for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
135
        {
136
76442
            for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
137
            {
138
76042
                get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
139
76042
                getalpha = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
140
76042
                get += (height - 1 - y) * width;
141
76042
                get += width - 1 - x;
142
76042
                getalpha += (height - 1 - y) * width;
143
76042
                getalpha += width - 1 - x;
144
145
76042
                blend_func(context, x + newxpos, y + newypos, *get, *getalpha);
146
            }
147
        }
148
    }
149
    else
150
    {
151
3
        height = pixelmap -> gx_pixelmap_width;
152
153
3
        newxpos = xpos + cx - cy;
154
3
        newypos = ypos + cx - (height - 1 - cy);
155
156
331
        for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
157
        {
158
76576
            for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
159
            {
160
76248
                get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
161
76248
                getalpha = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
162
76248
                get += x * height;
163
76248
                get += height - 1 - y;
164
76248
                getalpha += x * height;
165
76248
                getalpha += height - 1 - y;
166
167
76248
                blend_func(context, x + newxpos, y + newypos, *get, *getalpha);
168
            }
169
        }
170
    }
171
}
172
173
/**************************************************************************/
174
/*                                                                        */
175
/*  FUNCTION                                               RELEASE        */
176
/*                                                                        */
177
/*    _gx_display_driver_332rgb_pixelmap_alpha_rotate     PORTABLE C      */
178
/*                                                           6.1.10       */
179
/*  AUTHOR                                                                */
180
/*                                                                        */
181
/*    Kenneth Maxwell, Microsoft Corporation                              */
182
/*                                                                        */
183
/*  DESCRIPTION                                                           */
184
/*                                                                        */
185
/*    Internal helper function that rotates an 332rgb format pixelmap     */
186
/*    with alpha.                                                         */
187
/*                                                                        */
188
/*  INPUT                                                                 */
189
/*                                                                        */
190
/*    context                               Drawing context               */
191
/*    xpos                                  x-coord of top-left draw point*/
192
/*    ypos                                  y-coord of top-left draw point*/
193
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
194
/*    angle                                 The angle to rotate           */
195
/*    cx                                    x-coord of rotate center      */
196
/*    cy                                    y-coord of rotate center      */
197
/*                                                                        */
198
/*  OUTPUT                                                                */
199
/*                                                                        */
200
/*    status                                Completion status             */
201
/*                                                                        */
202
/*  CALLS                                                                 */
203
/*                                                                        */
204
/*    _gx_utility_math_cos                  Compute the cosine value      */
205
/*    _gx_utility_math_sin                  Compute the sine value        */
206
/*    [gx_display_driver_pixel_blend]       Basic display driver pixel    */
207
/*                                            blend function              */
208
/*                                                                        */
209
/*  CALLED BY                                                             */
210
/*                                                                        */
211
/*    _gx_display_driver_8bpp_pixelmap_rotate                             */
212
/*                                                                        */
213
/**************************************************************************/
214
1069
static VOID _gx_display_driver_332rgb_pixelmap_alpha_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
215
                                                            INT angle, INT cx, INT cy)
216
{
217
GX_UBYTE     *get;
218
GX_UBYTE     *getalpha;
219
INT           srcxres;
220
INT           srcyres;
221
INT           cosv;
222
INT           sinv;
223
USHORT        red;
224
USHORT        green;
225
USHORT        blue;
226
INT           idxminx;
227
INT           idxmaxx;
228
INT           idxmaxy;
229
INT          *mx;
230
INT          *my;
231
INT           xres;
232
INT           yres;
233
INT           x;
234
INT           y;
235
INT           xx;
236
INT           yy;
237
USHORT        a;
238
USHORT        b;
239
USHORT        c;
240
USHORT        d;
241
USHORT        alpha[4];
242
INT           xdiff;
243
INT           ydiff;
244
INT           newxpos;
245
INT           newypos;
246
GX_DISPLAY   *display;
247
GX_RECTANGLE *clip;
248
VOID          (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR color, GX_UBYTE alpha);
249
250
1069
    clip = context -> gx_draw_context_clip;
251
1069
    display = context -> gx_draw_context_display;
252
1069
    blend_func = display -> gx_display_driver_pixel_blend;
253
1069
    if (!blend_func)
254
    {
255
1
        return;
256
    }
257
258
1068
    mx = _gx_system_scratchpad;
259
1068
    my = mx + 4;
260
261
1068
    mx[0] = mx[3] = -1;
262
1068
    mx[1] = mx[2] = 1;
263
264
1068
    my[0] = my[1] = 1;
265
1068
    my[2] = my[3] = -1;
266
267
1068
    idxminx = (angle / 90) & 0x3;
268
1068
    idxmaxx = (idxminx + 2) & 0x3;
269
1068
    idxmaxy = (idxminx + 1) & 0x3;
270
271
    /* Calculate the source x and y center. */
272
1068
    srcxres = pixelmap -> gx_pixelmap_width >> 1;
273
1068
    srcyres = pixelmap -> gx_pixelmap_height >> 1;
274
275
1068
    cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
276
1068
    sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
277
278
1068
    xres = GX_FIXED_VAL_TO_INT(mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv);
279
1068
    yres = GX_FIXED_VAL_TO_INT(my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv);
280
281
    /* Calculate the new rotation axis. */
282
1068
    xres = GX_FIXED_VAL_TO_INT((cx - srcxres) * cosv - (cy - srcyres) * sinv) + xres;
283
1068
    yres = GX_FIXED_VAL_TO_INT((cy - srcyres) * cosv + (cx - srcxres) * sinv) + yres;
284
285
1068
    newxpos = xpos + cx - xres;
286
1068
    newypos = ypos + cy - yres;
287
288
    /* Loop through the source's pixels.  */
289
228803
    for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
290
    {
291
60108951
        for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
292
        {
293
59881216
            xx = (x - xres) * cosv + (y - yres) * sinv;
294
59881216
            yy = (y - yres) * cosv - (x - xres) * sinv;
295
296
59881216
            xdiff = GX_FIXED_VAL_TO_INT(xx << 8) & 0xff;
297
59881216
            ydiff = GX_FIXED_VAL_TO_INT(yy << 8) & 0xff;
298
299
59881216
            xx = GX_FIXED_VAL_TO_INT(xx) + cx;
300
59881216
            yy = GX_FIXED_VAL_TO_INT(yy) + cy;
301
302

59881216
            if ((xx >= -1) && (xx < pixelmap -> gx_pixelmap_width) &&
303
41870359
                (yy >= -1) && (yy < pixelmap -> gx_pixelmap_height))
304
            {
305

36403101
                if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_width - 1) && \
306
35899550
                    (yy >= 0) && (yy < pixelmap -> gx_pixelmap_height - 1))
307
                {
308
35724853
                    get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
309
35724853
                    get += yy * pixelmap -> gx_pixelmap_width;
310
35724853
                    get += xx;
311
312
35724853
                    getalpha = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
313
35724853
                    getalpha += yy * pixelmap -> gx_pixelmap_width;
314
35724853
                    getalpha += xx;
315
316
35724853
                    a = *get;
317
35724853
                    alpha[0] = *getalpha;
318
319
35724853
                    b = *(get + 1);
320
35724853
                    alpha[1] = *(getalpha + 1);
321
322
35724853
                    c = *(get + pixelmap -> gx_pixelmap_width);
323
35724853
                    alpha[2] = *(getalpha + pixelmap -> gx_pixelmap_width);
324
325
35724853
                    d = *(get + pixelmap -> gx_pixelmap_width + 1);
326
35724853
                    alpha[3] = *(getalpha + pixelmap -> gx_pixelmap_width + 1);
327
                }
328
                else
329
                {
330
678248
                    get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
331
678248
                    getalpha = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
332
333
678248
                    a = 0;
334
678248
                    b = 0;
335
678248
                    c = 0;
336
678248
                    d = 0;
337
338
678248
                    if (xx == -1)
339
                    {
340
                        /* handle left edge.  */
341
164169
                        if (yy >= 0)
342
                        {
343
163694
                            b = *(get + yy * pixelmap -> gx_pixelmap_width);
344
163694
                            alpha[1] = *(getalpha + yy * pixelmap -> gx_pixelmap_width);
345
                        }
346
347
164169
                        if (yy < pixelmap -> gx_pixelmap_height - 1)
348
                        {
349
163510
                            d = *(get + (yy + 1) * pixelmap -> gx_pixelmap_width);
350
163510
                            alpha[3] = *(getalpha + (yy + 1) * pixelmap -> gx_pixelmap_width);
351
                        }
352
                    }
353
514079
                    else if (yy == -1)
354
                    {
355
                        /* handle top edge.  */
356
134155
                        c = *(get + xx);
357
134155
                        alpha[2] = *(getalpha + xx);
358
359
134155
                        if (xx < pixelmap -> gx_pixelmap_width - 1)
360
                        {
361
133469
                            d = *(get + xx + 1);
362
133469
                            alpha[3] = *(getalpha + xx + 1);
363
                        }
364
                    }
365
379924
                    else if (xx == pixelmap -> gx_pixelmap_width - 1)
366
                    {
367
                        /* handle right edget. */
368
205227
                        a = *(get + yy * pixelmap -> gx_pixelmap_width + xx);
369
205227
                        alpha[0] = *(getalpha + yy * pixelmap -> gx_pixelmap_width + xx);
370
371
205227
                        if (yy < pixelmap -> gx_pixelmap_height - 1)
372
                        {
373
203519
                            c = *(get + (yy + 1) * pixelmap -> gx_pixelmap_width + xx);
374
203519
                            alpha[2] = *(getalpha + (yy + 1) * pixelmap -> gx_pixelmap_width + xx);
375
                        }
376
                    }
377
                    else
378
                    {
379
                        /* handle bottom edge. */
380
174697
                        a = *(get + yy * pixelmap -> gx_pixelmap_width + xx);
381
174697
                        alpha[0] = *(getalpha + yy * pixelmap -> gx_pixelmap_width + xx);
382
383
174697
                        b = *(get + yy * pixelmap -> gx_pixelmap_width + xx + 1);
384
174697
                        alpha[1] = *(getalpha + yy * pixelmap -> gx_pixelmap_width + xx + 1);
385
                    }
386
387
678248
                    if (!a)
388
                    {
389
298324
                        alpha[0] = 0;
390
                    }
391
392
678248
                    if (!b)
393
                    {
394
339857
                        alpha[1] = 0;
395
                    }
396
397
678248
                    if (!c)
398
                    {
399
340574
                        alpha[2] = 0;
400
                    }
401
402
678248
                    if (!d)
403
                    {
404
381269
                        alpha[3] = 0;
405
                    }
406
                }
407
408
36403101
                red = (USHORT)((REDVAL_332(a) * alpha[0] * (256 - xdiff) * (256 - ydiff) +
409
36403101
                                REDVAL_332(b) * alpha[1] * xdiff * (256 - ydiff) +
410
36403101
                                REDVAL_332(c) * alpha[2] * ydiff * (256 - xdiff) +
411
36403101
                                REDVAL_332(d) * alpha[3] * xdiff * ydiff) >> 16);
412
413
36403101
                green = (USHORT)((GREENVAL_332(a) * alpha[0] * (256 - xdiff) * (256 - ydiff) +
414
36403101
                                  GREENVAL_332(b) * alpha[1] * xdiff * (256 - ydiff) +
415
36403101
                                  GREENVAL_332(c) * alpha[2] * ydiff * (256 - xdiff) +
416
36403101
                                  GREENVAL_332(d) * alpha[3] * xdiff * ydiff) >> 16);
417
418
36403101
                blue = (USHORT)((BLUEVAL_332(a) * alpha[0] * (256 - xdiff) * (256 - ydiff) +
419
36403101
                                 BLUEVAL_332(b) * alpha[1] * xdiff * (256 - ydiff) +
420
36403101
                                 BLUEVAL_332(c) * alpha[2] * ydiff * (256 - xdiff) +
421
36403101
                                 BLUEVAL_332(d) * alpha[3] * xdiff * ydiff) >> 16);
422
423
36403101
                alpha[0] = (USHORT)((alpha[0] * (256 - xdiff) * (256 - ydiff) +
424
36403101
                                     alpha[1] * xdiff * (256 - ydiff) +
425
36403101
                                     alpha[2] * ydiff * (256 - xdiff) +
426
36403101
                                     alpha[3] * xdiff * ydiff) >> 16);
427
428
36403101
                if (alpha[0])
429
                {
430
24119432
                    red /= alpha[0];
431
24119432
                    green /= alpha[0];
432
24119432
                    blue /= alpha[0];
433
                }
434
435
36403101
                red = red > 7 ? 7 : red;
436
36403101
                green = green > 7 ? 7 : green;
437
36403101
                blue = blue > 3 ? 3 : blue;
438
36403101
                alpha[0] = alpha[0] > 255 ? 255 : alpha[0];
439
440
36403101
                blend_func(context, x + newxpos, y + newypos, (GX_COLOR)ASSEMBLECOLOR_332(red, green, blue), (GX_UBYTE)alpha[0]);
441
            }
442
        }
443
    }
444
}
445
446
/**************************************************************************/
447
/*                                                                        */
448
/*  FUNCTION                                               RELEASE        */
449
/*                                                                        */
450
/*    _gx_display_driver_332rgb_pixelmap_raw_rotate      PORTABLE C       */
451
/*                                                           6.1.10       */
452
/*  AUTHOR                                                                */
453
/*                                                                        */
454
/*    Kenneth Maxwell, Microsoft Corporation                              */
455
/*                                                                        */
456
/*  DESCRIPTION                                                           */
457
/*                                                                        */
458
/*    Internal helper function that rotates an 332rgb format pixelmap     */
459
/*    without compression, without alpha.                                 */
460
/*                                                                        */
461
/*  INPUT                                                                 */
462
/*                                                                        */
463
/*    context                               Drawing context               */
464
/*    xpos                                  x-coord of top-left draw point*/
465
/*    ypos                                  y-coord of top-left draw point*/
466
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
467
/*    angle                                 The angle to rotate           */
468
/*    cx                                    x-coord of rotate center      */
469
/*    cy                                    y-coord of rotate center      */
470
/*                                                                        */
471
/*  OUTPUT                                                                */
472
/*                                                                        */
473
/*    status                                Completion status             */
474
/*                                                                        */
475
/*  CALLS                                                                 */
476
/*                                                                        */
477
/*    _gx_utility_math_cos                  Compute the cosine value      */
478
/*    _gx_utility_math_sin                  Compute the sine value        */
479
/*    [gx_display_driver_pixel_blend]       Basic display driver pixel    */
480
/*                                            blend function              */
481
/*                                                                        */
482
/*  CALLED BY                                                             */
483
/*                                                                        */
484
/*    _gx_display_driver_332rgb_pixelmap_rotate                           */
485
/*                                                                        */
486
/**************************************************************************/
487
713
static VOID _gx_display_driver_332rgb_pixelmap_raw_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
488
                                                          INT angle, INT cx, INT cy)
489
{
490
GX_UBYTE     *get;
491
INT           srcxres;
492
INT           srcyres;
493
INT           cosv;
494
INT           sinv;
495
USHORT        red;
496
USHORT        green;
497
USHORT        blue;
498
INT           idxminx;
499
INT           idxmaxx;
500
INT           idxmaxy;
501
INT          *mx;
502
INT          *my;
503
INT           xres;
504
INT           yres;
505
INT           x;
506
INT           y;
507
INT           xx;
508
INT           yy;
509
USHORT        a;
510
USHORT        b;
511
USHORT        c;
512
USHORT        d;
513
INT           alpha;
514
INT           xdiff;
515
INT           ydiff;
516
INT           newxpos;
517
INT           newypos;
518
GX_DISPLAY   *display;
519
GX_RECTANGLE *clip;
520
VOID          (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR color, GX_UBYTE alpha);
521
522
713
    clip = context -> gx_draw_context_clip;
523
713
    display = context -> gx_draw_context_display;
524
713
    blend_func = display -> gx_display_driver_pixel_blend;
525
713
    if (!blend_func)
526
    {
527
1
        return;
528
    }
529
530
712
    mx = _gx_system_scratchpad;
531
712
    my = mx + 4;
532
533
712
    mx[0] = mx[3] = -1;
534
712
    mx[1] = mx[2] = 1;
535
536
712
    my[0] = my[1] = 1;
537
712
    my[2] = my[3] = -1;
538
539
712
    idxminx = (angle / 90) & 0x3;
540
712
    idxmaxx = (idxminx + 2) & 0x3;
541
712
    idxmaxy = (idxminx + 1) & 0x3;
542
543
    /* Calculate the source x and y center. */
544
712
    srcxres = pixelmap -> gx_pixelmap_width >> 1;
545
712
    srcyres = pixelmap -> gx_pixelmap_height >> 1;
546
547
712
    cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
548
712
    sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
549
550
712
    xres = GX_FIXED_VAL_TO_INT(mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv);
551
712
    yres = GX_FIXED_VAL_TO_INT(my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv);
552
553
    /* Calculate the new rotation axis. */
554
712
    xres = GX_FIXED_VAL_TO_INT((cx - srcxres) * cosv - (cy - srcyres) * sinv) + xres;
555
712
    yres = GX_FIXED_VAL_TO_INT((cy - srcyres) * cosv + (cx - srcxres) * sinv) + yres;
556
557
712
    newxpos = xpos + cx - xres;
558
712
    newypos = ypos + cy - yres;
559
560
    /* Loop through the source's pixels.  */
561
150359
    for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
562
    {
563
33586559
        for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
564
        {
565
33436912
            xx = (x - xres) * cosv + (y - yres) * sinv;
566
33436912
            yy = (y - yres) * cosv - (x - xres) * sinv;
567
568
33436912
            xdiff = GX_FIXED_VAL_TO_INT(xx << 8) & 0xff;
569
33436912
            ydiff = GX_FIXED_VAL_TO_INT(yy << 8) & 0xff;
570
571
33436912
            xx = GX_FIXED_VAL_TO_INT(xx) + cx;
572
33436912
            yy = GX_FIXED_VAL_TO_INT(yy) + cy;
573
574

33436912
            if ((xx >= -1) && (xx < pixelmap -> gx_pixelmap_width) &&
575
25173357
                (yy >= -1) && (yy < pixelmap -> gx_pixelmap_height))
576
            {
577

18929707
                if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_width - 1) && \
578
18645079
                    (yy >= 0) && (yy < pixelmap -> gx_pixelmap_height - 1))
579
                {
580
18491434
                    get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
581
18491434
                    get += yy * pixelmap -> gx_pixelmap_width;
582
18491434
                    get += xx;
583
584
18491434
                    a = *get;
585
18491434
                    b = *(get + 1);
586
18491434
                    c = *(get + pixelmap -> gx_pixelmap_width);
587
18491434
                    d = *(get + pixelmap -> gx_pixelmap_width + 1);
588
589
18491434
                    alpha = 0xff;
590
                }
591
                else
592
                {
593
438273
                    get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
594
595
438273
                    a = 0;
596
438273
                    b = 0;
597
438273
                    c = 0;
598
438273
                    d = 0;
599
438273
                    alpha = 0;
600
601
438273
                    if (xx == -1)
602
                    {
603
                        /* handle left edge.  */
604
59013
                        if (yy >= 0)
605
                        {
606
58641
                            b = *(get + yy * pixelmap -> gx_pixelmap_width);
607
58641
                            alpha += xdiff * (256 - ydiff);
608
                        }
609
610
59013
                        if (yy < pixelmap -> gx_pixelmap_height - 1)
611
                        {
612
58560
                            d = *(get + (yy + 1) * pixelmap -> gx_pixelmap_width);
613
58560
                            alpha += xdiff * ydiff;
614
                        }
615
                    }
616
379260
                    else if (yy == -1)
617
                    {
618
                        /* handle top edge.  */
619
135992
                        c = *(get + xx);
620
135992
                        alpha += ydiff * (256 - xdiff);
621
622
135992
                        if (xx < pixelmap -> gx_pixelmap_width - 1)
623
                        {
624
135342
                            d = *(get + xx + 1);
625
135342
                            alpha += xdiff * ydiff;
626
                        }
627
                    }
628
243268
                    else if (xx == pixelmap -> gx_pixelmap_width - 1)
629
                    {
630
                        /* handle right edget. */
631
89623
                        a = *(get + yy * pixelmap -> gx_pixelmap_width + xx);
632
89623
                        alpha += (256 - xdiff) * (256 - ydiff);
633
634
89623
                        if (yy < pixelmap -> gx_pixelmap_height - 1)
635
                        {
636
88547
                            c = *(get + (yy + 1) * pixelmap -> gx_pixelmap_width + xx);
637
88547
                            alpha += ydiff * (256 - xdiff);
638
                        }
639
                    }
640
                    else
641
                    {
642
                        /* handle bottom edge. */
643
153645
                        a = *(get + yy * pixelmap -> gx_pixelmap_width + xx);
644
153645
                        alpha += (256 - xdiff) * (256 - ydiff);
645
646
153645
                        b = *(get + yy * pixelmap -> gx_pixelmap_width + xx + 1);
647
153645
                        alpha += xdiff * (256 - ydiff);
648
                    }
649
650
438273
                    alpha >>= 8;
651
                }
652
653
18929707
                red = (USHORT)((REDVAL_332(a) * (256 - xdiff) * (256 - ydiff) +
654
18929707
                                REDVAL_332(b) * xdiff * (256 - ydiff) +
655
18929707
                                REDVAL_332(c) * ydiff * (256 - xdiff) +
656
18929707
                                REDVAL_332(d) * xdiff * ydiff) >> 16);
657
658
18929707
                green = (USHORT)((GREENVAL_332(a) * (256 - xdiff) * (256 - ydiff) +
659
18929707
                                  GREENVAL_332(b) * xdiff * (256 - ydiff) +
660
18929707
                                  GREENVAL_332(c) * ydiff * (256 - xdiff) +
661
18929707
                                  GREENVAL_332(d) * xdiff * ydiff) >> 16);
662
663
18929707
                blue = (USHORT)((BLUEVAL_332(a) * (256 - xdiff) * (256 - ydiff) +
664
18929707
                                 BLUEVAL_332(b) * xdiff * (256 - ydiff) +
665
18929707
                                 BLUEVAL_332(c) * ydiff * (256 - xdiff) +
666
18929707
                                 BLUEVAL_332(d) * xdiff * ydiff) >> 16);
667
668

18929707
                if (alpha && (alpha < 0xff))
669
                {
670
433239
                    red = (USHORT)((red << 8) / alpha);
671
433239
                    green = (USHORT)((green << 8) / alpha);
672
433239
                    blue = (USHORT)((blue << 8) / alpha);
673
                }
674
675
18929707
                red = red > 7 ? 7 : red;
676
18929707
                green = green > 7 ? 7 : green;
677
18929707
                blue = blue > 3 ? 3 : blue;
678
18929707
                alpha = alpha > 255 ? 255 : alpha;
679
680
18929707
                blend_func(context, x + newxpos, y + newypos, (GX_COLOR)ASSEMBLECOLOR_332(red, green, blue), (GX_UBYTE)alpha);
681
            }
682
        }
683
    }
684
}
685
686
/**************************************************************************/
687
/*                                                                        */
688
/*  FUNCTION                                               RELEASE        */
689
/*                                                                        */
690
/*    _gx_display_driver_332rgb_pixelmap_rotate           PORTABLE C      */
691
/*                                                           6.1          */
692
/*  AUTHOR                                                                */
693
/*                                                                        */
694
/*    Kenneth Maxwell, Microsoft Corporation                              */
695
/*                                                                        */
696
/*  DESCRIPTION                                                           */
697
/*                                                                        */
698
/*    This service rotate a 332rgb format pixelmap to canvas memory.      */
699
/*                                                                        */
700
/*  INPUT                                                                 */
701
/*                                                                        */
702
/*    context                               Drawing context               */
703
/*    xpos                                  x-coord of top-left draw point*/
704
/*    ypos                                  y-coord of top-left draw point*/
705
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
706
/*    angle                                 The angle to rotate           */
707
/*    rot_cx                                x-coord of rotating center.   */
708
/*    rot_cy                                y-coord of rotationg center.  */
709
/*                                                                        */
710
/*  OUTPUT                                                                */
711
/*                                                                        */
712
/*    status                                Completion status             */
713
/*                                                                        */
714
/*  CALLS                                                                 */
715
/*                                                                        */
716
/*    _gx_display_driver_8bpp_pixelmap_rotate                             */
717
/*                                          Rotate 8bpp format pixelmap   */
718
/*    _gx_display_driver_332rgb_pixelmap_simple_alpha_rotate              */
719
/*                                          Rotate 332rgb format pixelmap */
720
/*                                            in simple case              */
721
/*    _gx_display_driver_332rgb_pixelmap_alpha_rotate                     */
722
/*                                          Rotate 332rgb format pixelmap */
723
/*                                            with alpha                  */
724
/*    _gx_display_driver_332rgb_pixelmap_raw_rotate                       */
725
/*                                          Rotate 332rgb format pixelmap */
726
/*                                            without alpha               */
727
/*                                                                        */
728
/*  CALLED BY                                                             */
729
/*                                                                        */
730
/*    Application Code                                                    */
731
/*    GUIX Internal Code                                                  */
732
/*                                                                        */
733
/**************************************************************************/
734
1799
VOID _gx_display_driver_332rgb_pixelmap_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
735
                                               INT angle, INT rot_cx, INT rot_cy)
736
{
737
1799
    switch (pixelmap -> gx_pixelmap_format)
738
    {
739
1798
    case GX_COLOR_FORMAT_8BIT_PACKED_PIXEL:
740
1798
        if (angle % 90 == 0)
741
        {
742
            /* Simple angle rotate: 90 degree, 180 degree and 270 degree.  */
743
16
            if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
744
            {
745
                /*Alpha, no compression.*/
746
10
                _gx_display_driver_332rgb_pixelmap_simple_alpha_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
747
            }
748
            else
749
            {
750
6
                _gx_display_driver_8bpp_pixelmap_simple_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
751
            }
752
        }
753
        else
754
        {
755
1782
            if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
756
            {
757
                /*Not correct yet.*/
758
1069
                _gx_display_driver_332rgb_pixelmap_alpha_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
759
            }
760
            else
761
            {
762
                /* no compression or alpha */
763
713
                _gx_display_driver_332rgb_pixelmap_raw_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
764
            }
765
        }
766
1798
        break;
767
    }
768
769
1799
    return;
770
}
771