GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_32bpp_pixelmap_rotate.c Lines: 260 260 100.0 %
Date: 2024-12-05 08:52:37 Branches: 114 114 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
21
#define REDVAL(_c)     (GX_UBYTE)((_c) >> 16)
22
#define GREENVAL(_c)   (GX_UBYTE)((_c) >> 8)
23
#define BLUEVAL(_c)    (GX_UBYTE)(_c)
24
25
#define ASSEMBLECOLOR(_r, _g, _b) \
26
    (0xff000000   |               \
27
     ((_r) << 16) |               \
28
     ((_g) << 8)  |               \
29
     (_b))
30
31
#define BYTE_RANGE(_c) _c > 255 ? 255 : _c
32
33
#define GX_SOURCE_CODE
34
35
36
/* Include necessary system files.  */
37
38
#include "gx_api.h"
39
#include "gx_display.h"
40
#include "gx_context.h"
41
#include "gx_utility.h"
42
#include "gx_system.h"
43
44
/**************************************************************************/
45
/*                                                                        */
46
/*  FUNCTION                                               RELEASE        */
47
/*                                                                        */
48
/*    _gx_display_driver_24xrgb_pixelmap_rotate           PORTABLE C      */
49
/*                                                           6.1.10       */
50
/*  AUTHOR                                                                */
51
/*                                                                        */
52
/*    Kenneth Maxwell, Microsoft Corporation                              */
53
/*                                                                        */
54
/*  DESCRIPTION                                                           */
55
/*                                                                        */
56
/*    Internal helper function that rotate an uncompressed pixelmap       */
57
/*      without alpha.                                                    */
58
/*                                                                        */
59
/*  INPUT                                                                 */
60
/*                                                                        */
61
/*    context                               Drawing context               */
62
/*    xpos                                  x-coord of top-left draw point*/
63
/*    ypos                                  y-coord of top-left draw point*/
64
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
65
/*    angle                                 The angle to rotate           */
66
/*    cx                                    x-coord of rotate center      */
67
/*    cy                                    y-coord of rotate center      */
68
/*                                                                        */
69
/*  OUTPUT                                                                */
70
/*                                                                        */
71
/*    status                                Completion status             */
72
/*                                                                        */
73
/*  CALLS                                                                 */
74
/*                                                                        */
75
/*    _gx_utility_math_cos                  Compute the cosine value      */
76
/*    _gx_utility_math_sin                  Compute the sine value        */
77
/*    [gx_display_driver_pixel_blend]       Basic display driver pixel    */
78
/*                                            blend function              */
79
/*                                                                        */
80
/*  CALLED BY                                                             */
81
/*                                                                        */
82
/*    _gx_display_driver_32bpp_pixelmap_rotate                            */
83
/*                                                                        */
84
/*  RELEASE HISTORY                                                       */
85
/*                                                                        */
86
/*    DATE              NAME                      DESCRIPTION             */
87
/*                                                                        */
88
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
89
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
90
/*                                            resulting in version 6.1    */
91
/*  01-31-2022     Ting Zhu                 Modified comment(s),          */
92
/*                                            corrected logic,            */
93
/*                                            resulting in version 6.1.10 */
94
/*                                                                        */
95
/**************************************************************************/
96
713
static VOID _gx_display_driver_24xrgb_pixelmap_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
97
                                                      INT angle, INT cx, INT cy)
