GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_1bpp_pixelmap_rotate.c Lines: 242 242 100.0 %
Date: 2024-12-05 08:52:37 Branches: 102 102 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_1bpp_pixelmap_raw_rotate         PORTABLE C      */
35
/*                                                           6.1.10       */
36
/*  AUTHOR                                                                */
37
/*                                                                        */
38
/*    Kenneth Maxwell, Microsoft Corporation                              */
39
/*                                                                        */
40
/*  DESCRIPTION                                                           */
41
/*                                                                        */
42
/*    Internal helper function that rotates an uncompressed pixelmap      */
43
/*      without transparency.                                             */
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
/*    status                                Completion status             */
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_1bpp_pixelmap_rotate                             */
67
/*                                                                        */
68
/*  RELEASE HISTORY                                                       */
69
/*                                                                        */
70
/*    DATE              NAME                      DESCRIPTION             */
71
/*                                                                        */
72
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
73
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
74
/*                                            resulting in version 6.1    */
75
/*  01-31-2022     Ting Zhu                 Modified comment(s),          */
76
/*                                            corrected logic,            */
77
/*                                            resulting in version 6.1.10 */
78
/*                                                                        */
79
/**************************************************************************/
80
712
static VOID _gx_display_driver_1bpp_pixelmap_raw_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
81
                                                        INT angle, INT cx, INT cy)
82
{
83
GX_UBYTE     *putrow;
84
GX_UBYTE     *put;
85
GX_UBYTE     *get;
86
INT           srcxres;
87
INT           srcyres;
88
INT           cosv;
89
INT           sinv;
90
INT           idxminx;
91
INT           idxmaxx;
92
INT           idxmaxy;
93
712
INT           mx[] = {-1, 1, 1, -1};
94
712
INT           my[] = {1, 1, -1, -1};
95
INT           xres;
96
INT           yres;
97
INT           x;
98
INT           y;
99
INT           xx;
100
INT           yy;
101
GX_RECTANGLE *clip;
102
INT           newxpos;
103
INT           newypos;
104
GX_UBYTE      putmask;
105
GX_UBYTE      getmask;
106
INT           putstride;
107
INT           getstride;
108
109
712
    clip = context -> gx_draw_context_clip;
110
111
    /* Set transparent color.  */
112
712
    idxminx = (angle / 90) & 0x3;
113
712
    idxmaxx = (idxminx + 2) & 0x3;
114
712
    idxmaxy = (idxminx + 1) & 0x3;
115
116
    /* Calculate the source x and y center. */
117
712
    srcxres = pixelmap -> gx_pixelmap_width >> 1;
118
712
    srcyres = pixelmap -> gx_pixelmap_height >> 1;
119
120
712
    cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
121
712
    sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
122
123
712
    xres = GX_FIXED_VAL_TO_INT((int)(mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv));
124
712
    yres = GX_FIXED_VAL_TO_INT((int)(my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv));
125
126
712
    getstride = (pixelmap -> gx_pixelmap_width + 7) >> 3;
127
712
    putstride = (context -> gx_draw_context_pitch + 7) >> 3;
128
712
    putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
129
712
    putrow += clip -> gx_rectangle_top * putstride;
130
712
    putrow += clip -> gx_rectangle_left >> 3;
131
132
    /* Calculate the new rotation axis. */
133
712
    xres = GX_FIXED_VAL_TO_INT((cx - srcxres) * cosv - (cy - srcyres) * sinv) + xres;
134
712
    yres = GX_FIXED_VAL_TO_INT((cy - srcyres) * cosv + (cx - srcxres) * sinv) + yres;
135
136
712
    newxpos = xpos + cx - xres;
137
712
    newypos = ypos + cy - yres;
138
139
    /* For every pixel in destination bitmap, find its position in source bitmap,
140
       and set the pixel with the value in source bitmap.  */
141
150359
    for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
142
    {
143
149647
        put = putrow;
144
149647
        putmask = (GX_UBYTE)(0x80 >> (clip -> gx_rectangle_left & 0x07));
145
146
34447700
        for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
147
        {
148
34298053
            xx = (x - xres) * cosv + (y - yres) * sinv;
149
34298053
            yy = (y - yres) * cosv - (x - xres) * sinv;
150
151
34298053
            xx = GX_FIXED_VAL_TO_INT(xx) + cx;
152
34298053
            yy = GX_FIXED_VAL_TO_INT(yy) + cy;
153
154

34298053
            if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_width) &&
155
25557400
                (yy >= 0) && (yy < pixelmap -> gx_pixelmap_height))
156
            {
157
19177278
                get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
158
19177278
                get += yy * getstride;
159
19177278
                get += xx >> 3;
160
19177278
                getmask = (GX_UBYTE)(0x80 >> (xx & 0x07));
161
162
19177278
                if ((*get) & getmask)
163
                {
164
8254568
                    *put |= putmask;
165
                }
166
                else
167
                {
168
10922710
                    *put = (GX_UBYTE)(*put & (~putmask));
169
                }
170
            }
171
172
34298053
            putmask >>= 1;
173
34298053
            if (putmask == 0)
174
            {
175
4289770
                put++;
176
4289770
                putmask = 0x80;
177
            }
178
        }
