GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_8bpp_rotated_pixelmap_rotate.c Lines: 254 254 100.0 %
Date: 2026-03-06 19:21:09 Branches: 78 78 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
#define GX_SOURCE_CODE
22
23
/* Include necessary system files.  */
24
25
#include "gx_api.h"
26
#include "gx_display.h"
27
#include "gx_context.h"
28
#include "gx_utility.h"
29
#include "gx_system.h"
30
31
/**************************************************************************/
32
/*                                                                        */
33
/*  FUNCTION                                               RELEASE        */
34
/*                                                                        */
35
/*    _gx_display_driver_8bpp_rotated_pixelmap_raw_rotate PORTABLE C      */
36
/*                                                           6.1.4        */
37
/*  AUTHOR                                                                */
38
/*                                                                        */
39
/*    Kenneth Maxwell, Microsoft Corporation                              */
40
/*                                                                        */
41
/*  DESCRIPTION                                                           */
42
/*                                                                        */
43
/*    Internal helper function that rotate an uncompressed pixelmap       */
44
/*      without alpha.                                                    */
45
/*                                                                        */
46
/*  INPUT                                                                 */
47
/*                                                                        */
48
/*    context                               Drawing context               */
49
/*    xpos                                  x-coord of top-left draw point*/
50
/*    ypos                                  y-coord of top-left draw point*/
51
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
52
/*    angle                                 The angle to rotate           */
53
/*    cx                                    x-coord of rotate center      */
54
/*    cy                                    y-coord of rotate center      */
55
/*                                                                        */
56
/*  OUTPUT                                                                */
57
/*                                                                        */
58
/*    None                                                                */
59
/*                                                                        */
60
/*  CALLS                                                                 */
61
/*                                                                        */
62
/*    _gx_utility_math_cos                  Compute the cosine value      */
63
/*    _gx_utility_math_sin                  Compute the sine value        */
64
/*                                                                        */
65
/*  CALLED BY                                                             */
66
/*                                                                        */
67
/*    _gx_display_driver_8bpp_pixelmap_rotate                             */
68
/*                                                                        */
69
/**************************************************************************/
70
712
static VOID _gx_display_driver_8bpp_rotated_pixelmap_raw_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
71
                                                        INT angle, INT cx, INT cy)