98
{
99
GX_COLOR     *get;
100
INT           srcxres;
101
INT           srcyres;
102
INT           cosv;
103
INT           sinv;
104
INT           alpha;
105
GX_COLOR      red;
106
GX_COLOR      green;
107
GX_COLOR      blue;
108
INT           idxminx;
109
INT           idxmaxx;
110
INT           idxmaxy;
111
INT          *mx;
112
INT          *my;
113
INT           xres;
114
INT           yres;
115
INT           x;
116
INT           y;
117
INT           xx;
118
INT           yy;
119
GX_COLOR      a;
120
GX_COLOR      b;
121
GX_COLOR      c;
122
GX_COLOR      d;
123
INT           xdiff;
124
INT           ydiff;
125
INT           newxpos;
126
INT           newypos;
127
GX_DISPLAY   *display;
128
GX_RECTANGLE *clip;
129
VOID          (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR color, GX_UBYTE alpha);
130
131
713
    clip = context -> gx_draw_context_clip;
132
713
    display = context -> gx_draw_context_display;
133
713
    blend_func = display -> gx_display_driver_pixel_blend;
134
135
713
    if (!blend_func)
136
    {
137
1
        return;
138
    }
139
140
712
    mx = _gx_system_scratchpad;
141
712
    my = mx + 4;
142
143
712
    mx[0] = mx[3] = -1;
144
712
    mx[1] = mx[2] = 1;
145
146
712
    my[0] = my[1] = 1;
147
712
    my[2] = my[3] = -1;
148
149
712
    idxminx = (angle / 90) & 0x3;
150
712
    idxmaxx = (idxminx + 2) & 0x3;
151
712
    idxmaxy = (idxminx + 1) & 0x3;
152
153
    /* Calculate the source x and y center. */
154
712
    srcxres = pixelmap -> gx_pixelmap_width >> 1;
155
712
    srcyres = pixelmap -> gx_pixelmap_height >> 1;
156
157
712
    cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
158
712
    sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
159
160
712
    xres = mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv;
161
712
    yres = my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv;
162
163
712
    xres = GX_FIXED_VAL_TO_INT(xres);
164
712
    yres = GX_FIXED_VAL_TO_INT(yres);
165
166
    /* Calculate the new rotation axis. */
167
168
712
    x = (cx - srcxres) * cosv - (cy - srcyres) * sinv;
169
712
    y = (cy - srcyres) * cosv + (cx - srcxres) * sinv;
170
171
712
    xres = GX_FIXED_VAL_TO_INT(x) + xres;
172
712
    yres = GX_FIXED_VAL_TO_INT(y) + yres;
173
174
712
    newxpos = xpos + cx - xres;
175
712
    newypos = ypos + cy - yres;
176
177
    /* Loop through the destination's pixels.  */
178
149753
    for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
179
    {
180
33809071
        for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
181
        {
182
33660030
            xx = (x - xres) * cosv + (y - yres) * sinv;
183
33660030
            yy = (y - yres) * cosv - (x - xres) * sinv;
184
185
33660030
            xdiff = GX_FIXED_VAL_TO_INT(xx << 8) & 0xff;
186
33660030
            ydiff = GX_FIXED_VAL_TO_INT(yy << 8) & 0xff;
187
188
33660030
            xx = GX_FIXED_VAL_TO_INT(xx) + cx;
189
33660030
            yy = GX_FIXED_VAL_TO_INT(yy) + cy;
190
191

33660030
            if ((xx >= -1) && (xx < pixelmap -> gx_pixelmap_width) &&
192
25337253
                (yy >= -1) && (yy < pixelmap -> gx_pixelmap_height))
193
            {
194

19049704
                if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_width - 1) &&
195
18763787
                    (yy >= 0) && (yy < pixelmap -> gx_pixelmap_height - 1))
196
                {
197
18609240
                    get = (GX_COLOR *)pixelmap -> gx_pixelmap_data;
198
18609240
                    get += yy * pixelmap -> gx_pixelmap_width;
199
18609240
                    get += xx;
200
201
18609240
                    a = *get;
202
18609240
                    b = *(get + 1);
203
18609240
                    c = *(get + pixelmap -> gx_pixelmap_width);
204
18609240
                    d = *(get + pixelmap -> gx_pixelmap_width + 1);
205
206
18609240
                    alpha = 0xff;
207
                }
208
                else
209
                {
210
440464
                    get = (GX_COLOR *)pixelmap -> gx_pixelmap_data;
211
212
440464
                    a = 0;
213
440464
                    b = 0;
214
440464
                    c = 0;
215
440464
                    d = 0;
216
440464
                    alpha = 0;
217
218
440464
                    if (xx == -1)
219
                    {
220
                        /* handle left edge.  */
221
59074
                        if (yy >= 0)
222
                        {
223
58700
                            b = *(get + yy * pixelmap -> gx_pixelmap_width);
224
                        }
225
226
59074
                        if (yy < pixelmap -> gx_pixelmap_height - 1)
227
                        {
228
58622
                            d = *(get + (yy + 1) * pixelmap -> gx_pixelmap_width);
229
                        }
230
                    }
231
381390
                    else if (yy == -1)
232
                    {
233
                        /* handle top edge.  */
234
137355
                        c = *(get + xx);
235
236
137355
                        if (xx < pixelmap -> gx_pixelmap_width - 1)
237
                        {
238
136708
                            d = *(get + xx + 1);
239
                        }
240
                    }
241
244035
                    else if (xx == pixelmap -> gx_pixelmap_width - 1)
242
                    {
243
                        /* handle right edget. */
244
89488
                        a = *(get + yy * pixelmap -> gx_pixelmap_width + xx);
245
246
89488
                        if (yy < pixelmap -> gx_pixelmap_height - 1)
247
                        {
248
88412
                            c = *(get + (yy + 1) * pixelmap -> gx_pixelmap_width + xx);
249
                        }
250
                    }
251
                    else
252
                    {
253
                        /* handle bottom edge. */
254
154547
                        a = *(get + yy * pixelmap -> gx_pixelmap_width + xx);
255
154547
                        b = *(get + yy * pixelmap -> gx_pixelmap_width + xx + 1);
256
                    }
257
258
440464
                    if (a)
259
                    {
260
244035
                        alpha += (256 - xdiff) * (256 - ydiff);
261
                    }
262
263
440464
                    if (b)
264
                    {
265
213247
                        alpha += xdiff * (256 - ydiff);
266
                    }
267
268
440464
                    if (c)
269
                    {
270
225767
                        alpha += ydiff * (256 - xdiff);
271
                    }
272
273
440464
                    if (d)
274
                    {
275
195330
                        alpha += xdiff * ydiff;
276
                    }
277
278
440464
                    alpha >>= 8;
279
                }
280
281
19049704
                red = (GX_COLOR)(REDVAL(a) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
282
19049704
                                 REDVAL(b) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) +         \
283
19049704
                                 REDVAL(c) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) +         \
284
19049704
                                 REDVAL(d) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16;
285
286
19049704
                green = (GX_COLOR)(GREENVAL(a) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
287
19049704
                                   GREENVAL(b) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) +         \
288
19049704
                                   GREENVAL(c) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) +         \
