From 581481c2ef5464de251269e4a8fe2ab524dd4835 Mon Sep 17 00:00:00 2001 From: Mike Bell Date: Sat, 9 Sep 2023 01:28:48 +0100 Subject: [PATCH 1/5] Improve pretty_poly performance (cherry picked from commit 1077a12ff4fd958a7ea6d9e4fa5a86551eba5126) --- libraries/pico_vector/pretty_poly.cpp | 56 ++++++++++++++++++++------- libraries/pico_vector/pretty_poly.hpp | 2 +- 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/libraries/pico_vector/pretty_poly.cpp b/libraries/pico_vector/pretty_poly.cpp index 78617ca60..727588359 100644 --- a/libraries/pico_vector/pretty_poly.cpp +++ b/libraries/pico_vector/pretty_poly.cpp @@ -79,35 +79,42 @@ namespace pretty_poly { std::swap(sx, ex); } + if (ey < 0 || sy >= (int)node_buffer_size) return; + /*sx <<= settings::antialias; ex <<= settings::antialias; sy <<= settings::antialias; ey <<= settings::antialias;*/ int x = sx; - int y = sy; int e = 0; int xinc = sign(ex - sx); int einc = abs(ex - sx) + 1; - - // todo: preclamp sy and ey (and therefore count) no need to perform - // that test inside the loop int dy = ey - sy; - int count = dy; + + if (sy < 0) { + e = einc * -sy; + int xjump = e / dy; + e -= dy * xjump; + x += xinc * xjump; + sy = 0; + } + + int y = sy; + + int count = std::min((int)node_buffer_size, ey) - sy; debug(" + line segment from %d, %d to %d, %d\n", sx, sy, ex, ey); // loop over scanlines while(count--) { // consume accumulated error while(e > dy) {e -= dy; x += xinc;} - if(y >= 0 && y < (int)node_buffer_size) { - // clamp node x value to tile bounds - int nx = std::max(std::min(x, (int)(tile_bounds.w << settings::antialias)), 0); - debug(" + adding node at %d, %d\n", x, y); - // add node to node list - nodes[y][node_counts[y]++] = nx; - } + // clamp node x value to tile bounds + int nx = std::max(std::min(x, (int)(tile_bounds.w << settings::antialias)), 0); + debug(" + adding node at %d, %d\n", x, y); + // add node to node list + nodes[y][node_counts[y]++] = nx; // step to next scanline and accumulate error y++; @@ -138,11 +145,17 @@ namespace pretty_poly { } } - void render_nodes(const tile_t &tile) { + void render_nodes(const tile_t &tile, rect_t &bounds) { + int maxy = -1; + bounds.y = 0; + bounds.x = tile.bounds.w; + int maxx = 0; for(auto y = 0; y < (int)node_buffer_size; y++) { if(node_counts[y] == 0) { + if (y == bounds.y) ++bounds.y; continue; } + maxy = y; std::sort(&nodes[y][0], &nodes[y][0] + node_counts[y]); @@ -154,6 +167,9 @@ namespace pretty_poly { continue; } + bounds.x = std::min(sx >> settings::antialias, bounds.x); + maxx = std::max((ex - 1) >> settings::antialias, maxx); + debug(" - render span at %d from %d to %d\n", y, sx, ex); for(int x = sx; x < ex; x++) { @@ -161,6 +177,9 @@ namespace pretty_poly { } } } + + bounds.w = (maxx >= bounds.x) ? maxx + 1 - bounds.x : 0; + bounds.h = (maxy >= bounds.y) ? maxy + 1 - bounds.y : 0; } template @@ -225,7 +244,16 @@ namespace pretty_poly { debug(" : render the tile\n"); // render the tile - render_nodes(tile); + rect_t bounds; + render_nodes(tile, bounds); + + tile.data += bounds.x + tile.stride * bounds.y; + bounds.x += tile.bounds.x; + bounds.y += tile.bounds.y; + tile.bounds = bounds.intersection(tile.bounds); + if (tile.bounds.empty()) { + continue; + } settings::callback(tile); } diff --git a/libraries/pico_vector/pretty_poly.hpp b/libraries/pico_vector/pretty_poly.hpp index d1ee2430d..474d29bd2 100644 --- a/libraries/pico_vector/pretty_poly.hpp +++ b/libraries/pico_vector/pretty_poly.hpp @@ -62,7 +62,7 @@ namespace pretty_poly { template void build_nodes(const contour_t &contour, const tile_t &tile, point_t origin = point_t(0, 0), int scale = 65536); - void render_nodes(const tile_t &tile); + void render_nodes(const tile_t &tile, rect_t &bounds); template void draw_polygon(T *points, unsigned count); From 41eb2b503e462c095f6f6dd2a08f26f034e9159d Mon Sep 17 00:00:00 2001 From: Mike Bell Date: Sun, 10 Sep 2023 00:08:35 +0100 Subject: [PATCH 2/5] Additional improvements to pretty_poly --- libraries/pico_vector/pretty_poly.cpp | 95 +++++++++++++++++++++------ 1 file changed, 76 insertions(+), 19 deletions(-) diff --git a/libraries/pico_vector/pretty_poly.cpp b/libraries/pico_vector/pretty_poly.cpp index 727588359..be1d5527b 100644 --- a/libraries/pico_vector/pretty_poly.cpp +++ b/libraries/pico_vector/pretty_poly.cpp @@ -79,39 +79,57 @@ namespace pretty_poly { std::swap(sx, ex); } + // Early out if line is completely outside the tile if (ey < 0 || sy >= (int)node_buffer_size) return; - /*sx <<= settings::antialias; - ex <<= settings::antialias; - sy <<= settings::antialias; - ey <<= settings::antialias;*/ + debug(" + line segment from %d, %d to %d, %d\n", sx, sy, ex, ey); + + // Determine how many in-bounds lines to render + int y = std::max(0, sy); + int count = std::min((int)node_buffer_size, ey) - y; + + // Handle cases where x is completely off to one side or other + if (std::max(sx, ex) <= 0) { + while (count--) { + nodes[y][node_counts[y]++] = 0; + ++y; + } + return; + } + const int full_tile_width = (tile_bounds.w << settings::antialias); + if (std::min(sx, ex) >= full_tile_width) { + while (count--) { + nodes[y][node_counts[y]++] = full_tile_width; + ++y; + } + return; + } + + // Normal case int x = sx; int e = 0; - int xinc = sign(ex - sx); - int einc = abs(ex - sx) + 1; - int dy = ey - sy; + const int xinc = sign(ex - sx); + const int einc = abs(ex - sx) + 1; + const int dy = ey - sy; + // If sy < 0 jump to the start, note this does use a divide + // but potentially saves many wasted loops below, so is likely worth it. if (sy < 0) { e = einc * -sy; int xjump = e / dy; e -= dy * xjump; x += xinc * xjump; - sy = 0; } - int y = sy; - - int count = std::min((int)node_buffer_size, ey) - sy; - debug(" + line segment from %d, %d to %d, %d\n", sx, sy, ex, ey); // loop over scanlines while(count--) { // consume accumulated error while(e > dy) {e -= dy; x += xinc;} // clamp node x value to tile bounds - int nx = std::max(std::min(x, (int)(tile_bounds.w << settings::antialias)), 0); + int nx = std::max(std::min(x, full_tile_width), 0); debug(" + adding node at %d, %d\n", x, y); // add node to node list nodes[y][node_counts[y]++] = nx; @@ -150,15 +168,18 @@ namespace pretty_poly { bounds.y = 0; bounds.x = tile.bounds.w; int maxx = 0; + int anitialias_mask = (1 << settings::antialias) - 1; + for(auto y = 0; y < (int)node_buffer_size; y++) { if(node_counts[y] == 0) { if (y == bounds.y) ++bounds.y; continue; } - maxy = y; std::sort(&nodes[y][0], &nodes[y][0] + node_counts[y]); + uint8_t* row_data = &tile.data[(y >> settings::antialias) * tile.stride]; + bool rendered_any = false; for(auto i = 0u; i < node_counts[y]; i += 2) { int sx = nodes[y][i + 0]; int ex = nodes[y][i + 1]; @@ -167,19 +188,55 @@ namespace pretty_poly { continue; } - bounds.x = std::min(sx >> settings::antialias, bounds.x); + rendered_any = true; + maxx = std::max((ex - 1) >> settings::antialias, maxx); debug(" - render span at %d from %d to %d\n", y, sx, ex); - for(int x = sx; x < ex; x++) { - tile.data[(x >> settings::antialias) + (y >> settings::antialias) * tile.stride]++; - } + if (settings::antialias) { + int ax = sx >> settings::antialias; + const int aex = ex >> settings::antialias; + + bounds.x = std::min(ax, bounds.x); + + if (ax == aex) { + row_data[ax] += ex - sx; + continue; + } + + row_data[ax] += (1 << settings::antialias) - (sx & anitialias_mask); + for(ax++; ax < aex; ax++) { + row_data[ax] += (1 << settings::antialias); + } + + // This might add 0 to the byte after the end of the row, we pad the tile data + // by 1 byte to ensure that is OK + row_data[ax] += ex & anitialias_mask; + } + else { + bounds.x = std::min(sx, bounds.x); + for(int x = sx; x < ex; x++) { + row_data[x]++; + } + } + } + + if (rendered_any) { + debug(" - rendered line %d\n", y); + maxy = y; + } + else if (y == bounds.y) { + debug(" - render nothing on line %d\n", y); + ++bounds.y; } } + bounds.y >>= settings::antialias; + maxy >>= settings::antialias; bounds.w = (maxx >= bounds.x) ? maxx + 1 - bounds.x : 0; bounds.h = (maxy >= bounds.y) ? maxy + 1 - bounds.y : 0; + debug(" - rendered tile bounds %d, %d (%d x %d)\n", bounds.x, bounds.y, bounds.w, bounds.h); } template @@ -214,7 +271,7 @@ namespace pretty_poly { debug(" - clip %d, %d (%d x %d)\n", settings::clip.x, settings::clip.y, settings::clip.w, settings::clip.h); - memset(nodes, 0, node_buffer_size * sizeof(unsigned) * 32); + //memset(nodes, 0, node_buffer_size * sizeof(unsigned) * 32); // iterate over tiles debug(" - processing tiles\n"); From 841c141ebf3361d18b995aa2a50b360eef4be4fc Mon Sep 17 00:00:00 2001 From: Mike Bell Date: Sun, 10 Sep 2023 13:22:21 +0100 Subject: [PATCH 3/5] Interpolators for line segment, and faster transforms --- libraries/pico_vector/pico_vector.cmake | 2 +- libraries/pico_vector/pico_vector.cpp | 32 ++++++++--------- libraries/pico_vector/pretty_poly.cpp | 35 +++++++++++++------ libraries/pico_vector/pretty_poly_types.hpp | 33 +++++++++++++++-- .../modules/picovector/micropython.cmake | 2 ++ 5 files changed, 74 insertions(+), 30 deletions(-) diff --git a/libraries/pico_vector/pico_vector.cmake b/libraries/pico_vector/pico_vector.cmake index cecbff4f9..92a168d2b 100644 --- a/libraries/pico_vector/pico_vector.cmake +++ b/libraries/pico_vector/pico_vector.cmake @@ -6,4 +6,4 @@ add_library(pico_vector target_include_directories(pico_vector INTERFACE ${CMAKE_CURRENT_LIST_DIR}) -target_link_libraries(pico_vector pico_stdlib) \ No newline at end of file +target_link_libraries(pico_vector pico_stdlib hardware_interp) \ No newline at end of file diff --git a/libraries/pico_vector/pico_vector.cpp b/libraries/pico_vector/pico_vector.cpp index 0e13d60de..d748ad605 100644 --- a/libraries/pico_vector/pico_vector.cpp +++ b/libraries/pico_vector/pico_vector.cpp @@ -10,44 +10,42 @@ namespace pimoroni { } void PicoVector::rotate(std::vector> &contours, Point origin, float angle) { - pretty_poly::mat3_t t2 = pretty_poly::mat3_t::translation(origin.x, origin.y); - pretty_poly::mat3_t t1 = pretty_poly::mat3_t::translation(-origin.x, -origin.y); - angle = 2 * M_PI * (angle / 360.0f); - pretty_poly::mat3_t r = pretty_poly::mat3_t::rotation(angle); + pretty_poly::point_t t{(picovector_point_type)origin.x, (picovector_point_type)origin.y}; + angle = (2 * (float)M_PI / 360.f) * angle; + pretty_poly::mat2_t r = pretty_poly::mat2_t::rotation(angle); for(auto &contour : contours) { for(auto i = 0u; i < contour.count; i++) { - contour.points[i] *= t1; + contour.points[i] -= t; contour.points[i] *= r; - contour.points[i] *= t2; + contour.points[i] += t; } } } void PicoVector::translate(std::vector> &contours, Point translation) { - pretty_poly::mat3_t t = pretty_poly::mat3_t::translation(translation.x, translation.y); + pretty_poly::point_t t{(picovector_point_type)translation.x, (picovector_point_type)translation.y}; for(auto &contour : contours) { for(auto i = 0u; i < contour.count; i++) { - contour.points[i] *= t; + contour.points[i] += t; } } } void PicoVector::rotate(pretty_poly::contour_t &contour, Point origin, float angle) { - pretty_poly::mat3_t t2 = pretty_poly::mat3_t::translation(origin.x, origin.y); - pretty_poly::mat3_t t1 = pretty_poly::mat3_t::translation(-origin.x, -origin.y); - angle = 2 * M_PI * (angle / 360.0f); - pretty_poly::mat3_t r = pretty_poly::mat3_t::rotation(angle); + pretty_poly::point_t t{(picovector_point_type)origin.x, (picovector_point_type)origin.y}; + angle = (2 * (float)M_PI / 360.f) * angle; + pretty_poly::mat2_t r = pretty_poly::mat2_t::rotation(angle); for(auto i = 0u; i < contour.count; i++) { - contour.points[i] *= t1; + contour.points[i] -= t; contour.points[i] *= r; - contour.points[i] *= t2; + contour.points[i] += t; } } void PicoVector::translate(pretty_poly::contour_t &contour, Point translation) { - pretty_poly::mat3_t t = pretty_poly::mat3_t::translation(translation.x, translation.y); + pretty_poly::point_t t{(picovector_point_type)translation.x, (picovector_point_type)translation.y}; for(auto i = 0u; i < contour.count; i++) { - contour.points[i] *= t; + contour.points[i] += t; } } @@ -115,7 +113,7 @@ namespace pimoroni { pretty_poly::point_t caret(0, 0); // Prepare a transformation matrix for character and offset rotation - angle = 2 * M_PI * (angle / 360.0f); + angle = (2 * (float)M_PI / 360.f) * angle; pretty_poly::mat3_t transform = pretty_poly::mat3_t::rotation(angle); // Align text from the bottom left diff --git a/libraries/pico_vector/pretty_poly.cpp b/libraries/pico_vector/pretty_poly.cpp index be1d5527b..5d13a48e7 100644 --- a/libraries/pico_vector/pretty_poly.cpp +++ b/libraries/pico_vector/pretty_poly.cpp @@ -8,6 +8,7 @@ #include "pretty_poly.hpp" +#include "hardware/interp.h" #ifdef PP_DEBUG #define debug(...) printf(__VA_ARGS__) @@ -79,8 +80,8 @@ namespace pretty_poly { std::swap(sx, ex); } - // Early out if line is completely outside the tile - if (ey < 0 || sy >= (int)node_buffer_size) return; + // Early out if line is completely outside the tile, or has no lines + if (ey < 0 || sy >= (int)node_buffer_size || sy == ey) return; debug(" + line segment from %d, %d to %d, %d\n", sx, sy, ex, ey); @@ -123,13 +124,16 @@ namespace pretty_poly { x += xinc * xjump; } + interp1->base[1] = full_tile_width; + interp1->accum[0] = x; + // loop over scanlines while(count--) { // consume accumulated error - while(e > dy) {e -= dy; x += xinc;} + while(e > dy) {e -= dy; interp1->add_raw[0] = xinc;} // clamp node x value to tile bounds - int nx = std::max(std::min(x, full_tile_width), 0); + const int nx = interp1->peek[0]; debug(" + adding node at %d, %d\n", x, y); // add node to node list nodes[y][node_counts[y]++] = nx; @@ -270,6 +274,14 @@ namespace pretty_poly { debug(" - bounds %d, %d (%d x %d)\n", polygon_bounds.x, polygon_bounds.y, polygon_bounds.w, polygon_bounds.h); debug(" - clip %d, %d (%d x %d)\n", settings::clip.x, settings::clip.y, settings::clip.w, settings::clip.h); + interp_hw_save_t interp1_save; + interp_save(interp1, &interp1_save); + + interp_config cfg = interp_default_config(); + interp_config_set_clamp(&cfg, true); + interp_config_set_signed(&cfg, true); + interp_set_config(interp1, 0, &cfg); + interp1->base[0] = 0; //memset(nodes, 0, node_buffer_size * sizeof(unsigned) * 32); @@ -303,18 +315,21 @@ namespace pretty_poly { // render the tile rect_t bounds; render_nodes(tile, bounds); - - tile.data += bounds.x + tile.stride * bounds.y; - bounds.x += tile.bounds.x; - bounds.y += tile.bounds.y; - tile.bounds = bounds.intersection(tile.bounds); - if (tile.bounds.empty()) { + if (bounds.empty()) { continue; } + tile.data += bounds.x + tile.stride * bounds.y; + tile.bounds.x += bounds.x; + tile.bounds.y += bounds.y; + tile.bounds.w = bounds.w; + tile.bounds.h = bounds.h; + settings::callback(tile); } } + + interp_restore(interp1, &interp1_save); } } diff --git a/libraries/pico_vector/pretty_poly_types.hpp b/libraries/pico_vector/pretty_poly_types.hpp index 51076f8a3..5677bbc3f 100644 --- a/libraries/pico_vector/pretty_poly_types.hpp +++ b/libraries/pico_vector/pretty_poly_types.hpp @@ -14,7 +14,7 @@ namespace pretty_poly { // 3x3 matrix for coordinate transformations struct mat3_t { - float v00, v10, v20, v01, v11, v21, v02, v12, v22 = 0.0f; + float v00 = 0.0f, v10 = 0.0f, v20 = 0.0f, v01 = 0.0f, v11 = 0.0f, v21 = 0.0f, v02 = 0.0f, v12 = 0.0f, v22 = 0.0f; mat3_t() = default; mat3_t(const mat3_t &m) = default; inline mat3_t& operator*= (const mat3_t &m) { @@ -43,6 +43,29 @@ namespace pretty_poly { mat3_t r = mat3_t::identity(); r.v00 = x; r.v11 = y; return r;} }; + // 2x2 matrix for rotations and scales + struct mat2_t { + float v00 = 0.0f, v10 = 0.0f, v01 = 0.0f, v11 = 0.0f; + mat2_t() = default; + mat2_t(const mat2_t &m) = default; + inline mat2_t& operator*= (const mat2_t &m) { + float r00 = this->v00 * m.v00 + this->v01 * m.v10; + float r01 = this->v00 * m.v01 + this->v01 * m.v11; + float r10 = this->v10 * m.v00 + this->v11 * m.v10; + float r11 = this->v10 * m.v01 + this->v11 * m.v11; + this->v00 = r00; this->v01 = r01; + this->v10 = r10; this->v11 = r11; + return *this; + } + + static mat2_t identity() {mat2_t m; m.v00 = m.v11 = 1.0f; return m;} + static mat2_t rotation(float a) { + float c = cosf(a), s = sinf(a); mat2_t r; + r.v00 = c; r.v01 = -s; r.v10 = s; r.v11 = c; return r;} + static mat2_t scale(float x, float y) { + mat2_t r; r.v00 = x; r.v11 = y; return r;} + }; + // point type for contour points template struct __attribute__ ((packed)) point_t { @@ -52,6 +75,7 @@ namespace pretty_poly { inline point_t& operator-= (const point_t &a) {x -= a.x; y -= a.y; return *this;} inline point_t& operator+= (const point_t &a) {x += a.x; y += a.y; return *this;} inline point_t& operator*= (const float a) {x *= a; y *= a; return *this;} + inline point_t& operator*= (const mat2_t &a) {this->transform(a); return *this;} inline point_t& operator*= (const mat3_t &a) {this->transform(a); return *this;} inline point_t& operator/= (const float a) {x /= a; y /= a; return *this;} inline point_t& operator/= (const point_t &a) {x /= a.x; y /= a.y; return *this;} @@ -60,6 +84,11 @@ namespace pretty_poly { this->x = (m.v00 * tx + m.v01 * ty + m.v02); this->y = (m.v10 * tx + m.v11 * ty + m.v12); } + void transform(const mat2_t &m) { + float tx = x, ty = y; + this->x = (m.v00 * tx + m.v01 * ty); + this->y = (m.v10 * tx + m.v11 * ty); + } }; @@ -78,7 +107,7 @@ namespace pretty_poly { int x, y, w, h; rect_t() : x(0), y(0), w(0), h(0) {} rect_t(int x, int y, int w, int h) : x(x), y(y), w(w), h(h) {} - bool empty() const {return this->w == 0 && this->h == 0;} + bool empty() const {return this->w == 0 || this->h == 0;} rect_t intersection(const rect_t &c) { return rect_t(std::max(this->x, c.x), std::max(this->y, c.y), std::max(0, std::min(this->x + this->w, c.x + c.w) - std::max(this->x, c.x)), diff --git a/micropython/modules/picovector/micropython.cmake b/micropython/modules/picovector/micropython.cmake index 69624f20a..c513cdcc5 100644 --- a/micropython/modules/picovector/micropython.cmake +++ b/micropython/modules/picovector/micropython.cmake @@ -18,4 +18,6 @@ target_compile_definitions(usermod_picovector INTERFACE MODULE_PICOVECTOR_ENABLED=1 ) +target_link_libraries(usermod_picovector INTERFACE hardware_interp) + target_link_libraries(usermod INTERFACE usermod_picovector) From cdd648f3f63adfc80b7e38216af8f05fea728e41 Mon Sep 17 00:00:00 2001 From: Mike Bell Date: Sun, 10 Sep 2023 17:18:56 +0100 Subject: [PATCH 4/5] Small improvements to rotated font rendering --- libraries/pico_vector/alright_fonts.cpp | 22 +++++++++++++++------ libraries/pico_vector/alright_fonts.hpp | 3 ++- libraries/pico_vector/pico_vector.cpp | 2 +- libraries/pico_vector/pretty_poly.cpp | 12 +++++------ libraries/pico_vector/pretty_poly.hpp | 2 +- libraries/pico_vector/pretty_poly_types.hpp | 2 +- 6 files changed, 27 insertions(+), 16 deletions(-) diff --git a/libraries/pico_vector/alright_fonts.cpp b/libraries/pico_vector/alright_fonts.cpp index 9a6a9131c..a679c97b9 100644 --- a/libraries/pico_vector/alright_fonts.cpp +++ b/libraries/pico_vector/alright_fonts.cpp @@ -41,7 +41,8 @@ namespace alright_fonts { } } - void render_character(text_metrics_t &tm, uint16_t codepoint, pretty_poly::point_t origin, pretty_poly::mat3_t transform) { + template + void render_character(text_metrics_t &tm, uint16_t codepoint, pretty_poly::point_t origin, mat_t transform) { if(tm.face.glyphs.count(codepoint) == 1) { glyph_t glyph = tm.face.glyphs[codepoint]; @@ -51,26 +52,35 @@ namespace alright_fonts { unsigned scale = tm.size << 9; std::vector> contours; + contours.reserve(glyph.contours.size()); + unsigned int total_points = 0; for(auto i = 0u; i < glyph.contours.size(); i++) { - unsigned int count = glyph.contours[i].count; - point_t *points = (point_t *)malloc(sizeof(point_t) * count); + total_points += glyph.contours[i].count;; + } + + point_t *points = (point_t *)malloc(sizeof(point_t) * total_points); + + for(auto i = 0u; i < glyph.contours.size(); i++) { + const unsigned int count = glyph.contours[i].count; for(auto j = 0u; j < count; j++) { point_t point(glyph.contours[i].points[j].x, glyph.contours[i].points[j].y); point *= transform; points[j] = point_t(point.x, point.y); } contours.emplace_back(points, count); + points += count; } pretty_poly::draw_polygon(contours, origin, scale); - for(auto contour : contours) { - free(contour.points); - } + free(contours[0].points); } } + template void render_character(text_metrics_t &tm, uint16_t codepoint, pretty_poly::point_t origin, pretty_poly::mat3_t transform); + template void render_character(text_metrics_t &tm, uint16_t codepoint, pretty_poly::point_t origin, pretty_poly::mat2_t transform); + /* load functions */ diff --git a/libraries/pico_vector/alright_fonts.hpp b/libraries/pico_vector/alright_fonts.hpp index 0bff4629c..0590a59c9 100644 --- a/libraries/pico_vector/alright_fonts.hpp +++ b/libraries/pico_vector/alright_fonts.hpp @@ -70,5 +70,6 @@ namespace alright_fonts { */ void render_character(text_metrics_t &tm, uint16_t codepoint, pretty_poly::point_t origin); - void render_character(text_metrics_t &tm, uint16_t codepoint, pretty_poly::point_t origin, pretty_poly::mat3_t transform); + template + void render_character(text_metrics_t &tm, uint16_t codepoint, pretty_poly::point_t origin, mat_t transform); } \ No newline at end of file diff --git a/libraries/pico_vector/pico_vector.cpp b/libraries/pico_vector/pico_vector.cpp index d748ad605..e4fb4a9f4 100644 --- a/libraries/pico_vector/pico_vector.cpp +++ b/libraries/pico_vector/pico_vector.cpp @@ -114,7 +114,7 @@ namespace pimoroni { // Prepare a transformation matrix for character and offset rotation angle = (2 * (float)M_PI / 360.f) * angle; - pretty_poly::mat3_t transform = pretty_poly::mat3_t::rotation(angle); + pretty_poly::mat2_t transform = pretty_poly::mat2_t::rotation(angle); // Align text from the bottom left caret.y += text_metrics.line_height; diff --git a/libraries/pico_vector/pretty_poly.cpp b/libraries/pico_vector/pretty_poly.cpp index 5d13a48e7..cc0c526d2 100644 --- a/libraries/pico_vector/pretty_poly.cpp +++ b/libraries/pico_vector/pretty_poly.cpp @@ -252,7 +252,7 @@ namespace pretty_poly { } template - void draw_polygon(std::vector> contours, point_t origin, int scale) { + void draw_polygon(const std::vector>& contours, point_t origin, int scale) { debug("> draw polygon with %lu contours\n", contours.size()); @@ -306,7 +306,7 @@ namespace pretty_poly { memset(tile.data, 0, tile_buffer_size); // build the nodes for each contour - for(contour_t &contour : contours) { + for(const contour_t &contour : contours) { debug(" : build nodes for contour\n"); build_nodes(contour, tile, origin, scale); } @@ -333,7 +333,7 @@ namespace pretty_poly { } } -template void pretty_poly::draw_polygon(std::vector> contours, point_t origin, int scale); -template void pretty_poly::draw_polygon(std::vector> contours, point_t origin, int scale); -template void pretty_poly::draw_polygon(std::vector> contours, point_t origin, int scale); -template void pretty_poly::draw_polygon(std::vector> contours, point_t origin, int scale); \ No newline at end of file +template void pretty_poly::draw_polygon(const std::vector>& contours, point_t origin, int scale); +template void pretty_poly::draw_polygon(const std::vector>& contours, point_t origin, int scale); +template void pretty_poly::draw_polygon(const std::vector>& contours, point_t origin, int scale); +template void pretty_poly::draw_polygon(const std::vector>& contours, point_t origin, int scale); \ No newline at end of file diff --git a/libraries/pico_vector/pretty_poly.hpp b/libraries/pico_vector/pretty_poly.hpp index 474d29bd2..21827c55c 100644 --- a/libraries/pico_vector/pretty_poly.hpp +++ b/libraries/pico_vector/pretty_poly.hpp @@ -68,5 +68,5 @@ namespace pretty_poly { void draw_polygon(T *points, unsigned count); template - void draw_polygon(std::vector> contours, point_t origin = point_t(0, 0), int scale = 65536); + void draw_polygon(const std::vector>& contours, point_t origin = point_t(0, 0), int scale = 65536); } \ No newline at end of file diff --git a/libraries/pico_vector/pretty_poly_types.hpp b/libraries/pico_vector/pretty_poly_types.hpp index 5677bbc3f..f278ff56f 100644 --- a/libraries/pico_vector/pretty_poly_types.hpp +++ b/libraries/pico_vector/pretty_poly_types.hpp @@ -145,7 +145,7 @@ namespace pretty_poly { //point_t *begin() const { return points; }; //point_t *end() const { return points + count * sizeof(point_t); }; - rect_t bounds() { + rect_t bounds() const { T minx = this->points[0].x, maxx = minx; T miny = this->points[0].y, maxy = miny; for(auto i = 1u; i < this->count; i++) { From 80e1e167826e9e179c6dc8bca7940927dfb7b54e Mon Sep 17 00:00:00 2001 From: Mike Bell Date: Sun, 10 Sep 2023 23:03:55 +0100 Subject: [PATCH 5/5] Fixes from compiling with gcc 12 --- libraries/pico_vector/pretty_poly.hpp | 1 + libraries/pico_vector/pretty_poly_types.hpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/pico_vector/pretty_poly.hpp b/libraries/pico_vector/pretty_poly.hpp index 21827c55c..ac31260a0 100644 --- a/libraries/pico_vector/pretty_poly.hpp +++ b/libraries/pico_vector/pretty_poly.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "pretty_poly_types.hpp" diff --git a/libraries/pico_vector/pretty_poly_types.hpp b/libraries/pico_vector/pretty_poly_types.hpp index f278ff56f..9cf400727 100644 --- a/libraries/pico_vector/pretty_poly_types.hpp +++ b/libraries/pico_vector/pretty_poly_types.hpp @@ -1,6 +1,7 @@ #pragma once #include #include +#include #ifdef PP_DEBUG #define debug(...) printf(__VA_ARGS__) @@ -138,7 +139,7 @@ namespace pretty_poly { unsigned count; contour_t() {} - contour_t(std::vector> v) : points(v.data()), count(v.size()) {}; + contour_t(const std::vector>& v) : points(v.data()), count(v.size()) {}; contour_t(point_t *points, unsigned count) : points(points), count(count) {}; // TODO: Make this work, it's so much nicer to use auto point : contour