72
{
73
GX_UBYTE     *putrow;
74
GX_UBYTE     *put;
75
GX_UBYTE     *get;
76
INT           srcxres;
77
INT           srcyres;
78
INT           cosv;
79
INT           sinv;
80
INT           idxminx;
81
INT           idxmaxx;
82
INT           idxmaxy;
83
712
INT           mx[] = {-1, 1, 1, -1};
84
712
INT           my[] = {1, 1, -1, -1};
85
INT           xres;
86
INT           yres;
87
INT           x;
88
INT           y;
89
INT           xx;
90
INT           yy;
91
GX_RECTANGLE *clip;
92
GX_RECTANGLE  rotated_clip;
93
INT           newxpos;
94
INT           newypos;
95
96
712
    clip = context -> gx_draw_context_clip;
97
98
    /* Set transparent color.  */
99
712
    idxminx = (angle / 90) & 0x3;
100
712
    idxmaxx = (idxminx + 2) & 0x3;
101
712
    idxmaxy = (idxminx + 1) & 0x3;
102
103
    /* Calculate the source x and y center. */
104
712
    srcxres = pixelmap -> gx_pixelmap_height >> 1;
105
712
    srcyres = pixelmap -> gx_pixelmap_width >> 1;
106
107
712
    GX_SWAP_VALS(xpos, ypos);
108
712
    GX_SWAP_VALS(cx, cy);
109
110
712
    if (context->gx_draw_context_display->gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
111
    {
112
356
        srcyres = pixelmap->gx_pixelmap_width - 1 - srcyres;
113
114
356
        ypos = context->gx_draw_context_canvas->gx_canvas_x_resolution - ypos - pixelmap->gx_pixelmap_width;
115
356
        cy = pixelmap->gx_pixelmap_width - cy - 1;
116
117
356
        rotated_clip.gx_rectangle_left = clip->gx_rectangle_top;
118
356
        rotated_clip.gx_rectangle_right = clip->gx_rectangle_bottom;
119
356
        rotated_clip.gx_rectangle_top = (GX_VALUE)(context->gx_draw_context_canvas->gx_canvas_x_resolution - 1 - clip->gx_rectangle_right);
120
356
        rotated_clip.gx_rectangle_bottom = (GX_VALUE)(context->gx_draw_context_canvas->gx_canvas_x_resolution - 1 - clip->gx_rectangle_left);
121
    }
122
    else
123
    {
124
356
        srcxres = pixelmap->gx_pixelmap_height - 1 - srcxres;
125
126
356
        xpos = context->gx_draw_context_canvas->gx_canvas_y_resolution - xpos - pixelmap->gx_pixelmap_height;
127
356
        cx = pixelmap->gx_pixelmap_height - cx - 1;
128
129
356
        rotated_clip.gx_rectangle_left = (GX_VALUE)(context->gx_draw_context_canvas->gx_canvas_y_resolution - 1 - clip->gx_rectangle_bottom);
130
356
        rotated_clip.gx_rectangle_right = (GX_VALUE)(context->gx_draw_context_canvas->gx_canvas_y_resolution - 1 - clip->gx_rectangle_top);
131
356
        rotated_clip.gx_rectangle_top = clip->gx_rectangle_left;
132
356
        rotated_clip.gx_rectangle_bottom = clip->gx_rectangle_right;
133
    }
134
135
712
    cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
136
712
    sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
137
138
712
    xres = GX_FIXED_VAL_TO_INT((mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv));
139
712
    yres = GX_FIXED_VAL_TO_INT((my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv));
140
141
712
    putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
142
712
    putrow += rotated_clip.gx_rectangle_top * context -> gx_draw_context_pitch;
143
712
    putrow += rotated_clip.gx_rectangle_left;
144
145
    /* Calculate the new rotation axis. */
146
712
    x = GX_FIXED_VAL_TO_INT((cx - srcxres) * cosv - (cy - srcyres) * sinv);
147
712
    y = GX_FIXED_VAL_TO_INT((cy - srcyres) * cosv + (cx - srcxres) * sinv);
148
149
712
    x += xres;
150
712
    y += yres;
151
152
712
    newxpos = xpos + cx - x;
153
712
    newypos = ypos + cy - y;
154
155
    /* For every pixel in destination bitmap, find its position in source bitmap,
156
       and set the pixel with the value in source bitmap.  */
157
169496
    for (y = rotated_clip.gx_rectangle_top - newypos; y <= rotated_clip.gx_rectangle_bottom - newypos; y++)
158
    {
159
168784
        put = putrow;
160
161
39729232
        for (x = rotated_clip.gx_rectangle_left - newxpos; x <= rotated_clip.gx_rectangle_right - newxpos; x++)
162
        {
163
39560448
            xx = GX_FIXED_VAL_TO_INT((x - xres) * cosv + (y - yres) * sinv);
164
39560448
            yy = GX_FIXED_VAL_TO_INT((y - yres) * cosv - (x - xres) * sinv);
165
166
39560448
            xx += srcxres;
167
39560448
            yy += srcyres;
168
169

39560448
            if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_height) &&
170
23577627
                (yy >= 0) && (yy < pixelmap -> gx_pixelmap_width))
171
            {
172
21623996
                get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
173
21623996
                get += yy * pixelmap -> gx_pixelmap_height;
174
21623996
                get += xx;
175
176
21623996
                *put = *get;
177
            }
178
179
39560448
            put++;
180
        }
181
168784
        putrow += context -> gx_draw_context_pitch;
182
    }
