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

59881216
            if ((xx >= -1) && (xx < pixelmap -> gx_pixelmap_width) &&
325
41870359
                (yy >= -1) && (yy < pixelmap -> gx_pixelmap_height))
326
            {
327

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

33436912
            if ((xx >= -1) && (xx < pixelmap -> gx_pixelmap_width) &&
608
25173357
                (yy >= -1) && (yy < pixelmap -> gx_pixelmap_height))
609
            {
610

18929707
                if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_width - 1) && \
611
18645079
                    (yy >= 0) && (yy < pixelmap -> gx_pixelmap_height - 1))
612
                {
613
18491434
                    get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
614
18491434
                    get += yy * pixelmap -> gx_pixelmap_width;
615
18491434
                    get += xx;
616
617
18491434
                    a = *get;
618
18491434
                    b = *(get + 1);
619
18491434
                    c = *(get + pixelmap -> gx_pixelmap_width);
620
18491434
                    d = *(get + pixelmap -> gx_pixelmap_width + 1);
621
622
18491434
                    alpha = 0xff;
623
                }
624
                else
625
                {
626
438273
                    get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
627
628
438273
                    a = 0;
629
438273
                    b = 0;
630
438273
                    c = 0;
631
438273
                    d = 0;
632
438273
                    alpha = 0;
633
634
438273
                    if (xx == -1)
635
                    {
636
                        /* handle left edge.  */
637
59013
                        if (yy >= 0)
638
                        {
639
58641
                            b = *(get + yy * pixelmap -> gx_pixelmap_width);
640
58641
                            alpha += xdiff * (256 - ydiff);
641
                        }
642
643
59013
                        if (yy < pixelmap -> gx_pixelmap_height - 1)
644
                        {
645
58560
                            d = *(get + (yy + 1) * pixelmap -> gx_pixelmap_width);
646
58560
                            alpha += xdiff * ydiff;
647
                        }
648
                    }
649
379260
                    else if (yy == -1)
650
                    {
651
                        /* handle top edge.  */
652
135992
                        c = *(get + xx);
653
135992
                        alpha += ydiff * (256 - xdiff);
654
655
135992
                        if (xx < pixelmap -> gx_pixelmap_width - 1)
656
                        {
657
135342
                            d = *(get + xx + 1);
658
135342
                            alpha += xdiff * ydiff;
659
                        }
660
                    }
661
243268
                    else if (xx == pixelmap -> gx_pixelmap_width - 1)
662
                    {
663
                        /* handle right edget. */
664
89623
                        a = *(get + yy * pixelmap -> gx_pixelmap_width + xx);
665
89623
                        alpha += (256 - xdiff) * (256 - ydiff);
666
667
89623
                        if (yy < pixelmap -> gx_pixelmap_height - 1)
668
                        {
669
88547
                            c = *(get + (yy + 1) * pixelmap -> gx_pixelmap_width + xx);
670
88547
                            alpha += ydiff * (256 - xdiff);
671
                        }
672
                    }
673
                    else
674
                    {
675
                        /* handle bottom edge. */
676
153645
                        a = *(get + yy * pixelmap -> gx_pixelmap_width + xx);
677
153645
                        alpha += (256 - xdiff) * (256 - ydiff);
678
679
153645
                        b = *(get + yy * pixelmap -> gx_pixelmap_width + xx + 1);
680
153645
                        alpha += xdiff * (256 - ydiff);
681
                    }
682
683
438273
                    alpha >>= 8;
684
                }
685
686
18929707
                red = (USHORT)((REDVAL_332(a) * (256 - xdiff) * (256 - ydiff) +
687
18929707
                                REDVAL_332(b) * xdiff * (256 - ydiff) +
688
18929707
                                REDVAL_332(c) * ydiff * (256 - xdiff) +
689
18929707
                                REDVAL_332(d) * xdiff * ydiff) >> 16);
690
691
18929707
                green = (USHORT)((GREENVAL_332(a) * (256 - xdiff) * (256 - ydiff) +
692
18929707
                                  GREENVAL_332(b) * xdiff * (256 - ydiff) +
693
18929707
                                  GREENVAL_332(c) * ydiff * (256 - xdiff) +
694
18929707
                                  GREENVAL_332(d) * xdiff * ydiff) >> 16);
695
696
18929707
                blue = (USHORT)((BLUEVAL_332(a) * (256 - xdiff) * (256 - ydiff) +
697
18929707
                                 BLUEVAL_332(b) * xdiff * (256 - ydiff) +
698
18929707
                                 BLUEVAL_332(c) * ydiff * (256 - xdiff) +
699
18929707
                                 BLUEVAL_332(d) * xdiff * ydiff) >> 16);
