GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_32bpp_pixelmap_rotate.c Lines: 260 260 100.0 %
Date: 2026-03-06 19:21:09 Branches: 114 114 100.0 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 * Copyright (c) 2026-present Eclipse ThreadX contributors
4
 *
5
 * This program and the accompanying materials are made available under the
6
 * terms of the MIT License which is available at
7
 * https://opensource.org/licenses/MIT.
8
 *
9
 * SPDX-License-Identifier: MIT
10
 **************************************************************************/
11
12
13
/**************************************************************************/
14
/**************************************************************************/
15
/**                                                                       */
16
/** GUIX Component                                                        */
17
/**                                                                       */
18
/**   Display Management (Display)                                        */
19
/**                                                                       */
20
/**************************************************************************/
21
22
#define REDVAL(_c)     (GX_UBYTE)((_c) >> 16)
23
#define GREENVAL(_c)   (GX_UBYTE)((_c) >> 8)
24
#define BLUEVAL(_c)    (GX_UBYTE)(_c)
25
26
#define ASSEMBLECOLOR(_r, _g, _b) \
27
    (0xff000000   |               \
28
     ((_r) << 16) |               \
29
     ((_g) << 8)  |               \
30
     (_b))
31
32
#define BYTE_RANGE(_c) _c > 255 ? 255 : _c
33
34
#define GX_SOURCE_CODE
35
36
37
/* Include necessary system files.  */
38
39
#include "gx_api.h"
40
#include "gx_display.h"
41
#include "gx_context.h"
42
#include "gx_utility.h"
43
#include "gx_system.h"
44
45
/**************************************************************************/
46
/*                                                                        */
47
/*  FUNCTION                                               RELEASE        */
48
/*                                                                        */
49
/*    _gx_display_driver_24xrgb_pixelmap_rotate           PORTABLE C      */
50
/*                                                           6.1.10       */
51
/*  AUTHOR                                                                */
52
/*                                                                        */
53
/*    Kenneth Maxwell, Microsoft Corporation                              */
54
/*                                                                        */
55
/*  DESCRIPTION                                                           */
56
/*                                                                        */
57
/*    Internal helper function that rotate an uncompressed pixelmap       */
58
/*      without alpha.                                                    */
59
/*                                                                        */
60
/*  INPUT                                                                 */
61
/*                                                                        */
62
/*    context                               Drawing context               */
63
/*    xpos                                  x-coord of top-left draw point*/
64
/*    ypos                                  y-coord of top-left draw point*/
65
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
66
/*    angle                                 The angle to rotate           */
67
/*    cx                                    x-coord of rotate center      */
68
/*    cy                                    y-coord of rotate center      */
69
/*                                                                        */
70
/*  OUTPUT                                                                */
71
/*                                                                        */
72
/*    status                                Completion status             */
73
/*                                                                        */
74
/*  CALLS                                                                 */
75
/*                                                                        */
76
/*    _gx_utility_math_cos                  Compute the cosine value      */
77
/*    _gx_utility_math_sin                  Compute the sine value        */
78
/*    [gx_display_driver_pixel_blend]       Basic display driver pixel    */
79
/*                                            blend function              */
80
/*                                                                        */
81
/*  CALLED BY                                                             */
82
/*                                                                        */
83
/*    _gx_display_driver_32bpp_pixelmap_rotate                            */
84
/*                                                                        */
85
/**************************************************************************/
86
713
static VOID _gx_display_driver_24xrgb_pixelmap_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_DISPLAY   *display;
118
GX_RECTANGLE *clip;
119
VOID          (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR color, GX_UBYTE alpha);
120
121
713
    clip = context -> gx_draw_context_clip;
122
713
    display = context -> gx_draw_context_display;
123
713
    blend_func = display -> gx_display_driver_pixel_blend;
124
125
713
    if (!blend_func)
126
    {
127
1
        return;
128
    }
129
130
712
    mx = _gx_system_scratchpad;
131
712
    my = mx + 4;
132
133
712
    mx[0] = mx[3] = -1;
134
712
    mx[1] = mx[2] = 1;
135
136
712
    my[0] = my[1] = 1;
137
712
    my[2] = my[3] = -1;
138
139
712
    idxminx = (angle / 90) & 0x3;
140
712
    idxmaxx = (idxminx + 2) & 0x3;
141
712
    idxmaxy = (idxminx + 1) & 0x3;
142
143
    /* Calculate the source x and y center. */
144
712
    srcxres = pixelmap -> gx_pixelmap_width >> 1;
145
712
    srcyres = pixelmap -> gx_pixelmap_height >> 1;
146
147
712
    cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
148
712
    sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
149
150
712
    xres = mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv;
151
712
    yres = my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv;
152
153
712
    xres = GX_FIXED_VAL_TO_INT(xres);
154
712
    yres = GX_FIXED_VAL_TO_INT(yres);
155
156
    /* Calculate the new rotation axis. */
157
158
712
    x = (cx - srcxres) * cosv - (cy - srcyres) * sinv;
159
712
    y = (cy - srcyres) * cosv + (cx - srcxres) * sinv;
160
161
712
    xres = GX_FIXED_VAL_TO_INT(x) + xres;
162
712
    yres = GX_FIXED_VAL_TO_INT(y) + yres;
163
164
712
    newxpos = xpos + cx - xres;
165
712
    newypos = ypos + cy - yres;
166
167
    /* Loop through the destination's pixels.  */
168
149753
    for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
169
    {
170
33809071
        for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
171
        {
172
33660030
            xx = (x - xres) * cosv + (y - yres) * sinv;
173
33660030
            yy = (y - yres) * cosv - (x - xres) * sinv;
174
175
33660030
            xdiff = GX_FIXED_VAL_TO_INT(xx << 8) & 0xff;
176
33660030
            ydiff = GX_FIXED_VAL_TO_INT(yy << 8) & 0xff;
177
178
33660030
            xx = GX_FIXED_VAL_TO_INT(xx) + cx;
179
33660030
            yy = GX_FIXED_VAL_TO_INT(yy) + cy;
180
181

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

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

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

47490784
            if ((xx >= -1) && (xx < pixelmap -> gx_pixelmap_width) &&
440
32474471
                (yy >= -1) && (yy < pixelmap -> gx_pixelmap_height))
441
            {
442

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