183
712
}
184
185
/**************************************************************************/
186
/*                                                                        */
187
/*  FUNCTION                                               RELEASE        */
188
/*                                                                        */
189
/*    _gx_display_driver_8bpp_rotated_pixelmap_transparent_rotate         */
190
/*                                                        PORTABLE C      */
191
/*                                                           6.1.4        */
192
/*  AUTHOR                                                                */
193
/*                                                                        */
194
/*    Kenneth Maxwell, Microsoft Corporation                              */
195
/*                                                                        */
196
/*  DESCRIPTION                                                           */
197
/*                                                                        */
198
/*    Internal helper function that rotate an uncompressed pixelmap       */
199
/*      without alpha.                                                    */
200
/*                                                                        */
201
/*  INPUT                                                                 */
202
/*                                                                        */
203
/*    context                               Drawing context               */
204
/*    xpos                                  x-coord of top-left draw point*/
205
/*    ypos                                  y-coord of top-left draw point*/
206
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
207
/*    angle                                 The angle to rotate           */
208
/*    cx                                    x-coord of rotate center      */
209
/*    cy                                    y-coord of rotate center      */
210
/*                                                                        */
211
/*  OUTPUT                                                                */
212
/*                                                                        */
213
/*    None                                                                */
214
/*                                                                        */
215
/*  CALLS                                                                 */
216
/*                                                                        */
217
/*    _gx_utility_math_cos                  Compute the cosine value      */
218
/*    _gx_utility_math_sin                  Compute the sine value        */
219
/*                                                                        */
220
/*  CALLED BY                                                             */
221
/*                                                                        */
222
/*    GUIX Internal Code                                                  */
223
/*                                                                        */
224
/**************************************************************************/
225
712
static VOID _gx_display_driver_8bpp_rotated_pixelmap_transparent_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
226
                                                                INT angle, INT cx, INT cy)
227
{
228
GX_UBYTE     *putrow;
229
GX_UBYTE     *put;
230
GX_UBYTE     *get;
231
INT           srcxres;
232
INT           srcyres;
233
INT           cosv;
234
INT           sinv;
235
INT           idxminx;
236
INT           idxmaxx;
237
INT           idxmaxy;
238
712
INT           mx[] = {-1, 1, 1, -1};
239
712
INT           my[] = {1, 1, -1, -1};
240
INT           xres;
241
INT           yres;
242
INT           x;
243
INT           y;
244
INT           xx;
245
INT           yy;
246
GX_RECTANGLE *clip;
247
GX_RECTANGLE  rotated_clip;
248
INT           newxpos;
249
INT           newypos;
250
251
712
    clip = context -> gx_draw_context_clip;
252
253
    /* Set transparent color.  */
254
712
    idxminx = (angle / 90) & 0x3;
255
712
    idxmaxx = (idxminx + 2) & 0x3;
256
712
    idxmaxy = (idxminx + 1) & 0x3;
257
258
    /* Calculate the source x and y center. */
259
712
    srcxres = pixelmap -> gx_pixelmap_height >> 1;
260
712
    srcyres = pixelmap -> gx_pixelmap_width >> 1;
261
262
712
    GX_SWAP_VALS(xpos, ypos);
263
712
    GX_SWAP_VALS(cx, cy);
264
265
712
    if (context->gx_draw_context_display->gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
266
    {
267
356
        srcyres = pixelmap->gx_pixelmap_width - 1 - srcyres;
268
269
356
        ypos = context->gx_draw_context_canvas->gx_canvas_x_resolution - ypos - pixelmap->gx_pixelmap_width;
270
356
        cy = pixelmap->gx_pixelmap_width - cy - 1;
271
272
356
        rotated_clip.gx_rectangle_left = clip->gx_rectangle_top;
273
356
        rotated_clip.gx_rectangle_right = clip->gx_rectangle_bottom;
274
356
        rotated_clip.gx_rectangle_top = (GX_VALUE)(context->gx_draw_context_canvas->gx_canvas_x_resolution - 1 - clip->gx_rectangle_right);
275
356
        rotated_clip.gx_rectangle_bottom = (GX_VALUE)(context->gx_draw_context_canvas->gx_canvas_x_resolution - 1 - clip->gx_rectangle_left);
276
    }
277
    else
278
    {
279
356
        srcxres = pixelmap->gx_pixelmap_height - 1 - srcxres;
280
281
356
        xpos = context->gx_draw_context_canvas->gx_canvas_y_resolution - xpos - pixelmap->gx_pixelmap_height;
282
356
        cx = pixelmap->gx_pixelmap_height - cx - 1;
283
284
356
        rotated_clip.gx_rectangle_left = (GX_VALUE)(context->gx_draw_context_canvas->gx_canvas_y_resolution - 1 - clip->gx_rectangle_bottom);
285
356
        rotated_clip.gx_rectangle_right = (GX_VALUE)(context->gx_draw_context_canvas->gx_canvas_y_resolution - 1 - clip->gx_rectangle_top);
286
356
        rotated_clip.gx_rectangle_top = clip->gx_rectangle_left;
287
356
        rotated_clip.gx_rectangle_bottom = clip->gx_rectangle_right;
288
    }
289
290
712
    cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
291
712
    sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
292
293
712
    xres = GX_FIXED_VAL_TO_INT((mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv));
294
712
    yres = GX_FIXED_VAL_TO_INT((my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv));
295
296
712
    putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
297
712
    putrow += rotated_clip.gx_rectangle_top * context -> gx_draw_context_pitch;
298
712
    putrow += rotated_clip.gx_rectangle_left;
299
300
    /* Calculate the new rotation axis. */
301
712
    x = (cx - srcxres) * cosv - (cy - srcyres) * sinv;
302
712
    y = (cy - srcyres) * cosv + (cx - srcxres) * sinv;
303
304
712
    x = GX_FIXED_VAL_TO_INT(x) + xres;
305
712
    y = GX_FIXED_VAL_TO_INT(y) + yres;
306
307
712
    newxpos = xpos + cx - x;
308
712
    newypos = ypos + cy - y;
309
310
    /* For every pixel in destination bitmap, find its position in source bitmap,
311
       and set the pixel with the value in source bitmap.  */
312
212088
    for (y = rotated_clip.gx_rectangle_top - newypos; y <= rotated_clip.gx_rectangle_bottom - newypos; y++)
313
    {
314
211376
        put = putrow;
315
316
63219344
        for (x = rotated_clip.gx_rectangle_left - newxpos; x <= rotated_clip.gx_rectangle_right - newxpos; x++)
317
        {
318
63007968
            xx = GX_FIXED_VAL_TO_INT((x - xres) * cosv + (y - yres) * sinv);
319
63007968
            yy = GX_FIXED_VAL_TO_INT((y - yres) * cosv - (x - xres) * sinv);
320
321
63007968
            xx += srcxres;
322
63007968
            yy += srcyres;
323
324

63007968
            if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_height) &&
325
45519322
                (yy >= 0) && (yy < pixelmap -> gx_pixelmap_width))
326
            {
327
37230728
                get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
328
37230728
                get += yy * pixelmap -> gx_pixelmap_height;
329
37230728
                get += xx;
330
331
37230728
                if ((*get) != pixelmap -> gx_pixelmap_transparent_color)
332
                {
333
25899334
                    *put = *get;
334
                }
335
            }
336
63007968
            put++;
337
        }
338
211376
        putrow += context -> gx_draw_context_pitch;
339
    }
