GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_16bpp_pixelmap_rotate.c Lines: 309 309 100.0 %
Date: 2024-12-05 08:52:37 Branches: 128 128 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) >> 11) & 0x1f)
22
#define GREENVAL(_c) (GX_UBYTE)(((_c) >> 5) & 0x3f)
23
#define BLUEVAL(_c)  (GX_UBYTE)(((_c)) & 0x1f)
24
25
#define ASSEMBLECOLOR(_r, _g, _b) \
26
    ((((_r) & 0x1f) << 11) |      \
27
     (((_g) & 0x3f) << 5) |       \
28
     (((_b) & 0x1f)))
29
30
#define GX_SOURCE_CODE
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_565rgb_pixelmap_raw_rotate       PORTABLE C      */
45
/*                                                           6.1.10       */
46
/*  AUTHOR                                                                */
47
/*                                                                        */
48
/*    Kenneth Maxwell, Microsoft Corporation                              */
49
/*                                                                        */
50
/*  DESCRIPTION                                                           */
51
/*                                                                        */
52
/*    Internal helper function that rotate an uncompressed pixelmap       */
53
/*      without alpha.                                                    */
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
/*    status                                Completion status             */
68
/*                                                                        */
69
/*  CALLS                                                                 */
70
/*                                                                        */
71
/*    _gx_utility_math_cos                  Compute the cosine value      */
72
/*    _gx_utility_math_sin                  Compute the sine value        */
73
/*    [gx_display_driver_pixel_blend]       Display driver basic pixel    */
74
/*                                             blend function             */
75
/*                                                                        */
76
/*  CALLED BY                                                             */
77
/*                                                                        */
78
/*    GUIX Internal Code                                                  */
79
/*                                                                        */
80
/*  RELEASE HISTORY                                                       */
81
/*                                                                        */
82
/*    DATE              NAME                      DESCRIPTION             */
83
/*                                                                        */
84
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
85
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
86
/*                                            resulting in version 6.1    */
87
/*  01-31-2022     Ting Zhu                 Modified comment(s),          */
88
/*                                            corrected logic,            */
89
/*                                            resulting in version 6.1.10 */
90
/*                                                                        */
91
/**************************************************************************/
92
722
static VOID _gx_display_driver_565rgb_pixelmap_raw_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
93
                                                          INT angle, INT cx, INT cy)
