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

59533020
            if ((xx >= -1) && (xx < pixelmap -> gx_pixelmap_height) &&
197
35843378
                (yy >= -1) && (yy < pixelmap -> gx_pixelmap_width))
198
            {
199

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

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

94814736
            if ((xx >= -1) && (xx < pixelmap -> gx_pixelmap_height) &&
477
68979534
                (yy >= -1) && (yy < pixelmap -> gx_pixelmap_width))
478
            {
479

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