GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_8bpp_rotated_pixelmap_rotate.c Lines: 254 254 100.0 %
Date: 2024-12-05 08:52:37 Branches: 78 78 100.0 %

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

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

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