diff --git a/libraries/pico_vector/alright_fonts.cpp b/libraries/pico_vector/alright_fonts.cpp index 5289c50f..071f53dc 100644 --- a/libraries/pico_vector/alright_fonts.cpp +++ b/libraries/pico_vector/alright_fonts.cpp @@ -11,6 +11,19 @@ using namespace pretty_poly; namespace alright_fonts { + /* + utility functions + */ + pretty_poly::rect_t measure_character(text_metrics_t &tm, uint16_t codepoint) { + if(tm.face.glyphs.count(codepoint) == 1) { + glyph_t glyph = tm.face.glyphs[codepoint]; + + return {0, 0, ((glyph.advance * tm.size) / 128), tm.size}; + } + + return {0, 0, 0, 0}; + } + /* render functions */ diff --git a/libraries/pico_vector/alright_fonts.hpp b/libraries/pico_vector/alright_fonts.hpp index 4bc7afff..4882beba 100644 --- a/libraries/pico_vector/alright_fonts.hpp +++ b/libraries/pico_vector/alright_fonts.hpp @@ -52,14 +52,19 @@ namespace alright_fonts { void set_size(int s) { size = s; - line_height = size * 1.2; + line_height = size; letter_spacing = 0; - word_spacing = size; + word_spacing = size / 2; } text_metrics_t() {}; }; + /* + utility functions + */ + pretty_poly::rect_t measure_character(text_metrics_t &tm, uint16_t codepoint); + /* render functions */ diff --git a/libraries/pico_vector/pico_vector.cpp b/libraries/pico_vector/pico_vector.cpp index e4f91971..0d1996f8 100644 --- a/libraries/pico_vector/pico_vector.cpp +++ b/libraries/pico_vector/pico_vector.cpp @@ -13,16 +13,56 @@ namespace pimoroni { // TODO: Normalize types somehow, so we're not converting? pretty_poly::point_t caret = pretty_poly::point_t(origin.x, origin.y); - for (auto c : text) { - alright_fonts::render_character(text_metrics, c, caret); - if(text_metrics.face.glyphs.count(c) == 1) { - alright_fonts::glyph_t glyph = text_metrics.face.glyphs[c]; - caret.x += ((glyph.advance * text_metrics.size) / 128); - if(caret.x > graphics->bounds.w) { - caret.y += text_metrics.size; - caret.x = origin.x; - } + // Align text from the bottom left + caret.y += text_metrics.size; + + int16_t space_width = alright_fonts::measure_character(text_metrics, ' ').w; + if (space_width == 0) { + space_width = text_metrics.word_spacing; + } + + size_t i = 0; + + while(i < text.length()) { + size_t next_space = text.find(' ', i + 1); + + if(next_space == std::string::npos) { + next_space = text.length(); + } + + size_t next_linebreak = text.find('\n', i + 1); + + if(next_linebreak == std::string::npos) { + next_linebreak = text.length(); + } + + size_t next_break = std::min(next_space, next_linebreak); + + uint16_t word_width = 0; + for(size_t j = i; j < next_break; j++) { + word_width += alright_fonts::measure_character(text_metrics, text[j]).w; + word_width += text_metrics.letter_spacing; + } + + if(caret.x != 0 && caret.x + word_width > graphics->clip.w) { + caret.x = 0; + caret.y += text_metrics.line_height; + } + + for(size_t j = i; j < std::min(next_break + 1, text.length()); j++) { + if (text[j] == '\n') { // Linebreak + caret.x = 0; + caret.y += text_metrics.line_height; + } else if (text[j] == ' ') { // Space + caret.x += space_width; + } else { + alright_fonts::render_character(text_metrics, text[j], caret); } + caret.x += alright_fonts::measure_character(text_metrics, text[j]).w; + caret.x += text_metrics.letter_spacing; + } + + i = next_break + 1; } return Point(caret.x, caret.y); diff --git a/libraries/pico_vector/pico_vector.hpp b/libraries/pico_vector/pico_vector.hpp index b8132730..1533aa06 100644 --- a/libraries/pico_vector/pico_vector.hpp +++ b/libraries/pico_vector/pico_vector.hpp @@ -21,7 +21,7 @@ namespace pimoroni { } } } - }, pretty_poly::NONE, {0, 0, graphics->bounds.w, graphics->bounds.h}); + }, pretty_poly::X4, {0, 0, graphics->bounds.w, graphics->bounds.h}); }; bool set_font(std::string_view font_path, unsigned int font_size) {