289
19049704
                                   GREENVAL(d) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16;
290
291
19049704
                blue = (GX_COLOR)(BLUEVAL(a) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
292
19049704
                                  BLUEVAL(b) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) +         \
293
19049704
                                  BLUEVAL(c) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) +         \
294
19049704
                                  BLUEVAL(d) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16;
295
296

19049704
                if ((alpha > 0) && (alpha < 0xff))
297
                {
298
435396
                    red = (red << 8) / (GX_COLOR)alpha;
299
435396
                    green = (green << 8) / (GX_COLOR)alpha;
300
435396
                    blue = (blue << 8) / (GX_COLOR)alpha;
301
                }
302
303
19049704
                red = BYTE_RANGE(red);
304
19049704
                green = BYTE_RANGE(green);
305
19049704
                blue = BYTE_RANGE(blue);
306
19049704
                alpha = BYTE_RANGE(alpha);
307
308
19049704
                blend_func(context, x + newxpos, y + newypos, ASSEMBLECOLOR(red, green, blue), (GX_UBYTE)alpha);
309
            }
310
        }
311
    }
312
}
313
314
/**************************************************************************/
315
/*                                                                        */
316
/*  FUNCTION                                               RELEASE        */
317
/*                                                                        */
318
/*    _gx_utility_24xrgb_pixelmap_alpha_rotate            PORTABLE C      */
319
/*                                                           6.1.10       */
320
/*  AUTHOR                                                                */
321
/*                                                                        */
322
/*    Kenneth Maxwell, Microsoft Corporation                              */
323
/*                                                                        */
324
/*  DESCRIPTION                                                           */
325
/*                                                                        */
326
/*    Internal helper function that rotate an uncompressed pixelmap       */
327
/*      with alpha.                                                       */
328
/*                                                                        */
329
/*  INPUT                                                                 */
330
/*                                                                        */
331
/*    context                               Drawing context               */
332
/*    xpos                                  x-coord of top-left draw point*/
333
/*    ypos                                  y-coord of top-left draw point*/
334
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
335
/*    angle                                 The angle to rotate           */
336
/*    cx                                    x-coord of rotate center      */
337
/*    cy                                    y-coord of rotate center      */
338
/*                                                                        */
339
/*  OUTPUT                                                                */
340
/*                                                                        */
341
/*    None                                                                */
342
/*                                                                        */
343
/*  CALLS                                                                 */
344
/*                                                                        */
345
/*    _gx_utility_math_cos                  Compute the cosine value      */
346
/*    _gx_utility_math_sin                  Compute the sine value        */
347
/*    [gx_display_driver_pixel_blend]       Basic display driver pixel    */
348
/*                                            blend function              */
349
/*                                                                        */
350
/*  CALLED BY                                                             */
351
/*                                                                        */
352
/*    _gx_display_driver_32bpp_pixelmap_rotate                            */
353
/*                                                                        */
354
/*  RELEASE HISTORY                                                       */
355
/*                                                                        */
356
/*    DATE              NAME                      DESCRIPTION             */
357
/*                                                                        */
358
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
359
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
360
/*                                            resulting in version 6.1    */
361
/*  01-31-2022     Ting Zhu                 Modified comment(s),          */
362
/*                                            corrected logic,            */
363
/*                                            resulting in version 6.1.10 */
364
/*                                                                        */
365
/**************************************************************************/
366
713
static VOID _gx_display_driver_24xrgb_pixelmap_alpha_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
367
                                                            INT angle, INT cx, INT cy)
