From 20cde4e4732abefce867b913907f541d5cdafb29 Mon Sep 17 00:00:00 2001 From: Ryan Turner Date: Tue, 19 May 2026 19:49:09 -0500 Subject: [PATCH] gfx: fix printBuffer wrap, UB glyph access order, and text_size.y Three bugs fixed in gfx_printBuffer: 1. Word-wrap was remeasuring line size from the start of the buffer instead of from the current position, causing incorrect alignment on wrapped lines. Pass &buf[i] to get_line_size and pass reset_x (not start.x) to get_reset_x so the left margin is preserved across wraps. 2. The glyph array was indexed unconditionally before the '\n'/'\r' check. For fonts whose first glyph is 0x20 (space), a newline character (0x0A) produces a negative index, which is undefined behaviour. Move the control-character check before the glyph lookup. 3. text_size.y was computed as (saved_start_y - start.y) + line_h. Because start.y grows downward as lines are added, the subtraction underflows for any multi-line string. Correct to (start.y - saved_start_y) + line_h. Also change saved_start_y to int16_t to match point_t.y. Co-authored-by: GitHub Copilot Signed-off-by: Ryan Turner --- openrtx/src/core/graphics.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/openrtx/src/core/graphics.c b/openrtx/src/core/graphics.c index 5d7d2a46..f77e1eb5 100644 --- a/openrtx/src/core/graphics.c +++ b/openrtx/src/core/graphics.c @@ -451,27 +451,18 @@ point_t gfx_printBuffer(point_t start, fontSize_t size, textAlign_t alignment, uint16_t reset_x = get_reset_x(alignment, line_size, start.x); start.x = reset_x; // Save initial start.y value to calculate vertical size - uint16_t saved_start_y = start.y; + int16_t saved_start_y = start.y; uint16_t line_h = 0; /* For each char in the string */ for(unsigned i = 0; i < len; i++) { char c = buf[i]; - GFXglyph glyph = f.glyph[c - f.first]; - uint8_t *bitmap = f.bitmap; - uint16_t bo = glyph.bitmapOffset; - uint8_t w = glyph.width, h = glyph.height; - int8_t xo = glyph.xOffset, - yo = glyph.yOffset; - uint8_t xx, yy, bits = 0, bit = 0; - line_h = h; - - // Handle newline and carriage return + // Handle newline and carriage return before accessing glyph table if (c == '\n') { - if(alignment!=TEXT_ALIGN_CENTER) + if(alignment != TEXT_ALIGN_CENTER) { start.x = reset_x; } @@ -489,12 +480,23 @@ point_t gfx_printBuffer(point_t start, fontSize_t size, textAlign_t alignment, continue; } + GFXglyph glyph = f.glyph[c - f.first]; + uint8_t *bitmap = f.bitmap; + + uint16_t bo = glyph.bitmapOffset; + uint8_t w = glyph.width, h = glyph.height; + int8_t xo = glyph.xOffset, + yo = glyph.yOffset; + uint8_t xx, yy, bits = 0, bit = 0; + line_h = h; + // Handle wrap around if (start.x + glyph.xAdvance > CONFIG_SCREEN_WIDTH) { - // Compute size of the first row in pixels - line_size = get_line_size(f, buf, len); - start.x = reset_x = get_reset_x(alignment, line_size, start.x); + // Compute size of the remaining text for this new line + line_size = get_line_size(f, &buf[i], len - i); + // Pass reset_x (the original start x) not start.x (current pos) + start.x = reset_x = get_reset_x(alignment, line_size, reset_x); start.y += f.yAdvance; } @@ -532,7 +534,7 @@ point_t gfx_printBuffer(point_t start, fontSize_t size, textAlign_t alignment, // Calculate text size point_t text_size = {0, 0}; text_size.x = line_size; - text_size.y = (saved_start_y - start.y) + line_h; + text_size.y = (start.y - saved_start_y) + line_h; return text_size; }