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

59533020
            if ((xx >= -1) && (xx < pixelmap -> gx_pixelmap_height) &&
205
35843378
                (yy >= -1) && (yy < pixelmap -> gx_pixelmap_width))
206
            {
207

32921507
                if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_height - 1) &&
208
32269236
                    (yy >= 0) && (yy < pixelmap -> gx_pixelmap_width - 1))
209
                {
210
32134753
                    get = (GX_COLOR *)pixelmap -> gx_pixelmap_data;
211
32134753
                    get += yy * pixelmap -> gx_pixelmap_height;
212
32134753
                    get += xx;
213
214
32134753
                    a = *get;
215
32134753
                    b = *(get + 1);
216
32134753
                    c = *(get + pixelmap -> gx_pixelmap_height);
217
32134753
                    d = *(get + pixelmap -> gx_pixelmap_height + 1);
218
219
32134753
                    alpha = 0xff;
220
                }
221
                else
222
                {
223
786754
                    get = (GX_COLOR *)pixelmap -> gx_pixelmap_data;
224
225
786754
                    a = 0;
226
786754
                    b = 0;
227
786754
                    c = 0;
228
786754
                    d = 0;
229
786754
                    alpha = 0;
230
231
786754
                    if (xx == -1)
232
                    {
233
                        /* Handle left edge.  */
234
258752
                        if (yy >= 0)
235
                        {
236
257677
                            b = *(get + yy * pixelmap -> gx_pixelmap_height);
237
                        }
238
239
258752
                        if (yy < pixelmap -> gx_pixelmap_width - 1)
240
                        {
241
257731
                            d = *(get + (yy + 1) * pixelmap -> gx_pixelmap_height);
242
                        }
243
                    }
244
528002
                    else if (yy == -1)
245
                    {
246
                        /* Handle top edge.  */
247
135087
                        c = *(get + xx);
248
249
135087
                        if (xx < pixelmap -> gx_pixelmap_height - 1)
250
                        {
251
134043
                            d = *(get + xx + 1);
252
                        }
253
                    }
254
392915
                    else if (xx == pixelmap -> gx_pixelmap_height - 1)
255
                    {
256
                        /* Handle right edget.  */
257
258432
                        a = *(get + yy * pixelmap -> gx_pixelmap_height + xx);
258
259
258432
                        if (yy < pixelmap -> gx_pixelmap_width - 1)
260
                        {
261
257386
                            c = *(get + (yy + 1) * pixelmap -> gx_pixelmap_height + xx);
262
                        }
263
                    }
264
                    else
265
                    {
266
                        /* Handle bottom edge.  */
267
134483
                        a = *(get + yy * pixelmap -> gx_pixelmap_height + xx);
268
134483
                        b = *(get + yy * pixelmap -> gx_pixelmap_height + xx + 1);
269
                    }
270
271
786754
                    if (a)
272
                    {
273
392915
                        alpha += (256 - xdiff) * (256 - ydiff);
274
                    }
275
276
786754
                    if (b)
277
                    {
278
392160
                        alpha += xdiff * (256 - ydiff);
279
                    }
280
281
786754
                    if (c)
282
                    {
283
392473
                        alpha += ydiff * (256 - xdiff);
284
                    }
285
286
786754
                    if (d)
287
                    {
288
391774
                        alpha += xdiff * ydiff;
289
                    }
290
291
786754
                    alpha >>= 8;
292
                }
293
294
32921507
                red = (GX_COLOR)(REDVAL_24BPP(a) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
295
32921507
                                 REDVAL_24BPP(b) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) +         \
296
32921507
                                 REDVAL_24BPP(c) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) +         \
297
32921507
                                 REDVAL_24BPP(d) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16;
298
299
32921507
                green = (GX_COLOR)(GREENVAL_24BPP(a) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
300
32921507
                                   GREENVAL_24BPP(b) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) +         \
301
32921507
                                   GREENVAL_24BPP(c) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) +         \
302
32921507
                                   GREENVAL_24BPP(d) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16;
303
304
32921507
                blue = (GX_COLOR)(BLUEVAL_24BPP(a) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
305
32921507
                                  BLUEVAL_24BPP(b) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) +         \
306
32921507
                                  BLUEVAL_24BPP(c) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) +         \
