From 3b8740fab6c8cbef454249c116d2b4998d083250 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Fri, 1 Apr 2022 15:37:02 +0100 Subject: [PATCH] Bitmap Fonts: Add letter spacing. --- libraries/badger2040/badger2040.cpp | 8 ++++---- libraries/badger2040/badger2040.hpp | 4 ++-- libraries/bitmap_fonts/bitmap_fonts.cpp | 8 ++++---- libraries/bitmap_fonts/bitmap_fonts.hpp | 4 ++-- micropython/modules/badger2040/badger2040.cpp | 14 +++++++++----- 5 files changed, 21 insertions(+), 17 deletions(-) diff --git a/libraries/badger2040/badger2040.cpp b/libraries/badger2040/badger2040.cpp index ee5c489d..c41c1a7b 100644 --- a/libraries/badger2040/badger2040.cpp +++ b/libraries/badger2040/badger2040.cpp @@ -343,7 +343,7 @@ namespace pimoroni { } } - void Badger2040::text(std::string message, int32_t x, int32_t y, float s, float a) { + void Badger2040::text(std::string message, int32_t x, int32_t y, float s, float a, uint8_t letter_spacing) { if (_bitmap_font) { bitmap::text(_bitmap_font, [this](int32_t x, int32_t y, int32_t w, int32_t h) { for(auto px = 0; px < w; px++) { @@ -351,7 +351,7 @@ namespace pimoroni { pixel(x + px, y + py); } } - }, message, x, y, 296 - x, std::max(1.0f, s)); + }, message, x, y, 296 - x, std::max(1.0f, s), letter_spacing); } else { hershey::text(_font, [this](int32_t x1, int32_t y1, int32_t x2, int32_t y2) { line(x1, y1, x2, y2); @@ -359,8 +359,8 @@ namespace pimoroni { } } - int32_t Badger2040::measure_text(std::string message, float s) { - if (_bitmap_font) return bitmap::measure_text(_bitmap_font, message, std::max(1.0f, s)); + int32_t Badger2040::measure_text(std::string message, float s, uint8_t letter_spacing) { + if (_bitmap_font) return bitmap::measure_text(_bitmap_font, message, std::max(1.0f, s), letter_spacing); return hershey::measure_text(_font, message, s); } diff --git a/libraries/badger2040/badger2040.hpp b/libraries/badger2040/badger2040.hpp index 8ea3375a..774a9e67 100644 --- a/libraries/badger2040/badger2040.hpp +++ b/libraries/badger2040/badger2040.hpp @@ -69,10 +69,10 @@ namespace pimoroni { // text (fonts: sans, sans_bold, gothic, cursive_bold, cursive, serif_italic, serif, serif_bold) const hershey::font_glyph_t* glyph_data(unsigned char c); - void text(std::string message, int32_t x, int32_t y, float s = 1.0f, float a = 0.0f); + void text(std::string message, int32_t x, int32_t y, float s = 1.0f, float a = 0.0f, uint8_t letter_spacing = 1); int32_t glyph(unsigned char c, int32_t x, int32_t y, float s = 1.0f, float a = 0.0f); - int32_t measure_text(std::string message, float s = 1.0f); + int32_t measure_text(std::string message, float s = 1.0f, uint8_t letter_spacing = 1); int32_t measure_glyph(unsigned char c, float s = 1.0f); void debug_command(uint8_t command, size_t len, const uint8_t *data); diff --git a/libraries/bitmap_fonts/bitmap_fonts.cpp b/libraries/bitmap_fonts/bitmap_fonts.cpp index 9866bdc8..e563de08 100644 --- a/libraries/bitmap_fonts/bitmap_fonts.cpp +++ b/libraries/bitmap_fonts/bitmap_fonts.cpp @@ -21,7 +21,7 @@ namespace bitmap { return font->widths[char_index] * scale; } - int32_t measure_text(const font_t *font, const std::string &t, const uint8_t scale) { + int32_t measure_text(const font_t *font, const std::string &t, const uint8_t scale, const uint8_t letter_spacing) { int32_t text_width = 0; unicode_sorta::codepage_t codepage = unicode_sorta::PAGE_195; for(auto c : t) { @@ -32,7 +32,7 @@ namespace bitmap { continue; } text_width += measure_character(font, c, scale, codepage); - text_width += 1 * scale; + text_width += letter_spacing * scale; codepage = unicode_sorta::PAGE_195; // Reset back to default } return text_width; @@ -119,7 +119,7 @@ namespace bitmap { } } - void text(const font_t *font, rect_func rectangle, const std::string &t, const int32_t x, const int32_t y, const int32_t wrap, const uint8_t scale) { + void text(const font_t *font, rect_func rectangle, const std::string &t, const int32_t x, const int32_t y, const int32_t wrap, const uint8_t scale, const uint8_t letter_spacing) { uint32_t co = 0, lo = 0; // character and line (if wrapping) offset unicode_sorta::codepage_t codepage = unicode_sorta::PAGE_195; @@ -161,7 +161,7 @@ namespace bitmap { } character(font, rectangle, t[j], x + co, y + lo, scale, codepage); co += measure_character(font, t[j], scale, codepage); - co += 1 * scale; + co += letter_spacing * scale; codepage = unicode_sorta::PAGE_195; } diff --git a/libraries/bitmap_fonts/bitmap_fonts.hpp b/libraries/bitmap_fonts/bitmap_fonts.hpp index 5de76d49..9860e00d 100644 --- a/libraries/bitmap_fonts/bitmap_fonts.hpp +++ b/libraries/bitmap_fonts/bitmap_fonts.hpp @@ -19,8 +19,8 @@ namespace bitmap { typedef std::function rect_func; int32_t measure_character(const font_t *font, const char c, const uint8_t scale, unicode_sorta::codepage_t codepage = unicode_sorta::PAGE_195); - int32_t measure_text(const font_t *font, const std::string &t, const uint8_t scale); + int32_t measure_text(const font_t *font, const std::string &t, const uint8_t scale = 2, const uint8_t letter_spacing = 1); void character(const font_t *font, rect_func rectangle, const char c, const int32_t x, const int32_t y, const uint8_t scale = 2, unicode_sorta::codepage_t codepage = unicode_sorta::PAGE_195); - void text(const font_t *font, rect_func rectangle, const std::string &t, const int32_t x, const int32_t y, const int32_t wrap, const uint8_t scale = 2); + void text(const font_t *font, rect_func rectangle, const std::string &t, const int32_t x, const int32_t y, const int32_t wrap, const uint8_t scale = 2, const uint8_t letter_spacing = 1); } \ No newline at end of file diff --git a/micropython/modules/badger2040/badger2040.cpp b/micropython/modules/badger2040/badger2040.cpp index 69747fd4..e242552f 100644 --- a/micropython/modules/badger2040/badger2040.cpp +++ b/micropython/modules/badger2040/badger2040.cpp @@ -408,14 +408,15 @@ mp_obj_t Badger2040_icon(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_a mp_obj_t Badger2040_text(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_self, ARG_message, ARG_x, ARG_y, ARG_scale, ARG_rotation }; + enum { ARG_self, ARG_message, ARG_x, ARG_y, ARG_scale, ARG_rotation, ARG_letter_spacing }; static const mp_arg_t allowed_args[] = { { MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_message, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_x, MP_ARG_REQUIRED | MP_ARG_INT }, { MP_QSTR_y, MP_ARG_REQUIRED | MP_ARG_INT }, { MP_QSTR_scale, MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_rotation, MP_ARG_OBJ, {.u_obj = mp_const_none} } + { MP_QSTR_rotation, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_letter_spacing, MP_ARG_INT, {.u_int = 1} } }; // Parse args. @@ -423,6 +424,7 @@ mp_obj_t Badger2040_text(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_a mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); std::string message = mp_obj_to_string_r(args[ARG_message].u_obj); + int spacing = args[ARG_letter_spacing].u_int; int x = args[ARG_x].u_int; int y = args[ARG_y].u_int; float scale = 1.0f; @@ -435,7 +437,7 @@ mp_obj_t Badger2040_text(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_a } _Badger2040_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, _Badger2040_obj_t); - self->badger2040->text(message, x, y, scale, rotation); + self->badger2040->text(message, x, y, scale, rotation, spacing); return mp_const_none; } @@ -484,17 +486,19 @@ mp_obj_t Badger2040_glyph(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ } mp_obj_t Badger2040_measure_text(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_self, ARG_message, ARG_scale }; + enum { ARG_self, ARG_message, ARG_scale, ARG_letter_spacing }; static const mp_arg_t allowed_args[] = { { MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_message, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_scale, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_letter_spacing, MP_ARG_INT, {.u_int = 1} } }; // Parse args. mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + int spacing = args[ARG_letter_spacing].u_int; std::string message = mp_obj_to_string_r(args[ARG_message].u_obj); float scale = 1.0f; if (args[ARG_scale].u_obj != mp_const_none) { @@ -502,7 +506,7 @@ mp_obj_t Badger2040_measure_text(size_t n_args, const mp_obj_t *pos_args, mp_map } _Badger2040_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, _Badger2040_obj_t); - return mp_obj_new_int(self->badger2040->measure_text(message, scale)); + return mp_obj_new_int(self->badger2040->measure_text(message, scale, spacing)); } mp_obj_t Badger2040_measure_glyph(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {