Repository navigation
Fix scrolling text smearing at text sizes above 1 - #69
Merged
Merged
Conversation
endText() moves the text one pixel per frame and, rather than repainting the screen, erases only the single line the text just vacated. That erase has to land exactly on the trailing edge, because nothing else will cover it. It did not. The travel distance came from textFontWidth() and textFontHeight(), which scale with textSize(), but the erase was positioned from _font->width and _font->height, which do not. The two agree only at textSize(1). Above that the erase fell short of the trailing edge and left a line of pixels behind on every frame, so glyphs smeared in the scroll direction. Use the scaled accessors for the erase as well. SCROLL_RIGHT was the least affected because the space-glyph bitmap drawn just after the erase already covers the full scaled height, which is why horizontal scrolling could look correct while vertical scrolling did not. Modelling the painted and erased regions frame by frame, stale pixels per frame before and after, for Font_5x7: size LEFT RIGHT UP DOWN LEFT RIGHT UP DOWN 1x1 0 0 0 0 0 0 0 0 2x2 14 0 20 20 -> 0 0 0 0 3x1 7 0 20 40 0 0 0 0 1x3 14 0 10 0 0 0 0 0 The two bitmap() calls are left alone: they take unscaled source dimensions plus separate scale factors, so passing _font->width and _font->height there is correct. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
leonardocavagnis
self-requested a review
September 7, 2026 14:58
leonardocavagnis
approved these changes
Sep 7, 2026
leonardocavagnis
left a comment
Contributor
There was a problem hiding this comment.
LGTM :)
Tested on 128x64 I2C OLED (Chip controller: ST7315)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The problem
endText()scrolls by one pixel per frame and, rather than repainting the screen, erases only the single line the text just vacated. That erase has to land exactly on the trailing edge, because nothing else will cover it.It doesn't. The travel distance is computed from
textFontWidth()/textFontHeight(), which scale withtextSize(), while the erase is positioned from_font->width/_font->height, which don't:The two agree only at
textSize(1). Above that the erase falls short of the trailing edge and leaves a line of pixels behind on every frame, so glyphs smear in the scroll direction.The fix
Use the scaled accessors for the erase as well. Six lines across the four scroll branches.
The two
bitmap()calls inSCROLL_RIGHTandSCROLL_DOWNare deliberately left alone:bitmap()takes unscaled source dimensions plus separate scale factors, so passing_font->width/_font->heightthere is already correct.Why horizontal scrolling looked fine
SCROLL_RIGHTwas the least affected because the space-glyphbitmap()drawn just after the erase already covers the full scaled height.SCROLL_LEFTleaves a 1px-wide column behind, which is invisible whenever the trailing column of the last glyph happens to be blank. The vertical directions have no such cover, which is why they were the visible ones.Verification
Modelling the painted and erased regions frame by frame, counting pixels from frame N that frame N+1 neither repaints nor erases (Font_5x7):
Zero stale pixels in every direction at every size, including the non-uniform ones from
textSize(sx, sy).Originally found on a 128x64 I2C OLED driven through a
Print-based ArduinoGraphics backend:SCROLL_UPattextSize(2)tore the glyphs and left the previous word's pixels on screen. Confirmed fixed there.🤖 Generated with Claude Code