From c45646a3ce99a88354e1a407957a5421e733be02 Mon Sep 17 00:00:00 2001 From: harrand Date: Thu, 16 Nov 2023 04:01:20 +0000 Subject: [PATCH 1/8] [ren.mesh_renderer] using mesh_renderer directly is once again supported --- demo/gl/tz_mesh_demo/main.cpp | 5 ++--- src/tz/ren/shaders/mesh.vertex.tzsl | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/demo/gl/tz_mesh_demo/main.cpp b/demo/gl/tz_mesh_demo/main.cpp index 096a113df9..d438326202 100644 --- a/demo/gl/tz_mesh_demo/main.cpp +++ b/demo/gl/tz_mesh_demo/main.cpp @@ -6,7 +6,6 @@ #include "tz/core/matrix_transform.hpp" #include "tz/ren/mesh.hpp" -#include "tz/ren/mesh2.hpp" struct dbgui_data_t { bool mesh_renderer_enabled = false; @@ -22,8 +21,8 @@ int main() { dbgui_init(); - tz::ren::mesh_renderer2 mr; - tz::ren::mesh_renderer2::mesh m; + tz::ren::mesh_renderer mr; + tz::ren::mesh_renderer::mesh m; m.indices = {0u, 1u, 2u}; m.vertices = { diff --git a/src/tz/ren/shaders/mesh.vertex.tzsl b/src/tz/ren/shaders/mesh.vertex.tzsl index 4f9b72916b..d0b1b075e6 100644 --- a/src/tz/ren/shaders/mesh.vertex.tzsl +++ b/src/tz/ren/shaders/mesh.vertex.tzsl @@ -48,7 +48,7 @@ resource(id = 2) const buffer camera_buffer output(id = 0) vec2 out::texcoord; output(id = 1) vec3 out::normal; output(id = 2) vec3 out::colour; -output(id = 3) uvec2 out::impl_unused; +output(id = 3) vec3 out::impl_unused; output(id = 4) texture_locator out::textures[MAX_TEX_COUNT]; void main() From c70511c875178dc22b4c8128cd82fa8c4454dcd4 Mon Sep 17 00:00:00 2001 From: harrand Date: Thu, 16 Nov 2023 04:06:39 +0000 Subject: [PATCH 2/8] [demo] added tz_text_rendering_demo, which is currently empty --- demo/CMakeLists.txt | 1 + demo/ren/CMakeLists.txt | 1 + demo/ren/tz_text_rendering_demo/CMakeLists.txt | 5 +++++ demo/ren/tz_text_rendering_demo/main.cpp | 13 +++++++++++++ 4 files changed, 20 insertions(+) create mode 100644 demo/ren/CMakeLists.txt create mode 100644 demo/ren/tz_text_rendering_demo/CMakeLists.txt create mode 100644 demo/ren/tz_text_rendering_demo/main.cpp diff --git a/demo/CMakeLists.txt b/demo/CMakeLists.txt index 78acc8d4d4..8e79406bee 100644 --- a/demo/CMakeLists.txt +++ b/demo/CMakeLists.txt @@ -30,3 +30,4 @@ endfunction() add_subdirectory(core) add_subdirectory(gl) +add_subdirectory(ren) diff --git a/demo/ren/CMakeLists.txt b/demo/ren/CMakeLists.txt new file mode 100644 index 0000000000..7cc6a00ad3 --- /dev/null +++ b/demo/ren/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(tz_text_rendering_demo) \ No newline at end of file diff --git a/demo/ren/tz_text_rendering_demo/CMakeLists.txt b/demo/ren/tz_text_rendering_demo/CMakeLists.txt new file mode 100644 index 0000000000..7e8aa850e7 --- /dev/null +++ b/demo/ren/tz_text_rendering_demo/CMakeLists.txt @@ -0,0 +1,5 @@ +add_demo( + TARGET tz_text_rendering_demo + SOURCE_FILES + main.cpp +) diff --git a/demo/ren/tz_text_rendering_demo/main.cpp b/demo/ren/tz_text_rendering_demo/main.cpp new file mode 100644 index 0000000000..0849d76f03 --- /dev/null +++ b/demo/ren/tz_text_rendering_demo/main.cpp @@ -0,0 +1,13 @@ +#include "tz/tz.hpp" +#include "tz/gl/device.hpp" + +int main() +{ + tz::initialise({.name = "tz_text_rendering_demo"}); + { + tz::begin_frame(); + tz::gl::get_device().render(); + tz::end_frame(); + } + tz::terminate(); +} \ No newline at end of file From b561fb13c244b14e75fb5b4c84b9a7a21362a592 Mon Sep 17 00:00:00 2001 From: harrand Date: Thu, 16 Nov 2023 06:54:02 +0000 Subject: [PATCH 3/8] [ttf] fixed a bug where advance_width/left_side_bearings are not retrieved correctly --- .../ren/tz_text_rendering_demo/CMakeLists.txt | 8 ++++++++ demo/ren/tz_text_rendering_demo/main.cpp | 6 ++++++ src/tz/io/ttf.cpp | 20 ++++++++++++++++--- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/demo/ren/tz_text_rendering_demo/CMakeLists.txt b/demo/ren/tz_text_rendering_demo/CMakeLists.txt index 7e8aa850e7..cb4565156d 100644 --- a/demo/ren/tz_text_rendering_demo/CMakeLists.txt +++ b/demo/ren/tz_text_rendering_demo/CMakeLists.txt @@ -3,3 +3,11 @@ add_demo( SOURCE_FILES main.cpp ) + +add_text( + TARGET tz_text_rendering_demo + INPUT_DIR ${PROJECT_SOURCE_DIR} + OUTPUT_DIR ${PROJECT_BINARY_DIR} + TEXT_FILES + demo/ren/tz_text_rendering_demo/res/ProggyClean.ttf +) diff --git a/demo/ren/tz_text_rendering_demo/main.cpp b/demo/ren/tz_text_rendering_demo/main.cpp index 0849d76f03..ea6c2d6af1 100644 --- a/demo/ren/tz_text_rendering_demo/main.cpp +++ b/demo/ren/tz_text_rendering_demo/main.cpp @@ -1,10 +1,16 @@ #include "tz/tz.hpp" #include "tz/gl/device.hpp" +#include "tz/io/ttf.hpp" + +#include "tz/core/imported_text.hpp" +#include ImportedTextHeader(ProggyClean, ttf) int main() { tz::initialise({.name = "tz_text_rendering_demo"}); { + tz::io::ttf ttf = tz::io::ttf::from_memory(ImportedTextData(ProggyClean, ttf)); + tz::begin_frame(); tz::gl::get_device().render(); tz::end_frame(); diff --git a/src/tz/io/ttf.cpp b/src/tz/io/ttf.cpp index 234d6df85a..4f18bea60b 100644 --- a/src/tz/io/ttf.cpp +++ b/src/tz/io/ttf.cpp @@ -618,7 +618,21 @@ namespace tz::io char c = ttf_alphabet[i]; auto index = this->cmap.glyph_index_map[c | 0] | 0; auto glyfd = this->glyf.glyfs[index]; - auto hmtxd = this->hmtx.hmetrics[index]; + // its possible index > hmetrics.length + // spec:The table uses a longHorMetric record to give the advance width and left side bearing of a glyph. Records are indexed by glyph ID. As an optimization, the number of records can be less than the number of glyphs, in which case the advance width value of the last record applies to all remaining glyph IDs + // If numberOfHMetrics is less than the total number of glyphs, then the hMetrics array is followed by an array for the left side bearing values of the remaining glyphs. + std::size_t advance_width, left_side_bearing; + if(std::cmp_greater_equal(index, this->hmtx.hmetrics.size())) + { + advance_width = hmtx.hmetrics.back().advance_width; + left_side_bearing = hmtx.left_side_bearings[index - hmtx.hmetrics.size()]; + } + else + { + auto hmtxd = this->hmtx.hmetrics[index]; + advance_width = hmtxd.advance_width; + left_side_bearing = hmtxd.left_side_bearing; + } ttf_glyph_shape_info shape; tz::assert(glyfd.x_coords.size() == glyfd.y_coords.size()); @@ -644,8 +658,8 @@ namespace tz::io { .position = static_cast(tz::vector{glyfd.xmin, glyfd.ymin}), .dimensions = static_cast(tz::vector{glyfd.xmax - glyfd.xmin, glyfd.ymax - glyfd.ymin}), - .left_side_bearing = static_cast(hmtxd.left_side_bearing), - .right_side_bearing = static_cast(hmtxd.advance_width - hmtxd.left_side_bearing - (glyfd.xmax - glyfd.xmin)) + .left_side_bearing = static_cast(left_side_bearing), + .right_side_bearing = static_cast(advance_width - left_side_bearing - (glyfd.xmax - glyfd.xmin)) }, .shape = shape }; From ca8e6f5fd35b933bcd89c681623a175085766570 Mon Sep 17 00:00:00 2001 From: harrand Date: Thu, 16 Nov 2023 07:34:52 +0000 Subject: [PATCH 4/8] [ttf] visualiser within tz_text_rendering_demo --- demo/ren/tz_text_rendering_demo/main.cpp | 85 +++++++++++++++++++++++- src/tz/io/ttf.cpp | 9 +-- src/tz/io/ttf.hpp | 11 ++- 3 files changed, 97 insertions(+), 8 deletions(-) diff --git a/demo/ren/tz_text_rendering_demo/main.cpp b/demo/ren/tz_text_rendering_demo/main.cpp index ea6c2d6af1..27ad059666 100644 --- a/demo/ren/tz_text_rendering_demo/main.cpp +++ b/demo/ren/tz_text_rendering_demo/main.cpp @@ -5,15 +5,94 @@ #include "tz/core/imported_text.hpp" #include ImportedTextHeader(ProggyClean, ttf) + +// debug rendering +#include "tz/ren/mesh.hpp" + +struct dbgui_data_t +{ + bool text_renderer_enabled = false; +} dbgui_data; +void dbgui_init(); + +static tz::io::ttf::rasterise_info rast +{ + .dimensions = {32u, 32u}, + .angle_threshold = 3.0f, + .range = 2.0f, + .scale = 2.0f, + .translate = tz::vec2::zero() +}; + int main() { tz::initialise({.name = "tz_text_rendering_demo"}); { + dbgui_init(); tz::io::ttf ttf = tz::io::ttf::from_memory(ImportedTextData(ProggyClean, ttf)); + tz::io::image img_c = ttf.rasterise_msdf('c', rast); + + tz::ren::mesh_renderer mr; + mr.append_to_render_graph(); - tz::begin_frame(); - tz::gl::get_device().render(); - tz::end_frame(); + tz::ren::mesh_renderer::mesh quad; + quad.vertices = + { + {.position = {0.5f, 0.5f, 0.0f}, .texcoord = {1.0f, 1.0f}}, + {.position = {0.5f, -0.5f, 0.0f}, .texcoord = {1.0f, 0.0f}}, + {.position = {-0.5f, -0.5f, 0.0f}, .texcoord = {0.0f, 0.0f}}, + {.position = {-0.5f, 0.5f, 0.0f}, .texcoord = {0.0f, 1.0f}} + }; + quad.indices = {0u, 1u, 3u, 1u, 2u, 3u}; + auto mesh = mr.add_mesh(quad); + auto tex = mr.add_texture(img_c); + mr.camera_perspective({.aspect_ratio = 1920.0f/1080.0f, .fov = 1.5708f}); + mr.set_camera_transform({.translate = {0.0f, 0.0f, 1.0f}}); + + auto obj = mr.add_object + ({ + .mesh = mesh, + .bound_textures = {{.texture = tex}} + }); + + while(!tz::window().is_close_requested()) + { + tz::begin_frame(); + tz::gl::get_device().render(); + tz::dbgui::run([&mr, &ttf, obj]() + { + if(dbgui_data.text_renderer_enabled) + { + if(ImGui::Begin("Text Renderer", &dbgui_data.text_renderer_enabled)) + { + bool changed = false; + changed |= ImGui::SliderInt2("Dimensions", reinterpret_cast(rast.dimensions.data().data()), 1u, 512u, "%u"); + changed |= ImGui::SliderFloat("Angle Threshold", &rast.angle_threshold, 0.0f, 5.0f); + changed |= ImGui::SliderFloat("Range", &rast.range, 0.0f, 16.0f); + changed |= ImGui::SliderFloat("Scale", &rast.scale, 0.01f, 64.0f); + changed |= ImGui::SliderFloat2("Translate", rast.translate.data().data(), -16.0f, 16.0f); + + if(changed) + { + auto new_tex = mr.add_texture(ttf.rasterise_msdf('c', rast)); + mr.get_object(obj).bound_textures[0].texture = new_tex; + } + + ImGui::End(); + } + } + }); + tz::end_frame(); + } } tz::terminate(); +} + +// invoked when dbgui needs to set up initial state. +void dbgui_init() +{ + tz::dbgui::game_menu().add_callback([]() + { + ImGui::MenuItem("Text Renderer", nullptr, &dbgui_data.text_renderer_enabled); + }); } \ No newline at end of file diff --git a/src/tz/io/ttf.cpp b/src/tz/io/ttf.cpp index 4f18bea60b..8fd34a21bf 100644 --- a/src/tz/io/ttf.cpp +++ b/src/tz/io/ttf.cpp @@ -38,7 +38,7 @@ namespace tz::io return ttf::from_memory(buffer); } - tz::io::image ttf::rasterise_msdf(char c) const + tz::io::image ttf::rasterise_msdf(char c, rasterise_info i) const { tz::io::image ret; @@ -69,9 +69,10 @@ namespace tz::io // } // generate bitmap - msdfgen::edgeColoringSimple(shape, 3.0f); - msdfgen::Bitmap msdf(128u, 128u); - msdfgen::generateMSDF(msdf, shape, 128.0f, 1.0f, msdfgen::Vector2(100.0f, -100.0f)); + //shape.normalize(); + msdfgen::edgeColoringSimple(shape, i.angle_threshold); + msdfgen::Bitmap msdf(i.dimensions[0], i.dimensions[1]); + msdfgen::generateMSDF(msdf, shape, i.range, i.scale, msdfgen::Vector2(i.translate[0], i.translate[1])); ret.width = msdf.width(); ret.height = msdf.height(); ret.data.resize(1 * 4u * ret.width * ret.height, std::byte{0}); diff --git a/src/tz/io/ttf.hpp b/src/tz/io/ttf.hpp index 70526d5c40..a4fdedcf93 100644 --- a/src/tz/io/ttf.hpp +++ b/src/tz/io/ttf.hpp @@ -183,7 +183,16 @@ namespace tz::io static ttf from_memory(std::string_view sv); static ttf from_file(const char* path); - tz::io::image rasterise_msdf(char c) const; + struct rasterise_info + { + tz::vec2ui dimensions; + float angle_threshold; + float range; + float scale; + tz::vec2 translate; + }; + + tz::io::image rasterise_msdf(char c, rasterise_info i) const; ttf(std::string_view ttf_data); private: std::string_view parse_header(std::string_view str); From eef448b75cea15adf23adb49406a8afe9a696f54 Mon Sep 17 00:00:00 2001 From: harrand Date: Thu, 16 Nov 2023 13:06:06 +0000 Subject: [PATCH 5/8] [ttf] bug fixes. xcoord and ycoord from glyf are incorrect though. not sure why, flags seem to be logic'd correctly? --- demo/ren/tz_text_rendering_demo/main.cpp | 2 +- src/tz/io/ttf.cpp | 23 ++++++++++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/demo/ren/tz_text_rendering_demo/main.cpp b/demo/ren/tz_text_rendering_demo/main.cpp index 27ad059666..7304f9fec5 100644 --- a/demo/ren/tz_text_rendering_demo/main.cpp +++ b/demo/ren/tz_text_rendering_demo/main.cpp @@ -30,7 +30,7 @@ int main() { dbgui_init(); tz::io::ttf ttf = tz::io::ttf::from_memory(ImportedTextData(ProggyClean, ttf)); - tz::io::image img_c = ttf.rasterise_msdf('c', rast); + tz::io::image img_c = ttf.rasterise_msdf('A', rast); tz::ren::mesh_renderer mr; mr.append_to_render_graph(); diff --git a/src/tz/io/ttf.cpp b/src/tz/io/ttf.cpp index 8fd34a21bf..47fc24a7f6 100644 --- a/src/tz/io/ttf.cpp +++ b/src/tz/io/ttf.cpp @@ -381,7 +381,7 @@ namespace tz::io { g.flags[i] = static_cast(*ptr); ptr++; - if(static_cast(g.flags[i]) & 0x00001000) // repeat bit + if(1 == ((static_cast(g.flags[i]) >> 3) & 1)) { std::uint8_t repeat_count = *ptr; while(repeat_count-- > 0) @@ -421,6 +421,8 @@ namespace tz::io break; } g.x_coords[i] = cur_coord + prev_coord; + //tz::assert(this->head.xmin <= g.x_coords[i]); + //tz::assert(this->head.xmax >= g.x_coords[i]); prev_coord = g.x_coords[i]; } g.y_coords.resize((last_index + 1)); @@ -451,6 +453,8 @@ namespace tz::io break; } g.y_coords[i] = cur_coord + prev_coord; + //tz::assert(this->head.ymin <= g.y_coords[i]); + //tz::assert(this->head.ymax >= g.y_coords[i]); prev_coord = g.y_coords[i]; } }; @@ -639,13 +643,18 @@ namespace tz::io tz::assert(glyfd.x_coords.size() == glyfd.y_coords.size()); std::size_t contour_cursor = 0; shape.contours.resize(glyfd.number_of_contours); - for(std::size_t i = 1; i < glyfd.x_coords.size(); i++) + std::optional cache = std::nullopt; + for(std::size_t i = 0; i < glyfd.x_coords.size(); i++) { - auto beg = static_cast(tz::vec2i{glyfd.x_coords[i - 1], glyfd.y_coords[i - 1]}); - beg /= this->head.units_per_em; - auto end = static_cast(tz::vec2i{glyfd.x_coords[i], glyfd.y_coords[i]}); - end /= this->head.units_per_em; - shape.contours[contour_cursor].edges.push_back({beg, end}); + if(!cache.has_value()) + { + cache = static_cast(tz::vec2i{glyfd.x_coords[i], glyfd.y_coords[i]}); + } + else + { + shape.contours[contour_cursor].edges.push_back({cache.value(), static_cast(tz::vec2i{glyfd.x_coords[i], glyfd.y_coords[i]})}); + cache = std::nullopt; + } if(i == glyfd.end_pts_of_contours[contour_cursor]) { // contour ends here. From 3913764e85cc06f02257516f8d5aeb4df4628d7a Mon Sep 17 00:00:00 2001 From: harrand Date: Sat, 18 Nov 2023 09:57:26 +0000 Subject: [PATCH 6/8] [ttf] fixed a few bugs. im now convinced the outlines are all correct --- demo/ren/tz_text_rendering_demo/main.cpp | 6 +-- src/tz/io/ttf.cpp | 59 ++++++++++++++++-------- 2 files changed, 44 insertions(+), 21 deletions(-) diff --git a/demo/ren/tz_text_rendering_demo/main.cpp b/demo/ren/tz_text_rendering_demo/main.cpp index 7304f9fec5..63b91f1cfc 100644 --- a/demo/ren/tz_text_rendering_demo/main.cpp +++ b/demo/ren/tz_text_rendering_demo/main.cpp @@ -20,7 +20,7 @@ static tz::io::ttf::rasterise_info rast .dimensions = {32u, 32u}, .angle_threshold = 3.0f, .range = 2.0f, - .scale = 2.0f, + .scale = 1.0f, .translate = tz::vec2::zero() }; @@ -68,9 +68,9 @@ int main() bool changed = false; changed |= ImGui::SliderInt2("Dimensions", reinterpret_cast(rast.dimensions.data().data()), 1u, 512u, "%u"); changed |= ImGui::SliderFloat("Angle Threshold", &rast.angle_threshold, 0.0f, 5.0f); - changed |= ImGui::SliderFloat("Range", &rast.range, 0.0f, 16.0f); + changed |= ImGui::SliderFloat("Range", &rast.range, 0.01f, 2.0f); changed |= ImGui::SliderFloat("Scale", &rast.scale, 0.01f, 64.0f); - changed |= ImGui::SliderFloat2("Translate", rast.translate.data().data(), -16.0f, 16.0f); + changed |= ImGui::SliderFloat2("Translate", rast.translate.data().data(), -1.0f, 1.0f); if(changed) { diff --git a/src/tz/io/ttf.cpp b/src/tz/io/ttf.cpp index 47fc24a7f6..149f49dd97 100644 --- a/src/tz/io/ttf.cpp +++ b/src/tz/io/ttf.cpp @@ -69,9 +69,11 @@ namespace tz::io // } // generate bitmap - //shape.normalize(); + shape.normalize(); + i.scale *= i.dimensions.length(); msdfgen::edgeColoringSimple(shape, i.angle_threshold); msdfgen::Bitmap msdf(i.dimensions[0], i.dimensions[1]); + msdfgen::generateMSDF(msdf, shape, i.range, i.scale, msdfgen::Vector2(i.translate[0], i.translate[1])); ret.width = msdf.width(); ret.height = msdf.height(); @@ -83,9 +85,12 @@ namespace tz::io { for(std::size_t i = 0; i < 3; i++) { - imgdata(x, y)[i] = static_cast(msdf(x, y)[i] * 255); - imgdata(x, y)[3] = std::byte{255}; + float val = msdf(x, y)[i]; + tz::assert(val >= 0.0f); + tz::assert(val <= 1.0f); + imgdata(x, y)[i] = static_cast(val * 255); } + imgdata(x, y)[3] = std::byte{255}; } } @@ -328,7 +333,7 @@ namespace tz::io if(this->head.index_to_loc_format == 0) { // 16 bit - for(std::size_t i = 0; std::cmp_less(i, this->maxp.num_glyphs); i++) + for(std::size_t i = 0; std::cmp_less(i, this->maxp.num_glyphs + 1); i++) { this->loca.locations16.push_back(ttf_read_value(ptr)); } @@ -336,7 +341,7 @@ namespace tz::io else { // 32 bit - for(std::size_t i = 0; std::cmp_less(i, this->maxp.num_glyphs); i++) + for(std::size_t i = 0; std::cmp_less(i, this->maxp.num_glyphs + 1); i++) { this->loca.locations32.push_back(ttf_read_value(ptr)); } @@ -361,7 +366,7 @@ namespace tz::io { auto& g = this->glyf.glyfs.emplace_back(); g.number_of_contours = ttf_read_value(ptr); - tz::assert(g.number_of_contours > 0, "Only support simple glyphs. Number of contours: %d", (int)g.number_of_contours); + tz::assert(g.number_of_contours >= 0, "Only support simple glyphs. Number of contours: %d", (int)g.number_of_contours); g.xmin = ttf_read_value(ptr); g.ymin = ttf_read_value(ptr); g.xmax = ttf_read_value(ptr); @@ -375,6 +380,10 @@ namespace tz::io std::memcpy(g.instructions.data(), ptr, g.instructions.size()); std::advance(ptr, g.instructions.size()); + if(g.number_of_contours == 0) + { + return; + } int last_index = g.end_pts_of_contours.back(); g.flags.resize(last_index + 1); for(int i = 0; i < (last_index + 1); i++) @@ -410,10 +419,10 @@ namespace tz::io case 1: cur_coord = 0; break; - case 2: + case 3: cur_coord = -ttf_read_value(ptr); break; - case 3: + case 2: cur_coord = ttf_read_value(ptr); break; default: @@ -421,8 +430,8 @@ namespace tz::io break; } g.x_coords[i] = cur_coord + prev_coord; - //tz::assert(this->head.xmin <= g.x_coords[i]); - //tz::assert(this->head.xmax >= g.x_coords[i]); + tz::assert(g.xmin <= g.x_coords[i]); + tz::assert(g.xmax >= g.x_coords[i]); prev_coord = g.x_coords[i]; } g.y_coords.resize((last_index + 1)); @@ -442,10 +451,10 @@ namespace tz::io case 1: cur_coord = 0; break; - case 2: + case 3: cur_coord = -ttf_read_value(ptr); break; - case 3: + case 2: cur_coord = ttf_read_value(ptr); break; default: @@ -453,8 +462,8 @@ namespace tz::io break; } g.y_coords[i] = cur_coord + prev_coord; - //tz::assert(this->head.ymin <= g.y_coords[i]); - //tz::assert(this->head.ymax >= g.y_coords[i]); + tz::assert(g.ymin <= g.y_coords[i]); + tz::assert(g.ymax >= g.y_coords[i]); prev_coord = g.y_coords[i]; } }; @@ -466,7 +475,8 @@ namespace tz::io for(std::uint16_t loc16 : this->loca.locations16) { auto loca_offset = loc16 * multiplier; - read_glyph(ptrcpy + loca_offset); + ptrcpy = ptr + loca_offset; + read_glyph(ptrcpy); } } else @@ -476,8 +486,8 @@ namespace tz::io for(std::uint32_t loc32 : this->loca.locations32) { auto loca_offset = loc32 * multiplier; - ptr = ptrcpy + loca_offset; - read_glyph(ptrcpy + loca_offset); + ptrcpy = ptr + loca_offset; + read_glyph(ptrcpy); } } this->glyf.canary = true; @@ -652,13 +662,26 @@ namespace tz::io } else { - shape.contours[contour_cursor].edges.push_back({cache.value(), static_cast(tz::vec2i{glyfd.x_coords[i], glyfd.y_coords[i]})}); + shape.contours[contour_cursor].edges.push_back({ + cache.value(), + static_cast(tz::vec2i{glyfd.x_coords[i], glyfd.y_coords[i]}) + }); cache = std::nullopt; } if(i == glyfd.end_pts_of_contours[contour_cursor]) { // contour ends here. contour_cursor++; + cache = std::nullopt; + } + } + + for(auto& contour : shape.contours) + { + for (auto& [a, b] : contour.edges) + { + a /= this->head.units_per_em; + b /= this->head.units_per_em; } } From a19b0495a9b2811752a7425946b758718585c8e1 Mon Sep 17 00:00:00 2001 From: harrand Date: Sat, 18 Nov 2023 12:04:33 +0000 Subject: [PATCH 7/8] [ttf] correct float->byte transformation in ttf::rasterise_msdf --- demo/ren/tz_text_rendering_demo/main.cpp | 6 +++--- src/tz/io/ttf.cpp | 5 +---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/demo/ren/tz_text_rendering_demo/main.cpp b/demo/ren/tz_text_rendering_demo/main.cpp index 63b91f1cfc..147e09b2cd 100644 --- a/demo/ren/tz_text_rendering_demo/main.cpp +++ b/demo/ren/tz_text_rendering_demo/main.cpp @@ -19,9 +19,9 @@ static tz::io::ttf::rasterise_info rast { .dimensions = {32u, 32u}, .angle_threshold = 3.0f, - .range = 2.0f, - .scale = 1.0f, - .translate = tz::vec2::zero() + .range = 0.1f, + .scale = 72.0f, + .translate = tz::vec2::zero() }; int main() diff --git a/src/tz/io/ttf.cpp b/src/tz/io/ttf.cpp index 149f49dd97..9739c56653 100644 --- a/src/tz/io/ttf.cpp +++ b/src/tz/io/ttf.cpp @@ -70,7 +70,6 @@ namespace tz::io // generate bitmap shape.normalize(); - i.scale *= i.dimensions.length(); msdfgen::edgeColoringSimple(shape, i.angle_threshold); msdfgen::Bitmap msdf(i.dimensions[0], i.dimensions[1]); @@ -86,9 +85,7 @@ namespace tz::io for(std::size_t i = 0; i < 3; i++) { float val = msdf(x, y)[i]; - tz::assert(val >= 0.0f); - tz::assert(val <= 1.0f); - imgdata(x, y)[i] = static_cast(val * 255); + imgdata(x, y)[i] = static_cast(255 - std::clamp(val * 256.0f, 0.0f, 255.0f)); } imgdata(x, y)[3] = std::byte{255}; } From b3338fdc2d519e7fbca0539794e04c406263e81c Mon Sep 17 00:00:00 2001 From: harrand Date: Sat, 18 Nov 2023 13:15:51 +0000 Subject: [PATCH 8/8] [tz_text_rendering_demo] default to size 64 instead of 72 --- demo/ren/tz_text_rendering_demo/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/ren/tz_text_rendering_demo/main.cpp b/demo/ren/tz_text_rendering_demo/main.cpp index 147e09b2cd..428f7e9663 100644 --- a/demo/ren/tz_text_rendering_demo/main.cpp +++ b/demo/ren/tz_text_rendering_demo/main.cpp @@ -20,7 +20,7 @@ static tz::io::ttf::rasterise_info rast .dimensions = {32u, 32u}, .angle_threshold = 3.0f, .range = 0.1f, - .scale = 72.0f, + .scale = 64.0f, .translate = tz::vec2::zero() };