diff options
author | Thomas Martitz <kugel@rockbox.org> | 2011-11-11 19:05:11 +0000 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2011-11-11 19:05:11 +0000 |
commit | 312b2a2de7a35f8c4b0dc355b7b291085a9a5ea4 (patch) | |
tree | 922fc139712760cd89c0caa7c3724b5a5020765c /firmware/drivers | |
parent | 158e14a8c696b29ec7fa21da5b1a801c31c473e9 (diff) | |
download | rockbox-312b2a2de7a35f8c4b0dc355b7b291085a9a5ea4.tar.gz rockbox-312b2a2de7a35f8c4b0dc355b7b291085a9a5ea4.zip |
Document the internal alpha channel format better, and fixes for 32bit alpha bitmaps.
For images, rows need to be even (this is not true for anti-aliased font files).
Fix stride and size calculation. This makes images that have odd pixel rows display properly and fixes buffer overflows.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30966 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers')
-rw-r--r-- | firmware/drivers/lcd-16bit-common.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/firmware/drivers/lcd-16bit-common.c b/firmware/drivers/lcd-16bit-common.c index 7b37bf7c30..47f5968228 100644 --- a/firmware/drivers/lcd-16bit-common.c +++ b/firmware/drivers/lcd-16bit-common.c | |||
@@ -229,6 +229,25 @@ 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 | |||
233 | /* About Rockbox' internal alpha channel format (for ALPHA_COLOR_FONT_DEPTH == 2) | ||
234 | * | ||
235 | * For each pixel, 4bit of alpha information is stored in a byte-stream, | ||
236 | * so two pixels are packed into one byte. | ||
237 | * The lower nibble is the first pixel, the upper one the second. The stride is | ||
238 | * horizontal. E.g row0: pixel0: byte0[0:3], pixel1: byte0[4:7], pixel2: byte1[0:3],... | ||
239 | * The format is independant of the internal display orientation, as to | ||
240 | * support the same font files on | ||
241 | * The values go linear from 0 (fully transparent) to 15 (fully opaque). | ||
242 | * | ||
243 | * This might suggest that rows need to have an even number of pixels. | ||
244 | * However this is generally not the case. lcd_alpha_bitmap_part_mix() can deal | ||
245 | * with uneven colums (i.e. two rows can share one byte). And font files do | ||
246 | * exploit this. | ||
247 | * However, this is difficult to do for image files, especially bottom-up bitmaps, | ||
248 | * so lcd_bmp() do expect even rows. | ||
249 | */ | ||
250 | |||
232 | #define ALPHA_COLOR_FONT_DEPTH 2 | 251 | #define ALPHA_COLOR_FONT_DEPTH 2 |
233 | #define ALPHA_COLOR_LOOKUP_SHIFT (1 << ALPHA_COLOR_FONT_DEPTH) | 252 | #define ALPHA_COLOR_LOOKUP_SHIFT (1 << ALPHA_COLOR_FONT_DEPTH) |
234 | #define ALPHA_COLOR_LOOKUP_SIZE ((1 << ALPHA_COLOR_LOOKUP_SHIFT) - 1) | 253 | #define ALPHA_COLOR_LOOKUP_SIZE ((1 << ALPHA_COLOR_LOOKUP_SHIFT) - 1) |
@@ -357,17 +376,16 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image, | |||
357 | dmask = 0xffffffff; | 376 | dmask = 0xffffffff; |
358 | drmode &= DRMODE_SOLID; /* mask out inversevid */ | 377 | drmode &= DRMODE_SOLID; /* mask out inversevid */ |
359 | } | 378 | } |
360 | if (drmode == DRMODE_BG) | ||
361 | { | ||
362 | dmask = ~dmask; | ||
363 | } | ||
364 | /* sourcing from an image ignore drawmode. | 379 | /* sourcing from an image ignore drawmode. |
365 | * Set to DRMODE_BG as we use its code path in the switch below */ | 380 | * Set to DRMODE_BG as we use its code path in the switch below */ |
366 | if (image != NULL) | 381 | if (image != NULL) |
367 | { | 382 | { |
368 | dmask = 0; | ||
369 | drmode = DRMODE_BG; | 383 | drmode = DRMODE_BG; |
370 | } | 384 | } |
385 | if (drmode == DRMODE_BG) | ||
386 | { | ||
387 | dmask = ~dmask; | ||
388 | } | ||
371 | 389 | ||
372 | dst_row = LCDADDR(x, y); | 390 | dst_row = LCDADDR(x, y); |
373 | 391 | ||
@@ -560,7 +578,7 @@ void ICODE_ATTR lcd_bmp_part(const struct bitmap* bm, int src_x, int src_y, | |||
560 | else if (bm->alpha_offset > 0) | 578 | else if (bm->alpha_offset > 0) |
561 | lcd_alpha_bitmap_part_mix((fb_data*)bm->data, bm->data+bm->alpha_offset, | 579 | lcd_alpha_bitmap_part_mix((fb_data*)bm->data, bm->data+bm->alpha_offset, |
562 | src_x, src_y, x, y, width, height, | 580 | src_x, src_y, x, y, width, height, |
563 | bitmap_stride, bm->width); | 581 | bitmap_stride, ALIGN_UP(bm->width, 2)); |
564 | else | 582 | else |
565 | lcd_bitmap_transparent_part((fb_data*)bm->data, | 583 | lcd_bitmap_transparent_part((fb_data*)bm->data, |
566 | src_x, src_y, bitmap_stride, x, y, width, height); | 584 | src_x, src_y, bitmap_stride, x, y, width, height); |