diff options
Diffstat (limited to 'firmware/drivers/lcd-bitmap-common.c')
-rw-r--r-- | firmware/drivers/lcd-bitmap-common.c | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/firmware/drivers/lcd-bitmap-common.c b/firmware/drivers/lcd-bitmap-common.c index d195fd8ebe..170ad374ea 100644 --- a/firmware/drivers/lcd-bitmap-common.c +++ b/firmware/drivers/lcd-bitmap-common.c | |||
@@ -32,6 +32,10 @@ | |||
32 | #include "string-extra.h" | 32 | #include "string-extra.h" |
33 | #include "diacritic.h" | 33 | #include "diacritic.h" |
34 | 34 | ||
35 | #ifdef LOGF_ENABLE | ||
36 | #include "panic.h" | ||
37 | #endif | ||
38 | |||
35 | #ifndef LCDFN /* Not compiling for remote - define macros for main LCD. */ | 39 | #ifndef LCDFN /* Not compiling for remote - define macros for main LCD. */ |
36 | #define LCDFN(fn) lcd_ ## fn | 40 | #define LCDFN(fn) lcd_ ## fn |
37 | #define FBFN(fn) fb_ ## fn | 41 | #define FBFN(fn) fb_ ## fn |
@@ -77,7 +81,10 @@ struct viewport* LCDFN(init_viewport)(struct viewport* vp) | |||
77 | { | 81 | { |
78 | struct frame_buffer_t *fb_default = &LCDFN(framebuffer_default); | 82 | struct frame_buffer_t *fb_default = &LCDFN(framebuffer_default); |
79 | if (!vp) /* NULL vp grabs default viewport */ | 83 | if (!vp) /* NULL vp grabs default viewport */ |
84 | { | ||
80 | vp = &default_vp; | 85 | vp = &default_vp; |
86 | vp->buffer = fb_default; | ||
87 | } | ||
81 | 88 | ||
82 | /* use defaults if no buffer is provided */ | 89 | /* use defaults if no buffer is provided */ |
83 | if (vp->buffer == NULL || vp->buffer->elems == 0) | 90 | if (vp->buffer == NULL || vp->buffer->elems == 0) |
@@ -92,6 +99,19 @@ struct viewport* LCDFN(init_viewport)(struct viewport* vp) | |||
92 | 99 | ||
93 | if (vp->buffer->get_address_fn == NULL) | 100 | if (vp->buffer->get_address_fn == NULL) |
94 | vp->buffer->get_address_fn = fb_default->get_address_fn; | 101 | vp->buffer->get_address_fn = fb_default->get_address_fn; |
102 | |||
103 | #ifdef LOGF_ENABLE | ||
104 | if ((size_t)LCD_NBELEMS(vp->width, vp->height) > vp->buffer->elems) | ||
105 | { | ||
106 | if (vp->buffer != fb_default) | ||
107 | panicf("viewport %d x %d > buffer", vp->width, vp->height); | ||
108 | logf("viewport %d x %d, %d x %d [%lu] > buffer [%lu]", vp->x, vp->y, | ||
109 | vp->width, vp->height, | ||
110 | (unsigned long) LCD_NBELEMS(vp->width, vp->height), | ||
111 | (unsigned long) vp->buffer->elems); | ||
112 | |||
113 | } | ||
114 | #endif | ||
95 | } | 115 | } |
96 | return vp; | 116 | return vp; |
97 | } | 117 | } |
@@ -474,32 +494,34 @@ static bool LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string, | |||
474 | int width, height; | 494 | int width, height; |
475 | int w, h, cwidth; | 495 | int w, h, cwidth; |
476 | bool restart; | 496 | bool restart; |
497 | struct viewport * vp = LCDFN(current_viewport); | ||
477 | 498 | ||
478 | if (!string) | 499 | if (!string) |
479 | return false; | 500 | return false; |
480 | 501 | ||
481 | /* prepare rectangle for scrolling. x and y must be calculated early | 502 | /* prepare rectangle for scrolling. x and y must be calculated early |
482 | * for find_scrolling_line() to work */ | 503 | * for find_scrolling_line() to work */ |
483 | cwidth = font_get(LCDFN(current_viewport)->font)->maxwidth; | 504 | |
484 | height = font_get(LCDFN(current_viewport)->font)->height; | 505 | cwidth = font_get(vp->font)->maxwidth; |
506 | /* get width (pixels) of the string */ | ||
507 | LCDFN(getstringsize)(string, &w, &h); | ||
508 | height = h; | ||
509 | |||
485 | y = y * (linebased ? height : 1); | 510 | y = y * (linebased ? height : 1); |
486 | x = x * (linebased ? cwidth : 1); | 511 | x = x * (linebased ? cwidth : 1); |
487 | width = LCDFN(current_viewport)->width - x; | 512 | width = vp->width - x; |
488 | 513 | ||
489 | if (y >= LCDFN(current_viewport)->height) | 514 | if (y >= vp->height || (height + y) > (vp->height)) |
490 | return false; | 515 | return false; |
491 | 516 | ||
492 | s = find_scrolling_line(x, y); | 517 | s = find_scrolling_line(x, y); |
493 | restart = !s; | 518 | restart = !s; |
494 | 519 | ||
495 | /* get width (pixeks) of the string */ | ||
496 | LCDFN(getstringsize)(string, &w, &h); | ||
497 | |||
498 | /* Remove any previously scrolling line at the same location. If | 520 | /* Remove any previously scrolling line at the same location. If |
499 | * the string width is too small to scroll the scrolling line is | 521 | * the string width is too small to scroll the scrolling line is |
500 | * cleared as well */ | 522 | * cleared as well */ |
501 | if (w < width || restart) { | 523 | if (w < width || restart) { |
502 | LCDFN(scroll_stop_viewport_rect)(LCDFN(current_viewport), x, y, width, height); | 524 | LCDFN(scroll_stop_viewport_rect)(vp, x, y, width, height); |
503 | LCDFN(putsxyofs)(x, y, x_offset, string); | 525 | LCDFN(putsxyofs)(x, y, x_offset, string); |
504 | /* nothing to scroll, or out of scrolling lines. Either way, get out */ | 526 | /* nothing to scroll, or out of scrolling lines. Either way, get out */ |
505 | if (w < width || LCDFN(scroll_info).lines >= LCDM(SCROLLABLE_LINES)) | 527 | if (w < width || LCDFN(scroll_info).lines >= LCDM(SCROLLABLE_LINES)) |
@@ -512,7 +534,7 @@ static bool LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string, | |||
512 | strlcpy(s->linebuffer, string, sizeof(s->linebuffer)); | 534 | strlcpy(s->linebuffer, string, sizeof(s->linebuffer)); |
513 | /* scroll bidirectional or forward only depending on the string width */ | 535 | /* scroll bidirectional or forward only depending on the string width */ |
514 | if ( LCDFN(scroll_info).bidir_limit ) { | 536 | if ( LCDFN(scroll_info).bidir_limit ) { |
515 | s->bidir = w < (LCDFN(current_viewport)->width) * | 537 | s->bidir = w < (vp->width) * |
516 | (100 + LCDFN(scroll_info).bidir_limit) / 100; | 538 | (100 + LCDFN(scroll_info).bidir_limit) / 100; |
517 | } | 539 | } |
518 | else | 540 | else |
@@ -526,7 +548,7 @@ static bool LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string, | |||
526 | s->y = y; | 548 | s->y = y; |
527 | s->width = width; | 549 | s->width = width; |
528 | s->height = height; | 550 | s->height = height; |
529 | s->vp = LCDFN(current_viewport); | 551 | s->vp = vp; |
530 | s->start_tick = current_tick + LCDFN(scroll_info).delay; | 552 | s->start_tick = current_tick + LCDFN(scroll_info).delay; |
531 | LCDFN(scroll_info).lines++; | 553 | LCDFN(scroll_info).lines++; |
532 | } else { | 554 | } else { |