94
{
95
USHORT       *get;
96
INT           srcxres;
97
INT           srcyres;
98
INT           cosv;
99
INT           sinv;
100
INT           alpha;
101
USHORT        red;
102
USHORT        green;
103
USHORT        blue;
104
INT           idxminx;
105
INT           idxmaxx;
106
INT           idxmaxy;
107
INT          *mx;
108
INT          *my;
109
INT           xres;
110
INT           yres;
111
INT           x;
112
INT           y;
113
INT           xx;
114
INT           yy;
115
USHORT        a;
116
USHORT        b;
117
USHORT        c;
118
USHORT        d;
119
INT           xdiff;
120
INT           ydiff;
121
INT           newxpos;
122
INT           newypos;
123
GX_DISPLAY   *display;
124
GX_RECTANGLE *clip;
125
VOID          (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR color, GX_UBYTE alpha);
126
127
722
    clip = context -> gx_draw_context_clip;
128
722
    display = context -> gx_draw_context_display;
129
722
    blend_func = display -> gx_display_driver_pixel_blend;
130
131
722
    if (!blend_func)
132
    {
133
1
        return;
134
    }
135
136
721
    mx = _gx_system_scratchpad;
137
721
    my = mx + 4;
138
139
721
    mx[0] = mx[3] = -1;
140
721
    mx[1] = mx[2] = 1;
141
142
721
    my[0] = my[1] = 1;
143
721
    my[2] = my[3] = -1;
144
145
721
    idxminx = (angle / 90) & 0x3;
146
721
    idxmaxx = (idxminx + 2) & 0x3;
147
721
    idxmaxy = (idxminx + 1) & 0x3;
148
149
    /* Calculate the source x and y center. */
150
721
    srcxres = pixelmap -> gx_pixelmap_width >> 1;
151
721
    srcyres = pixelmap -> gx_pixelmap_height >> 1;
152
153
721
    cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
154
721
    sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
155
156
721
    xres = GX_FIXED_VAL_TO_INT(mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv);
157
721
    yres = GX_FIXED_VAL_TO_INT(my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv);
158
159
    /* Calculate the new rotation axis. */
160
161
721
    xres = GX_FIXED_VAL_TO_INT((cx - srcxres) * cosv - (cy - srcyres) * sinv) + xres;
162
721
    yres = GX_FIXED_VAL_TO_INT((cy - srcyres) * cosv + (cx - srcxres) * sinv) + yres;
163
164
721
    newxpos = xpos + cx - xres;
165
721
    newypos = ypos + cy - yres;
166
167
    /* Loop through the destination's pixels.  */
168
152028
    for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
169
    {
170
34388381
        for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
171
        {
172
34237074
            xx = (x - xres) * cosv + (y - yres) * sinv;
173
34237074
            yy = (y - yres) * cosv - (x - xres) * sinv;
174
175
34237074
            xdiff = GX_FIXED_VAL_TO_INT(xx << 8) & 0xff;
176
34237074
            ydiff = GX_FIXED_VAL_TO_INT(yy << 8) & 0xff;
177
178
34237074
            xx = GX_FIXED_VAL_TO_INT(xx) + cx;
179
34237074
            yy = GX_FIXED_VAL_TO_INT(yy) + cy;
180
181

34237074
            if ((xx >= -1) && (xx < pixelmap -> gx_pixelmap_width) &&
182
25732179
                (yy >= -1) && (yy < pixelmap -> gx_pixelmap_height))
183
            {
184

19326463
                if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_width - 1) &&
185
19036082
                    (yy >= 0) && (yy < pixelmap -> gx_pixelmap_height - 1))
186
                {
187
18879375
                    get = (USHORT *)pixelmap -> gx_pixelmap_data;
188
18879375
                    get += yy * pixelmap -> gx_pixelmap_width;
189
18879375
                    get += xx;
190
191
18879375
                    a = *get;
192
18879375
                    b = *(get + 1);
193
18879375
                    c = *(get + pixelmap -> gx_pixelmap_width);
194
18879375
                    d = *(get + pixelmap -> gx_pixelmap_width + 1);
195
196
18879375
                    alpha = 0xff;
197
                }
198
                else
199
                {
200
447088
                    get = (USHORT *)pixelmap -> gx_pixelmap_data;
201
202
447088
                    a = 0;
203
447088
                    b = 0;
204
447088
                    c = 0;
205
447088
                    d = 0;
206
447088
                    alpha = 0;
207
208
447088
                    if (xx == -1)
209
                    {
210
                        /* handle left edge.  */
211
60226
                        if (yy >= 0)
212
                        {
213
59852
                            b = *(get + yy * pixelmap -> gx_pixelmap_width);
214
59852
                            alpha += xdiff * (256 - ydiff);
215
                        }
216
217
60226
                        if (yy < pixelmap -> gx_pixelmap_height - 1)
218
                        {
219
59765
                            d = *(get + (yy + 1) * pixelmap -> gx_pixelmap_width);
220
59765
                            alpha += xdiff * ydiff;
221
                        }
222
                    }
223
386862
                    else if (yy == -1)
224
                    {
225
                        /* handle top edge.  */
226
139533
                        c = *(get + xx);
227
139533
                        alpha += ydiff * (256 - xdiff);
228
229
139533
                        if (xx < pixelmap -> gx_pixelmap_width - 1)
230
                        {
231
138872
                            d = *(get + xx + 1);
232
138872
                            alpha += xdiff * ydiff;
233
                        }
234
                    }
235
247329
                    else if (xx == pixelmap -> gx_pixelmap_width - 1)
236
                    {
237
                        /* handle right edge. */
238
90622
                        a = *(get + yy * pixelmap -> gx_pixelmap_width + xx);
239
90622
                        alpha += (256 - xdiff) * (256 - ydiff);
240
241
90622
                        if (yy < pixelmap -> gx_pixelmap_height - 1)
242
                        {
243
89537
                            c = *(get + (yy + 1) * pixelmap -> gx_pixelmap_width + xx);
244
89537
                            alpha += ydiff * (256 - xdiff);
245
                        }
246
                    }
247
                    else
248
                    {
249
                        /* handle bottom edge. */
250
156707
                        a = *(get + yy * pixelmap -> gx_pixelmap_width + xx);
251
156707
                        alpha += (256 - xdiff) * (256 - ydiff);
252
253
156707
                        b = *(get + yy * pixelmap -> gx_pixelmap_width + xx + 1);
254
156707
                        alpha += xdiff * (256 - ydiff);
255
                    }
256
257
447088
                    alpha >>= 8;
258
                }
259
260
19326463
                red = (USHORT)((REDVAL(a) * (256 - xdiff) * (256 - ydiff) +
261
19326463
                                REDVAL(b) * xdiff * (256 - ydiff) +
262
19326463
                                REDVAL(c) * ydiff * (256 - xdiff) +
263
19326463
                                REDVAL(d) * xdiff * ydiff) >> 16);
264
265
19326463
                green = (USHORT)((GREENVAL(a) * (256 - xdiff) * (256 - ydiff) +
266
19326463
                                  GREENVAL(b) * xdiff * (256 - ydiff) +
267
19326463
                                  GREENVAL(c) * ydiff * (256 - xdiff) +
268
19326463
                                  GREENVAL(d) * xdiff * ydiff) >> 16);
269
270
19326463
                blue = (USHORT)((BLUEVAL(a) * (256 - xdiff) * (256 - ydiff) +
271
19326463
                                 BLUEVAL(b) * xdiff * (256 - ydiff) +
272
19326463
                                 BLUEVAL(c) * ydiff * (256 - xdiff) +
273
19326463
                                 BLUEVAL(d) * xdiff * ydiff) >> 16);
274
275

19326463
                if ((alpha > 0) && (alpha < 0xff))
276
                {
277
441966
                    red = (USHORT)((red << 8) / alpha);
278
441966
                    green = (USHORT)((green << 8) / alpha);
279
441966
                    blue = (USHORT)((blue << 8) / alpha);
280
                }
281
282
19326463
                red = red > 31 ? 31 : red;
283
19326463
                green = green > 63 ? 63 : green;
284
19326463
                blue = blue > 31 ? 31 : blue;
285
19326463
                alpha = alpha > 255 ? 255 : alpha;
286
287
19326463
                blend_func(context, x + newxpos, y + newypos, (GX_COLOR)ASSEMBLECOLOR(red, green, blue), (GX_UBYTE)alpha);
288
            }
289
        }
