From 88055b2f2e8059fdf6e146efcd8ebe8939eeea79 Mon Sep 17 00:00:00 2001 From: Jonathan Gordon Date: Wed, 2 Jul 2008 09:42:36 +0000 Subject: [PATCH] fix FS#9140 by changing stop_scroll so it stops scrolling lines which would overlap the current viewport. This shouldnt cause any problems because when this happens the vp owning the line should redraw when the new vp's screen is exited. Also fix a potential bug where only one scrolling line in a viewport was stopped git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17913 a1c6a512-1295-4272-9138-f99709370657 --- firmware/scroll_engine.c | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/firmware/scroll_engine.c b/firmware/scroll_engine.c index 200695b5d6..9607c90448 100644 --- a/firmware/scroll_engine.c +++ b/firmware/scroll_engine.c @@ -84,6 +84,18 @@ void lcd_stop_scroll(void) lcd_scroll_info.lines = 0; } +/* returns true if the 'line' in 'lines_vp' would scroll into 'othervp' */ +static bool line_overlaps_viewport(struct viewport *lines_vp, int line, + struct viewport *othervp) +{ + int y = (font_get(lines_vp->font)->height*line) + lines_vp->y; + if (y < othervp->y || y > othervp->y + othervp->height) + return false; + else if ((lines_vp->x + lines_vp->width < othervp->x) || + (othervp->x + othervp->width < lines_vp->x)) + return false; + return true; +} /* Stop scrolling line y in the specified viewport, or all lines if y < 0 */ void lcd_scroll_stop_line(struct viewport* current_vp, int y) { @@ -91,8 +103,11 @@ void lcd_scroll_stop_line(struct viewport* current_vp, int y) while (i < lcd_scroll_info.lines) { - if ((lcd_scroll_info.scroll[i].vp == current_vp) && - ((y < 0) || (lcd_scroll_info.scroll[i].y == y))) + if (((lcd_scroll_info.scroll[i].vp == current_vp) && + ((y < 0) || (lcd_scroll_info.scroll[i].y == y))) || + ((lcd_scroll_info.scroll[i].vp != current_vp) && + line_overlaps_viewport(lcd_scroll_info.scroll[i].vp, + lcd_scroll_info.scroll[i].y, current_vp))) { /* If i is not the last active line in the array, then move the last item to position i */ @@ -102,8 +117,10 @@ void lcd_scroll_stop_line(struct viewport* current_vp, int y) } lcd_scroll_info.lines--; - /* A line can only appear once, so we're done. */ - return ; + /* A line can only appear once, so we're done, + * unless we are clearing the whole viewport */ + if (y >= 0) + return ; } else { @@ -165,8 +182,11 @@ void lcd_remote_scroll_stop_line(struct viewport* current_vp, int y) while (i < lcd_remote_scroll_info.lines) { - if ((lcd_remote_scroll_info.scroll[i].vp == current_vp) && - ((y < 0) || (lcd_remote_scroll_info.scroll[i].y == y))) + if (((lcd_remote_scroll_info.scroll[i].vp == current_vp) && + ((y < 0) || (lcd_remote_scroll_info.scroll[i].y == y))) || + (((lcd_remote_scroll_info.scroll[i].vp != current_vp) && + line_overlaps_viewport(lcd_scroll_info.scroll[i].vp, + lcd_scroll_info.scroll[i].y, current_vp)))) { /* If i is not the last active line in the array, then move the last item to position i */ @@ -176,8 +196,10 @@ void lcd_remote_scroll_stop_line(struct viewport* current_vp, int y) } lcd_remote_scroll_info.lines--; - /* A line can only appear once, so we're done. */ - return ; + /* A line can only appear once, so we're done, + * unless we are clearing the whole viewport */ + if (y >= 0) + return ; } else {