340
712
}
341
342
/**************************************************************************/
343
/*                                                                        */
344
/*  FUNCTION                                               RELEASE        */
345
/*                                                                        */
346
/*    _gx_display_driver_8bpp_rotated_pixelmap_simple_rotate              */
347
/*                                                        PORTABLE C      */
348
/*                                                           6.1.4        */
349
/*  AUTHOR                                                                */
350
/*                                                                        */
351
/*    Kenneth Maxwell, Microsoft Corporation                              */
352
/*                                                                        */
353
/*  DESCRIPTION                                                           */
354
/*                                                                        */
355
/*    Internal help function that hangles 90, 180 and 270 degree pixelmap */
356
/*    rotation.                                                           */
357
/*                                                                        */
358
/*  INPUT                                                                 */
359
/*                                                                        */
360
/*    context                               Drawing context               */
361
/*    xpos                                  x-coord of top-left draw point*/
362
/*    ypos                                  y-coord of top-left draw point*/
363
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
364
/*    angle                                 The angle to rotate           */
365
/*    cx                                    x-coord of rotate center      */
366
/*    cy                                    y-coord of rotate center      */
367
/*                                                                        */
368
/*  OUTPUT                                                                */
369
/*                                                                        */
370
/*    None                                                                */
371
/*                                                                        */
372
/*  CALLS                                                                 */
373
/*                                                                        */
374
/*    None                                                                */
375
/*                                                                        */
376
/*  CALLED BY                                                             */
377
/*                                                                        */
378
/*    _gx_display_driver_8bpp_pixelmap_rotate                             */
379
/*                                                                        */
380
/**************************************************************************/
381
6
static VOID _gx_display_driver_8bpp_rotated_pixelmap_simple_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
382
                                                           INT angle, INT cx, INT cy)