179
149647
        putrow += putstride;
180
    }
181
712
}
182
183
/**************************************************************************/
184
/*                                                                        */
185
/*  FUNCTION                                               RELEASE        */
186
/*                                                                        */
187
/*    _gx_display_driver_1bpp_pixelmap_transparent_rotate PORTABLE C      */
188
/*                                                           6.1.10       */
189
/*  AUTHOR                                                                */
190
/*                                                                        */
191
/*    Kenneth Maxwell, Microsoft Corporation                              */
192
/*                                                                        */
193
/*  DESCRIPTION                                                           */
194
/*                                                                        */
195
/*    Internal helper function that rotate an uncompressed pixelmap       */
196
/*      with transparent info.                                            */
197
/*                                                                        */
198
/*  INPUT                                                                 */
199
/*                                                                        */
200
/*    context                               Drawing context               */
201
/*    xpos                                  x-coord of top-left draw point*/
202
/*    ypos                                  y-coord of top-left draw point*/
203
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
204
/*    angle                                 The angle to rotate           */
205
/*    rot_cx                                x-coord of rotate center      */
206
/*    rot_cy                                y-coord of rotate center      */
207
/*                                                                        */
208
/*  OUTPUT                                                                */
209
/*                                                                        */
210
/*    status                                Completion status             */
211
/*                                                                        */
212
/*  CALLS                                                                 */
213
/*                                                                        */
214
/*    _gx_utility_math_cos                  Compute the cosine value      */
215
/*    _gx_utility_math_sin                  Compute the sine value        */
216
/*                                                                        */
217
/*  CALLED BY                                                             */
218
/*                                                                        */
219
/*    _gx_display_driver_1bpp_pixelmap_rotate                             */
220
/*                                                                        */
221
/*  RELEASE HISTORY                                                       */
222
/*                                                                        */
223
/*    DATE              NAME                      DESCRIPTION             */
224
/*                                                                        */
225
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
226
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
227
/*                                            resulting in version 6.1    */
228
/*  01-31-2022     Ting Zhu                 Modified comment(s),          */
229
/*                                            corrected logic,            */
230
/*                                            resulting in version 6.1.10 */
231
/*                                                                        */
232
/**************************************************************************/
233
712
static VOID _gx_display_driver_1bpp_pixelmap_transparent_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
234
                                                                INT angle, INT cx, INT cy)