700
701

18929707
                if (alpha && (alpha < 0xff))
702
                {
703
433239
                    red = (USHORT)((red << 8) / alpha);
704
433239
                    green = (USHORT)((green << 8) / alpha);
705
433239
                    blue = (USHORT)((blue << 8) / alpha);
706
                }
707
708
18929707
                red = red > 7 ? 7 : red;
709
18929707
                green = green > 7 ? 7 : green;
710
18929707
                blue = blue > 3 ? 3 : blue;
711
18929707
                alpha = alpha > 255 ? 255 : alpha;
712
713
18929707
                blend_func(context, x + newxpos, y + newypos, (GX_COLOR)ASSEMBLECOLOR_332(red, green, blue), (GX_UBYTE)alpha);
714
            }
715
        }
716
    }
717
}
718
719
/**************************************************************************/
720
/*                                                                        */
721
/*  FUNCTION                                               RELEASE        */
722
/*                                                                        */
723
/*    _gx_display_driver_332rgb_pixelmap_rotate           PORTABLE C      */
724
/*                                                           6.1          */
725
/*  AUTHOR                                                                */
726
/*                                                                        */
727
/*    Kenneth Maxwell, Microsoft Corporation                              */
728
/*                                                                        */
729
/*  DESCRIPTION                                                           */
730
/*                                                                        */
731
/*    This service rotate a 332rgb format pixelmap to canvas memory.      */
732
/*                                                                        */
733
/*  INPUT                                                                 */
734
/*                                                                        */
735
/*    context                               Drawing context               */
736
/*    xpos                                  x-coord of top-left draw point*/
737
/*    ypos                                  y-coord of top-left draw point*/
738
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
739
/*    angle                                 The angle to rotate           */
740
/*    rot_cx                                x-coord of rotating center.   */
741
/*    rot_cy                                y-coord of rotationg center.  */
742
/*                                                                        */
743
/*  OUTPUT                                                                */
744
/*                                                                        */
745
/*    status                                Completion status             */
746
/*                                                                        */
747
/*  CALLS                                                                 */
748
/*                                                                        */
749
/*    _gx_display_driver_8bpp_pixelmap_rotate                             */
750
/*                                          Rotate 8bpp format pixelmap   */
751
/*    _gx_display_driver_332rgb_pixelmap_simple_alpha_rotate              */
752
/*                                          Rotate 332rgb format pixelmap */
753
/*                                            in simple case              */
754
/*    _gx_display_driver_332rgb_pixelmap_alpha_rotate                     */
755
/*                                          Rotate 332rgb format pixelmap */
756
/*                                            with alpha                  */
757
/*    _gx_display_driver_332rgb_pixelmap_raw_rotate                       */
758
/*                                          Rotate 332rgb format pixelmap */
759
/*                                            without alpha               */
760
/*                                                                        */
761
/*  CALLED BY                                                             */
762
/*                                                                        */
763
/*    Application Code                                                    */
764
/*    GUIX Internal Code                                                  */
765
/*                                                                        */
766
/*  RELEASE HISTORY                                                       */
767
/*                                                                        */
768
/*    DATE              NAME                      DESCRIPTION             */
769
/*                                                                        */
770
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
771
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
772
/*                                            resulting in version 6.1    */
773
/*                                                                        */
774
/**************************************************************************/
775
1799
VOID _gx_display_driver_332rgb_pixelmap_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
776
                                               INT angle, INT rot_cx, INT rot_cy)
777
{
778
1799
    switch (pixelmap -> gx_pixelmap_format)
779
    {
780
1798
    case GX_COLOR_FORMAT_8BIT_PACKED_PIXEL:
781
1798
        if (angle % 90 == 0)
782
        {
783
            /* Simple angle rotate: 90 degree, 180 degree and 270 degree.  */
784
16
            if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
785
            {
786
                /*Alpha, no compression.*/
787
10
                _gx_display_driver_332rgb_pixelmap_simple_alpha_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
788
            }
789
            else
790
            {
791
6
                _gx_display_driver_8bpp_pixelmap_simple_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
792
            }
793
        }
794
        else
795
        {
796
1782
            if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
797
            {
798
                /*Not correct yet.*/
799
1069
                _gx_display_driver_332rgb_pixelmap_alpha_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
800
            }
801
            else
802
            {
803
                /* no compression or alpha */
804
713
                _gx_display_driver_332rgb_pixelmap_raw_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
805
            }
806
        }
807
1798
        break;
808
    }
809
810
1799
    return;
811
}
812