368
{
369
GX_COLOR     *get;
370
INT           srcxres;
371
INT           srcyres;
372
INT           cosv;
373
INT           sinv;
374
INT           alpha;
375
GX_COLOR      red;
376
GX_COLOR      green;
377
GX_COLOR      blue;
378
INT           idxminx;
379
INT           idxmaxx;
380
INT           idxmaxy;
381
INT          *mx;
382
INT          *my;
383
INT           xres;
384
INT           yres;
385
INT           x;
386
INT           y;
387
INT           xx;
388
INT           yy;
389
GX_COLOR      a;
390
GX_COLOR      b;
391
GX_COLOR      c;
392
GX_COLOR      d;
393
INT           xdiff;
394
INT           ydiff;
395
INT           newxpos;
396
INT           newypos;
397
GX_DISPLAY   *display;
398
GX_RECTANGLE *clip;
399
VOID          (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR color, GX_UBYTE alpha);
400
401
713
    clip = context -> gx_draw_context_clip;
402
713
    display = context -> gx_draw_context_display;
403
713
    blend_func = display -> gx_display_driver_pixel_blend;
404
405
713
    if (!blend_func)
406
    {
407
1
        return;
408
    }
409
410
712
    mx = _gx_system_scratchpad;
411
712
    my = mx + 4;
412
413
712
    mx[0] = mx[3] = -1;
414
712
    mx[1] = mx[2] = 1;
415
416
712
    my[0] = my[1] = 1;
417
712
    my[2] = my[3] = -1;
418
419
712
    idxminx = (angle / 90) & 0x3;
420
712
    idxmaxx = (idxminx + 2) & 0x3;
421
712
    idxmaxy = (idxminx + 1) & 0x3;
422
423
    /* Calculate the source x and y center. */
424
712
    srcxres = pixelmap -> gx_pixelmap_width >> 1;
425
712
    srcyres = pixelmap -> gx_pixelmap_height >> 1;
426
427
    /* Calculate the new rotation axis. */
428
712
    cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
429
712
    sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
430
431
712
    xres = mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv;
432
712
    yres = my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv;
433
434
712
    xres = GX_FIXED_VAL_TO_INT(xres);
435
712
    yres = GX_FIXED_VAL_TO_INT(yres);
436
437
712
    x = (cx - srcxres) * cosv - (cy - srcyres) * sinv;
438
712
    y = (cy - srcyres) * cosv + (cx - srcxres) * sinv;
439
440
712
    xres = GX_FIXED_VAL_TO_INT(x) + xres;
441
712
    yres = GX_FIXED_VAL_TO_INT(y) + yres;
442
443
712
    newxpos = xpos + cx - xres;
444
712
    newypos = ypos + cy - yres;
445
446
    /* Loop through the source's pixels.  */
447
166985
    for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
448
    {
449
47657057
        for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
450
        {
451
47490784
            xx = (x - xres) * cosv + (y - yres) * sinv;
452
47490784
            yy = (y - yres) * cosv - (x - xres) * sinv;
453
454
47490784
            xdiff = GX_FIXED_VAL_TO_INT(xx << 8) & 0xff;
455
47490784
            ydiff = GX_FIXED_VAL_TO_INT(yy << 8) & 0xff;
456
457
47490784
            xx = GX_FIXED_VAL_TO_INT(xx) + cx;
458
47490784
            yy = GX_FIXED_VAL_TO_INT(yy) + cy;
459
460

47490784
            if ((xx >= -1) && (xx < pixelmap -> gx_pixelmap_width) &&
461
32474471
                (yy >= -1) && (yy < pixelmap -> gx_pixelmap_height))
462
            {
463

28767330
                if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_width - 1) && \
464
28383002
                    (yy >= 0) && (yy < pixelmap -> gx_pixelmap_height - 1))
465
                {
466
28265958
                    get = (GX_COLOR *)pixelmap -> gx_pixelmap_data;
467
28265958
                    get += yy * pixelmap -> gx_pixelmap_width;
468
28265958
                    get += xx;
469
470
28265958
                    a = *get;
471
28265958
                    b = *(get + 1);
472
28265958
                    c = *(get + pixelmap -> gx_pixelmap_width);
473
28265958
                    d = *(get + pixelmap -> gx_pixelmap_width + 1);
474
                }
475
                else
476
                {
477
501372
                    get = (GX_COLOR *)pixelmap -> gx_pixelmap_data;
478
479
501372
                    a = 0;
480
501372
                    b = a;
481
501372
                    c = a;
482
501372
                    d = a;
483
484
501372
                    if (xx == -1)
485
                    {
486
                        /* handle left edge.  */
487
135366
                        if (yy >= 0)
488
                        {
489
135040
                            b = *(get + yy * pixelmap -> gx_pixelmap_width);
490
                        }
491
492
135366
                        if (yy < pixelmap -> gx_pixelmap_height - 1)
493
                        {
494
134904
                            d = *(get + (yy + 1) * pixelmap -> gx_pixelmap_width);
495
                        }
496
                    }
497
366006
                    else if (yy == -1)
498
                    {
499
                        /* handle top edge.  */
500
93807
                        c = *(get + xx);
501
502
93807
                        if (xx < pixelmap -> gx_pixelmap_width - 1)
503
                        {
504
93403
                            d = *(get + xx + 1);
505
                        }
506
                    }
507
272199
                    else if (xx == pixelmap -> gx_pixelmap_width - 1)
508
                    {
509
                        /* handle right edget. */
510
155155
                        a = *(get + yy * pixelmap -> gx_pixelmap_width + xx);
511
512
155155
                        if (yy < pixelmap -> gx_pixelmap_height - 1)
513
                        {
514
154163
                            c = *(get + (yy + 1) * pixelmap -> gx_pixelmap_width + xx);
515
                        }
516
                    }
517
                    else
518
                    {
519
                        /* handle bottom edge. */
520
117044
                        a = *(get + yy * pixelmap -> gx_pixelmap_width + xx);
521
117044
                        b = *(get + yy * pixelmap -> gx_pixelmap_width + xx + 1);
522
                    }
523
                }
524
525
28767330
                red = (REDVAL(a) * (a >> 24) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
526
28767330
                       REDVAL(b) * (b >> 24) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) +         \
527
28767330
                       REDVAL(c) * (c >> 24) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) +         \
528
28767330
                       REDVAL(d) * (d >> 24) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16;
529
530
28767330
                green = (GREENVAL(a) * (a >> 24) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
531
28767330
                         GREENVAL(b) * (b >> 24) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) +         \
532
28767330
                         GREENVAL(c) * (c >> 24) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) +         \
