diff options
author | Thomas Martitz <kugel@rockbox.org> | 2011-11-08 21:36:49 +0000 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2011-11-08 21:36:49 +0000 |
commit | f443e7bbf7771ce3a79b1c2116b9cf216f15938f (patch) | |
tree | eeaf47216f88c811529ade5a7c27bd76203bb02b /firmware/drivers/lcd-16bit-common.c | |
parent | 13209604c1512658e729d0bd9f1c54cf3e53568d (diff) | |
download | rockbox-f443e7bbf7771ce3a79b1c2116b9cf216f15938f.tar.gz rockbox-f443e7bbf7771ce3a79b1c2116b9cf216f15938f.zip |
Support for transparency in 32bit bitmaps on color targets.
This uses the alpha blending capabilities introduced with anti-aliased fonts
to draw bitmaps with transparency information. The bmp loader is extended to read
this information (pass FORMAT_TRANSPARENT in format). The alpha information will
be used when drawing the bitmap.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30937 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers/lcd-16bit-common.c')
-rw-r--r-- | firmware/drivers/lcd-16bit-common.c | 58 |
1 files changed, 48 insertions, 10 deletions
diff --git a/firmware/drivers/lcd-16bit-common.c b/firmware/drivers/lcd-16bit-common.c index bbac2b295a..7b37bf7c30 100644 --- a/firmware/drivers/lcd-16bit-common.c +++ b/firmware/drivers/lcd-16bit-common.c | |||
@@ -229,7 +229,6 @@ void lcd_mono_bitmap(const unsigned char *src, int x, int y, int width, int heig | |||
229 | lcd_mono_bitmap_part(src, 0, 0, width, x, y, width, height); | 229 | lcd_mono_bitmap_part(src, 0, 0, width, x, y, width, height); |
230 | } | 230 | } |
231 | 231 | ||
232 | /* draw alpha bitmap for anti-alias font */ | ||
233 | #define ALPHA_COLOR_FONT_DEPTH 2 | 232 | #define ALPHA_COLOR_FONT_DEPTH 2 |
234 | #define ALPHA_COLOR_LOOKUP_SHIFT (1 << ALPHA_COLOR_FONT_DEPTH) | 233 | #define ALPHA_COLOR_LOOKUP_SHIFT (1 << ALPHA_COLOR_FONT_DEPTH) |
235 | #define ALPHA_COLOR_LOOKUP_SIZE ((1 << ALPHA_COLOR_LOOKUP_SHIFT) - 1) | 234 | #define ALPHA_COLOR_LOOKUP_SIZE ((1 << ALPHA_COLOR_LOOKUP_SHIFT) - 1) |
@@ -285,11 +284,17 @@ static inline unsigned blend_color(unsigned c, unsigned a) | |||
285 | return blend_two_colors(c, current_vp->fg_pattern, a); | 284 | return blend_two_colors(c, current_vp->fg_pattern, a); |
286 | } | 285 | } |
287 | 286 | ||
288 | void ICODE_ATTR lcd_alpha_bitmap_part(const unsigned char *src, int src_x, | 287 | /* Blend an image with an alpha channel |
289 | int src_y, int stride, int x, int y, | 288 | * if image is NULL, drawing will happen according to the drawmode |
290 | int width, int height) | 289 | * src is the alpha channel (4bit per pixel) */ |
290 | static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image, | ||
291 | const unsigned char *src, int src_x, | ||
292 | int src_y, int x, int y, | ||
293 | int width, int height, | ||
294 | int stride_image, int stride_src) | ||
291 | { | 295 | { |
292 | fb_data *dst, *dst_row; | 296 | fb_data *dst, *dst_row; |
297 | const fb_data *image_row; | ||
293 | unsigned dmask = 0x00000000; | 298 | unsigned dmask = 0x00000000; |
294 | int drmode = current_vp->drawmode; | 299 | int drmode = current_vp->drawmode; |
295 | /* nothing to draw? */ | 300 | /* nothing to draw? */ |
@@ -356,13 +361,22 @@ void ICODE_ATTR lcd_alpha_bitmap_part(const unsigned char *src, int src_x, | |||
356 | { | 361 | { |
357 | dmask = ~dmask; | 362 | dmask = ~dmask; |
358 | } | 363 | } |
364 | /* sourcing from an image ignore drawmode. | ||
365 | * Set to DRMODE_BG as we use its code path in the switch below */ | ||
366 | if (image != NULL) | ||
367 | { | ||
368 | dmask = 0; | ||
369 | drmode = DRMODE_BG; | ||
370 | } | ||
359 | 371 | ||
360 | dst_row = LCDADDR(x, y); | 372 | dst_row = LCDADDR(x, y); |
361 | 373 | ||
362 | int col, row = height; | 374 | int col, row = height; |
363 | unsigned data, pixels; | 375 | unsigned data, pixels; |
364 | unsigned skip_end = (stride - width); | 376 | unsigned skip_end = (stride_src - width); |
365 | unsigned skip_start = src_y * stride + src_x; | 377 | unsigned skip_start = src_y * stride_src + src_x; |
378 | unsigned skip_start_image = STRIDE_MAIN(src_y * stride_image + src_x, | ||
379 | src_x * stride_image + src_y); | ||
366 | 380 | ||
367 | #ifdef ALPHA_BITMAP_READ_WORDS | 381 | #ifdef ALPHA_BITMAP_READ_WORDS |
368 | uint32_t *src_w = (uint32_t *)((uintptr_t)src & ~3); | 382 | uint32_t *src_w = (uint32_t *)((uintptr_t)src & ~3); |
@@ -379,6 +393,9 @@ void ICODE_ATTR lcd_alpha_bitmap_part(const unsigned char *src, int src_x, | |||
379 | #ifdef ALPHA_BITMAP_READ_WORDS | 393 | #ifdef ALPHA_BITMAP_READ_WORDS |
380 | pixels = 8 - pixels; | 394 | pixels = 8 - pixels; |
381 | #endif | 395 | #endif |
396 | if (image) | ||
397 | image += skip_start_image; | ||
398 | image_row = image; | ||
382 | 399 | ||
383 | /* go through the rows and update each pixel */ | 400 | /* go through the rows and update each pixel */ |
384 | do | 401 | do |
@@ -386,6 +403,12 @@ void ICODE_ATTR lcd_alpha_bitmap_part(const unsigned char *src, int src_x, | |||
386 | col = width; | 403 | col = width; |
387 | dst = dst_row; | 404 | dst = dst_row; |
388 | dst_row += ROW_INC; | 405 | dst_row += ROW_INC; |
406 | if (image_row) { | ||
407 | image = image_row; | ||
408 | image_row += STRIDE_MAIN(stride_image,1); | ||
409 | } | ||
410 | else | ||
411 | image = dst; | ||
389 | #ifdef ALPHA_BITMAP_READ_WORDS | 412 | #ifdef ALPHA_BITMAP_READ_WORDS |
390 | #define UPDATE_SRC_ALPHA do { \ | 413 | #define UPDATE_SRC_ALPHA do { \ |
391 | if (--pixels) \ | 414 | if (--pixels) \ |
@@ -431,10 +454,11 @@ void ICODE_ATTR lcd_alpha_bitmap_part(const unsigned char *src, int src_x, | |||
431 | uintptr_t bo = lcd_backdrop_offset; | 454 | uintptr_t bo = lcd_backdrop_offset; |
432 | do | 455 | do |
433 | { | 456 | { |
434 | *dst = blend_two_colors(*dst, *(fb_data *)((uintptr_t)dst + bo), | 457 | *dst = blend_two_colors(*(fb_data *)((uintptr_t)dst + bo), |
435 | data & ALPHA_COLOR_LOOKUP_SIZE ); | 458 | *image, data & ALPHA_COLOR_LOOKUP_SIZE ); |
436 | 459 | ||
437 | dst += COL_INC; | 460 | dst += COL_INC; |
461 | image += STRIDE_MAIN(1, stride_image); | ||
438 | UPDATE_SRC_ALPHA; | 462 | UPDATE_SRC_ALPHA; |
439 | } | 463 | } |
440 | while (--col); | 464 | while (--col); |
@@ -443,9 +467,10 @@ void ICODE_ATTR lcd_alpha_bitmap_part(const unsigned char *src, int src_x, | |||
443 | { | 467 | { |
444 | do | 468 | do |
445 | { | 469 | { |
446 | *dst = blend_two_colors(*dst, current_vp->bg_pattern, | 470 | *dst = blend_two_colors(current_vp->bg_pattern, |
447 | data & ALPHA_COLOR_LOOKUP_SIZE ); | 471 | *image, data & ALPHA_COLOR_LOOKUP_SIZE ); |
448 | dst += COL_INC; | 472 | dst += COL_INC; |
473 | image += STRIDE_MAIN(1, stride_image); | ||
449 | UPDATE_SRC_ALPHA; | 474 | UPDATE_SRC_ALPHA; |
450 | } | 475 | } |
451 | while (--col); | 476 | while (--col); |
@@ -516,6 +541,15 @@ void ICODE_ATTR lcd_alpha_bitmap_part(const unsigned char *src, int src_x, | |||
516 | } while (--row); | 541 | } while (--row); |
517 | } | 542 | } |
518 | 543 | ||
544 | |||
545 | /* draw alpha bitmap for anti-alias font */ | ||
546 | void ICODE_ATTR lcd_alpha_bitmap_part(const unsigned char *src, int src_x, | ||
547 | int src_y, int stride, int x, int y, | ||
548 | int width, int height) | ||
549 | { | ||
550 | lcd_alpha_bitmap_part_mix(NULL, src, src_x, src_y, x, y, width, height, 0, stride); | ||
551 | } | ||
552 | |||
519 | /* Draw a partial bitmap (mono or native) including alpha channel */ | 553 | /* Draw a partial bitmap (mono or native) including alpha channel */ |
520 | void ICODE_ATTR lcd_bmp_part(const struct bitmap* bm, int src_x, int src_y, | 554 | void ICODE_ATTR lcd_bmp_part(const struct bitmap* bm, int src_x, int src_y, |
521 | int x, int y, int width, int height) | 555 | int x, int y, int width, int height) |
@@ -523,6 +557,10 @@ void ICODE_ATTR lcd_bmp_part(const struct bitmap* bm, int src_x, int src_y, | |||
523 | int bitmap_stride = STRIDE_MAIN(bm->width, bm->height); | 557 | int bitmap_stride = STRIDE_MAIN(bm->width, bm->height); |
524 | if (bm->format == FORMAT_MONO) | 558 | if (bm->format == FORMAT_MONO) |
525 | lcd_mono_bitmap_part(bm->data, src_x, src_y, bitmap_stride, x, y, width, height); | 559 | lcd_mono_bitmap_part(bm->data, src_x, src_y, bitmap_stride, x, y, width, height); |
560 | else if (bm->alpha_offset > 0) | ||
561 | lcd_alpha_bitmap_part_mix((fb_data*)bm->data, bm->data+bm->alpha_offset, | ||
562 | src_x, src_y, x, y, width, height, | ||
563 | bitmap_stride, bm->width); | ||
526 | else | 564 | else |
527 | lcd_bitmap_transparent_part((fb_data*)bm->data, | 565 | lcd_bitmap_transparent_part((fb_data*)bm->data, |
528 | src_x, src_y, bitmap_stride, x, y, width, height); | 566 | src_x, src_y, bitmap_stride, x, y, width, height); |