1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** GUIX Component */
17 /** */
18 /** Display Management (Display) */
19 /** */
20 /**************************************************************************/
21
22 #define BYTE_RANGE(_c) _c > 255 ? 255 : _c
23
24 #define GX_SOURCE_CODE
25
26
27 /* Include necessary system files. */
28
29 #include "gx_api.h"
30 #include "gx_display.h"
31 #include "gx_context.h"
32 #include "gx_utility.h"
33 #include "gx_system.h"
34
35 /**************************************************************************/
36 /* */
37 /* FUNCTION RELEASE */
38 /* */
39 /* _gx_display_driver_32bpp_rotated_pixelmap_raw_rotate */
40 /* */
41 /* PORTABLE C */
42 /* 6.1.5 */
43 /* AUTHOR */
44 /* */
45 /* Kenneth Maxwell, Microsoft Corporation */
46 /* */
47 /* DESCRIPTION */
48 /* */
49 /* Internal helper function that rotate an rotated uncompressed */
50 /* pixelmap without alpha. */
51 /* */
52 /* INPUT */
53 /* */
54 /* context Drawing context */
55 /* xpos x-coord of top-left draw point*/
56 /* ypos y-coord of top-left draw point*/
57 /* pixelmap Pointer to GX_PIXELMAP struct */
58 /* angle The angle to rotate */
59 /* cx x-coord of rotate center */
60 /* cy y-coord of rotate center */
61 /* */
62 /* OUTPUT */
63 /* */
64 /* status Completion status */
65 /* */
66 /* CALLS */
67 /* */
68 /* _gx_utility_math_cos Compute the cosine value */
69 /* _gx_utility_math_sin Compute the sine value */
70 /* [gx_display_driver_pixel_blend] Basic display driver pixel */
71 /* blend function */
72 /* */
73 /* CALLED BY */
74 /* */
75 /* _gx_display_driver_32bpp_rotated_pixelmap_rotate */
76 /* */
77 /* RELEASE HISTORY */
78 /* */
79 /* DATE NAME DESCRIPTION */
80 /* */
81 /* 02-02-2021 Kenneth Maxwell Initial Version 6.1.4 */
82 /* 03-02-2021 Ting Zhu Modified comment(s), changed */
83 /* blend function set macro, */
84 /* resulting in version 6.1.5 */
85 /* */
86 /**************************************************************************/
_gx_display_driver_32bpp_rotated_pixelmap_raw_rotate(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,INT angle,INT cx,INT cy)87 static VOID _gx_display_driver_32bpp_rotated_pixelmap_raw_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
88 INT angle, INT cx, INT cy)
89 {
90 GX_COLOR *get;
91 INT srcxres;
92 INT srcyres;
93 INT cosv;
94 INT sinv;
95 INT alpha;
96 GX_COLOR red;
97 GX_COLOR green;
98 GX_COLOR blue;
99 INT idxminx;
100 INT idxmaxx;
101 INT idxmaxy;
102 INT *mx;
103 INT *my;
104 INT xres;
105 INT yres;
106 INT x;
107 INT y;
108 INT xx;
109 INT yy;
110 GX_COLOR a;
111 GX_COLOR b;
112 GX_COLOR c;
113 GX_COLOR d;
114 INT xdiff;
115 INT ydiff;
116 INT newxpos;
117 INT newypos;
118 GX_RECTANGLE *clip;
119 GX_RECTANGLE rotated_clip;
120 VOID (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR fcolor, GX_UBYTE alpha);
121
122 GX_SET_32BPP_BLEND_FUNCTION(blend_func, context -> gx_draw_context_display -> gx_display_color_format);
123
124 clip = context -> gx_draw_context_clip;
125
126 mx = _gx_system_scratchpad;
127 my = mx + 4;
128
129 mx[0] = mx[3] = -1;
130 mx[1] = mx[2] = 1;
131
132 my[0] = my[1] = 1;
133 my[2] = my[3] = -1;
134
135 idxminx = (angle / 90) & 0x3;
136 idxmaxx = (idxminx + 2) & 0x3;
137 idxmaxy = (idxminx + 1) & 0x3;
138
139 /* Calculate the source x and y center. */
140 srcxres = pixelmap -> gx_pixelmap_height >> 1;
141 srcyres = pixelmap -> gx_pixelmap_width >> 1;
142
143 GX_SWAP_VALS(xpos, ypos);
144 GX_SWAP_VALS(cx, cy);
145
146 if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
147 {
148 srcyres = pixelmap -> gx_pixelmap_width - 1 - srcyres;
149
150 ypos = context -> gx_draw_context_canvas -> gx_canvas_x_resolution - ypos - pixelmap -> gx_pixelmap_width;
151 cy = pixelmap -> gx_pixelmap_width - cy - 1;
152
153 rotated_clip.gx_rectangle_left = clip -> gx_rectangle_top;
154 rotated_clip.gx_rectangle_right = clip -> gx_rectangle_bottom;
155 rotated_clip.gx_rectangle_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - 1 - clip -> gx_rectangle_right);
156 rotated_clip.gx_rectangle_bottom = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - 1 - clip -> gx_rectangle_left);
157 }
158 else
159 {
160 srcxres = pixelmap -> gx_pixelmap_height - 1 - srcxres;
161
162 xpos = context -> gx_draw_context_canvas -> gx_canvas_y_resolution - xpos - pixelmap -> gx_pixelmap_height;
163 cx = pixelmap -> gx_pixelmap_height - cx - 1;
164
165 rotated_clip.gx_rectangle_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - 1 - clip -> gx_rectangle_bottom);
166 rotated_clip.gx_rectangle_right = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - 1 - clip -> gx_rectangle_top);
167 rotated_clip.gx_rectangle_top = clip -> gx_rectangle_left;
168 rotated_clip.gx_rectangle_bottom = clip -> gx_rectangle_right;
169 }
170
171 cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
172 sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
173
174 xres = mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv;
175 yres = my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv;
176
177 xres = GX_FIXED_VAL_TO_INT(xres);
178 yres = GX_FIXED_VAL_TO_INT(yres);
179
180 /* Calculate the new rotation axis. */
181
182 x = (cx - srcxres) * cosv - (cy - srcyres) * sinv;
183 y = (cy - srcyres) * cosv + (cx - srcxres) * sinv;
184
185 x = GX_FIXED_VAL_TO_INT(x) + xres;
186 y = GX_FIXED_VAL_TO_INT(y) + yres;
187
188 newxpos = xpos + cx - x;
189 newypos = ypos + cy - y;
190
191 /* Loop through the destination's pixels. */
192 for (y = rotated_clip.gx_rectangle_top - newypos; y <= rotated_clip.gx_rectangle_bottom - newypos; y++)
193 {
194 for (x = rotated_clip.gx_rectangle_left - newxpos; x <= rotated_clip.gx_rectangle_right - newxpos; x++)
195 {
196 xx = (x - xres) * cosv + (y - yres) * sinv;
197 yy = (y - yres) * cosv - (x - xres) * sinv;
198
199 xdiff = GX_FIXED_VAL_TO_INT(xx << 8) & 0xff;
200 ydiff = GX_FIXED_VAL_TO_INT(yy << 8) & 0xff;
201
202 xx = GX_FIXED_VAL_TO_INT(xx) + srcxres;
203 yy = GX_FIXED_VAL_TO_INT(yy) + srcyres;
204
205 if ((xx >= -1) && (xx < pixelmap -> gx_pixelmap_height) &&
206 (yy >= -1) && (yy < pixelmap -> gx_pixelmap_width))
207 {
208 if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_height - 1) &&
209 (yy >= 0) && (yy < pixelmap -> gx_pixelmap_width - 1))
210 {
211 get = (GX_COLOR *)pixelmap -> gx_pixelmap_data;
212 get += yy * pixelmap -> gx_pixelmap_height;
213 get += xx;
214
215 a = *get;
216 b = *(get + 1);
217 c = *(get + pixelmap -> gx_pixelmap_height);
218 d = *(get + pixelmap -> gx_pixelmap_height + 1);
219
220 alpha = 0xff;
221 }
222 else
223 {
224 get = (GX_COLOR *)pixelmap -> gx_pixelmap_data;
225
226 a = 0;
227 b = 0;
228 c = 0;
229 d = 0;
230 alpha = 0;
231
232 if (xx == -1)
233 {
234 /* Handle left edge. */
235 if (yy >= 0)
236 {
237 b = *(get + yy * pixelmap -> gx_pixelmap_height);
238 }
239
240 if (yy < pixelmap -> gx_pixelmap_width - 1)
241 {
242 d = *(get + (yy + 1) * pixelmap -> gx_pixelmap_height);
243 }
244 }
245 else if (yy == -1)
246 {
247 /* Handle top edge. */
248 c = *(get + xx);
249
250 if (xx < pixelmap -> gx_pixelmap_height - 1)
251 {
252 d = *(get + xx + 1);
253 }
254 }
255 else if (xx == pixelmap -> gx_pixelmap_height - 1)
256 {
257 /* Handle right edget. */
258 a = *(get + yy * pixelmap -> gx_pixelmap_height + xx);
259
260 if (yy < pixelmap -> gx_pixelmap_width - 1)
261 {
262 c = *(get + (yy + 1) * pixelmap -> gx_pixelmap_height + xx);
263 }
264 }
265 else
266 {
267 /* Handle bottom edge. */
268 a = *(get + yy * pixelmap -> gx_pixelmap_height + xx);
269 b = *(get + yy * pixelmap -> gx_pixelmap_height + xx + 1);
270 }
271
272 if (a)
273 {
274 alpha += (256 - xdiff) * (256 - ydiff);
275 }
276
277 if (b)
278 {
279 alpha += xdiff * (256 - ydiff);
280 }
281
282 if (c)
283 {
284 alpha += ydiff * (256 - xdiff);
285 }
286
287 if (d)
288 {
289 alpha += xdiff * ydiff;
290 }
291
292 alpha >>= 8;
293 }
294
295 red = (GX_COLOR)(REDVAL_24BPP(a) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
296 REDVAL_24BPP(b) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) + \
297 REDVAL_24BPP(c) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) + \
298 REDVAL_24BPP(d) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16;
299
300 green = (GX_COLOR)(GREENVAL_24BPP(a) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
301 GREENVAL_24BPP(b) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) + \
302 GREENVAL_24BPP(c) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) + \
303 GREENVAL_24BPP(d) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16;
304
305 blue = (GX_COLOR)(BLUEVAL_24BPP(a) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
306 BLUEVAL_24BPP(b) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) + \
307 BLUEVAL_24BPP(c) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) + \
308 BLUEVAL_24BPP(d) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16;
309
310 if ((alpha > 0) && (alpha < 0xff))
311 {
312 red = (red << 8) / (GX_COLOR)alpha;
313 green = (green << 8) / (GX_COLOR)alpha;
314 blue = (blue << 8) / (GX_COLOR)alpha;
315 }
316
317 red = BYTE_RANGE(red);
318 green = BYTE_RANGE(green);
319 blue = BYTE_RANGE(blue);
320 alpha = BYTE_RANGE(alpha);
321
322 blend_func(context, x + newxpos, y + newypos, ASSEMBLECOLOR_32ARGB((ULONG)0xff, red, green, blue), (GX_UBYTE)alpha);
323 }
324 }
325 }
326 }
327
328 /**************************************************************************/
329 /* */
330 /* FUNCTION RELEASE */
331 /* */
332 /* _gx_utility_32bppted_pixelmap_alpha_rotate PORTABLE C */
333 /* 6.1.5 */
334 /* AUTHOR */
335 /* */
336 /* Kenneth Maxwell, Microsoft Corporation */
337 /* */
338 /* DESCRIPTION */
339 /* */
340 /* Internal helper function that rotate an rotated uncompressed */
341 /* pixelmap with alpha. */
342 /* */
343 /* INPUT */
344 /* */
345 /* context Drawing context */
346 /* xpos x-coord of top-left draw point*/
347 /* ypos y-coord of top-left draw point*/
348 /* pixelmap Pointer to GX_PIXELMAP struct */
349 /* angle The angle to rotate */
350 /* cx x-coord of rotate center */
351 /* cy y-coord of rotate center */
352 /* */
353 /* OUTPUT */
354 /* */
355 /* None */
356 /* */
357 /* CALLS */
358 /* */
359 /* _gx_utility_math_cos Compute the cosine value */
360 /* _gx_utility_math_sin Compute the sine value */
361 /* [gx_display_driver_pixel_blend] Basic display driver pixel */
362 /* blend function */
363 /* */
364 /* CALLED BY */
365 /* */
366 /* _gx_display_driver_32bpp_rotated_pixelmap_rotate */
367 /* */
368 /* RELEASE HISTORY */
369 /* */
370 /* DATE NAME DESCRIPTION */
371 /* */
372 /* 02-02-2021 Kenneth Maxwell Initial Version 6.1.4 */
373 /* 03-02-2021 Ting Zhu Modified comment(s), changed */
374 /* blend function set macro, */
375 /* resulting in version 6.1.5 */
376 /* */
377 /**************************************************************************/
_gx_display_driver_32bpp_rotated_pixelmap_alpha_rotate(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,INT angle,INT cx,INT cy)378 static VOID _gx_display_driver_32bpp_rotated_pixelmap_alpha_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
379 INT angle, INT cx, INT cy)
380 {
381 GX_COLOR *get;
382 INT srcxres;
383 INT srcyres;
384 INT cosv;
385 INT sinv;
386 INT alpha;
387 GX_COLOR red;
388 GX_COLOR green;
389 GX_COLOR blue;
390 INT idxminx;
391 INT idxmaxx;
392 INT idxmaxy;
393 INT *mx;
394 INT *my;
395 INT xres;
396 INT yres;
397 INT x;
398 INT y;
399 INT xx;
400 INT yy;
401 GX_COLOR a;
402 GX_COLOR b;
403 GX_COLOR c;
404 GX_COLOR d;
405 INT xdiff;
406 INT ydiff;
407 INT newxpos;
408 INT newypos;
409 GX_RECTANGLE *clip;
410 GX_RECTANGLE rotated_clip;
411 VOID (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR fcolor, GX_UBYTE alpha);
412
413 GX_SET_32BPP_BLEND_FUNCTION(blend_func, context -> gx_draw_context_display -> gx_display_color_format);
414
415 clip = context -> gx_draw_context_clip;
416
417 mx = _gx_system_scratchpad;
418 my = mx + 4;
419
420 mx[0] = mx[3] = -1;
421 mx[1] = mx[2] = 1;
422
423 my[0] = my[1] = 1;
424 my[2] = my[3] = -1;
425
426 idxminx = (angle / 90) & 0x3;
427 idxmaxx = (idxminx + 2) & 0x3;
428 idxmaxy = (idxminx + 1) & 0x3;
429
430 /* Calculate the source x and y center. */
431 srcxres = pixelmap -> gx_pixelmap_height >> 1;
432 srcyres = pixelmap -> gx_pixelmap_width >> 1;
433
434 GX_SWAP_VALS(xpos, ypos);
435 GX_SWAP_VALS(cx, cy);
436
437 if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
438 {
439 srcyres = pixelmap -> gx_pixelmap_width - 1 - srcyres;
440
441 ypos = context -> gx_draw_context_canvas -> gx_canvas_x_resolution - ypos - pixelmap -> gx_pixelmap_width;
442 cy = pixelmap -> gx_pixelmap_width - cy - 1;
443
444 rotated_clip.gx_rectangle_left = clip -> gx_rectangle_top;
445 rotated_clip.gx_rectangle_right = clip -> gx_rectangle_bottom;
446 rotated_clip.gx_rectangle_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - 1 - clip -> gx_rectangle_right);
447 rotated_clip.gx_rectangle_bottom = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - 1 - clip -> gx_rectangle_left);
448 }
449 else
450 {
451 srcxres = pixelmap -> gx_pixelmap_height - 1 - srcxres;
452
453 xpos = context -> gx_draw_context_canvas -> gx_canvas_y_resolution - xpos - pixelmap -> gx_pixelmap_height;
454 cx = pixelmap -> gx_pixelmap_height - cx - 1;
455
456 rotated_clip.gx_rectangle_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - 1 - clip -> gx_rectangle_bottom);
457 rotated_clip.gx_rectangle_right = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - 1 - clip -> gx_rectangle_top);
458 rotated_clip.gx_rectangle_top = clip -> gx_rectangle_left;
459 rotated_clip.gx_rectangle_bottom = clip -> gx_rectangle_right;
460 }
461
462 cosv = _gx_utility_math_cos(GX_FIXED_VAL_MAKE(angle));
463 sinv = _gx_utility_math_sin(GX_FIXED_VAL_MAKE(angle));
464
465 xres = mx[idxmaxx] * (srcxres + 2) * cosv - my[idxmaxx] * (srcyres + 2) * sinv;
466 yres = my[idxmaxy] * (srcyres + 2) * cosv + mx[idxmaxy] * (srcxres + 2) * sinv;
467
468 xres = GX_FIXED_VAL_TO_INT(xres);
469 yres = GX_FIXED_VAL_TO_INT(yres);
470
471 x = GX_FIXED_VAL_TO_INT(xres) + xres;
472 y = GX_FIXED_VAL_TO_INT(yres) + yres;
473
474 newxpos = xpos + cx - x;
475 newypos = ypos + cy - y;
476
477 /* Loop through the source's pixels. */
478 for (y = rotated_clip.gx_rectangle_top - newypos; y <= rotated_clip.gx_rectangle_bottom - newypos; y++)
479 {
480 for (x = rotated_clip.gx_rectangle_left - newxpos; x <= rotated_clip.gx_rectangle_right - newxpos; x++)
481 {
482 xx = (x - xres) * cosv + (y - yres) * sinv;
483 yy = (y - yres) * cosv - (x - xres) * sinv;
484
485 xdiff = GX_FIXED_VAL_TO_INT(xx << 8) & 0xff;
486 ydiff = GX_FIXED_VAL_TO_INT(yy << 8) & 0xff;
487
488 xx = GX_FIXED_VAL_TO_INT(xx);
489 yy = GX_FIXED_VAL_TO_INT(yy);
490
491 xx += srcxres;
492 yy += srcyres;
493
494 if ((xx >= -1) && (xx < pixelmap -> gx_pixelmap_height) &&
495 (yy >= -1) && (yy < pixelmap -> gx_pixelmap_width))
496 {
497 if ((xx >= 0) && (xx < pixelmap -> gx_pixelmap_height - 1) && \
498 (yy >= 0) && (yy < pixelmap -> gx_pixelmap_width - 1))
499 {
500 get = (GX_COLOR *)pixelmap -> gx_pixelmap_data;
501 get += yy * pixelmap -> gx_pixelmap_height;
502 get += xx;
503
504 a = *get;
505 b = *(get + 1);
506 c = *(get + pixelmap -> gx_pixelmap_height);
507 d = *(get + pixelmap -> gx_pixelmap_height + 1);
508 }
509 else
510 {
511 get = (GX_COLOR *)pixelmap -> gx_pixelmap_data;
512
513 a = 0;
514 b = a;
515 c = a;
516 d = a;
517
518 if (xx == -1)
519 {
520 /* Handle left edge. */
521 if (yy >= 0)
522 {
523 b = *(get + yy * pixelmap -> gx_pixelmap_height);
524 }
525
526 if (yy < pixelmap -> gx_pixelmap_width - 1)
527 {
528 d = *(get + (yy + 1) * pixelmap -> gx_pixelmap_height);
529 }
530 }
531 else if (yy == -1)
532 {
533 /* Handle top edge. */
534 c = *(get + xx);
535
536 if (xx < pixelmap -> gx_pixelmap_height - 1)
537 {
538 d = *(get + xx + 1);
539 }
540 }
541 else if (xx == pixelmap -> gx_pixelmap_height - 1)
542 {
543 /* Handle right edget. */
544 a = *(get + yy * pixelmap -> gx_pixelmap_height + xx);
545
546 if (yy < pixelmap -> gx_pixelmap_width - 1)
547 {
548 c = *(get + (yy + 1) * pixelmap -> gx_pixelmap_height + xx);
549 }
550 }
551 else
552 {
553 /* Handle bottom edge. */
554 a = *(get + yy * pixelmap -> gx_pixelmap_height + xx);
555 b = *(get + yy * pixelmap -> gx_pixelmap_height + xx + 1);
556 }
557 }
558
559 red = (REDVAL_24BPP(a) * (a >> 24) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
560 REDVAL_24BPP(b) * (b >> 24) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) + \
561 REDVAL_24BPP(c) * (c >> 24) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) + \
562 REDVAL_24BPP(d) * (d >> 24) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16;
563
564 green = (GREENVAL_24BPP(a) * (a >> 24) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
565 GREENVAL_24BPP(b) * (b >> 24) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) + \
566 GREENVAL_24BPP(c) * (c >> 24) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) + \
567 GREENVAL_24BPP(d) * (d >> 24) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16;
568
569 blue = (BLUEVAL_24BPP(a) * (a >> 24) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
570 BLUEVAL_24BPP(b) * (b >> 24) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) + \
571 BLUEVAL_24BPP(c) * (c >> 24) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) + \
572 BLUEVAL_24BPP(d) * (d >> 24) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16;
573
574 alpha = (INT)(((a >> 24) * (256 - (GX_COLOR)xdiff) * (256 - (GX_COLOR)ydiff) + \
575 (b >> 24) * (GX_COLOR)xdiff * (256 - (GX_COLOR)ydiff) + \
576 (c >> 24) * (GX_COLOR)ydiff * (256 - (GX_COLOR)xdiff) + \
577 (d >> 24) * (GX_COLOR)xdiff * (GX_COLOR)ydiff) >> 16);
578
579 if (alpha)
580 {
581 red /= (UINT)alpha;
582 green /= (UINT)alpha;
583 blue /= (UINT)alpha;
584 }
585
586 red = BYTE_RANGE(red);
587 green = BYTE_RANGE(green);
588 blue = BYTE_RANGE(blue);
589 alpha = BYTE_RANGE(alpha);
590
591 blend_func(context, x + newxpos, y + newypos, (GX_COLOR)ASSEMBLECOLOR_32ARGB((ULONG)0xff, red, green, blue), (GX_UBYTE)alpha);
592 }
593 }
594 }
595 }
596
597 /**************************************************************************/
598 /* */
599 /* FUNCTION RELEASE */
600 /* */
601 /* _gx_display_driver_32bpp_rotated_pixelmap_simple_rotate */
602 /* */
603 /* PORTABLE C */
604 /* 6.1.5 */
605 /* AUTHOR */
606 /* */
607 /* Kenneth Maxwell, Microsoft Corporation */
608 /* */
609 /* DESCRIPTION */
610 /* */
611 /* Internal help function that hangles 90, 180 and 270 degree rotated */
612 /* pixelmap rotation. */
613 /* */
614 /* INPUT */
615 /* */
616 /* context Drawing context */
617 /* xpos x-coord of top-left draw point*/
618 /* ypos y-coord of top-left draw point*/
619 /* pixelmap Pointer to GX_PIXELMAP struct */
620 /* angle The angle to rotate */
621 /* cx x-coord of rotate center */
622 /* cy y-coord of rotate center */
623 /* */
624 /* OUTPUT */
625 /* */
626 /* None */
627 /* */
628 /* CALLS */
629 /* */
630 /* [gx_display_driver_pixel_blend] Basic display driver pixel */
631 /* blend function */
632 /* */
633 /* CALLED BY */
634 /* */
635 /* GUIX Internal Code */
636 /* */
637 /* RELEASE HISTORY */
638 /* */
639 /* DATE NAME DESCRIPTION */
640 /* */
641 /* 02-02-2021 Kenneth Maxwell Initial Version 6.1.4 */
642 /* 03-02-2021 Ting Zhu Modified comment(s), changed */
643 /* blend function set macro, */
644 /* resulting in version 6.1.5 */
645 /* */
646 /**************************************************************************/
_gx_display_driver_32bpp_rotated_pixelmap_simple_rotate(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,INT angle,INT cx,INT cy)647 static VOID _gx_display_driver_32bpp_rotated_pixelmap_simple_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
648 INT angle, INT cx, INT cy)
649 {
650 GX_COLOR *putrow;
651 GX_COLOR *put;
652 GX_COLOR *get;
653 INT width;
654 INT height;
655 INT x;
656 INT y;
657 GX_RECTANGLE *clip;
658 GX_RECTANGLE rotated_clip;
659 INT newxpos;
660 INT newypos;
661 VOID (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR fcolor, GX_UBYTE alpha);
662
663 GX_SET_32BPP_BLEND_FUNCTION(blend_func, context -> gx_draw_context_display -> gx_display_color_format);
664
665 clip = context -> gx_draw_context_clip;
666
667 GX_SWAP_VALS(xpos, ypos);
668 GX_SWAP_VALS(cx, cy);
669
670 if (context -> gx_draw_context_display -> gx_display_rotation_angle == GX_SCREEN_ROTATION_CW)
671 {
672 ypos = context -> gx_draw_context_canvas -> gx_canvas_x_resolution - ypos - pixelmap -> gx_pixelmap_width;
673 cy = pixelmap -> gx_pixelmap_width - cy - 1;
674
675 rotated_clip.gx_rectangle_left = clip -> gx_rectangle_top;
676 rotated_clip.gx_rectangle_right = clip -> gx_rectangle_bottom;
677 rotated_clip.gx_rectangle_top = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - 1 - clip -> gx_rectangle_right);
678 rotated_clip.gx_rectangle_bottom = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_x_resolution - 1 - clip -> gx_rectangle_left);
679 }
680 else
681 {
682 xpos = context -> gx_draw_context_canvas -> gx_canvas_y_resolution - xpos - pixelmap -> gx_pixelmap_height;
683 cx = pixelmap -> gx_pixelmap_height - cx - 1;
684
685 rotated_clip.gx_rectangle_left = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - 1 - clip -> gx_rectangle_bottom);
686 rotated_clip.gx_rectangle_right = (GX_VALUE)(context -> gx_draw_context_canvas -> gx_canvas_y_resolution - 1 - clip -> gx_rectangle_top);
687 rotated_clip.gx_rectangle_top = clip -> gx_rectangle_left;
688 rotated_clip.gx_rectangle_bottom = clip -> gx_rectangle_right;
689 }
690
691 if (angle == 90)
692 {
693 width = pixelmap -> gx_pixelmap_width;
694 height = pixelmap -> gx_pixelmap_height;
695
696 newxpos = xpos + cx - (width - 1 - cy);
697 newypos = ypos + cy - cx;
698
699 putrow = context -> gx_draw_context_memory;
700 putrow += rotated_clip.gx_rectangle_top * context -> gx_draw_context_pitch;
701 putrow += rotated_clip.gx_rectangle_left;
702
703 for (y = rotated_clip.gx_rectangle_top - newypos; y <= rotated_clip.gx_rectangle_bottom - newypos; y++)
704 {
705 put = putrow;
706
707 for (x = rotated_clip.gx_rectangle_left - newxpos; x <= rotated_clip.gx_rectangle_right - newxpos; x++)
708 {
709 get = (GX_COLOR *)pixelmap -> gx_pixelmap_data;
710 get += (width - 1 - x) * height;
711 get += y;
712
713 if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
714 {
715 blend_func(context, rotated_clip.gx_rectangle_left + x, rotated_clip.gx_rectangle_top + y, (*get) | 0xff000000, (GX_UBYTE)((*get) >> 24));
716 }
717 else
718 {
719 *put++ = *get;
720 }
721 }
722
723 putrow += context -> gx_draw_context_pitch;
724 }
725 }
726 else if (angle == 180)
727 {
728
729 width = pixelmap -> gx_pixelmap_height;
730 height = pixelmap -> gx_pixelmap_width;
731
732 newxpos = xpos + cx - (width - 1 - cx);
733 newypos = ypos + cy - (height - 1 - cy);
734
735 putrow = context -> gx_draw_context_memory;
736 putrow += rotated_clip.gx_rectangle_top * context -> gx_draw_context_pitch;
737 putrow += rotated_clip.gx_rectangle_left;
738
739 for (y = rotated_clip.gx_rectangle_top - newypos; y <= rotated_clip.gx_rectangle_bottom - newypos; y++)
740 {
741 put = putrow;
742 for (x = rotated_clip.gx_rectangle_left - newxpos; x <= rotated_clip.gx_rectangle_right - newxpos; x++)
743 {
744 get = (GX_COLOR *)pixelmap -> gx_pixelmap_data;
745 get += (height - 1 - y) * width;
746 get += width - 1 - x;
747
748 if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
749 {
750 blend_func(context, rotated_clip.gx_rectangle_left + x, rotated_clip.gx_rectangle_top + y, (*get) | 0xff000000, (GX_UBYTE)((*get) >> 24));
751 }
752 else
753 {
754 *put++ = *get;
755 }
756 }
757
758 putrow += context -> gx_draw_context_pitch;
759 }
760 }
761 else
762 {
763 height = pixelmap -> gx_pixelmap_height;
764
765 newxpos = xpos + cx - cy;
766 newypos = ypos + cx - (height - 1 - cy);
767
768 putrow = context -> gx_draw_context_memory;
769 putrow += rotated_clip.gx_rectangle_top * context -> gx_draw_context_pitch;
770 putrow += rotated_clip.gx_rectangle_left;
771
772 for (y = rotated_clip.gx_rectangle_top - newypos; y <= rotated_clip.gx_rectangle_bottom - newypos; y++)
773 {
774 put = putrow;
775
776 for (x = rotated_clip.gx_rectangle_left - newxpos; x <= rotated_clip.gx_rectangle_right - newxpos; x++)
777 {
778 get = (GX_COLOR *)pixelmap -> gx_pixelmap_data;
779 get += x * height;
780 get += height - 1 - y;
781
782 if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
783 {
784 blend_func(context, rotated_clip.gx_rectangle_left + x, rotated_clip.gx_rectangle_top + y, (*get) | 0xff000000, (GX_UBYTE)((*get) >> 24));
785 }
786 else
787 {
788 *put++ = *get;
789 }
790 }
791
792 putrow += context -> gx_draw_context_pitch;
793 }
794 }
795 }
796
797 /**************************************************************************/
798 /* */
799 /* FUNCTION RELEASE */
800 /* */
801 /* _gx_display_driver_32bpp_rotated_pixelmap_rotate PORTABLE C */
802 /* 6.1.4 */
803 /* AUTHOR */
804 /* */
805 /* Kenneth Maxwell, Microsoft Corporation */
806 /* */
807 /* DESCRIPTION */
808 /* */
809 /* This service rotate a rotated pixelmap directly to canvas memory. */
810 /* */
811 /* INPUT */
812 /* */
813 /* context Drawing context */
814 /* xpos x-coord of top-left draw point*/
815 /* ypos y-coord of top-left draw point*/
816 /* pixelmap Pointer to GX_PIXELMAP struct */
817 /* angle The angle to rotate */
818 /* rot_cx x-coord of rotating center. */
819 /* rot_cy y-coord of rotationg center. */
820 /* */
821 /* OUTPUT */
822 /* */
823 /* None */
824 /* */
825 /* CALLS */
826 /* */
827 /* _gx_display_driver_32bpp_rotated_pixelmap_simple_rotate */
828 /* _gx_display_driver_32bpp_rotated_pixelmap_alpha_rotate */
829 /* _gx_display_driver_32bpp_rotated_pixelmap_rotate */
830 /* */
831 /* CALLED BY */
832 /* */
833 /* GUIX Internal Code */
834 /* */
835 /* RELEASE HISTORY */
836 /* */
837 /* DATE NAME DESCRIPTION */
838 /* */
839 /* 02-02-2021 Kenneth Maxwell Initial Version 6.1.4 */
840 /* */
841 /**************************************************************************/
_gx_display_driver_32bpp_rotated_pixelmap_rotate(GX_DRAW_CONTEXT * context,INT xpos,INT ypos,GX_PIXELMAP * pixelmap,INT angle,INT rot_cx,INT rot_cy)842 VOID _gx_display_driver_32bpp_rotated_pixelmap_rotate(GX_DRAW_CONTEXT *context, INT xpos, INT ypos, GX_PIXELMAP *pixelmap,
843 INT angle, INT rot_cx, INT rot_cy)
844 {
845 switch (pixelmap -> gx_pixelmap_format)
846 {
847 case GX_COLOR_FORMAT_24XRGB:
848 case GX_COLOR_FORMAT_32ARGB:
849 if (angle % 90 == 0)
850 {
851 /* Simple angle rotate: 90 degree, 180 degree and 270 degree. */
852 _gx_display_driver_32bpp_rotated_pixelmap_simple_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
853 }
854 else
855 {
856 if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
857 {
858 /* With alpha. */
859 _gx_display_driver_32bpp_rotated_pixelmap_alpha_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
860 }
861 else
862 {
863 /* Without alpha. */
864 _gx_display_driver_32bpp_rotated_pixelmap_raw_rotate(context, xpos, ypos, pixelmap, angle, rot_cx, rot_cy);
865 }
866 }
867 break;
868 }
869
870 return;
871 }
872
873