summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2014-01-09 00:18:01 +0100
committerThomas Martitz <kugel@rockbox.org>2014-01-09 00:43:46 +0100
commitfde92de2243729dfa0edb5301a31c2c15d7bf707 (patch)
tree9978d86c78c444e29d16bf54d67ce7c00dd3a86e
parent124e9c1cb62539a78e01af7f80c28e3a029af874 (diff)
downloadrockbox-fde92de2243729dfa0edb5301a31c2c15d7bf707.tar.gz
rockbox-fde92de2243729dfa0edb5301a31c2c15d7bf707.zip
lcd_nine_segment_bmp: Fixes for non-ideal image dimensions.
1) The 9-segment images need not be multiple of 3 pixels anymore. If it isn't the inner segments will be smaller than the corners. 2) If the desired actual images is not a multiple of the segment sizes the function drawed more than the desired rectangle. This is fixed by drawing the last segment only partially. Change-Id: Ic918facd8734fa4a4aa72536f0b67de82d81651e
-rw-r--r--firmware/drivers/lcd-bitmap-common.c91
1 files changed, 57 insertions, 34 deletions
diff --git a/firmware/drivers/lcd-bitmap-common.c b/firmware/drivers/lcd-bitmap-common.c
index 81decadbcb..a102eaea66 100644
--- a/firmware/drivers/lcd-bitmap-common.c
+++ b/firmware/drivers/lcd-bitmap-common.c
@@ -447,44 +447,67 @@ void LCDFN(bmp)(const struct bitmap* bm, int x, int y)
447void LCDFN(nine_segment_bmp)(const struct bitmap* bm, int x, int y, 447void LCDFN(nine_segment_bmp)(const struct bitmap* bm, int x, int y,
448 int width, int height) 448 int width, int height)
449{ 449{
450 int seg_w = bm->width / 3; 450 int seg_w, seg_h, src_x, src_y, dst_x, dst_y;
451 int seg_h = bm->height / 3; 451 /* if the bitmap dimensions are not multiples of 3 bytes reduce the
452 int src_x, src_y, dst_x, dst_y; 452 * inner segments accordingly. A 8x8 image becomes 3x3 for each
453 453 * corner, and 2x2 for the inner segments */
454 /* top */ 454 int corner_w = (bm->width + 2) / 3;
455 src_x = seg_w; src_y = 0; 455 int corner_h = (bm->height + 2) / 3;
456 dst_x = seg_w; dst_y = 0; 456 seg_w = bm->width - (2 * corner_w);
457 for (; dst_x < width - seg_w; dst_x += seg_w) 457 seg_h = bm->height - (2 * corner_h);
458 LCDFN(bmp_part)(bm, src_x, src_y, dst_x, dst_y, seg_w, seg_h); 458
459 /* bottom */ 459 /* top & bottom in a single loop*/
460 src_x = seg_w; src_y = bm->height - seg_h; 460 src_x = corner_w;
461 dst_x = seg_w; dst_y = height - seg_h; 461 dst_x = corner_w;
462 int src_y_top = 0;
463 int dst_y_top = 0;
464 int src_y_btm = bm->height - corner_h;
465 int dst_y_btm = height - corner_h;
462 for (; dst_x < width - seg_w; dst_x += seg_w) 466 for (; dst_x < width - seg_w; dst_x += seg_w)
463 LCDFN(bmp_part)(bm, src_x, src_y, dst_x, dst_y, seg_w, seg_h); 467 {
468 /* cap the last segment to the remaining width */
469 int w = MIN(seg_w, (width - dst_x - seg_w));
470 LCDFN(bmp_part)(bm, src_x, src_y_top, dst_x, dst_y_top, w, seg_h);
471 LCDFN(bmp_part)(bm, src_x, src_y_btm, dst_x, dst_y_btm, w, seg_h);
472 }
464 473
465 /* left */ 474 /* left & right in a single loop */
466 src_x = 0; src_y = seg_h; 475 src_y = corner_h;
467 dst_x = 0; dst_y = seg_h; 476 dst_y = corner_h;
468 for (; dst_y < height - seg_h; dst_y += seg_h) 477 int src_x_l = 0;
469 LCDFN(bmp_part)(bm, src_x, src_y, dst_x, dst_y, seg_w, seg_h); 478 int dst_x_l = 0;
470 /* right */ 479 int src_x_r = bm->width - corner_w;
471 src_x = bm->width - seg_w; src_y = seg_h; 480 int dst_x_r = width - corner_w;
472 dst_x = width - seg_w; dst_y = seg_h;
473 for (; dst_y < height - seg_h; dst_y += seg_h)
474 LCDFN(bmp_part)(bm, src_x, src_y, dst_x, dst_y, seg_w, seg_h);
475 /* center */
476 dst_y = seg_h; src_y = seg_h; src_x = seg_w;
477 for (; dst_y < height - seg_h; dst_y += seg_h) 481 for (; dst_y < height - seg_h; dst_y += seg_h)
478 { 482 {
479 dst_x = seg_w; 483 /* cap the last segment to the remaining height */
480 for (; dst_x < width - seg_w; dst_x += seg_w) 484 int h = MIN(seg_h, (height - dst_y - seg_h));
481 LCDFN(bmp_part)(bm, src_x, src_y, dst_x, dst_y, seg_w, seg_h); 485 LCDFN(bmp_part)(bm, src_x_l, src_y, dst_x_l, dst_y, seg_w, h);
486 LCDFN(bmp_part)(bm, src_x_r, src_y, dst_x_r, dst_y, seg_w, h);
487 }
488 /* center, need not be drawn if the desired rectangle is smaller than
489 * the sides. in that case the rect is completely filled already */
490 if (width > (2*corner_w) && height > (2*corner_h))
491 {
492 dst_y = src_y = corner_h;
493 src_x = corner_w;
494 for (; dst_y < height - seg_h; dst_y += seg_h)
495 {
496 /* cap the last segment to the remaining height */
497 int h = MIN(seg_h, (height - dst_y - seg_h));
498 dst_x = corner_w;
499 for (; dst_x < width - seg_w; dst_x += seg_w)
500 {
501 /* cap the last segment to the remaining width */
502 int w = MIN(seg_w, (width - dst_x - seg_w));
503 LCDFN(bmp_part)(bm, src_x, src_y, dst_x, dst_y, w, h);
504 }
505 }
482 } 506 }
483
484 /* 4 corners */ 507 /* 4 corners */
485 LCDFN(bmp_part)(bm, 0, 0, x, y, seg_w, seg_h); 508 LCDFN(bmp_part)(bm, 0, 0, x, y, corner_w, corner_h);
486 LCDFN(bmp_part)(bm, bm->width - seg_w, 0, width - seg_w, 0, seg_w, seg_h); 509 LCDFN(bmp_part)(bm, bm->width - corner_w, 0, width - corner_w, 0, corner_w, corner_h);
487 LCDFN(bmp_part)(bm, 0, bm->width - seg_h, 0, height - seg_h, seg_w, seg_h); 510 LCDFN(bmp_part)(bm, 0, bm->width - corner_h, 0, height - corner_h, corner_w, corner_h);
488 LCDFN(bmp_part)(bm, bm->width - seg_w, bm->width - seg_h, 511 LCDFN(bmp_part)(bm, bm->width - corner_w, bm->width - corner_h,
489 width - seg_w, height - seg_h, seg_w, seg_h); 512 width - corner_w, height - corner_h, corner_w, corner_h);
490} 513}