235
{
236
GX_UBYTE     *putrow;
237
GX_UBYTE     *put;
238
GX_UBYTE     *get;
239
GX_UBYTE      putmask;
240
GX_UBYTE      transmask;
241
GX_UBYTE      getmask;
242
INT           putstride;
243
INT           getstride;
244
INT           srcxres;
245
INT           srcyres;
246
INT           cosv;
247
INT           sinv;
248
INT           idxminx;
249
INT           idxmaxx;
250
INT           idxmaxy;
251
712
INT           mx[] = {-1, 1, 1, -1};
252
712
INT           my[] = {1, 1, -1, -1};
253
INT           xres;
254
INT           yres;
255
INT           x;
256
INT           y;
257
INT           xx;
258
INT           yy;
259
GX_RECTANGLE *clip;
260
INT           newxpos;
261
INT           newypos;
262
263
712
    clip = context -> gx_draw_context_clip;
264
712
    putstride = (context -> gx_draw_context_pitch + 7) >> 3;
265
712
    getstride = (pixelmap -> gx_pixelmap_width + 3) >> 2;
266
267
    /* Set transparent color.  */
268
712
    idxminx = (angle / 90) & 0x3;
269
712
    idxmaxx = (idxminx + 2) & 0x3;
270
712
    idxmaxy = (idxminx + 1) & 0x3;
271
272
    /* Calculate the source x and y center. */
273
712
    srcxres = pixelmap -> gx_pixelmap_width >> 1;
274
712
    srcyres = pixelmap -> gx_pixelmap_height >> 1;
275
276
712
    cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
277
712
    sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
278
279
712
    xres = GX_FIXED_VAL_TO_INT((mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv));
280
712
    yres = GX_FIXED_VAL_TO_INT((my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv));
281
282
712
    putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
283
712
    putrow += clip -> gx_rectangle_top * putstride;
284
712
    putrow += clip -> gx_rectangle_left >> 3;
285
286
    /* Calculate the new rotation axis. */
287
712
    xres = GX_FIXED_VAL_TO_INT((cx - srcxres) * cosv - (cy - srcyres) * sinv) + xres;
288
712
    yres = GX_FIXED_VAL_TO_INT((cy - srcyres) * cosv + (cx - srcxres) * sinv) + yres;
289
290
712
    newxpos = xpos + cx - xres;
291
712
    newypos = ypos + cy - yres;
292
293
    /* For every pixel in destination bitmap, find its position in source bitmap,
294
       and set the pixel with the value in source bitmap.  */
295
166948
    for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
296
    {
297
166236
        put = putrow;
298
166236
        putmask = (GX_UBYTE)(0x80 >> (clip -> gx_rectangle_left & 0x07));
299
300
44643251
        for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
301
        {
302
44477015
            xx = GX_FIXED_VAL_TO_INT((x - xres) * cosv + (y - yres) * sinv) + cx;
303
44477015
            yy = GX_FIXED_VAL_TO_INT((y - yres) * cosv - (x - xres) * sinv) + cy;
304
305

44477015
            if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_width) &&
306
30360721
                (yy >= 0) && (yy < pixelmap -> gx_pixelmap_height))
307
            {
308
26410992
                get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
309
26410992
                get += yy * getstride;
310
26410992
                get += xx >> 2;
311
312
26410992
                transmask = (GX_UBYTE)(0x40 >> ((xx & 0x03) << 1));
313
26410992
                if (transmask & (*get))
314
                {
315
16141951
                    getmask = (GX_UBYTE)(transmask << 1);
316
16141951
                    if ((*get) & getmask)
317
                    {
318
5988038
                        *put |= putmask;
319
                    }
320
                    else
321
                    {
322
10153913
                        *put = (GX_UBYTE)(*put & (~putmask));
323
                    }
324
                }
325
            }
326
327
44477015
            putmask >>= 1;
328
44477015
            if (putmask == 0)
329
            {
330
5553005
                put++;
331
5553005
                putmask = 0x80;
332
            }
333
        }
334
166236
        putrow += putstride;
335
    }
336
712
}
337
338
/**************************************************************************/
339
/*                                                                        */
340
/*  FUNCTION                                               RELEASE        */
341
/*                                                                        */
342
/*    _gx_display_driver_1bpp_pixelmap_simple_rotate      PORTABLE C      */
343
/*                                                           6.1.7        */
344
/*  AUTHOR                                                                */
345
/*                                                                        */
346
/*    Kenneth Maxwell, Microsoft Corporation                              */
347
/*                                                                        */
348
/*  DESCRIPTION                                                           */
349
/*                                                                        */
350
/*    Internal help function that hangles 90, 180 and 270 degree pixelmap */
351
/*    rotation.                                                           */
352
/*                                                                        */
353
/*  INPUT                                                                 */
354
/*                                                                        */
355
/*    context                               Drawing context               */
356
/*    xpos                                  x-coord of top-left draw point*/
357
/*    ypos                                  y-coord of top-left draw point*/
358
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
359
/*    angle                                 The angle to rotate           */
360
/*    rot_cx                                x-coord of rotate center      */
361
/*    rot_cy                                y-coord of rotate center      */
362
/*                                                                        */
363
/*  OUTPUT                                                                */
364
/*                                                                        */
365
/*    status                                Completion status             */
366
/*                                                                        */
367
/*  CALLS                                                                 */
368
/*                                                                        */
369
/*    None                                                                */
370
/*                                                                        */
371
/*  CALLED BY                                                             */
372
/*                                                                        */
373
/*    _gx_display_driver_1bpp_pixelmap_rotate                             */
374
/*                                                                        */
375
/*  RELEASE HISTORY                                                       */
376
/*                                                                        */
377
/*    DATE              NAME                      DESCRIPTION             */
378
/*                                                                        */
379
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
380
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
381
/*                                            resulting in version 6.1    */
382
/*  06-02-2021     Kenneth Maxwell          Modified comment(s),          */
383
/*                                            removed unused variable     */
384
/*                                            assignment,                 */
385
/*                                            resulting in version 6.1.7  */
386
/*                                                                        */
387
/**************************************************************************/
388
6
static VOID _gx_display_driver_1bpp_pixelmap_simple_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
389
                                                           INT angle, INT cx, INT cy)