290
    }
291
}
292
293
/**************************************************************************/
294
/*                                                                        */
295
/*  FUNCTION                                               RELEASE        */
296
/*                                                                        */
297
/*    _gx_display_driver_565rgb_pixelmap_alpha_rotate     PORTABLE C      */
298
/*                                                           6.1.10       */
299
/*  AUTHOR                                                                */
300
/*                                                                        */
301
/*    Kenneth Maxwell, Microsoft Corporation                              */
302
/*                                                                        */
303
/*  DESCRIPTION                                                           */
304
/*                                                                        */
305
/*    Internal helper function that rotate an uncompressed pixelmap       */
306
/*      with alpha.                                                       */
307
/*                                                                        */
308
/*  INPUT                                                                 */
309
/*                                                                        */
310
/*    context                               Drawing context               */
311
/*    xpos                                  x-coord of top-left draw point*/
312
/*    ypos                                  y-coord of top-left draw point*/
313
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
314
/*    angle                                 The angle to rotate           */
315
/*    cx                                    x-coord of rotate center      */
316
/*    cy                                    y-coord of rotate center      */
317
/*                                                                        */
318
/*  OUTPUT                                                                */
319
/*                                                                        */
320
/*    status                                Completion status             */
321
/*                                                                        */
322
/*  CALLS                                                                 */
323
/*                                                                        */
324
/*    _gx_utility_math_cos                  Compute the cosine value      */
325
/*    _gx_utility_math_sin                  Compute the sine value        */
326
/*    [gx_display_driver_pixel_blend]       Display driver basic pixel    */
327
/*                                             blend function             */
328
/*                                                                        */
329
/*  CALLED BY                                                             */
330
/*                                                                        */
331
/*    GUIX Internal Code                                                  */
332
/*                                                                        */
333
/*  RELEASE HISTORY                                                       */
334
/*                                                                        */
335
/*    DATE              NAME                      DESCRIPTION             */
336
/*                                                                        */
337
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
338
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
339
/*                                            resulting in version 6.1    */
340
/*  01-31-2022     Ting Zhu                 Modified comment(s),          */
341
/*                                            corrected logic,            */
342
/*                                            resulting in version 6.1.10 */
343
/*                                                                        */
344
/**************************************************************************/
345
1093
static VOID _gx_display_driver_565rgb_pixelmap_alpha_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
346
                                                            INT angle, INT cx, INT cy)