383
{
384
GX_UBYTE     *putrow;
385
GX_UBYTE     *put;
386
GX_UBYTE     *get;
387
INT           width;
388
INT           height;
389
INT           x;
390
INT           y;
391
GX_RECTANGLE *clip;
392
GX_RECTANGLE  rotated_clip;
393
INT           newxpos;
394
INT           newypos;
395
396
6
clip = context->gx_draw_context_clip;
397
398
6
GX_SWAP_VALS(xpos, ypos);
399
6
GX_SWAP_VALS(cx, cy);
400
401
6
if (context->gx_draw_context_display->gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
402
{
403
3
    ypos = context->gx_draw_context_canvas->gx_canvas_x_resolution - ypos - pixelmap->gx_pixelmap_width;
404
3
    cy = pixelmap->gx_pixelmap_width - cy - 1;
405
406
3
    rotated_clip.gx_rectangle_left = clip->gx_rectangle_top;
407
3
    rotated_clip.gx_rectangle_right = clip->gx_rectangle_bottom;
408
3
    rotated_clip.gx_rectangle_top = (GX_VALUE)(context->gx_draw_context_canvas->gx_canvas_x_resolution - 1 - clip->gx_rectangle_right);
409
3
    rotated_clip.gx_rectangle_bottom = (GX_VALUE)(context->gx_draw_context_canvas->gx_canvas_x_resolution - 1 - clip->gx_rectangle_left);
410
}
411
else
412
{
413
3
    xpos = context->gx_draw_context_canvas->gx_canvas_y_resolution - xpos - pixelmap->gx_pixelmap_height;
414
3
    cx = pixelmap->gx_pixelmap_height - cx - 1;
415
416
3
    rotated_clip.gx_rectangle_left = (GX_VALUE)(context->gx_draw_context_canvas->gx_canvas_y_resolution - 1 - clip->gx_rectangle_bottom);
417
3
    rotated_clip.gx_rectangle_right = (GX_VALUE)(context->gx_draw_context_canvas->gx_canvas_y_resolution - 1 - clip->gx_rectangle_top);
418
3
    rotated_clip.gx_rectangle_top = clip->gx_rectangle_left;
419
3
    rotated_clip.gx_rectangle_bottom = clip->gx_rectangle_right;
420
}
421
422
6
    if (angle == 90)
423
    {
424
2
        width = pixelmap -> gx_pixelmap_width;
425
2
        height = pixelmap -> gx_pixelmap_height;
426
427
2
        newxpos = xpos + cx - (width - 1 - cy);
428
2
        newypos = ypos + cy - cx;
429
430
2
        putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
431
2
        putrow += rotated_clip.gx_rectangle_top * context -> gx_draw_context_pitch;
432
2
        putrow += rotated_clip.gx_rectangle_left;
433
434
254
        for (y = rotated_clip.gx_rectangle_top - newypos; y <= rotated_clip.gx_rectangle_bottom - newypos; y++)
435
        {
436
252
            put = putrow;
437
438
60732
            for (x = rotated_clip.gx_rectangle_left - newxpos; x <= rotated_clip.gx_rectangle_right - newxpos; x++)
439
            {
440
60480
                get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
441
60480
                get += (width - 1 - x) * height;
442
60480
                get += y;
443
444
60480
                *put++ = *get;
445
            }
446
447
252
            putrow += context -> gx_draw_context_pitch;
448
        }
449
    }
450
4
    else if (angle == 180)
451
    {
452
453
2
        width = pixelmap -> gx_pixelmap_height;
454
2
        height = pixelmap -> gx_pixelmap_width;
455
456
2
        newxpos = xpos + cx - (width - 1 - cx);
457
2
        newypos = ypos + cy - (height - 1 - cy);
458
459
2
        putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
460
2
        putrow += rotated_clip.gx_rectangle_top * context -> gx_draw_context_pitch;
461
2
        putrow += rotated_clip.gx_rectangle_left;
462
463
482
        for (y = rotated_clip.gx_rectangle_top - newypos; y <= rotated_clip.gx_rectangle_bottom - newypos; y++)
464
        {
465
480
            put = putrow;
466
60960
            for (x = rotated_clip.gx_rectangle_left - newxpos; x <= rotated_clip.gx_rectangle_right - newxpos; x++)
467
            {
468
60480
                get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
469
60480
                get += (height - 1 - y) * width;
470
60480
                get += width - 1 - x;
471
472
60480
                *put++ = *get;
473
            }
474
475
480
            putrow += context -> gx_draw_context_pitch;
476
        }
477
    }
478
    else
479
    {
480
2
        height = pixelmap -> gx_pixelmap_height;
481
482
2
        newxpos = xpos + cx - cy;
483
2
        newypos = ypos + cx - (height - 1 - cy);
484
485
2
        putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
486
2
        putrow += rotated_clip.gx_rectangle_top * context -> gx_draw_context_pitch;
487
2
        putrow += rotated_clip.gx_rectangle_left;
488
489
254
        for (y = rotated_clip.gx_rectangle_top - newypos; y <= rotated_clip.gx_rectangle_bottom - newypos; y++)
490
        {
491
252
            put = putrow;
492
493
60732
            for (x = rotated_clip.gx_rectangle_left - newxpos; x <= rotated_clip.gx_rectangle_right - newxpos; x++)
494
            {
495
60480
                get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
496
60480
                get += x * height;
497
60480
                get += height - 1 - y;
498
499
60480
                *put++ = *get;
500
            }
501
502
252
            putrow += context -> gx_draw_context_pitch;
503
        }
504
    }
505
6
}
506
507
/**************************************************************************/
508
/*                                                                        */
509
/*  FUNCTION                                               RELEASE        */
510
/*                                                                        */
511
/*    _gx_display_driver_8bpp_rotated_pixelmap_simple_transparent_rotate  */
512
/*                                                        PORTABLE C      */
513
/*                                                           6.1.4        */
514
/*  AUTHOR                                                                */
515
/*                                                                        */
516
/*    Kenneth Maxwell, Microsoft Corporation                              */
517
/*                                                                        */
518
/*  DESCRIPTION                                                           */
519
/*                                                                        */
520
/*    Internal help function that hangles 90, 180 and 270 degree pixelmap */
521
/*    rotation.                                                           */
522
/*                                                                        */
523
/*  INPUT                                                                 */
524
/*                                                                        */
525
/*    context                               Drawing context               */
526
/*    xpos                                  x-coord of top-left draw point*/
527
/*    ypos                                  y-coord of top-left draw point*/
528
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
529
/*    angle                                 The angle to rotate           */
530
/*    cx                                    x-coord of rotate center      */
531
/*    cy                                    y-coord of rotate center      */
532
/*                                                                        */
533
/*  OUTPUT                                                                */
534
/*                                                                        */
535
/*    None                                                                */
536
/*                                                                        */
537
/*  CALLS                                                                 */
538
/*                                                                        */
539
/*    None                                                                */
540
/*                                                                        */
541
/*  CALLED BY                                                             */
542
/*                                                                        */
543
/*    _gx_display_driver_8bpp_pixelmap_rotate                             */
544
/*                                                                        */
545
/**************************************************************************/
546
6
static VOID _gx_display_driver_8bpp_rotated_pixelmap_simple_transparent_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
547
                                                                       INT angle, INT cx, INT cy)