307
32921507
                                  BLUEVAL_24BPP(d) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16;
308
309

32921507
                if ((alpha > 0) && (alpha < 0xff))
310
                {
311
780000
                    red = (red << 8) / (GX_COLOR)alpha;
312
780000
                    green = (green << 8) / (GX_COLOR)alpha;
313
780000
                    blue = (blue << 8) / (GX_COLOR)alpha;
314
                }
315
316
32921507
                red = BYTE_RANGE(red);
317
32921507
                green = BYTE_RANGE(green);
318
32921507
                blue = BYTE_RANGE(blue);
319
32921507
                alpha = BYTE_RANGE(alpha);
320
321
32921507
                blend_func(context, x + newxpos, y + newypos, ASSEMBLECOLOR_32ARGB((ULONG)0xff, red, green, blue), (GX_UBYTE)alpha);
322
            }
323
        }
324
    }
325
}
326
327
/**************************************************************************/
328
/*                                                                        */
329
/*  FUNCTION                                               RELEASE        */
330
/*                                                                        */
331
/*    _gx_utility_32bppted_pixelmap_alpha_rotate          PORTABLE C      */
332
/*                                                           6.1.5        */
333
/*  AUTHOR                                                                */
334
/*                                                                        */
335
/*    Kenneth Maxwell, Microsoft Corporation                              */
336
/*                                                                        */
337
/*  DESCRIPTION                                                           */
338
/*                                                                        */
339
/*    Internal helper function that rotate an rotated uncompressed        */
340
/*    pixelmap with alpha.                                                */
341
/*                                                                        */
342
/*  INPUT                                                                 */
343
/*                                                                        */
344
/*    context                               Drawing context               */
345
/*    xpos                                  x-coord of top-left draw point*/
346
/*    ypos                                  y-coord of top-left draw point*/
347
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
348
/*    angle                                 The angle to rotate           */
349
/*    cx                                    x-coord of rotate center      */
350
/*    cy                                    y-coord of rotate center      */
351
/*                                                                        */
352
/*  OUTPUT                                                                */
353
/*                                                                        */
354
/*    None                                                                */
355
/*                                                                        */
356
/*  CALLS                                                                 */
357
/*                                                                        */
358
/*    _gx_utility_math_cos                  Compute the cosine value      */
359
/*    _gx_utility_math_sin                  Compute the sine value        */
360
/*    [gx_display_driver_pixel_blend]       Basic display driver pixel    */
361
/*                                            blend function              */
362
/*                                                                        */
363
/*  CALLED BY                                                             */
364
/*                                                                        */
365
/*    _gx_display_driver_32bpp_rotated_pixelmap_rotate                    */
366
/*                                                                        */
367
/*  RELEASE HISTORY                                                       */
368
/*                                                                        */
369
/*    DATE              NAME                      DESCRIPTION             */
370
/*                                                                        */
371
/*  02-02-2021     Kenneth Maxwell          Initial Version 6.1.4         */
372
/*  03-02-2021     Ting Zhu                 Modified comment(s), changed  */
373
/*                                            blend function set macro,   */
374
/*                                            resulting in version 6.1.5  */
375
/*                                                                        */
376
/**************************************************************************/
377
1072
static VOID _gx_display_driver_32bpp_rotated_pixelmap_alpha_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
378
                                                                   INT angle, INT cx, INT cy)