390
{
391
GX_UBYTE     *putrow;
392
GX_UBYTE     *put;
393
GX_UBYTE      putmask;
394
GX_UBYTE     *get;
395
GX_UBYTE      getmask;
396
INT           putstride;
397
INT           width;
398
INT           height;
399
INT           x;
400
INT           y;
401
GX_RECTANGLE *clip;
402
INT           newxpos;
403
INT           newypos;
404
405
6
    clip = context -> gx_draw_context_clip;
406
6
    putstride = (context -> gx_draw_context_pitch + 7) >> 3;
407
408
6
    putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
409
6
    putrow += clip -> gx_rectangle_top * putstride;
410
6
    putrow += clip -> gx_rectangle_left >> 3;
411
412
6
    if (angle == 90)
413
    {
414
2
        width = pixelmap -> gx_pixelmap_height;
415
2
        height = (pixelmap -> gx_pixelmap_width + 7) >> 3;
416
417
2
        newxpos = xpos + cx - (width - 1 - cy);
418
2
        newypos = ypos + cy - cx;
419
420
473
        for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
421
        {
422
471
            put = putrow;
423
471
            putmask = (GX_UBYTE)(0x80 >> (clip -> gx_rectangle_left & 0x07));
424
425
59817
            for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
426
            {
427
59346
                get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
428
59346
                get += (width - 1 - x) * height;
429
59346
                get += y >> 3;
430
431
59346
                getmask = (GX_UBYTE)(0x80 >> (y & 0x07));
432
433
59346
                if ((*get) & getmask)
434
                {
435
25869
                    *put |= putmask;
436
                }
437
                else
438
                {
439
33477
                    *put = (GX_UBYTE)(*put & (~putmask));
440
                }
441
442
59346
                putmask >>= 1;
443
59346
                if (putmask == 0)
444
                {
445
7536
                    putmask = 0x80;
446
7536
                    put++;
447
                }
448
            }
449
471
            putrow += putstride;
450
        }
451
    }
452
4
    else if (angle == 180)
453
    {
454
2
        width = pixelmap -> gx_pixelmap_width;
455
2
        height = pixelmap -> gx_pixelmap_height;
456
457
2
        newxpos = xpos + cx - (width - 1 - cx);
458
2
        newypos = ypos + cy - (height - 1 - cy);
459
460
235
        for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
461
        {
462
233
            putmask = (GX_UBYTE)(0x80 >> (clip -> gx_rectangle_left & 0x07));
463
233
            put = putrow;
464
465
51552
            for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
466
            {
467
51319
                get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
468
51319
                get += (height - 1 - y) * ((width + 7) >> 3);
469
51319
                get += (width - 1 - x) >> 3;
470
471
51319
                getmask = (GX_UBYTE)(0x80 >> ((width - 1 - x) & 0x07));
472
473
51319
                if ((*get) & getmask)
474
                {
475
22704
                    *put |= putmask;
476
                }
477
                else
478
                {
479
28615
                    *put = (GX_UBYTE)(*put & (~putmask));
480
                }
481
482
51319
                putmask >>= 1;
483
51319
                if (putmask == 0)
484
                {
485
6455
                    putmask = 0x80;
486
6455
                    put++;
487
                }
488
            }
489
233
            putrow += putstride;
490
        }
491
    }
492
    else
493
    {
494
2
        height = pixelmap -> gx_pixelmap_width;
495
496
2
        newxpos = xpos + cx - cy;
497
2
        newypos = ypos + cx - (height - 1 - cy);
498
499
349
        for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
500
        {
501
347
            putmask = (GX_UBYTE)(0x80 >> (clip -> gx_rectangle_left & 0x07));
502
347
            put = putrow;
503
504
44069
            for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
505
            {
506
43722
                get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
507
43722
                get += x * ((height + 7) >> 3);
508
43722
                get += (height - 1 - y) >> 3;
509
510
43722
                getmask = (GX_UBYTE)(0x80 >> ((height - 1 - y) & 0x07));
511
512
43722
                if ((*get) & getmask)
513
                {
514
17931
                    *put |= putmask;
515
                }
516
                else
517
                {
518
25791
                    *put = (GX_UBYTE)(*put & (~putmask));
519
                }
520
521
43722
                putmask >>= 1;
522
43722
                if (putmask == 0)
523
                {
524
5312
                    putmask = 0x80;
525
5312
                    put++;
526
                }
527
            }
528
529
347
            putrow += putstride;
530
        }
531
    }
532
6
}
533
/**************************************************************************/
534
/*                                                                        */
535
/*  FUNCTION                                               RELEASE        */
536
/*                                                                        */
537
/*    _gx_display_driver_1bpp_pixelmap_simple_transparent_rotate          */
538
/*                                                        PORTABLE C      */
539
/*                                                           6.1.7        */
540
/*  AUTHOR                                                                */
541
/*                                                                        */
542
/*    Kenneth Maxwell, Microsoft Corporation                              */
543
/*                                                                        */
544
/*  DESCRIPTION                                                           */
545
/*                                                                        */
546
/*    Internal help function that hangles 90, 180 and 270 degree pixelmap */
547
/*    rotation.                                                           */
548
/*                                                                        */
549
/*  INPUT                                                                 */
550
/*                                                                        */
551
/*    context                               Drawing context               */
552
/*    xpos                                  x-coord of top-left draw point*/
553
/*    ypos                                  y-coord of top-left draw point*/
554
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
555
/*    angle                                 The angle to rotate           */
556
/*    rot_cx                                x-coord of rotate center      */
557
/*    rot_cy                                y-coord of rotate center      */
558
/*                                                                        */
559
/*  OUTPUT                                                                */
560
/*                                                                        */
561
/*    status                                Completion status             */
562
/*                                                                        */
563
/*  CALLS                                                                 */
564
/*                                                                        */
565
/*    None                                                                */
566
/*                                                                        */
567
/*  CALLED BY                                                             */
568
/*                                                                        */
569
/*    _gx_display_driver_1bpp_pixelmap_rotate                             */
570
/*                                                                        */
571
/*  RELEASE HISTORY                                                       */
572
/*                                                                        */
573
/*    DATE              NAME                      DESCRIPTION             */
574
/*                                                                        */
575
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
576
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
577
/*                                            resulting in version 6.1    */
578
/*  06-02-2021     Kenneth Maxwell          Modified comment(s),          */
579
/*                                            removed unused variable     */
580
/*                                            assignment,                 */
581
/*                                            resulting in version 6.1.7  */
582
/*                                                                        */
583
/**************************************************************************/
584
6
static VOID _gx_display_driver_1bpp_pixelmap_simple_transparent_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
585
                                                                       INT angle, INT cx, INT cy)
