summaryrefslogtreecommitdiff
path: root/firmware/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers')
-rw-r--r--firmware/drivers/lcd-16bit-common.c445
1 files changed, 220 insertions, 225 deletions
diff --git a/firmware/drivers/lcd-16bit-common.c b/firmware/drivers/lcd-16bit-common.c
index 27e6c23885..af1171b401 100644
--- a/firmware/drivers/lcd-16bit-common.c
+++ b/firmware/drivers/lcd-16bit-common.c
@@ -336,7 +336,7 @@ void lcd_mono_bitmap(const unsigned char *src, int x, int y, int width, int heig
336} 336}
337 337
338 338
339/* About Rockbox' internal alpha channel format (for ALPHA_COLOR_FONT_DEPTH == 2) 339/* About Rockbox' internal alpha channel format (for ALPHA_BPP == 4)
340 * 340 *
341 * For each pixel, 4bit of alpha information is stored in a byte-stream, 341 * For each pixel, 4bit of alpha information is stored in a byte-stream,
342 * so two pixels are packed into one byte. 342 * so two pixels are packed into one byte.
@@ -355,11 +355,15 @@ void lcd_mono_bitmap(const unsigned char *src, int x, int y, int width, int heig
355 * so lcd_bmp() do expect even rows. 355 * so lcd_bmp() do expect even rows.
356 */ 356 */
357 357
358#define ALPHA_COLOR_FONT_DEPTH 2 358#define ALPHA_BPP 4
359#define ALPHA_COLOR_LOOKUP_SHIFT (1 << ALPHA_COLOR_FONT_DEPTH) 359#define ALPHA_MASK ((1 << ALPHA_BPP) - 1)
360#define ALPHA_COLOR_LOOKUP_SIZE ((1 << ALPHA_COLOR_LOOKUP_SHIFT) - 1) 360#define ALPHA_PIXELS_PER_BYTE (CHAR_BIT / ALPHA_BPP)
361#define ALPHA_COLOR_PIXEL_PER_BYTE (8 >> ALPHA_COLOR_FONT_DEPTH) 361
362#define ALPHA_COLOR_PIXEL_PER_WORD (32 >> ALPHA_COLOR_FONT_DEPTH) 362#define ALPHA_WORD_T uint32_t
363#define ALPHA_WORD_LOAD load_le32
364#define ALPHA_WORDSIZE sizeof(ALPHA_WORD_T)
365#define ALPHA_PIXELS_PER_WORD (ALPHA_WORDSIZE * CHAR_BIT / ALPHA_BPP)
366
363#ifdef CPU_ARM 367#ifdef CPU_ARM
364#define BLEND_INIT do {} while (0) 368#define BLEND_INIT do {} while (0)
365#define BLEND_FINISH do {} while(0) 369#define BLEND_FINISH do {} while(0)
@@ -368,6 +372,7 @@ void lcd_mono_bitmap(const unsigned char *src, int x, int y, int width, int heig
368#define BLEND_CONT(acc, color, alpha) \ 372#define BLEND_CONT(acc, color, alpha) \
369 asm volatile("mla %0, %1, %2, %0" : "+&r" (acc) : "r" (color), "r" (alpha)) 373 asm volatile("mla %0, %1, %2, %0" : "+&r" (acc) : "r" (color), "r" (alpha))
370#define BLEND_OUT(acc) do {} while (0) 374#define BLEND_OUT(acc) do {} while (0)
375
371#elif defined(CPU_COLDFIRE) 376#elif defined(CPU_COLDFIRE)
372#define ALPHA_BITMAP_READ_WORDS 377#define ALPHA_BITMAP_READ_WORDS
373#define BLEND_INIT \ 378#define BLEND_INIT \
@@ -379,6 +384,7 @@ void lcd_mono_bitmap(const unsigned char *src, int x, int y, int width, int heig
379 asm volatile("mac.l %0, %1, %%acc0" :: "%d" (color), "d" (alpha)) 384 asm volatile("mac.l %0, %1, %%acc0" :: "%d" (color), "d" (alpha))
380#define BLEND_CONT BLEND_START 385#define BLEND_CONT BLEND_START
381#define BLEND_OUT(acc) asm volatile("movclr.l %%acc0, %0" : "=d" (acc)) 386#define BLEND_OUT(acc) asm volatile("movclr.l %%acc0, %0" : "=d" (acc))
387
382#else 388#else
383#define BLEND_INIT do {} while (0) 389#define BLEND_INIT do {} while (0)
384#define BLEND_FINISH do {} while(0) 390#define BLEND_FINISH do {} while(0)
@@ -390,7 +396,7 @@ void lcd_mono_bitmap(const unsigned char *src, int x, int y, int width, int heig
390/* Blend the given two colors */ 396/* Blend the given two colors */
391static inline unsigned blend_two_colors(unsigned c1, unsigned c2, unsigned a) 397static inline unsigned blend_two_colors(unsigned c1, unsigned c2, unsigned a)
392{ 398{
393 a += a >> (ALPHA_COLOR_LOOKUP_SHIFT - 1); 399 a += a >> (ALPHA_BPP - 1);
394#if (LCD_PIXELFORMAT == RGB565SWAPPED) 400#if (LCD_PIXELFORMAT == RGB565SWAPPED)
395 c1 = swap16(c1); 401 c1 = swap16(c1);
396 c2 = swap16(c2); 402 c2 = swap16(c2);
@@ -399,9 +405,9 @@ static inline unsigned blend_two_colors(unsigned c1, unsigned c2, unsigned a)
399 unsigned c2l = (c2 | (c2 << 16)) & 0x07e0f81f; 405 unsigned c2l = (c2 | (c2 << 16)) & 0x07e0f81f;
400 unsigned p; 406 unsigned p;
401 BLEND_START(p, c1l, a); 407 BLEND_START(p, c1l, a);
402 BLEND_CONT(p, c2l, ALPHA_COLOR_LOOKUP_SIZE + 1 - a); 408 BLEND_CONT(p, c2l, ALPHA_MASK + 1 - a);
403 BLEND_OUT(p); 409 BLEND_OUT(p);
404 p = (p >> ALPHA_COLOR_LOOKUP_SHIFT) & 0x07e0f81f; 410 p = (p >> ALPHA_BPP) & 0x07e0f81f;
405 p |= (p >> 16); 411 p |= (p >> 16);
406#if (LCD_PIXELFORMAT == RGB565SWAPPED) 412#if (LCD_PIXELFORMAT == RGB565SWAPPED)
407 return swap16(p); 413 return swap16(p);
@@ -410,251 +416,240 @@ static inline unsigned blend_two_colors(unsigned c1, unsigned c2, unsigned a)
410#endif 416#endif
411} 417}
412 418
413/* Blend an image with an alpha channel 419static void ICODE_ATTR lcd_alpha_bitmap_part_mix(
414 * if image is NULL, drawing will happen according to the drawmode 420 const fb_data* image, const unsigned char *alpha,
415 * src is the alpha channel (4bit per pixel) */ 421 int src_x, int src_y,
416static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image, 422 int x, int y, int width, int height,
417 const unsigned char *src, int src_x, 423 int stride_image, int stride_alpha)
418 int src_y, int x, int y,
419 int width, int height,
420 int stride_image, int stride_src)
421{ 424{
422 struct viewport *vp = lcd_current_viewport; 425 struct viewport *vp = lcd_current_viewport;
423 fb_data *dst, *dst_row; 426 unsigned int dmask = 0;
424 unsigned dmask = 0x00000000;
425 int drmode = vp->drawmode; 427 int drmode = vp->drawmode;
428 fb_data *dst;
429#ifdef ALPHA_BITMAP_READ_WORDS
430 ALPHA_WORD_T alpha_data, *alpha_word;
431 size_t alpha_offset = 0, alpha_pixels;
432#else
433 unsigned char alpha_data;
434 size_t alpha_pixels;
435#endif
426 436
427 if (!clip_viewport_rect(vp, &x, &y, &width, &height, &src_x, &src_y)) 437 if (!clip_viewport_rect(vp, &x, &y, &width, &height, &src_x, &src_y))
428 return; 438 return;
429 439
430 /* initialize blending */
431 BLEND_INIT;
432
433 /* the following drawmode combinations are possible:
434 * 1) COMPLEMENT: just negates the framebuffer contents
435 * 2) BG and BG+backdrop: draws _only_ background pixels with either
436 * the background color or the backdrop (if any). The backdrop
437 * is an image in native lcd format
438 * 3) FG and FG+image: draws _only_ foreground pixels with either
439 * the foreground color or an image buffer. The image is in
440 * native lcd format
441 * 4) SOLID, SOLID+backdrop, SOLID+image, SOLID+backdrop+image, i.e. all
442 * possible combinations of 2) and 3). Draws both, fore- and background,
443 * pixels. The rules of 2) and 3) apply.
444 *
445 * INVERSEVID swaps fore- and background pixels, i.e. background pixels
446 * become foreground ones and vice versa.
447 */
448 if (drmode & DRMODE_INVERSEVID) 440 if (drmode & DRMODE_INVERSEVID)
449 { 441 {
450 dmask = 0xffffffff; 442 dmask = 0xFFFFFFFFu;
451 drmode &= DRMODE_SOLID; /* mask out inversevid */ 443 drmode &= ~DRMODE_INVERSEVID;
452 } 444 }
453 445
454 /* Use extra bits to avoid if () in the switch-cases below */
455 if (image != NULL) 446 if (image != NULL)
456 drmode |= DRMODE_INT_IMG; 447 drmode |= DRMODE_INT_IMG;
457 448
458 if ((drmode & DRMODE_BG) && lcd_backdrop) 449 if ((drmode & DRMODE_BG) && lcd_backdrop)
459 drmode |= DRMODE_INT_BD; 450 drmode |= DRMODE_INT_BD;
460 451
461 dst_row = FBADDR(x, y);
462
463 int col, row = height;
464 unsigned data, pixels;
465 unsigned skip_end = (stride_src - width);
466 unsigned skip_start = src_y * stride_src + src_x;
467 unsigned skip_start_image = STRIDE_MAIN(src_y * stride_image + src_x,
468 src_x * stride_image + src_y);
469
470#ifdef ALPHA_BITMAP_READ_WORDS 452#ifdef ALPHA_BITMAP_READ_WORDS
471 uint32_t *src_w = (uint32_t *)((uintptr_t)src & ~3); 453#define INIT_ALPHA() \
472 skip_start += ALPHA_COLOR_PIXEL_PER_BYTE * ((uintptr_t)src & 3); 454 do { \
473 src_w += skip_start / ALPHA_COLOR_PIXEL_PER_WORD; 455 alpha_offset = src_y * stride_alpha + src_x; \
474 data = letoh32(*src_w++) ^ dmask; 456 } while(0)
475 pixels = skip_start % ALPHA_COLOR_PIXEL_PER_WORD; 457#define START_ALPHA() \
458 do { \
459 size_t __byteskip = (uintptr_t)alpha % ALPHA_WORDSIZE; \
460 size_t __byteoff = alpha_offset / ALPHA_PIXELS_PER_BYTE; \
461 alpha_word = (ALPHA_WORD_T *)ALIGN_DOWN(alpha + __byteoff, ALPHA_WORDSIZE); \
462 alpha_data = ALPHA_WORD_LOAD(alpha_word++) ^ dmask; \
463 alpha_pixels = ((__byteoff + __byteskip) % ALPHA_WORDSIZE) * ALPHA_PIXELS_PER_BYTE; \
464 alpha_pixels += alpha_offset % ALPHA_PIXELS_PER_BYTE; \
465 alpha_data >>= alpha_pixels * ALPHA_BPP; \
466 alpha_pixels = ALPHA_PIXELS_PER_WORD - alpha_pixels; \
467 } while(0)
468#define END_ALPHA() \
469 do { \
470 alpha_offset += stride_alpha; \
471 } while(0)
472#define READ_ALPHA() \
473 ({ \
474 if (alpha_pixels == 0) { \
475 alpha_data = ALPHA_WORD_LOAD(alpha_word++) ^ dmask; \
476 alpha_pixels = ALPHA_PIXELS_PER_WORD; \
477 } \
478 ALPHA_WORD_T __ret = alpha_data & ALPHA_MASK; \
479 alpha_data >>= ALPHA_BPP; \
480 alpha_pixels--; \
481 __ret; \
482 })
483#elif ALPHA_BPP == 4
484#define INIT_ALPHA() \
485 do { \
486 alpha_pixels = src_y * stride_alpha + src_x; \
487 stride_alpha = stride_alpha - width; \
488 alpha += alpha_pixels / ALPHA_PIXELS_PER_BYTE; \
489 alpha_pixels &= 1; \
490 if (alpha_pixels) { \
491 alpha_data = *alpha++ ^ dmask; \
492 alpha_data >>= ALPHA_BPP; \
493 } \
494 } while(0)
495#define START_ALPHA() do { } while(0)
496#define END_ALPHA() \
497 do { \
498 if (stride_alpha) { \
499 alpha_pixels = stride_alpha - alpha_pixels; \
500 alpha += alpha_pixels / ALPHA_PIXELS_PER_BYTE; \
501 alpha_data = *alpha++ ^ dmask; \
502 alpha_pixels &= 1; \
503 if (alpha_pixels) \
504 alpha_data >>= ALPHA_BPP; \
505 } \
506 } while(0)
507#define READ_ALPHA() \
508 ({ \
509 if (alpha_pixels == 0) \
510 alpha_data = *alpha++ ^ dmask; \
511 unsigned char __ret = alpha_data & ALPHA_MASK; \
512 alpha_data >>= ALPHA_BPP; \
513 alpha_pixels ^= 1; \
514 __ret; \
515 })
476#else 516#else
477 src += skip_start / ALPHA_COLOR_PIXEL_PER_BYTE; 517#define INIT_ALPHA() \
478 data = *src ^ dmask; 518 do { \
479 pixels = skip_start % ALPHA_COLOR_PIXEL_PER_BYTE; 519 alpha_pixels = src_y * stride_alpha + src_x; \
480#endif 520 stride_alpha = stride_alpha - width; \
481 data >>= pixels * ALPHA_COLOR_LOOKUP_SHIFT; 521 alpha += alpha_pixels / ALPHA_PIXELS_PER_BYTE; \
482#ifdef ALPHA_BITMAP_READ_WORDS 522 alpha_data = *alpha++ ^ dmask; \
483 pixels = 8 - pixels; 523 alpha_pixels %= ALPHA_PIXELS_PER_BYTE; \
524 alpha_data >>= ALPHA_BPP * alpha_pixels; \
525 alpha_pixels = ALPHA_PIXELS_PER_BYTE - alpha_pixels; \
526 } while(0)
527#define START_ALPHA() do { } while(0)
528#define END_ALPHA() \
529 do { \
530 if ((size_t)stride_alpha <= alpha_pixels) \
531 alpha_pixels -= stride_alpha; \
532 else { \
533 alpha_pixels = stride_alpha - alpha_pixels; \
534 alpha += alpha_pixels / ALPHA_PIXELS_PER_BYTE; \
535 alpha_data = *alpha++ ^ dmask; \
536 alpha_pixels %= ALPHA_PIXELS_PER_BYTE; \
537 alpha_data >>= ALPHA_BPP * alpha_pixels; \
538 alpha_pixels = ALPHA_PIXELS_PER_BYTE - alpha_pixels; \
539 } \
540 } while(0)
541#define READ_ALPHA() \
542 ({ \
543 if (alpha_pixels == 0) { \
544 alpha_data = *alpha++ ^ dmask; \
545 alpha_pixels = ALPHA_PIXELS_PER_BYTE; \
546 } \
547 unsigned char __ret = alpha_data & ALPHA_MASK; \
548 alpha_data >>= ALPHA_BPP; \
549 alpha_pixels--; \
550 __ret; \
551 })
484#endif 552#endif
485 553
486 /* image is only accessed in DRMODE_INT_IMG cases, i.e. when non-NULL. 554 dst = FBADDR(x, y);
487 * Therefore NULL accesses are impossible and we can increment 555 image += STRIDE_MAIN(src_y * stride_image + src_x,
488 * unconditionally (applies for stride at the end of the loop as well) */ 556 src_x * stride_image + src_y);
489 image += skip_start_image; 557
490 /* go through the rows and update each pixel */ 558 INIT_ALPHA();
559 BLEND_INIT;
560
491 do 561 do
492 { 562 {
493 /* saving lcd_current_viewport->fg/bg_pattern and lcd_backdrop_offset into these 563 intptr_t bo, io;
494 * temp vars just before the loop helps gcc to opimize the loop better 564 unsigned int fg, bg;
495 * (testing showed ~15% speedup) */ 565 int col = width;
496 unsigned fg, bg; 566 fb_data *dst_row = dst;
497 ptrdiff_t bo, img_offset; 567
498 col = width; 568 START_ALPHA();
499 dst = dst_row;
500 dst_row += ROW_INC;
501#ifdef ALPHA_BITMAP_READ_WORDS
502#define UPDATE_SRC_ALPHA do { \
503 if (--pixels) \
504 data >>= ALPHA_COLOR_LOOKUP_SHIFT; \
505 else \
506 { \
507 data = letoh32(*src_w++) ^ dmask; \
508 pixels = ALPHA_COLOR_PIXEL_PER_WORD; \
509 } \
510 } while (0)
511#elif ALPHA_COLOR_PIXEL_PER_BYTE == 2
512#define UPDATE_SRC_ALPHA do { \
513 if (pixels ^= 1) \
514 data >>= ALPHA_COLOR_LOOKUP_SHIFT; \
515 else \
516 data = *(++src) ^ dmask; \
517 } while (0)
518#else
519#define UPDATE_SRC_ALPHA do { \
520 if (pixels = (++pixels % ALPHA_COLOR_PIXEL_PER_BYTE)) \
521 data >>= ALPHA_COLOR_LOOKUP_SHIFT; \
522 else \
523 data = *(++src) ^ dmask; \
524 } while (0)
525#endif
526 569
527 switch (drmode) 570 switch (drmode)
528 { 571 {
529 case DRMODE_COMPLEMENT: 572 case DRMODE_COMPLEMENT:
530 do 573 do
531 { 574 {
532 *dst = blend_two_colors(*dst, ~(*dst), 575 *dst = blend_two_colors(*dst, ~(*dst), READ_ALPHA());
533 data & ALPHA_COLOR_LOOKUP_SIZE ); 576 dst += COL_INC;
534 dst += COL_INC; 577 } while (--col);
535 UPDATE_SRC_ALPHA; 578 break;
536 } 579 case DRMODE_BG|DRMODE_INT_BD:
537 while (--col); 580 bo = lcd_backdrop_offset;
538 break; 581 do
539 case DRMODE_BG|DRMODE_INT_BD:
540 bo = lcd_backdrop_offset;
541 do
542 {
543 fb_data c = *(fb_data *)((uintptr_t)dst + bo);
544 *dst = blend_two_colors(c, *dst, data & ALPHA_COLOR_LOOKUP_SIZE );
545 dst += COL_INC;
546 image += STRIDE_MAIN(1, stride_image);
547 UPDATE_SRC_ALPHA;
548 }
549 while (--col);
550 break;
551 case DRMODE_BG:
552 bg = vp->bg_pattern;
553 do
554 {
555 *dst = blend_two_colors(bg, *dst, data & ALPHA_COLOR_LOOKUP_SIZE );
556 dst += COL_INC;
557 UPDATE_SRC_ALPHA;
558 }
559 while (--col);
560 break;
561 case DRMODE_FG|DRMODE_INT_IMG:
562 img_offset = image - dst;
563 do
564 {
565 *dst = blend_two_colors(*dst, *(dst + img_offset), data & ALPHA_COLOR_LOOKUP_SIZE );
566 dst += COL_INC;
567 UPDATE_SRC_ALPHA;
568 }
569 while (--col);
570 break;
571 case DRMODE_FG:
572 fg = vp->fg_pattern;
573 do
574 {
575 *dst = blend_two_colors(*dst, fg, data & ALPHA_COLOR_LOOKUP_SIZE );
576 dst += COL_INC;
577 UPDATE_SRC_ALPHA;
578 }
579 while (--col);
580 break;
581 case DRMODE_SOLID|DRMODE_INT_BD:
582 bo = lcd_backdrop_offset;
583 fg = vp->fg_pattern;
584 do
585 {
586 fb_data *c = (fb_data *)((uintptr_t)dst + bo);
587 *dst = blend_two_colors(*c, fg, data & ALPHA_COLOR_LOOKUP_SIZE );
588 dst += COL_INC;
589 UPDATE_SRC_ALPHA;
590 }
591 while (--col);
592 break;
593 case DRMODE_SOLID|DRMODE_INT_IMG:
594 bg = vp->bg_pattern;
595 img_offset = image - dst;
596 do
597 {
598 *dst = blend_two_colors(bg, *(dst + img_offset), data & ALPHA_COLOR_LOOKUP_SIZE );
599 dst += COL_INC;
600 UPDATE_SRC_ALPHA;
601 }
602 while (--col);
603 break;
604 case DRMODE_SOLID|DRMODE_INT_BD|DRMODE_INT_IMG:
605 bo = lcd_backdrop_offset;
606 img_offset = image - dst;
607 do
608 {
609 fb_data *c = (fb_data *)((uintptr_t)dst + bo);
610 *dst = blend_two_colors(*c, *(dst + img_offset), data & ALPHA_COLOR_LOOKUP_SIZE );
611 dst += COL_INC;
612 UPDATE_SRC_ALPHA;
613 }
614 while (--col);
615 break;
616 case DRMODE_SOLID:
617 bg = vp->bg_pattern;
618 fg = vp->fg_pattern;
619 do
620 {
621 *dst = blend_two_colors(bg, fg, data & ALPHA_COLOR_LOOKUP_SIZE );
622 dst += COL_INC;
623 UPDATE_SRC_ALPHA;
624 }
625 while (--col);
626 break;
627 }
628#ifdef ALPHA_BITMAP_READ_WORDS
629 if (skip_end < pixels)
630 {
631 pixels -= skip_end;
632 data >>= skip_end * ALPHA_COLOR_LOOKUP_SHIFT;
633 } else {
634 pixels = skip_end - pixels;
635 src_w += pixels / ALPHA_COLOR_PIXEL_PER_WORD;
636 pixels %= ALPHA_COLOR_PIXEL_PER_WORD;
637 data = letoh32(*src_w++) ^ dmask;
638 data >>= pixels * ALPHA_COLOR_LOOKUP_SHIFT;
639 pixels = 8 - pixels;
640 }
641#else
642 if (skip_end)
643 {
644 pixels += skip_end;
645 if (pixels >= ALPHA_COLOR_PIXEL_PER_BYTE)
646 { 582 {
647 src += pixels / ALPHA_COLOR_PIXEL_PER_BYTE; 583 *dst = blend_two_colors(*PTR_ADD(dst, bo), *dst, READ_ALPHA());
648 pixels %= ALPHA_COLOR_PIXEL_PER_BYTE; 584 dst += COL_INC;
649 data = *src ^ dmask; 585 } while (--col);
650 data >>= pixels * ALPHA_COLOR_LOOKUP_SHIFT; 586 break;
651 } else 587 case DRMODE_BG:
652 data >>= skip_end * ALPHA_COLOR_LOOKUP_SHIFT; 588 bg = vp->bg_pattern;
589 do
590 {
591 *dst = blend_two_colors(bg, *dst, READ_ALPHA());
592 dst += COL_INC;
593 } while (--col);
594 break;
595 case DRMODE_FG|DRMODE_INT_IMG:
596 io = image - dst;
597 do
598 {
599 *dst = blend_two_colors(*dst, *(dst + io), READ_ALPHA());
600 dst += COL_INC;
601 } while (--col);
602 break;
603 case DRMODE_FG:
604 fg = vp->fg_pattern;
605 do
606 {
607 *dst = blend_two_colors(*dst, fg, READ_ALPHA());
608 dst += COL_INC;
609 } while (--col);
610 break;
611 case DRMODE_SOLID|DRMODE_INT_BD:
612 fg = vp->fg_pattern;
613 bo = lcd_backdrop_offset;
614 do
615 {
616 *dst = blend_two_colors(*PTR_ADD(dst, bo), fg, READ_ALPHA());
617 dst += COL_INC;
618 } while (--col);
619 break;
620 case DRMODE_SOLID|DRMODE_INT_IMG:
621 bg = vp->bg_pattern;
622 io = image - dst;
623 do
624 {
625 *dst = blend_two_colors(bg, *(dst + io), READ_ALPHA());
626 dst += COL_INC;
627 } while (--col);
628 break;
629 case DRMODE_SOLID|DRMODE_INT_BD|DRMODE_INT_IMG:
630 bo = lcd_backdrop_offset;
631 io = image - dst;
632 do
633 {
634 *dst = blend_two_colors(*PTR_ADD(dst, bo), *(dst + io), READ_ALPHA());
635 dst += COL_INC;
636 } while (--col);
637 break;
638 case DRMODE_SOLID:
639 fg = vp->fg_pattern;
640 bg = vp->bg_pattern;
641 do
642 {
643 *dst = blend_two_colors(bg, fg, READ_ALPHA());
644 dst += COL_INC;
645 } while (--col);
646 break;
653 } 647 }
654#endif
655 648
656 image += STRIDE_MAIN(stride_image,1); 649 END_ALPHA();
657 } while (--row); 650 image += STRIDE_MAIN(stride_image, 1);
651 dst = dst_row + ROW_INC;
652 } while (--height);
658 653
659 BLEND_FINISH; 654 BLEND_FINISH;
660} 655}