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

34237074
            if ((xx >= -1) && (xx < pixelmap -> gx_pixelmap_width) &&
172
25732179
                (yy >= -1) && (yy < pixelmap -> gx_pixelmap_height))
173
            {
174

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

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

61357578
            if ((xx >= -1) && (xx < pixelmap -> gx_pixelmap_width) &&
413
42728666
                (yy >= -1) && (yy < pixelmap -> gx_pixelmap_height))
414
            {
415

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