347
{
348
USHORT       *get;
349
GX_UBYTE     *getalpha;
350
INT           srcxres;
351
INT           srcyres;
352
INT           cosv;
353
INT           sinv;
354
USHORT        red;
355
USHORT        green;
356
USHORT        blue;
357
INT           idxminx;
358
INT           idxmaxx;
359
INT           idxmaxy;
360
INT          *mx;
361
INT          *my;
362
INT           xres;
363
INT           yres;
364
INT           x;
365
INT           y;
366
INT           xx;
367
INT           yy;
368
USHORT        a;
369
USHORT        b;
370
USHORT        c;
371
USHORT        d;
372
USHORT        alpha[4];
373
GX_FIXED_VAL  xdiff;
374
GX_FIXED_VAL  ydiff;
375
INT           newxpos;
376
INT           newypos;
377
GX_DISPLAY   *display;
378
GX_RECTANGLE *clip;
379
VOID          (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR color, GX_UBYTE alpha);
380
381
1093
    clip = context -> gx_draw_context_clip;
382
1093
    display = context -> gx_draw_context_display;
383
1093
    blend_func = display -> gx_display_driver_pixel_blend;
384
385
1093
    if (!blend_func)
386
    {
387
1
        return;
388
    }
389
390
1092
    mx = _gx_system_scratchpad;
391
1092
    my = mx + 4;
392
393
1092
    mx[0] = mx[3] = -1;
394
1092
    mx[1] = mx[2] = 1;
395
396
1092
    my[0] = my[1] = 1;
397
1092
    my[2] = my[3] = -1;
398
399
1092
    idxminx = (angle / 90) & 0x3;
400
1092
    idxmaxx = (idxminx + 2) & 0x3;
401
1092
    idxmaxy = (idxminx + 1) & 0x3;
402
403
    /* Calculate the source x and y center. */
404
1092
    srcxres = pixelmap -> gx_pixelmap_width >> 1;
405
1092
    srcyres = pixelmap -> gx_pixelmap_height >> 1;
406
407
1092
    cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
408
1092
    sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
409
410
1092
    xres = GX_FIXED_VAL_TO_INT(mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv);
411
1092
    yres = GX_FIXED_VAL_TO_INT(my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv);
412
413
1092
    xres = GX_FIXED_VAL_TO_INT((cx - srcxres) * cosv - (cy - srcyres) * sinv) + xres;
414
1092
    yres = GX_FIXED_VAL_TO_INT((cy - srcyres) * cosv + (cx - srcxres) * sinv) + yres;
415
416
1092
    newxpos = xpos + cx - xres;
417
1092
    newypos = ypos + cy - yres;
418
419
    /* Loop through the source's pixels.  */
420
232128
    for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
421
    {
422
61588614
        for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
423
        {
424
61357578
            xx = (x - xres) * cosv + (y - yres) * sinv;
425
61357578
            yy = (y - yres) * cosv - (x - xres) * sinv;
426
427
61357578
            xdiff = GX_FIXED_VAL_TO_INT(xx << 8) & 0xff;
428
61357578
            ydiff = GX_FIXED_VAL_TO_INT(yy << 8) & 0xff;
429
430
61357578
            xx = GX_FIXED_VAL_TO_INT(xx) + cx;
431
61357578
            yy = GX_FIXED_VAL_TO_INT(yy) + cy;
432
433

61357578
            if ((xx >= -1) && (xx < pixelmap -> gx_pixelmap_width) &&
434
42728666
                (yy >= -1) && (yy < pixelmap -> gx_pixelmap_height))
435
            {
436

37174803
                if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_width - 1) && \
437
36655749
                    (yy >= 0) && (yy < pixelmap -> gx_pixelmap_height - 1))
438
                {
439
36478677
                    get = (USHORT *)pixelmap -> gx_pixelmap_data;
440
36478677
                    get += yy * pixelmap -> gx_pixelmap_width;
441
36478677
                    get += xx;
442
443
36478677
                    getalpha = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
444
36478677
                    getalpha += yy * pixelmap -> gx_pixelmap_width;
445
36478677
                    getalpha += xx;
446
447
36478677
                    a = *get;
448
36478677
                    alpha[0] = *getalpha;
449
450
36478677
                    b = *(get + 1);
451
36478677
                    alpha[1] = *(getalpha + 1);
452
453
36478677
                    c = *(get + pixelmap -> gx_pixelmap_width);
454
36478677
                    alpha[2] = *(getalpha + pixelmap -> gx_pixelmap_width);
455
456
36478677
                    d = *(get + pixelmap -> gx_pixelmap_width + 1);
457
36478677
                    alpha[3] = *(getalpha + pixelmap -> gx_pixelmap_width + 1);
458
                }
459
                else
460
                {
461
696126
                    get = (USHORT *)pixelmap -> gx_pixelmap_data;
462
696126
                    getalpha = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
463
464
696126
                    a = 0;
465
696126
                    b = 0;
466
696126
                    c = 0;
467
696126
                    d = 0;
468
469
696126
                    if (xx == -1)
470
                    {
471
                        /* handle left edge.  */
472
171609
                        if (yy >= 0)
473
                        {
474
171110
                            b = *(get + yy * pixelmap -> gx_pixelmap_width);
475
171110
                            alpha[1] = *(getalpha + yy * pixelmap -> gx_pixelmap_width);
476
                        }
477
478
171609
                        if (yy < pixelmap -> gx_pixelmap_height - 1)
479
                        {
480
170904
                            d = *(get + (yy + 1) * pixelmap -> gx_pixelmap_width);
481
170904
                            alpha[3] = *(getalpha + (yy + 1) * pixelmap -> gx_pixelmap_width);
482
                        }
483
                    }
484
524517
                    else if (yy == -1)
485
                    {
486
                        /* handle top edge.  */
487
138878
                        c = *(get + xx);
488
138878
                        alpha[2] = *(getalpha + xx);
489
490
138878
                        if (xx < pixelmap -> gx_pixelmap_width - 1)
491
                        {
492
138166
                            d = *(get + xx + 1);
493
138166
                            alpha[3] = *(getalpha + xx + 1);
494
                        }
495
                    }
496
385639
                    else if (xx == pixelmap -> gx_pixelmap_width - 1)
497
                    {
498
                        /* handle right edget. */
499
208567
                        a = *(get + yy * pixelmap -> gx_pixelmap_width + xx);
500
208567
                        alpha[0] = *(getalpha + yy * pixelmap -> gx_pixelmap_width + xx);
501
502
208567
                        if (yy < pixelmap -> gx_pixelmap_height - 1)
503
                        {
504
206837
                            c = *(get + (yy + 1) * pixelmap -> gx_pixelmap_width + xx);
505
206837
                            alpha[2] = *(getalpha + (yy + 1) * pixelmap -> gx_pixelmap_width + xx);
506
                        }
507
                    }
508
                    else
509
                    {
510
                        /* handle bottom edge. */
511
177072
                        a = *(get + yy * pixelmap -> gx_pixelmap_width + xx);
512
177072
                        alpha[0] = *(getalpha + yy * pixelmap -> gx_pixelmap_width + xx);
513
514
177072
                        b = *(get + yy * pixelmap -> gx_pixelmap_width + xx + 1);
515
177072
                        alpha[1] = *(getalpha + yy * pixelmap -> gx_pixelmap_width + xx + 1);
516
                    }
517
518
696126
                    if (!a)
519
                    {
520
310895
                        alpha[0] = 0;
521
                    }
522
523
696126
                    if (!b)
524
                    {
525
348068
                        alpha[1] = 0;
526
                    }
527
528
696126
                    if (!c)
529
                    {
530
351019
                        alpha[2] = 0;
531
                    }
532
533
696126
                    if (!d)
534
                    {
535
387364
                        alpha[3] = 0;
536
                    }
537
                }
538
539
37174803
                red = (USHORT)((REDVAL(a) * alpha[0] * (256 - xdiff) * (256 - ydiff) +
540
37174803
                                REDVAL(b) * alpha[1] * xdiff * (256 - ydiff) +
541
37174803
                                REDVAL(c) * alpha[2] * ydiff * (256 - xdiff) +
542
37174803
                                REDVAL(d) * alpha[3] * xdiff * ydiff) >> 16);
543
544
37174803
                green = (USHORT)((GREENVAL(a) * alpha[0] * (256 - xdiff) * (256 - ydiff) +
545
37174803
                                  GREENVAL(b) * alpha[1] * xdiff * (256 - ydiff) +
546
37174803
                                  GREENVAL(c) * alpha[2] * ydiff * (256 - xdiff) +
547
37174803
                                  GREENVAL(d) * alpha[3] * xdiff * ydiff) >> 16);
548
549
37174803
                blue = (USHORT)((BLUEVAL(a) * alpha[0] * (256 - xdiff) * (256 - ydiff) +
550
37174803
                                 BLUEVAL(b) * alpha[1] * xdiff * (256 - ydiff) +
551
37174803
                                 BLUEVAL(c) * alpha[2] * ydiff * (256 - xdiff) +
552
37174803
                                 BLUEVAL(d) * alpha[3] * xdiff * ydiff) >> 16);
553
554
37174803
                alpha[0] = (USHORT)((alpha[0] * (256 - xdiff) * (256 - ydiff) +
555
37174803
                                     alpha[1] * xdiff * (256 - ydiff) +
556
37174803
                                     alpha[2] * ydiff * (256 - xdiff) +
557
37174803
                                     alpha[3] * xdiff * ydiff) >> 16);
558
559
37174803
                if (alpha[0])
560
                {
561
24546792
                    red /= alpha[0];
562
24546792
                    green /= alpha[0];
563
24546792
                    blue /= alpha[0];
564
                }
565
566
37174803
                red = red > 31 ? 31 : red;
567
37174803
                green = green > 63 ? 63 : green;
568
37174803
                blue = blue > 31 ? 31 : blue;
569
37174803
                alpha[0] = alpha[0] > 255 ? 255 : alpha[0];
570
571
37174803
                blend_func(context, x + newxpos, y + newypos, (GX_COLOR)ASSEMBLECOLOR(red, green, blue), (GX_UBYTE)alpha[0]);
572
            }
573
        }
