From 8170799f01e92bdf47f225854bea347decbe72a7 Mon Sep 17 00:00:00 2001 From: Adolfo Reyna Date: Sun, 18 Jan 2026 23:30:11 -0500 Subject: [PATCH] correct for narrow chars on fonts --- app | Bin 103648 -> 103648 bytes low_level_render.cpp | 60 +++++++++++++++++++++++++++++++------------ low_level_render.h | 4 +-- main.cpp | 2 +- 4 files changed, 47 insertions(+), 19 deletions(-) diff --git a/app b/app index 8a89bc8e9fb5601c66e3a4871ce9fd7e79eef0d7..e44f80c7ecf024ad5f021ccc54b2c1d39ecd8e24 100755 GIT binary patch delta 5176 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 Uc#mr8e&A-`%QYd!srgj*9|ww;YXATM diff --git a/low_level_render.cpp b/low_level_render.cpp index edc8a16..d2fc8bf 100644 --- a/low_level_render.cpp +++ b/low_level_render.cpp @@ -525,22 +525,34 @@ void LowLevelRenderer::draw_filled_circle(int x, int y, int radius, bool on) } } -void LowLevelRenderer::draw_char_vcol(int x, int y, char c) +int LowLevelRenderer::draw_char_vcol(int x, int y, char c) { - if (!current_font) return; + if (!current_font) return 0; // The font table starts at space (ASCII 32) if (c < 32 || c > 127) - return; + return 0; int font_idx = c - 32; const unsigned char* char_data = current_font->get_char_data(font_idx); - if (!char_data) return; + if (!char_data) return 0; int bytes_per_char = current_font->get_bytes_per_char(); int char_height = current_font->get_char_height(); - for (int col = 0; col < bytes_per_char; col++) + // Find the actual width by skipping trailing empty columns + int actual_width = 0; + for (int col = bytes_per_char - 1; col >= 0; col--) + { + if (char_data[col] != 0) + { + actual_width = col + 1; + break; + } + } + + // Draw only up to the actual width + for (int col = 0; col < actual_width; col++) { unsigned char column_byte = char_data[col]; @@ -553,35 +565,50 @@ void LowLevelRenderer::draw_char_vcol(int x, int y, char c) } } } + + return actual_width; } void LowLevelRenderer::draw_string(int x, int y, const std::string &text, int spacing) { if (!current_font) return; - int char_width = current_font->get_bytes_per_char(); + int current_x = x; for (size_t i = 0; i < text.length(); i++) { - draw_char_vcol(x + (i * (char_width + spacing)), y, text[i]); + int char_width = draw_char_vcol(current_x, y, text[i]); + current_x += char_width + spacing; } } -void LowLevelRenderer::draw_char_scaled(int x, int y, char c, int scale) +int LowLevelRenderer::draw_char_scaled(int x, int y, char c, int scale) { - if (!current_font) return; + if (!current_font) return 0; if (c < 32 || c > 127) - return; + return 0; if (scale < 1) scale = 1; // Safety check int font_idx = c - 32; const unsigned char* char_data = current_font->get_char_data(font_idx); - if (!char_data) return; + if (!char_data) return 0; int bytes_per_char = current_font->get_bytes_per_char(); int char_height = current_font->get_char_height(); - for (int col = 0; col < bytes_per_char; col++) + // Find the actual width by skipping trailing empty columns + int actual_width = 0; + for (int col = bytes_per_char - 1; col >= 0; col--) + { + if (char_data[col] != 0) + { + actual_width = col + 1; + break; + } + } + + // Draw only up to the actual width, scaled + for (int col = 0; col < actual_width; col++) { unsigned char column_byte = char_data[col]; @@ -602,18 +629,19 @@ void LowLevelRenderer::draw_char_scaled(int x, int y, char c, int scale) } } } + + return actual_width * scale; } void LowLevelRenderer::draw_string_scaled(int x, int y, const char* text, int scale, int spacing) { if (!current_font) return; - int char_width = current_font->get_bytes_per_char(); + int current_x = x; int i = 0; while(text[i] != '\0') { - // We multiply the character width and spacing by the scale - int next_x = x + (i * (char_width + spacing) * scale); - draw_char_scaled(next_x, y, text[i], scale); + int char_width = draw_char_scaled(current_x, y, text[i], scale); + current_x += char_width + (spacing * scale); i++; } } diff --git a/low_level_render.h b/low_level_render.h index fe725ec..1b46e26 100644 --- a/low_level_render.h +++ b/low_level_render.h @@ -140,9 +140,9 @@ public: void draw_circle(int x, int y, int radius, bool on); void draw_filled_circle(int x, int y, int radius, bool on); - void draw_char_vcol(int x, int y, char c); + int draw_char_vcol(int x, int y, char c); void draw_string(int x, int y, const std::string &text, int spacing = 1); - void draw_char_scaled(int x, int y, char c, int scale); + int draw_char_scaled(int x, int y, char c, int scale); void draw_string_scaled(int x, int y, const char* text, int scale, int spacing = 1); }; diff --git a/main.cpp b/main.cpp index b771d33..a8d2220 100644 --- a/main.cpp +++ b/main.cpp @@ -149,7 +149,7 @@ int main() */ // Text with different fonts - renderer.set_font(&font_HISKYF21_obj); + renderer.set_font(&font_acme_5_outlines_obj); renderer.draw_string_scaled(10, 10, "Drawing Demo", 2);