548
{
549
GX_UBYTE     *putrow;
550
GX_UBYTE     *put;
551
GX_UBYTE     *get;
552
INT           width;
553
INT           height;
554
INT           x;
555
INT           y;
556
GX_RECTANGLE *clip;
557
GX_RECTANGLE  rotated_clip;
558
INT           newxpos;
559
INT           newypos;
560
561
6
    clip = context -> gx_draw_context_clip;
562
563
6
    GX_SWAP_VALS(xpos, ypos);
564
6
    GX_SWAP_VALS(cx, cy);
565
566
6
    if (context->gx_draw_context_display->gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
567
    {
568
3
        ypos = context->gx_draw_context_canvas->gx_canvas_x_resolution - ypos - pixelmap->gx_pixelmap_width;
569
3
        cy = pixelmap->gx_pixelmap_width - cy - 1;
570
571
3
        rotated_clip.gx_rectangle_left = clip->gx_rectangle_top;
572
3
        rotated_clip.gx_rectangle_right = clip->gx_rectangle_bottom;
573
3
        rotated_clip.gx_rectangle_top = (GX_VALUE)(context->gx_draw_context_canvas->gx_canvas_x_resolution - 1 - clip->gx_rectangle_right);
574
3
        rotated_clip.gx_rectangle_bottom = (GX_VALUE)(context->gx_draw_context_canvas->gx_canvas_x_resolution - 1 - clip->gx_rectangle_left);
575
    }
576
    else
577
    {
578
3
        xpos = context->gx_draw_context_canvas->gx_canvas_y_resolution - xpos - pixelmap->gx_pixelmap_height;
579
3
        cx = pixelmap->gx_pixelmap_height - cx - 1;
580
581
3
        rotated_clip.gx_rectangle_left = (GX_VALUE)(context->gx_draw_context_canvas->gx_canvas_y_resolution - 1 - clip->gx_rectangle_bottom);
582
3
        rotated_clip.gx_rectangle_right = (GX_VALUE)(context->gx_draw_context_canvas->gx_canvas_y_resolution - 1 - clip->gx_rectangle_top);
583
3
        rotated_clip.gx_rectangle_top = clip->gx_rectangle_left;
584
3
        rotated_clip.gx_rectangle_bottom = clip->gx_rectangle_right;
585
    }
586
587
6
    if (angle == 90)
588
    {
589
2
        width = pixelmap -> gx_pixelmap_width;
590
2
        height = pixelmap -> gx_pixelmap_height;
591
592
2
        newxpos = xpos + cx - (width - 1 - cy);
593
2
        newypos = ypos + cy - cx;
594
595
2
        putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
596
2
        putrow += rotated_clip.gx_rectangle_top * context -> gx_draw_context_pitch;
597
2
        putrow += rotated_clip.gx_rectangle_left;
598
599
536
        for (y = rotated_clip.gx_rectangle_top - newypos; y <= rotated_clip.gx_rectangle_bottom - newypos; y++)
600
        {
601
534
            put = putrow;
602
603
104664
            for (x = rotated_clip.gx_rectangle_left - newxpos; x <= rotated_clip.gx_rectangle_right - newxpos; x++)
604
            {
605
104130
                get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
606
104130
                get += (width - 1 - x) * height;
607
104130
                get += y;
608
609
104130
                if ((*get) != pixelmap -> gx_pixelmap_transparent_color)
610
                {
611
72436
                    *put = *get;
612
                }
613
104130
                put++;
614
            }
615
534
            putrow += context -> gx_draw_context_pitch;
616
        }
617
    }
618
4
    else if (angle == 180)
619
    {
620
621
2
        width = pixelmap -> gx_pixelmap_height;
622
2
        height = pixelmap -> gx_pixelmap_width;
623
624
2
        newxpos = xpos + cx - (width - 1 - cx);
625
2
        newypos = ypos + cy - (height - 1 - cy);
626
627
2
        putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
628
2
        putrow += rotated_clip.gx_rectangle_top * context -> gx_draw_context_pitch;
629
2
        putrow += rotated_clip.gx_rectangle_left;
630
631
392
        for (y = rotated_clip.gx_rectangle_top - newypos; y <= rotated_clip.gx_rectangle_bottom - newypos; y++)
632
        {
633
390
            put = putrow;
634
104520
            for (x = rotated_clip.gx_rectangle_left - newxpos; x <= rotated_clip.gx_rectangle_right - newxpos; x++)
635
            {
636
104130
                get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
637
104130
                get += (height - 1 - y) * width;
638
104130
                get += width - 1 - x;
639
640
104130
                if ((*get) != pixelmap -> gx_pixelmap_transparent_color)
641
                {
642
72436
                    *put = *get;
643
                }
644
104130
                put++;
645
            }
646
647
390
            putrow += context -> gx_draw_context_pitch;
648
        }
649
    }
650
    else
651
    {
652
2
        height = pixelmap -> gx_pixelmap_height;
653
654
2
        newxpos = xpos + cx - cy;
655
2
        newypos = ypos + cx - (height - 1 - cy);
656
657
2
        putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
658
2
        putrow += rotated_clip.gx_rectangle_top * context -> gx_draw_context_pitch;
659
2
        putrow += rotated_clip.gx_rectangle_left;
660
661
536
        for (y = rotated_clip.gx_rectangle_top - newypos; y <= rotated_clip.gx_rectangle_bottom - newypos; y++)
662
        {
663
534
            put = putrow;
664
665
104664
            for (x = rotated_clip.gx_rectangle_left - newxpos; x <= rotated_clip.gx_rectangle_right - newxpos; x++)
666
            {
667
104130
                get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
668
104130
                get += x * height;
669
104130
                get += height - 1 - y;
670
671
104130
                if ((*get) != pixelmap -> gx_pixelmap_transparent_color)
672
                {
673
72436
                    *put = *get;
674
                }
675
104130
                put++;
676
            }
677
678
534
            putrow += context -> gx_draw_context_pitch;
679
        }
680
    }
681
6
}
682
683
/**************************************************************************/
684
/*                                                                        */
685
/*  FUNCTION                                               RELEASE        */
686
/*                                                                        */
687
/*    _gx_display_driver_8bpp_rotated_pixelmap_rotate     PORTABLE C      */
688
/*                                                           6.1.4        */
689
/*  AUTHOR                                                                */
690
/*                                                                        */
691
/*    Kenneth Maxwell, Microsoft Corporation                              */
692
/*                                                                        */
693
/*  DESCRIPTION                                                           */
694
/*                                                                        */
695
/*    This service rotate a pixelmap directly to canvas memory.           */
696
/*                                                                        */
697
/*  INPUT                                                                 */
698
/*                                                                        */
699
/*    context                               Drawing context               */
700
/*    xpos                                  x-coord of top-left draw point*/
701
/*    ypos                                  y-coord of top-left draw point*/
702
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
703
/*    angle                                 The angle to rotate           */
704
/*    rot_cx                                x-coord of rotating center.   */
705
/*    rot_cy                                y-coord of rotationg center.  */
706
/*                                                                        */
707
/*  OUTPUT                                                                */
708
/*                                                                        */
709
/*    status                                Completion status             */
710
/*                                                                        */
711
/*  CALLS                                                                 */
712
/*                                                                        */
713
/*    _gx_display_driver_8bpp_rotated_pixelmap_simple_transparent_rotate  */
714
/*    _gx_display_driver_8bpp_rotated_pixelmap_simple_rotate              */
715
/*    _gx_display_driver_8bpp_rotated_pixelmap_transparent_rotate         */
716
/*    _gx_display_driver_8bpp_rotated_pixelmap_raw_rotate                 */
717
/*                                                                        */
718
/*  CALLED BY                                                             */
719
/*                                                                        */
720
/*    Application Code                                                    */
721
/*    GUIX Internal Code                                                  */
722
/*                                                                        */
723
/**************************************************************************/
724
1436
VOID _gx_display_driver_8bpp_rotated_pixelmap_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
725
                                             INT angle, INT rot_cx, INT rot_cy)
726
{
727
1436
    if (angle % 90 == 0)
728
    {
729
        /* Simple angle rotate: 90 degree, 180 degree and 270 degree.  */
730
12
        if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_TRANSPARENT)
731
        {
732
6
            _gx_display_driver_8bpp_rotated_pixelmap_simple_transparent_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
733
        }
734
        else
735
        {
736
6
            _gx_display_driver_8bpp_rotated_pixelmap_simple_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
737
        }
738
    }
739
    else
740
    {
741
1424
        if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_TRANSPARENT)
742
        {
743
            /* no compression or alpha */
744
712
            _gx_display_driver_8bpp_rotated_pixelmap_transparent_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
745
        }
746
        else
747
        {
748
            /* no compression or alpha */
749
712
            _gx_display_driver_8bpp_rotated_pixelmap_raw_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
750
        }
751
    }
752
753
1436
    return;
754
}
755