574
    }
575
}
576
577
/**************************************************************************/
578
/*                                                                        */
579
/*  FUNCTION                                               RELEASE        */
580
/*                                                                        */
581
/*    _gx_display_driver_16bpp_pixelmap_simple_rotate     PORTABLE C      */
582
/*                                                           6.3.0        */
583
/*  AUTHOR                                                                */
584
/*                                                                        */
585
/*    Kenneth Maxwell, Microsoft Corporation                              */
586
/*                                                                        */
587
/*  DESCRIPTION                                                           */
588
/*                                                                        */
589
/*    Internal help function that hangles 90, 180 and 270 degree pixelmap */
590
/*    rotation.                                                           */
591
/*                                                                        */
592
/*  INPUT                                                                 */
593
/*                                                                        */
594
/*    context                               Drawing context               */
595
/*    xpos                                  x-coord of top-left draw point*/
596
/*    ypos                                  y-coord of top-left draw point*/
597
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
598
/*    angle                                 The angle to rotate           */
599
/*    cx                                    x-coord of rotate center      */
600
/*    cy                                    y-coord of rotate center      */
601
/*                                                                        */
602
/*  OUTPUT                                                                */
603
/*                                                                        */
604
/*    status                                Completion status             */
605
/*                                                                        */
606
/*  CALLS                                                                 */
607
/*                                                                        */
608
/*    None                                                                */
609
/*                                                                        */
610
/*  CALLED BY                                                             */
611
/*                                                                        */
612
/*    GUIX Internal Code                                                  */
613
/*                                                                        */
614
/*  RELEASE HISTORY                                                       */
615
/*                                                                        */
616
/*    DATE              NAME                      DESCRIPTION             */
617
/*                                                                        */
618
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
619
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
620
/*                                            resulting in version 6.1    */
621
/*  06-02-2021     Kenneth Maxwell          Modified comment(s),          */
622
/*                                            remove unused assignment,   */
623
/*                                            resulting in version 6.1.7  */
624
/*  10-31-2023     Ting Zhu                 Modified comment(s),          */
625
/*                                            added partial canvas buffer */
626
/*                                            support,                    */
627
/*                                            resulting in version 6.3.0  */
628
/*                                                                        */
629
/**************************************************************************/
630
16
VOID _gx_display_driver_16bpp_pixelmap_simple_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
631
                                                     INT angle, INT cx, INT cy)