533
28767330
                         GREENVAL(d) * (d >> 24) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16;
534
535
28767330
                blue = (BLUEVAL(a) * (a >> 24) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
536
28767330
                        BLUEVAL(b) * (b >> 24) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) +         \
537
28767330
                        BLUEVAL(c) * (c >> 24) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) +         \
538
28767330
                        BLUEVAL(d) * (d >> 24) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16;
539
540
28767330
                alpha = (INT)(((a >> 24) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
541
28767330
                               (b >> 24) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) +         \
542
28767330
                               (c >> 24) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) +         \
543
28767330
                               (d >> 24) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16);
544
545
28767330
                if (alpha)
546
                {
547
20689070
                    red /= (UINT)alpha;
548
20689070
                    green /= (UINT)alpha;
549
20689070
                    blue /= (UINT)alpha;
550
                }
551
552
28767330
                red = BYTE_RANGE(red);
553
28767330
                green = BYTE_RANGE(green);
554
28767330
                blue = BYTE_RANGE(blue);
555
28767330
                alpha = BYTE_RANGE(alpha);
556
557
28767330
                blend_func(context, x + newxpos, y + newypos, (GX_COLOR)ASSEMBLECOLOR(red, green, blue), (GX_UBYTE)alpha);
558
            }
559
        }