379
{
380
GX_COLOR     *get;
381
INT           srcxres;
382
INT           srcyres;
383
INT           cosv;
384
INT           sinv;
385
INT           alpha;
386
GX_COLOR      red;
387
GX_COLOR      green;
388
GX_COLOR      blue;
389
INT           idxminx;
390
INT           idxmaxx;
391
INT           idxmaxy;
392
INT          *mx;
393
INT          *my;
394
INT           xres;
395
INT           yres;
396
INT           x;
397
INT           y;
398
INT           xx;
399
INT           yy;
400
GX_COLOR      a;
401
GX_COLOR      b;
402
GX_COLOR      c;
403
GX_COLOR      d;
404
INT           xdiff;
405
INT           ydiff;
406
INT           newxpos;
407
INT           newypos;
408
GX_RECTANGLE *clip;
409
GX_RECTANGLE  rotated_clip;
410
VOID          (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR fcolor, GX_UBYTE alpha);
411
412
1072
    GX_SET_32BPP_BLEND_FUNCTION(blend_func, context -> gx_draw_context_display -> gx_display_color_format);
413
414
1071
    clip = context -> gx_draw_context_clip;
415
416
1071
    mx = _gx_system_scratchpad;
417
1071
    my = mx + 4;
418
419
1071
    mx[0] = mx[3] = -1;
420
1071
    mx[1] = mx[2] = 1;
421
422
1071
    my[0] = my[1] = 1;
423
1071
    my[2] = my[3] = -1;
424
425
1071
    idxminx = (angle / 90) & 0x3;
426
1071
    idxmaxx = (idxminx + 2) & 0x3;
427
1071
    idxmaxy = (idxminx + 1) & 0x3;
428
429
    /* Calculate the source x and y center.  */
430
1071
    srcxres = pixelmap -> gx_pixelmap_height >> 1;
431
1071
    srcyres = pixelmap -> gx_pixelmap_width >> 1;
432
433
1071
    GX_SWAP_VALS(xpos, ypos);
434
1071
    GX_SWAP_VALS(cx, cy);
435
436
1071
    if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
437
    {
438
714
        srcyres = pixelmap -> gx_pixelmap_width - 1 - srcyres;
439
440
714
        ypos = context -> gx_draw_context_canvas -> gx_canvas_x_resolution - ypos - pixelmap -> gx_pixelmap_width;
441
714
        cy = pixelmap -> gx_pixelmap_width - cy - 1;
442
443
714
        rotated_clip.gx_rectangle_left = clip -> gx_rectangle_top;
444
714
        rotated_clip.gx_rectangle_right = clip -> gx_rectangle_bottom;
445
714
        rotated_clip.gx_rectangle_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - 1 - clip -> gx_rectangle_right);
446
714
        rotated_clip.gx_rectangle_bottom = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - 1 - clip -> gx_rectangle_left);
447
    }
448
    else
449
    {
450
357
        srcxres = pixelmap -> gx_pixelmap_height - 1 - srcxres;
451
452
357
        xpos = context -> gx_draw_context_canvas -> gx_canvas_y_resolution - xpos - pixelmap -> gx_pixelmap_height;
453
357
        cx = pixelmap -> gx_pixelmap_height - cx - 1;
454
455
357
        rotated_clip.gx_rectangle_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - 1 - clip -> gx_rectangle_bottom);
456
357
        rotated_clip.gx_rectangle_right = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - 1 - clip -> gx_rectangle_top);
457
357
        rotated_clip.gx_rectangle_top = clip -> gx_rectangle_left;
458
357
        rotated_clip.gx_rectangle_bottom = clip -> gx_rectangle_right;
459
    }
460
461
1071
    cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
462
1071
    sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
463
464
1071
    xres = mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv;
465
1071
    yres = my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv;
466
467
1071
    xres = GX_FIXED_VAL_TO_INT(xres);
468
1071
    yres = GX_FIXED_VAL_TO_INT(yres);
469
470
1071
    x = GX_FIXED_VAL_TO_INT(xres) + xres;
471
1071
    y = GX_FIXED_VAL_TO_INT(yres) + yres;
472
473
1071
    newxpos = xpos + cx - x;
474
1071
    newypos = ypos + cy - y;
475
476
    /* Loop through the source's pixels.  */
477
319047
    for (y = rotated_clip.gx_rectangle_top - newypos; y <= rotated_clip.gx_rectangle_bottom - newypos; y++)