632
{
633
USHORT       *putrow;
634
USHORT       *put;
635
USHORT       *get;
636
INT           width;
637
INT           height;
638
INT           x;
639
INT           y;
640
GX_RECTANGLE *clip;
641
INT           newxpos;
642
INT           newypos;
643
644
16
    clip = context -> gx_draw_context_clip;
645
646
16
    putrow = (USHORT *)context -> gx_draw_context_memory;
647
648
16
    GX_CALCULATE_PUTROW(putrow, clip -> gx_rectangle_left, clip -> gx_rectangle_top, context);
649
650
16
    if (angle == 90)
651
    {
652
6
        width = pixelmap -> gx_pixelmap_height;
653
6
        height = pixelmap -> gx_pixelmap_width;
654
655
6
        newxpos = xpos + cx - (width - 1 - cy);
656
6
        newypos = ypos + cy - cx;
657
658
1422
        for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
659
        {
660
1416
            put = putrow;
661
662
179832
            for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
663
            {
664
178416
                get = (USHORT *)pixelmap -> gx_pixelmap_data;
665
178416
                get += (width - 1 - x) * height;
666
178416
                get += y;
667
668
178416
                *put++ = *get;
669
            }
670
671
1416
            putrow += context -> gx_draw_context_pitch;
672
        }
673
    }
674
10
    else if (angle == 180)
675
    {
676
677
5
        width = pixelmap -> gx_pixelmap_width;
678
5
        height = pixelmap -> gx_pixelmap_height;
679
680
5
        newxpos = xpos + cx - (width - 1 - cx);
681
5
        newypos = ypos + cy - (height - 1 - cy);
682
683
593
        for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
684
        {
685
588
            put = putrow;
686
127638
            for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
687
            {
688
127050
                get = (USHORT *)pixelmap -> gx_pixelmap_data;
689
127050
                get += (height - 1 - y) * width;
690
127050
                get += width - 1 - x;
691
692
127050
                *put++ = *get;
693
            }
694
695
588
            putrow += context -> gx_draw_context_pitch;
696
        }
697
    }
698
    else
699
    {
700
5
        height = pixelmap -> gx_pixelmap_width;
701
702
5
        newxpos = xpos + cx - cy;
703
5
        newypos = ypos + cx - (height - 1 - cy);
704
705
935
        for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
706
        {
707
930
            put = putrow;
708
709
118110
            for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
710
            {
711
117180
                get = (USHORT *)pixelmap -> gx_pixelmap_data;
712
117180
                get += x * height;
713
117180
                get += height - 1 - y;
714
715
117180
                *put++ = *get;
716
            }
717
718
930
            putrow += context -> gx_draw_context_pitch;
719
        }
720
    }
721
16
}
722
723
/**************************************************************************/
724
/*                                                                        */
725
/*  FUNCTION                                               RELEASE        */
726
/*                                                                        */
727
/*    _gx_display_driver_16bpp_pixelmap_simple_alpha_rotate               */
728
/*                                                        PORTABLE C      */
729
/*                                                           6.1.7        */
730
/*  AUTHOR                                                                */
731
/*                                                                        */
732
/*    Kenneth Maxwell, Microsoft Corporation                              */
733
/*                                                                        */
734
/*  DESCRIPTION                                                           */
735
/*                                                                        */
736
/*    Internal help function that hangles 90, 180 and 270 degree pixelmap */
737
/*    rotation with alpha channel.                                        */
738
/*                                                                        */
739
/*  INPUT                                                                 */
740
/*                                                                        */
741
/*    context                               Drawing context               */
742
/*    xpos                                  x-coord of top-left draw point*/
743
/*    ypos                                  y-coord of top-left draw point*/
744
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
745
/*    angle                                 The angle to rotate           */
746
/*    cx                                    x-coord of rotate center      */
747
/*    cy                                    y-coord of rotate center      */
748
/*                                                                        */
749
/*  OUTPUT                                                                */
750
/*                                                                        */
751
/*    status                                Completion status             */
752
/*                                                                        */
753
/*  CALLS                                                                 */
754
/*                                                                        */
755
/*    [gx_display_driver_pixel_blend]       Display driver basic pixel    */
756
/*                                             blend function             */
757
/*                                                                        */
758
/*  CALLED BY                                                             */
759
/*                                                                        */
760
/*    GUIX Internal Code                                                  */
761
/*                                                                        */
762
/*  RELEASE HISTORY                                                       */
763
/*                                                                        */
764
/*    DATE              NAME                      DESCRIPTION             */
765
/*                                                                        */
766
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
767
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
768
/*                                            resulting in version 6.1    */
769
/*  06-02-2021     Kenneth Maxwell          Modified comment(s),          */
770
/*                                            remove unused assignment,   */
771
/*                                            resulting in version 6.1.7  */
772
/*                                                                        */
773
/**************************************************************************/
774
25
VOID _gx_display_driver_16bpp_pixelmap_simple_alpha_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
775
                                                           INT angle, INT cx, INT cy)
