diff options
author | William Wilgus <wilgus.william@gmail.com> | 2020-10-31 00:18:57 -0400 |
---|---|---|
committer | William Wilgus <wilgus.william@gmail.com> | 2020-10-31 01:11:30 -0400 |
commit | 60f642ba4f6a9bf2d976f133b85b8f6a7502c14c (patch) | |
tree | a37547c0972899968a4a2ff148ded098d40f0f36 /firmware/drivers/lcd-bitmap-common.c | |
parent | 202f9df0c1e6132631e9e1372d50fe8dc8e87f20 (diff) | |
download | rockbox-60f642ba4f.tar.gz rockbox-60f642ba4f.zip |
lcd_framebuffer bugfixes, sanity checks
several issues I saw that could pontentially cause problems
scroll engine doesn't take text height into account when checking bounds
NBELEMS was one whole row too large hopefully I got them right this time
Change-Id: If303da8320429c3964fc675351cb088d46303745
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 @@ #include "string-extra.h" #include "diacritic.h" +#ifdef LOGF_ENABLE +#include "panic.h" +#endif + #ifndef LCDFN /* Not compiling for remote - define macros for main LCD. */ #define LCDFN(fn) lcd_ ## fn #define FBFN(fn) fb_ ## fn @@ -77,7 +81,10 @@ struct viewport* LCDFN(init_viewport)(struct viewport* vp) { struct frame_buffer_t *fb_default = &LCDFN(framebuffer_default); if (!vp) /* NULL vp grabs default viewport */ + { vp = &default_vp; + vp->buffer = fb_default; + } /* use defaults if no buffer is provided */ if (vp->buffer == NULL || vp->buffer->elems == 0) @@ -92,6 +99,19 @@ struct viewport* LCDFN(init_viewport)(struct viewport* vp) if (vp->buffer->get_address_fn == NULL) vp->buffer->get_address_fn = fb_default->get_address_fn; + +#ifdef LOGF_ENABLE + if ((size_t)LCD_NBELEMS(vp->width, vp->height) > vp->buffer->elems) + { + if (vp->buffer != fb_default) + panicf("viewport %d x %d > buffer", vp->width, vp->height); + logf("viewport %d x %d, %d x %d [%lu] > buffer [%lu]", vp->x, vp->y, + vp->width, vp->height, + (unsigned long) LCD_NBELEMS(vp->width, vp->height), + (unsigned long) vp->buffer->elems); + + } +#endif } return vp; } @@ -474,32 +494,34 @@ static bool LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string, int width, height; int w, h, cwidth; bool restart; + struct viewport * vp = LCDFN(current_viewport); if (!string) return false; /* prepare rectangle for scrolling. x and y must be calculated early * for find_scrolling_line() to work */ - cwidth = font_get(LCDFN(current_viewport)->font)->maxwidth; - height = font_get(LCDFN(current_viewport)->font)->height; + + cwidth = font_get(vp->font)->maxwidth; + /* get width (pixels) of the string */ + LCDFN(getstringsize)(string, &w, &h); + height = h; + y = y * (linebased ? height : 1); x = x * (linebased ? cwidth : 1); - width = LCDFN(current_viewport)->width - x; + width = vp->width - x; - if (y >= LCDFN(current_viewport)->height) + if (y >= vp->height || (height + y) > (vp->height)) return false; s = find_scrolling_line(x, y); restart = !s; - /* get width (pixeks) of the string */ - LCDFN(getstringsize)(string, &w, &h); - /* Remove any previously scrolling line at the same location. If * the string width is too small to scroll the scrolling line is * cleared as well */ if (w < width || restart) { - LCDFN(scroll_stop_viewport_rect)(LCDFN(current_viewport), x, y, width, height); + LCDFN(scroll_stop_viewport_rect)(vp, x, y, width, height); LCDFN(putsxyofs)(x, y, x_offset, string); /* nothing to scroll, or out of scrolling lines. Either way, get out */ 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, strlcpy(s->linebuffer, string, sizeof(s->linebuffer)); /* scroll bidirectional or forward only depending on the string width */ if ( LCDFN(scroll_info).bidir_limit ) { - s->bidir = w < (LCDFN(current_viewport)->width) * + s->bidir = w < (vp->width) * (100 + LCDFN(scroll_info).bidir_limit) / 100; } else @@ -526,7 +548,7 @@ static bool LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string, s->y = y; s->width = width; s->height = height; - s->vp = LCDFN(current_viewport); + s->vp = vp; s->start_tick = current_tick + LCDFN(scroll_info).delay; LCDFN(scroll_info).lines++; } else { |