478
    {
479
95132712
        for (x = rotated_clip.gx_rectangle_left - newxpos; x <= rotated_clip.gx_rectangle_right - newxpos; x++)
480
        {
481
94814736
            xx = (x - xres) * cosv + (y - yres) * sinv;
482
94814736
            yy = (y - yres) * cosv - (x - xres) * sinv;
483
484
94814736
            xdiff = GX_FIXED_VAL_TO_INT(xx << 8) & 0xff;
485
94814736
            ydiff = GX_FIXED_VAL_TO_INT(yy << 8) & 0xff;
486
487
94814736
            xx = GX_FIXED_VAL_TO_INT(xx);
488
94814736
            yy = GX_FIXED_VAL_TO_INT(yy);
489
490
94814736
            xx += srcxres;
491
94814736
            yy += srcyres;
492
493

94814736
            if ((xx >= -1) && (xx < pixelmap -> gx_pixelmap_height) &&
494
68979534
                (yy >= -1) && (yy < pixelmap -> gx_pixelmap_width))
495
            {
496

56497962
                if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_height - 1) && \
497
55794267
                    (yy >= 0) && (yy < pixelmap -> gx_pixelmap_width - 1))
498
                {
499
55509375
                    get = (GX_COLOR *)pixelmap -> gx_pixelmap_data;
500
55509375
                    get += yy * pixelmap -> gx_pixelmap_height;
501
55509375
                    get += xx;
502
503
55509375
                    a = *get;
504
55509375
                    b = *(get + 1);
505
55509375
                    c = *(get + pixelmap -> gx_pixelmap_height);
506
55509375
                    d = *(get + pixelmap -> gx_pixelmap_height + 1);
507
                }
508
                else
509
                {
510
988587
                    get = (GX_COLOR *)pixelmap -> gx_pixelmap_data;
511
512
988587
                    a = 0;
513
988587
                    b = a;
514
988587
                    c = a;
515
988587
                    d = a;
516
517
988587
                    if (xx == -1)
518
                    {
519
                        /* Handle left edge.  */
520
209077
                        if (yy >= 0)
521
                        {
522
208212
                            b = *(get + yy * pixelmap -> gx_pixelmap_height);
523
                        }
524
525
209077
                        if (yy < pixelmap -> gx_pixelmap_width - 1)
526
                        {
527
208210
                            d = *(get + (yy + 1) * pixelmap -> gx_pixelmap_height);
528
                        }
529
                    }
530
779510
                    else if (yy == -1)
531
                    {
532
                        /* Handle top edge.  */
533
285855
                        c = *(get + xx);
534
535
285855
                        if (xx < pixelmap -> gx_pixelmap_height - 1)
536
                        {
537
285000
                            d = *(get + xx + 1);
538
                        }
539
                    }
540
493655
                    else if (xx == pixelmap -> gx_pixelmap_height - 1)
541
                    {
542
                        /* Handle right edget.  */
543
208763
                        a = *(get + yy * pixelmap -> gx_pixelmap_height + xx);
544
545
208763
                        if (yy < pixelmap -> gx_pixelmap_width - 1)
546
                        {
547
207909
                            c = *(get + (yy + 1) * pixelmap -> gx_pixelmap_height + xx);
548
                        }
549
                    }
550
                    else
551
                    {
552
                        /* Handle bottom edge.  */
553
284892
                        a = *(get + yy * pixelmap -> gx_pixelmap_height + xx);
554
284892
                        b = *(get + yy * pixelmap -> gx_pixelmap_height + xx + 1);
555
                    }
556
                }
557
558
56497962
                red = (REDVAL_24BPP(a) * (a >> 24) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
559
56497962
                       REDVAL_24BPP(b) * (b >> 24) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) +         \
560
56497962
                       REDVAL_24BPP(c) * (c >> 24) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) +         \
561
56497962
                       REDVAL_24BPP(d) * (d >> 24) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16;
562
563
56497962
                green = (GREENVAL_24BPP(a) * (a >> 24) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
564
56497962
                         GREENVAL_24BPP(b) * (b >> 24) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) +         \
565
56497962
                         GREENVAL_24BPP(c) * (c >> 24) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) +         \
566
56497962
                         GREENVAL_24BPP(d) * (d >> 24) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16;
567
568
56497962
                blue = (BLUEVAL_24BPP(a) * (a >> 24) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
569
56497962
                        BLUEVAL_24BPP(b) * (b >> 24) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) +         \
570
56497962
                        BLUEVAL_24BPP(c) * (c >> 24) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) +         \
571
56497962
                        BLUEVAL_24BPP(d) * (d >> 24) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16;
572
573
56497962
                alpha = (INT)(((a >> 24) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
574
56497962
                               (b >> 24) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) +         \
575
56497962
                               (c >> 24) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) +         \
576
56497962
                               (d >> 24) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16);
577
578
56497962
                if (alpha)
579
                {
580
40156923
                    red /= (UINT)alpha;
581
40156923
                    green /= (UINT)alpha;
582
40156923
                    blue /= (UINT)alpha;
583
                }