586
{
587
GX_UBYTE     *get;
588
INT           width;
589
INT           height;
590
INT           x;
591
INT           y;
592
GX_RECTANGLE *clip;
593
INT           newxpos;
594
INT           newypos;
595
GX_UBYTE     *put;
596
GX_UBYTE     *putrow;
597
INT           putstride;
598
GX_UBYTE      putmask;
599
INT           getstride;
600
GX_UBYTE      transmask;
601
GX_UBYTE      getmask;
602
603
6
    clip = context -> gx_draw_context_clip;
604
    /* 1bpp transparent pixelmap is stored as one bit color, one bit trans-mask. */
605
6
    getstride = (pixelmap -> gx_pixelmap_width + 3) >> 2;
606
6
    putstride = (context -> gx_draw_context_pitch + 7) >> 3;
607
6
    putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
608
6
    putrow += clip -> gx_rectangle_top * putstride;
609
6
    putrow += clip -> gx_rectangle_left >> 3;
610
611
6
    clip = context -> gx_draw_context_clip;
612
613
6
    if (angle == 90)
614
    {
615
2
        width = pixelmap -> gx_pixelmap_height;
616
617
2
        newxpos = xpos + cx - (width - 1 - cy);
618
2
        newypos = ypos + cy - cx;
619
620
377
        for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
621
        {
622
375
            put = putrow;
623
375
            putmask = (GX_UBYTE)(0x80 >> (clip -> gx_rectangle_left & 0x07));
624
625
375
            transmask = (GX_UBYTE)(0x40 >> ((y & 0x03) << 1));
626
375
            getmask = (GX_UBYTE)(transmask << 1);
627
628
79260
            for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
629
            {
630
78885
                get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
631
78885
                get += (width - 1 - x) * getstride;
632
78885
                get += y >> 2;
633
634
                /* if not transparent, draw pixel. else skip. */
635
78885
                if (transmask & *(get))
636
                {
637
46717
                    if ((*get) & getmask)
638
                    {
639
16750
                        *put |= putmask;
640
                    }
641
                    else
642
                    {
643
29967
                        *put = (GX_UBYTE)(*put & (~putmask));
644
                    }
645
                }
646
647
78885
                putmask >>= 1;
648
78885
                if (putmask == 0)
649
                {
650
9675
                    putmask = 0x80;
651
9675
                    put++;
652
                }
653
            }
654
375
            putrow += putstride;
655
        }
656
    }
657
4
    else if (angle == 180)
658
    {
659
2
        width = pixelmap -> gx_pixelmap_width;
660
2
        height = pixelmap -> gx_pixelmap_height;
661
662
2
        newxpos = xpos + cx - (width - 1 - cx);
663
2
        newypos = ypos + cy - (height - 1 - cy);
664
665
365
        for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
666
        {
667
363
            put = putrow;
668
363
            putmask = (GX_UBYTE)(0x80 >> (clip -> gx_rectangle_left & 0x07));
669
670
69708
            for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
671
            {
672
69345
                get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
673
69345
                get += (height - 1 - y) * getstride;
674
69345
                get += (width - 1 - x) >> 2;
675
676
69345
                transmask = (GX_UBYTE)(0x40 >> (((width - 1 - x) & 0x03) << 1));
677
678
                /* if not transparent, draw pixel. else skip. */
679
69345
                if (transmask & *(get))
680
                {
681
44878
                    getmask = (GX_UBYTE)(transmask << 1);
682
44878
                    if ((*get) & getmask)
683
                    {
684
16750
                        *put |= putmask;
685
                    }
686
                    else
687
                    {
688
28128
                        *put = (GX_UBYTE)(*put & (~putmask));
689
                    }
690
                }
691
692
69345
                putmask >>= 1;
693
69345
                if (putmask == 0)
694
                {
695
8787
                    putmask = 0x80;
696
8787
                    put++;
697
                }
698
            }
699
363
            putrow += putstride;
700
        }
701
    }
702
    else
703
    {
704
2
        height = pixelmap -> gx_pixelmap_width;
705
706
2
        newxpos = xpos + cx - cy;
707
2
        newypos = ypos + cy - (height - 1 - cx);
708
709
293
        for (y = clip -> gx_rectangle_top - newypos; y <= clip -> gx_rectangle_bottom - newypos; y++)
710
        {
711
291
            put = putrow;
712
291
            putmask = (GX_UBYTE)(0x80 >> (clip -> gx_rectangle_left & 0x07));
713
714
66660
            for (x = clip -> gx_rectangle_left - newxpos; x <= clip -> gx_rectangle_right - newxpos; x++)
715
            {
716
66369
                get = (GX_UBYTE *)pixelmap -> gx_pixelmap_data;
717
66369
                get += x * getstride;
718
66369
                get += (height - 1 - y) >> 2;
719
720
66369
                transmask = (GX_UBYTE)(0x40 >> (((height - 1 - y) & 0x03) << 1));
721
722
                /* if not transparent, draw pixel. else skip. */
723
66369
                if (transmask & *(get))
724
                {
725
42907
                    getmask = (GX_UBYTE)(transmask << 1);
726
42907
                    if ((*get) & getmask)
727
                    {
728
16750
                        *put |= putmask;
729
                    }
730
                    else
731
                    {
732
26157
                        *put = (GX_UBYTE)(*put & (~putmask));
733
                    }
734
                }
735
736
66369
                putmask >>= 1;
737
66369
                if (putmask == 0)
738
                {
739
8259
                    putmask = 0x80;
740
8259
                    put++;
741
                }
742
            }
743
291
            putrow += putstride;
744
        }
745
    }
746
6
}
747
748
/**************************************************************************/
749
/*                                                                        */
750
/*  FUNCTION                                               RELEASE        */
751
/*                                                                        */
752
/*    _gx_display_driver_1bpp_pixelmap_rotate             PORTABLE C      */
753
/*                                                           6.1          */
754
/*  AUTHOR                                                                */
755
/*                                                                        */
756
/*    Kenneth Maxwell, Microsoft Corporation                              */
757
/*                                                                        */
758
/*  DESCRIPTION                                                           */
759
/*                                                                        */
760
/*    This service rotate a monochrome format pixelmap to canvas memory.  */
761
/*                                                                        */
762
/*  INPUT                                                                 */
763
/*                                                                        */
764
/*    context                               Drawing context               */
765
/*    xpos                                  x-coord of top-left draw point*/
766
/*    ypos                                  y-coord of top-left draw point*/
767
/*    pixelmap                              Pointer to GX_PIXELMAP struct */
768
/*    angle                                 The angle to rotate           */
769
/*    rot_cx                                x-coord of rotating center.   */
770
/*    rot_cy                                y-coord of rotationg center.  */
771
/*                                                                        */
772
/*  OUTPUT                                                                */
773
/*                                                                        */
774
/*    status                                Completion status             */
775
/*                                                                        */
776
/*  CALLS                                                                 */
777
/*                                                                        */
778
/*    _gx_display_driver_1bpp_pixelmap_simple_transparent_rotate          */
779
/*                                          Real pixelmap rotate function */
780
/*                                            which rotate image for 90,  */
781
/*                                            180 and 270 degree          */
782
/*    _gx_display_driver_1bpp_pixelmap_simple_rotate                      */
783
/*                                          Real pixelmap rotate function */
784
/*                                            which rotate image for 90,  */
785
/*                                            180 and 270 degree          */
786
/*    _gx_display_driver_1bpp_pixelmap_transparent_rotate                 */
787
/*                                          Real pixelmap rotate function */
788
/*    _gx_display_driver_1bpp_pixelmap_raw_rotate                         */
789
/*                                          Real pixelmap rotate function */
790
/*                                                                        */
791
/*  CALLED BY                                                             */
792
/*                                                                        */
793
/*    Application Code                                                    */
794
/*    GUIX Internal Code                                                  */
795
/*                                                                        */
796
/*  RELEASE HISTORY                                                       */
797
/*                                                                        */
798
/*    DATE              NAME                      DESCRIPTION             */
799
/*                                                                        */
800
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
801
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
802
/*                                            resulting in version 6.1    */
803
/*                                                                        */
804
/**************************************************************************/
805
1436
VOID _gx_display_driver_1bpp_pixelmap_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
806
                                             INT angle, INT rot_cx, INT rot_cy)
807
{
808
1436
    if (angle % 90 == 0)
809
    {
810
        /* Simple angle rotate: 90 degree, 180 degree and 270 degree.  */
811
12
        if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_TRANSPARENT)
812
        {
813
6
            _gx_display_driver_1bpp_pixelmap_simple_transparent_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
814
        }
815
        else
816
        {
817
6
            _gx_display_driver_1bpp_pixelmap_simple_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
818
        }
819
    }
820
    else
821
    {
822
1424
        if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_TRANSPARENT)
823
        {
824
            /* no compression or alpha */
825
712
            _gx_display_driver_1bpp_pixelmap_transparent_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
826
        }
827
        else
828
        {
829
            /* no compression or alpha */
830
712
            _gx_display_driver_1bpp_pixelmap_raw_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
831
        }
832
    }
833
834
1436
    return;
835
}
836