776
{
777
USHORT       *get;
778
GX_UBYTE     *getalpha;
779
INT           width;
780
INT           height;
781
INT           x;
782
INT           y;
783
GX_RECTANGLE *clip;
784
INT           newxpos;
785
INT           newypos;
786
VOID          (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR color, GX_UBYTE alpha);
787
788
25
    clip = context -> gx_draw_context_clip;
789
25
    blend_func = context -> gx_draw_context_display -> gx_display_driver_pixel_blend;
790
791
25
    if (GX_NULL == blend_func)
792
    {
793
1
        return;
794
    }
795
796
24
    if (angle == 90)
797
    {
798
8
        width = pixelmap -> gx_pixelmap_height;
799
8
        height = pixelmap -> gx_pixelmap_width;
800
801
8
        newxpos = xpos + cx - (width - 1 - cy);
802
8
        newypos = ypos + cy - cx;
803
804
1366
        for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
805
        {
806
277677
            for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
807
            {
808
276319
                get = (USHORT *)pixelmap -> gx_pixelmap_data;
809
276319
                getalpha = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
810
276319
                get += (width - 1 - x) * height;
811
276319
                get += y;
812
276319
                getalpha += (width - 1 - x) * height;
813
276319
                getalpha += y;
814
276319
                blend_func(context, x + newxpos, y + newypos, *get, *getalpha);
815
            }
816
        }
817
    }
818
16
    else if (angle == 180)
819
    {
820
821
8
        width = pixelmap -> gx_pixelmap_width;
822
8
        height = pixelmap -> gx_pixelmap_height;
823
824
8
        newxpos = xpos + cx - (width - 1 - cx);
825
8
        newypos = ypos + cy - (height - 1 - cy);
826
827
828
1216
        for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
829
        {
830
225777
            for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
831
            {
832
224569
                get = (USHORT *)pixelmap -> gx_pixelmap_data;
833
224569
                getalpha = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
834
224569
                get += (height - 1 - y) * width;
835
224569
                get += width - 1 - x;
836
224569
                getalpha += (height - 1 - y) * width;
837
224569
                getalpha += width - 1 - x;
838
839
224569
                blend_func(context, x + newxpos, y + newypos, *get, *getalpha);
840
            }
841
        }
842
    }
843
    else
844
    {
845
8
        height = pixelmap -> gx_pixelmap_width;
846
847
8
        newxpos = xpos + cx - cy;
848
8
        newypos = ypos + cx - (height - 1 - cy);
849
850
1031
        for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
851
        {
852
222274
            for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
853
            {
854
221251
                get = (USHORT *)pixelmap -> gx_pixelmap_data;
855
221251
                getalpha = (GX_UBYTE *)pixelmap -> gx_pixelmap_aux_data;
856
221251
                get += x * height;
857
221251
                get += height - 1 - y;
858
221251
                getalpha += x * height;
859
221251
                getalpha += height - 1 - y;
860
861
221251
                blend_func(context, x + newxpos, y + newypos, *get, *getalpha);
862
            }
863
        }
864
    }
865
}
866
867
/**************************************************************************/
868
/*                                                                        */
869
/*  FUNCTION                                               RELEASE        */
870
/*                                                                        */
871
/*    _gx_display_driver_16bpp_pixelmap_rotate            PORTABLE C      */
872
/*                                                           6.1          */
873
/*  AUTHOR                                                                */
874
/*                                                                        */
875
/*    Kenneth Maxwell, Microsoft Corporation                              */
876
/*                                                                        */
877
/*  DESCRIPTION                                                           */
878
/*                                                                        */
879
/*    This service rotate a pixelmap directly to canvas memory.           */
880
/*                                                                        */
881
/*  INPUT                                                                 */
882
/*                                                                        */
883
/*    context                               Drawing context               */
884
/*    xpos                                  x-coord of top-left draw point*/
885
/*    ypos                                  y-coord of top-left draw point*/
886
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
887
/*    angle                                 The angle to rotate           */
888
/*    rot_cx                                x-coord of rotating center.   */
889
/*    rot_cy                                y-coord of rotationg center.  */
890
/*                                                                        */
891
/*  OUTPUT                                                                */
892
/*                                                                        */
893
/*    status                                Completion status             */
894
/*                                                                        */
895
/*  CALLS                                                                 */
896
/*                                                                        */
897
/*    _gx_display_driver_16bpp_pixelmap_simple_alpha_rotate               */
898
/*                                          Real rotate functin           */
899
/*    _gx_display_driver_16bpp_pixelmap_simple_rotate                     */
900
/*                                          Real rotate functin           */
901
/*    _gx_display_driver_565rgb_pixelmap_alpha_rotate                     */
902
/*                                          Real rotate functin           */
903
/*    _gx_display_driver_565rgb_pixelmap_raw_rotate                       */
904
/*                                          Real rotate functin           */
905
/*                                                                        */
906
/*  CALLED BY                                                             */
907
/*                                                                        */
908
/*    Application Code                                                    */
909
/*    GUIX Internal Code                                                  */
910
/*                                                                        */
911
/*  RELEASE HISTORY                                                       */
912
/*                                                                        */
913
/*    DATE              NAME                      DESCRIPTION             */
914
/*                                                                        */
915
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
916
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
917
/*                                            added 565bgr format support,*/
918
/*                                            resulting in version 6.1    */
919
/*                                                                        */
920
/**************************************************************************/
921
1845
VOID _gx_display_driver_16bpp_pixelmap_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
922
                                              INT angle, INT rot_cx, INT rot_cy)
923
{
924
1845
    switch (pixelmap -> gx_pixelmap_format)
925
    {
926
1844
    case GX_COLOR_FORMAT_565RGB:
927
    case GX_COLOR_FORMAT_565BGR:
928
1844
        if (angle % 90 == 0)
929
        {
930
            /* Simple angle rotate: 90 degree, 180 degree and 270 degree.  */
931
29
            if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
932
            {
933
19
                _gx_display_driver_16bpp_pixelmap_simple_alpha_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
934
            }
935
            else
936
            {
937
10
                _gx_display_driver_16bpp_pixelmap_simple_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
938
            }
939
29
            break;
940
        }
941
        else
942
        {
943
            /* General rotation case. */
944
1815
            if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
945
            {
946
                /* alpha, no compression */
947
1093
                _gx_display_driver_565rgb_pixelmap_alpha_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
948
            }
949
            else
950
            {
951
952
                /* no compression or alpha */
953
722
                _gx_display_driver_565rgb_pixelmap_raw_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
954
            }
955
1815
            break;
956
        }
957
    }
958
1845
    return;
959
}
960