584
585
56497962
                red = BYTE_RANGE(red);
586
56497962
                green = BYTE_RANGE(green);
587
56497962
                blue = BYTE_RANGE(blue);
588
56497962
                alpha = BYTE_RANGE(alpha);
589
590
56497962
                blend_func(context, x + newxpos, y + newypos, (GX_COLOR)ASSEMBLECOLOR_32ARGB((ULONG)0xff, red, green, blue), (GX_UBYTE)alpha);
591
            }
592
        }
593
    }
594
}
595
596
/**************************************************************************/
597
/*                                                                        */
598
/*  FUNCTION                                               RELEASE        */
599
/*                                                                        */
600
/*    _gx_display_driver_32bpp_rotated_pixelmap_simple_rotate             */
601
/*                                                                        */
602
/*                                                        PORTABLE C      */
603
/*                                                           6.1.5        */
604
/*  AUTHOR                                                                */
605
/*                                                                        */
606
/*    Kenneth Maxwell, Microsoft Corporation                              */
607
/*                                                                        */
608
/*  DESCRIPTION                                                           */
609
/*                                                                        */
610
/*    Internal help function that hangles 90, 180 and 270 degree rotated  */
611
/*    pixelmap rotation.                                                  */
612
/*                                                                        */
613
/*  INPUT                                                                 */
614
/*                                                                        */
615
/*    context                               Drawing context               */
616
/*    xpos                                  x-coord of top-left draw point*/
617
/*    ypos                                  y-coord of top-left draw point*/
618
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
619
/*    angle                                 The angle to rotate           */
620
/*    cx                                    x-coord of rotate center      */
621
/*    cy                                    y-coord of rotate center      */
622
/*                                                                        */
623
/*  OUTPUT                                                                */
624
/*                                                                        */
625
/*    None                                                                */
626
/*                                                                        */
627
/*  CALLS                                                                 */
628
/*                                                                        */
629
/*    [gx_display_driver_pixel_blend]       Basic display driver pixel    */
630
/*                                            blend function              */
631
/*                                                                        */
632
/*  CALLED BY                                                             */
633
/*                                                                        */
634
/*    GUIX Internal Code                                                  */
635
/*                                                                        */
636
/*  RELEASE HISTORY                                                       */
637
/*                                                                        */
638
/*    DATE              NAME                      DESCRIPTION             */
639
/*                                                                        */
640
/*  02-02-2021     Kenneth Maxwell          Initial Version 6.1.4         */
641
/*  03-02-2021     Ting Zhu                 Modified comment(s), changed  */
642
/*                                            blend function set macro,   */
643
/*                                            resulting in version 6.1.5  */
644
/*                                                                        */
645
/**************************************************************************/
646
19
static VOID _gx_display_driver_32bpp_rotated_pixelmap_simple_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
647
                                                                    INT angle, INT cx, INT cy)
648
{
649
GX_COLOR     *putrow;
650
GX_COLOR     *put;
651
GX_COLOR     *get;
652
INT           width;
653
INT           height;
654
INT           x;
655
INT           y;
656
GX_RECTANGLE *clip;
657
GX_RECTANGLE  rotated_clip;
658
INT           newxpos;
659
INT           newypos;
660
VOID          (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR fcolor, GX_UBYTE alpha);
661
662
19
    GX_SET_32BPP_BLEND_FUNCTION(blend_func, context -> gx_draw_context_display -> gx_display_color_format);
663
664
18
    clip = context -> gx_draw_context_clip;
665
666
18
    GX_SWAP_VALS(xpos, ypos);
667
18
    GX_SWAP_VALS(cx, cy);
668
669
18
    if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
670
    {
671
12
        ypos = context -> gx_draw_context_canvas -> gx_canvas_x_resolution - ypos - pixelmap -> gx_pixelmap_width;
672
12
        cy = pixelmap -> gx_pixelmap_width - cy - 1;
673
674
12
        rotated_clip.gx_rectangle_left = clip -> gx_rectangle_top;
675
12
        rotated_clip.gx_rectangle_right = clip -> gx_rectangle_bottom;
676
12
        rotated_clip.gx_rectangle_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - 1 - clip -> gx_rectangle_right);
677
12
        rotated_clip.gx_rectangle_bottom = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - 1 - clip -> gx_rectangle_left);
