From c7d9fe411ae24963ccb9bda1ee8cb4f830a04f8d Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Tue, 15 Aug 2023 15:36:52 +0100 Subject: [PATCH] PicoVector: Bugfixes and font/aa options. --- libraries/pico_vector/pico_vector.cpp | 4 +- libraries/pico_vector/pico_vector.hpp | 37 ++++++++++++------- libraries/pico_vector/pretty_poly.hpp | 7 ++++ libraries/pico_vector/pretty_poly_types.hpp | 2 +- micropython/modules/picovector/picovector.c | 7 ++++ micropython/modules/picovector/picovector.cpp | 15 ++++++++ micropython/modules/picovector/picovector.h | 4 +- 7 files changed, 58 insertions(+), 18 deletions(-) diff --git a/libraries/pico_vector/pico_vector.cpp b/libraries/pico_vector/pico_vector.cpp index 0d1996f8..a060aa38 100644 --- a/libraries/pico_vector/pico_vector.cpp +++ b/libraries/pico_vector/pico_vector.cpp @@ -45,13 +45,13 @@ namespace pimoroni { } if(caret.x != 0 && caret.x + word_width > graphics->clip.w) { - caret.x = 0; + caret.x = origin.x; 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.x = origin.x; caret.y += text_metrics.line_height; } else if (text[j] == ' ') { // Space caret.x += space_width; diff --git a/libraries/pico_vector/pico_vector.hpp b/libraries/pico_vector/pico_vector.hpp index e1f18db5..80a6d27f 100644 --- a/libraries/pico_vector/pico_vector.hpp +++ b/libraries/pico_vector/pico_vector.hpp @@ -13,12 +13,14 @@ namespace pimoroni { PicoVector(PicoGraphics *graphics, void *mem = nullptr) : graphics(graphics) { pretty_poly::init(mem); + set_options([this](const pretty_poly::tile_t &tile) -> void { + uint8_t *tile_data = tile.data; - if(graphics->supports_alpha_blend()) { - set_options([this](const pretty_poly::tile_t &tile) -> void { + if(this->graphics->supports_alpha_blend() && pretty_poly::settings::antialias != pretty_poly::NONE) { for(auto y = 0; y < tile.bounds.h; y++) { - for(auto x = 0; x < tile.bounds.w; x++) { - uint8_t alpha = tile.get_value(x, y); + for(auto x = 0; x < (int)tile.stride; x++) { + uint8_t alpha = *tile_data++; + if(x > tile.bounds.w) continue; if (alpha >= 4) { this->graphics->pixel({x + tile.bounds.x, y + tile.bounds.y}); } else if (alpha > 0) { @@ -27,25 +29,32 @@ namespace pimoroni { } } } - }, pretty_poly::X4, {0, 0, graphics->bounds.w, graphics->bounds.h}); - } else { - set_options([this](const pretty_poly::tile_t &tile) -> void { + } else { for(auto y = 0; y < tile.bounds.h; y++) { - for(auto x = 0; x < tile.bounds.w; x++) { - uint8_t alpha = tile.get_value(x, y); - if (alpha > 0) { + for(auto x = 0; x < (int)tile.stride; x++) { + uint8_t alpha = *tile_data++; + if(x > tile.bounds.w) continue; + if (alpha) { this->graphics->pixel({x + tile.bounds.x, y + tile.bounds.y}); } } } - }, pretty_poly::NONE, {0, 0, graphics->bounds.w, graphics->bounds.h}); - } - }; + } + }, graphics->supports_alpha_blend() ? pretty_poly::X4 : pretty_poly::NONE, {0, 0, graphics->bounds.w, graphics->bounds.h}); + } + + void set_antialiasing(pretty_poly::antialias_t antialias) { + set_options(pretty_poly::settings::callback, antialias, pretty_poly::settings::clip); + } + + void set_font_size(unsigned int font_size) { + text_metrics.set_size(font_size); + } bool set_font(std::string_view font_path, unsigned int font_size) { bool result = text_metrics.face.load(font_path); - text_metrics.set_size(font_size); + set_font_size(font_size); return result; } diff --git a/libraries/pico_vector/pretty_poly.hpp b/libraries/pico_vector/pretty_poly.hpp index 58c2e789..d1ee2430 100644 --- a/libraries/pico_vector/pretty_poly.hpp +++ b/libraries/pico_vector/pretty_poly.hpp @@ -34,6 +34,13 @@ namespace pretty_poly { typedef std::function tile_callback_t; + // user settings + namespace settings { + extern rect_t clip; + extern tile_callback_t callback; + extern antialias_t antialias; + } + constexpr size_t buffer_size() { return tile_buffer_size + (node_buffer_size * sizeof(unsigned)) + (node_buffer_size * 32 * sizeof(int)); } diff --git a/libraries/pico_vector/pretty_poly_types.hpp b/libraries/pico_vector/pretty_poly_types.hpp index 5dcda206..643dba58 100644 --- a/libraries/pico_vector/pretty_poly_types.hpp +++ b/libraries/pico_vector/pretty_poly_types.hpp @@ -97,7 +97,7 @@ namespace pretty_poly { tile_t() {}; - int get_value(int x, int y) const { + inline int get_value(int x, int y) const { return this->data[x + y * this->stride]; } }; diff --git a/micropython/modules/picovector/picovector.c b/micropython/modules/picovector/picovector.c index 56f374c2..8b9b6be8 100644 --- a/micropython/modules/picovector/picovector.c +++ b/micropython/modules/picovector/picovector.c @@ -4,6 +4,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(VECTOR_polygon_obj, 2, VECTOR_polygon); STATIC MP_DEFINE_CONST_FUN_OBJ_KW(VECTOR_regular_polygon_obj, 6, VECTOR_regular_polygon); STATIC MP_DEFINE_CONST_FUN_OBJ_KW(VECTOR_text_obj, 4, VECTOR_text); STATIC MP_DEFINE_CONST_FUN_OBJ_3(VECTOR_set_font_obj, VECTOR_set_font); +STATIC MP_DEFINE_CONST_FUN_OBJ_2(VECTOR_set_font_size_obj, VECTOR_set_font_size); +STATIC MP_DEFINE_CONST_FUN_OBJ_2(VECTOR_set_antialiasing_obj, VECTOR_set_antialiasing); // class @@ -11,6 +13,8 @@ STATIC const mp_rom_map_elem_t VECTOR_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_polygon), MP_ROM_PTR(&VECTOR_polygon_obj) }, { MP_ROM_QSTR(MP_QSTR_regular_polygon), MP_ROM_PTR(&VECTOR_regular_polygon_obj) }, { MP_ROM_QSTR(MP_QSTR_set_font), MP_ROM_PTR(&VECTOR_set_font_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_font_size), MP_ROM_PTR(&VECTOR_set_font_size_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_antialiasing), MP_ROM_PTR(&VECTOR_set_antialiasing_obj) }, { MP_ROM_QSTR(MP_QSTR_text), MP_ROM_PTR(&VECTOR_text_obj) }, }; @@ -37,6 +41,9 @@ const mp_obj_type_t VECTOR_type = { STATIC const mp_map_elem_t VECTOR_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_picovector) }, { MP_OBJ_NEW_QSTR(MP_QSTR_PicoVector), (mp_obj_t)&VECTOR_type }, + { MP_ROM_QSTR(MP_QSTR_ANTIALIAS_NONE), MP_ROM_INT(0) }, + { MP_ROM_QSTR(MP_QSTR_ANTIALIAS_X4), MP_ROM_INT(1) }, + { MP_ROM_QSTR(MP_QSTR_ANTIALIAS_X16), MP_ROM_INT(2) }, }; STATIC MP_DEFINE_CONST_DICT(mp_module_VECTOR_globals, VECTOR_globals_table); diff --git a/micropython/modules/picovector/picovector.cpp b/micropython/modules/picovector/picovector.cpp index 6c69be06..60af3f9d 100644 --- a/micropython/modules/picovector/picovector.cpp +++ b/micropython/modules/picovector/picovector.cpp @@ -141,6 +141,21 @@ mp_obj_t VECTOR_set_font(mp_obj_t self_in, mp_obj_t font, mp_obj_t size) { return result ? mp_const_true : mp_const_false; } +mp_obj_t VECTOR_set_font_size(mp_obj_t self_in, mp_obj_t size) { + _VECTOR_obj_t *self = MP_OBJ_TO_PTR2(self_in, _VECTOR_obj_t); + + int font_size = mp_obj_get_int(size); + self->vector->set_font_size(font_size); + return mp_const_none; +} + +mp_obj_t VECTOR_set_antialiasing(mp_obj_t self_in, mp_obj_t aa) { + _VECTOR_obj_t *self = MP_OBJ_TO_PTR2(self_in, _VECTOR_obj_t); + + self->vector->set_antialiasing((pretty_poly::antialias_t)mp_obj_get_int(aa)); + return mp_const_none; +} + mp_obj_t VECTOR_text(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_self, ARG_text, ARG_x, ARG_y }; static const mp_arg_t allowed_args[] = { diff --git a/micropython/modules/picovector/picovector.h b/micropython/modules/picovector/picovector.h index 05109b9b..16a59fce 100644 --- a/micropython/modules/picovector/picovector.h +++ b/micropython/modules/picovector/picovector.h @@ -8,4 +8,6 @@ extern mp_obj_t VECTOR_make_new(const mp_obj_type_t *type, size_t n_args, size_t extern mp_obj_t VECTOR_polygon(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); extern mp_obj_t VECTOR_regular_polygon(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); extern mp_obj_t VECTOR_text(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); -extern mp_obj_t VECTOR_set_font(mp_obj_t self_in, mp_obj_t font, mp_obj_t size); \ No newline at end of file +extern mp_obj_t VECTOR_set_font(mp_obj_t self_in, mp_obj_t font, mp_obj_t size); +extern mp_obj_t VECTOR_set_font_size(mp_obj_t self_in, mp_obj_t size); +extern mp_obj_t VECTOR_set_antialiasing(mp_obj_t self_in, mp_obj_t aa); \ No newline at end of file