560
    }
561
}
562
563
/**************************************************************************/
564
/*                                                                        */
565
/*  FUNCTION                                               RELEASE        */
566
/*                                                                        */
567
/*    _gx_display_driver_24xrgb_pixelmap_simple_rotate    PORTABLE C      */
568
/*                                                           6.1.7        */
569
/*  AUTHOR                                                                */
570
/*                                                                        */
571
/*    Kenneth Maxwell, Microsoft Corporation                              */
572
/*                                                                        */
573
/*  DESCRIPTION                                                           */
574
/*                                                                        */
575
/*    Internal help function that hangles 90, 180 and 270 degree pixelmap */
576
/*    rotation.                                                           */
577
/*                                                                        */
578
/*  INPUT                                                                 */
579
/*                                                                        */
580
/*    context                               Drawing context               */
581
/*    xpos                                  x-coord of top-left draw point*/
582
/*    ypos                                  y-coord of top-left draw point*/
583
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
584
/*    angle                                 The angle to rotate           */
585
/*    cx                                    x-coord of rotate center      */
586
/*    cy                                    y-coord of rotate center      */
587
/*                                                                        */
588
/*  OUTPUT                                                                */
589
/*                                                                        */
590
/*    None                                                                */
591
/*                                                                        */
592
/*  CALLS                                                                 */
593
/*                                                                        */
594
/*    [gx_display_driver_pixel_blend]       Basic display driver pixel    */
595
/*                                            blend function              */
596
/*                                                                        */
597
/*  CALLED BY                                                             */
598
/*                                                                        */
599
/*    GUIX Internal Code                                                  */
600
/*                                                                        */
601
/*  RELEASE HISTORY                                                       */
602
/*                                                                        */
603
/*    DATE              NAME                      DESCRIPTION             */
604
/*                                                                        */
605
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
606
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
607
/*                                            resulting in version 6.1    */
608
/*  06-02-2021     Kenneth Maxwell          Modified comment(s),          */
609
/*                                            removed unused assignments, */
610
/*                                            resulting in version 6.1.7  */
611
/*                                                                        */
612
/**************************************************************************/
613
12
static VOID _gx_display_driver_24xrgb_pixelmap_simple_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
614
                                                             INT angle, INT cx, INT cy)