678
    }
679
    else
680
    {
681
6
        xpos = context -> gx_draw_context_canvas -> gx_canvas_y_resolution - xpos - pixelmap -> gx_pixelmap_height;
682
6
        cx = pixelmap -> gx_pixelmap_height - cx - 1;
683
684
6
        rotated_clip.gx_rectangle_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - 1 - clip -> gx_rectangle_bottom);
685
6
        rotated_clip.gx_rectangle_right = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - 1 - clip -> gx_rectangle_top);
686
6
        rotated_clip.gx_rectangle_top = clip -> gx_rectangle_left;
687
6
        rotated_clip.gx_rectangle_bottom = clip -> gx_rectangle_right;
688
    }
689
690
18
    if (angle == 90)
691
    {
692
6
        width = pixelmap -> gx_pixelmap_width;
693
6
        height = pixelmap -> gx_pixelmap_height;
694
695
6
        newxpos = xpos + cx - (width - 1 - cy);
696
6
        newypos = ypos + cy - cx;
697
698
6
        putrow = context -> gx_draw_context_memory;
699
6
        putrow += rotated_clip.gx_rectangle_top * context -> gx_draw_context_pitch;
700
6
        putrow += rotated_clip.gx_rectangle_left;
701
702
1185
        for (y = rotated_clip.gx_rectangle_top - newypos; y <= rotated_clip.gx_rectangle_bottom - newypos; y++)
703
        {
704
1179
            put = putrow;
705
706
248094
            for (x = rotated_clip.gx_rectangle_left - newxpos; x <= rotated_clip.gx_rectangle_right - newxpos; x++)
707
            {
708
246915
                get = (GX_COLOR *)pixelmap -> gx_pixelmap_data;
709
246915
                get += (width - 1 - x) * height;
710
246915
                get += y;
711
712
246915
                if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
713
                {
714
156195
                    blend_func(context, rotated_clip.gx_rectangle_left + x, rotated_clip.gx_rectangle_top + y, (*get) | 0xff000000, (GX_UBYTE)((*get) >> 24));
715
                }
716
                else
717
                {
718
90720
                    *put++ = *get;
719
                }
720
            }
721
722
1179
            putrow += context -> gx_draw_context_pitch;
723
        }
724
    }
725
12
    else if (angle == 180)
726
    {
727
728
6
        width = pixelmap -> gx_pixelmap_height;
729
6
        height = pixelmap -> gx_pixelmap_width;
730
731
6
        newxpos = xpos + cx - (width - 1 - cx);
732
6
        newypos = ypos + cy - (height - 1 - cy);
733
734
6
        putrow = context -> gx_draw_context_memory;
735
6
        putrow += rotated_clip.gx_rectangle_top * context -> gx_draw_context_pitch;
736
6
        putrow += rotated_clip.gx_rectangle_left;
737
738
1311
        for (y = rotated_clip.gx_rectangle_top - newypos; y <= rotated_clip.gx_rectangle_bottom - newypos; y++)
739
        {
740
1305
            put = putrow;
741
248220
            for (x = rotated_clip.gx_rectangle_left - newxpos; x <= rotated_clip.gx_rectangle_right - newxpos; x++)
742
            {
743
246915
                get = (GX_COLOR *)pixelmap -> gx_pixelmap_data;
744
246915
                get += (height - 1 - y) * width;
745
246915
                get += width - 1 - x;
746
747
246915
                if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
748
                {
749
156195
                    blend_func(context, rotated_clip.gx_rectangle_left + x, rotated_clip.gx_rectangle_top + y, (*get) | 0xff000000, (GX_UBYTE)((*get) >> 24));
750
                }
751
                else
752
                {
753
90720
                    *put++ = *get;
754
                }
755
            }
756
757
1305
            putrow += context -> gx_draw_context_pitch;
758
        }
759
    }
760
    else