615
{
616
GX_COLOR     *putrow;
617
GX_COLOR     *put;
618
GX_COLOR     *get;
619
INT           width;
620
INT           height;
621
INT           x;
622
INT           y;
623
GX_RECTANGLE *clip;
624
INT           newxpos;
625
INT           newypos;
626
627
GX_DISPLAY   *display;
628
VOID          (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR color, GX_UBYTE alpha);
629
630
12
    display = context -> gx_draw_context_display;
631
12
    blend_func = display -> gx_display_driver_pixel_blend;
632
633
12
    clip = context -> gx_draw_context_clip;
634
635
12
    if (angle == 90)
636
    {
637
4
        width = pixelmap -> gx_pixelmap_height;
638
4
        height = pixelmap -> gx_pixelmap_width;
639
640
4
        newxpos = xpos + cx - (width - 1 - cy);
641
4
        newypos = ypos + cy - cx;
642
643
4
        putrow = context -> gx_draw_context_memory;
644
4
        putrow += clip -> gx_rectangle_top * context -> gx_draw_context_pitch;
645
4
        putrow += clip -> gx_rectangle_left;
646
647
862
        for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
648
        {
649
858
            put = putrow;
650
651
150111
            for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
652
            {
653
149253
                get = (GX_COLOR *)pixelmap -> gx_pixelmap_data;
654
149253
                get += (width - 1 - x) * height;
655
149253
                get += y;
656
657
149253
                if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
658
                {
659
90285
                    blend_func(context, clip -> gx_rectangle_left + x, clip -> gx_rectangle_top + y, *get, (GX_UBYTE)((*get) >> 24));
660
                }
661
                else
662
                {
663
58968
                    *put++ = *get;
664
                }
665
            }
666
667
858
            putrow += context -> gx_draw_context_pitch;
668
        }
669
    }
670
8
    else if (angle == 180)
671
    {
672
673
4
        width = pixelmap -> gx_pixelmap_width;
674
4
        height = pixelmap -> gx_pixelmap_height;
675
676
4
        newxpos = xpos + cx - (width - 1 - cx);
677
4
        newypos = ypos + cy - (height - 1 - cy);
678
679
4
        putrow = context -> gx_draw_context_memory;
680
4
        putrow += clip -> gx_rectangle_top * context -> gx_draw_context_pitch;
681
4
        putrow += clip -> gx_rectangle_left;
682
683
536
        for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
684
        {
685
532
            put = putrow;
686
107632
            for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
687
            {
688
107100
                get = (GX_COLOR *)pixelmap -> gx_pixelmap_data;
689
107100
                get += (height - 1 - y) * width;
690
107100
                get += width - 1 - x;
691
692
107100
                if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
693
                {
694
58695
                    blend_func(context, clip -> gx_rectangle_left + x, clip -> gx_rectangle_top + y, *get, (GX_UBYTE)((*get) >> 24));
695
                }
696
                else
697
                {
698
48405
                    *put++ = *get;
699
                }
700
            }
701
702
532
            putrow += context -> gx_draw_context_pitch;
703
        }
704
    }
705
    else
706
    {
707
4
        height = pixelmap -> gx_pixelmap_width;
708
709
4
        newxpos = xpos + cx - cy;
710
4
        newypos = ypos + cx - (height - 1 - cy);
711
712
4
        putrow = context -> gx_draw_context_memory;
713
4
        putrow += clip -> gx_rectangle_top * context -> gx_draw_context_pitch;
714
4
        putrow += clip -> gx_rectangle_left;
715
716
578
        for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
717
        {
718
574
            put = putrow;
719
720
105187
            for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
721
            {
722
104613
                get = (GX_COLOR *)pixelmap -> gx_pixelmap_data;
723
104613
                get += x * height;
724
104613
                get += height - 1 - y;
725
726
104613
                if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
727
                {
728
61143
                    blend_func(context, clip -> gx_rectangle_left + x, clip -> gx_rectangle_top + y, *get, (GX_UBYTE)((*get) >> 24));
729
                }
730
                else
731
                {
732
43470
                    *put++ = *get;
733
                }
734
            }
735
736
574
            putrow += context -> gx_draw_context_pitch;
737
        }
738
    }
739
12
}
740
741
/**************************************************************************/
742
/*                                                                        */
743
/*  FUNCTION                                               RELEASE        */
744
/*                                                                        */
745
/*    _gx_display_driver_32bpp_pixelmap_rotate            PORTABLE C      */
746
/*                                                           6.1.9        */
747
/*  AUTHOR                                                                */
748
/*                                                                        */
749
/*    Kenneth Maxwell, Microsoft Corporation                              */
750
/*                                                                        */
751
/*  DESCRIPTION                                                           */
752
/*                                                                        */
753
/*    This service rotate a pixelmap directly to canvas memory.           */
754
/*                                                                        */
755
/*  INPUT                                                                 */
756
/*                                                                        */
757
/*    context                               Drawing context               */
758
/*    xpos                                  x-coord of top-left draw point*/
759
/*    ypos                                  y-coord of top-left draw point*/
760
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
761
/*    angle                                 The angle to rotate           */
762
/*    rot_cx                                x-coord of rotating center.   */
763
/*    rot_cy                                y-coord of rotationg center.  */
764
/*                                                                        */
765
/*  OUTPUT                                                                */
766
/*                                                                        */
767
/*    None                                                                */
768
/*                                                                        */
769
/*  CALLS                                                                 */
770
/*                                                                        */
771
/*    _gx_display_driver_24xrgb_pixelmap_simple_rotate                    */
772
/*                                          Real display driver pixelmap  */
773
/*                                            rotate function             */
774
/*    _gx_display_driver_24xrgb_pixelmap_alpha_rotate                     */
775
/*                                          Real display driver pixelmap  */
776
/*                                            rotate function             */
777
/*    _gx_display_driver_24xrgb_pixelmap_rotate                           */
778
/*                                          Real display driver pixelmap  */
779
/*                                            rotate function             */
780
/*                                                                        */
781
/*  CALLED BY                                                             */
782
/*                                                                        */
783
/*    GUIX Internal Code                                                  */
784
/*                                                                        */
785
/*  RELEASE HISTORY                                                       */
786
/*                                                                        */
787
/*    DATE              NAME                      DESCRIPTION             */
788
/*                                                                        */
789
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
790
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
791
/*                                            resulting in version 6.1    */
792
/*  10-15-2021     Ting Zhu                 Modified comment(s),          */
793
/*                                            corrected format type,      */
794
/*                                            resulting in version 6.1.9  */
795
/*                                                                        */
796
/**************************************************************************/
797
1439
VOID _gx_display_driver_32bpp_pixelmap_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
798
                                              INT angle, INT rot_cx, INT rot_cy)
799
{
800
1439
    switch (pixelmap -> gx_pixelmap_format)
801
    {
802
1438
    case GX_COLOR_FORMAT_24XRGB:
803
    case GX_COLOR_FORMAT_32ARGB:
804
1438
        if (angle % 90 == 0)
805
        {
806
            /* Simple angle rotate: 90 degree, 180 degree and 270 degree.  */
807
12
            _gx_display_driver_24xrgb_pixelmap_simple_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
808
        }
809
        else
810
        {
811
1426
            if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
812
            {
813
                /* with alpha. */
814
713
                _gx_display_driver_24xrgb_pixelmap_alpha_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
815
            }
816
            else
817
            {
818
                /* without alpha */
819
713
                _gx_display_driver_24xrgb_pixelmap_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
820
            }
821
        }
822
1438
        break;
823
    }
824
825
1439
    return;
826
}
827