761
    {
762
6
        height = pixelmap -> gx_pixelmap_height;
763
764
6
        newxpos = xpos + cx - cy;
765
6
        newypos = ypos + cx - (height - 1 - cy);
766
767
6
        putrow = context -> gx_draw_context_memory;
768
6
        putrow += rotated_clip.gx_rectangle_top * context -> gx_draw_context_pitch;
769
6
        putrow += rotated_clip.gx_rectangle_left;
770
771
1185
        for (y = rotated_clip.gx_rectangle_top - newypos; y <= rotated_clip.gx_rectangle_bottom - newypos; y++)
772
        {
773
1179
            put = putrow;
774
775
248094
            for (x = rotated_clip.gx_rectangle_left - newxpos; x <= rotated_clip.gx_rectangle_right - newxpos; x++)
776
            {
777
246915
                get = (GX_COLOR *)pixelmap -> gx_pixelmap_data;
778
246915
                get += x * height;
779
246915
                get += height - 1 - y;
780
781
246915
                if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
782
                {
783
156195
                    blend_func(context, rotated_clip.gx_rectangle_left + x, rotated_clip.gx_rectangle_top + y, (*get) | 0xff000000, (GX_UBYTE)((*get) >> 24));
784
                }
785
                else
786
                {
787
90720
                    *put++ = *get;
788
                }
789
            }
790
791
1179
            putrow += context -> gx_draw_context_pitch;
792
        }
793
    }
794
}
795
796
/**************************************************************************/
797
/*                                                                        */
798
/*  FUNCTION                                               RELEASE        */
799
/*                                                                        */
800
/*    _gx_display_driver_32bpp_rotated_pixelmap_rotate   PORTABLE C       */
801
/*                                                           6.1.4        */
802
/*  AUTHOR                                                                */
803
/*                                                                        */
804
/*    Kenneth Maxwell, Microsoft Corporation                              */
805
/*                                                                        */
806
/*  DESCRIPTION                                                           */
807
/*                                                                        */
808
/*    This service rotate a rotated pixelmap directly to canvas memory.   */
809
/*                                                                        */
810
/*  INPUT                                                                 */
811
/*                                                                        */
812
/*    context                               Drawing context               */
813
/*    xpos                                  x-coord of top-left draw point*/
814
/*    ypos                                  y-coord of top-left draw point*/
815
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
816
/*    angle                                 The angle to rotate           */
817
/*    rot_cx                                x-coord of rotating center.   */
818
/*    rot_cy                                y-coord of rotationg center.  */
819
/*                                                                        */
820
/*  OUTPUT                                                                */
821
/*                                                                        */
822
/*    None                                                                */
823
/*                                                                        */
824
/*  CALLS                                                                 */
825
/*                                                                        */
826
/*    _gx_display_driver_32bpp_rotated_pixelmap_simple_rotate             */
827
/*    _gx_display_driver_32bpp_rotated_pixelmap_alpha_rotate              */
828
/*    _gx_display_driver_32bpp_rotated_pixelmap_rotate                    */
829
/*                                                                        */
830
/*  CALLED BY                                                             */
831
/*                                                                        */
832
/*    GUIX Internal Code                                                  */
833
/*                                                                        */
834
/*  RELEASE HISTORY                                                       */
835
/*                                                                        */
836
/*    DATE              NAME                      DESCRIPTION             */
837
/*                                                                        */
838
/*  02-02-2021     Kenneth Maxwell          Initial Version 6.1.4         */
839
/*                                                                        */
840
/**************************************************************************/
841
2166
VOID _gx_display_driver_32bpp_rotated_pixelmap_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
842
                                                      INT angle, INT rot_cx, INT rot_cy)
843
{
844
2166
    switch (pixelmap -> gx_pixelmap_format)
845
    {
846
2163
    case GX_COLOR_FORMAT_24XRGB:
847
    case GX_COLOR_FORMAT_32ARGB:
848
2163
        if (angle % 90 == 0)
849
        {
850
            /* Simple angle rotate: 90 degree, 180 degree and 270 degree.  */
851
19
            _gx_display_driver_32bpp_rotated_pixelmap_simple_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
852
        }
853
        else
854
        {
855
2144
            if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
856
            {
857
                /* With alpha.  */
858
1072
                _gx_display_driver_32bpp_rotated_pixelmap_alpha_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
859
            }
860
            else
861
            {
862
                /* Without alpha.  */
863
1072
                _gx_display_driver_32bpp_rotated_pixelmap_raw_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
864
            }
865
        }
866
2163
        break;
867
    }
868
869
2166
    return;
870
}
871