From 11b3e960d5148b5e0f18deb830c8fe60f79457d4 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Fri, 1 Apr 2022 17:38:39 +0300 Subject: [PATCH] Support shaping utf32-text directly in ui::font --- libs/ui/include/psemek/ui/font.hpp | 1 + libs/ui/include/psemek/ui/kerned_font.hpp | 4 ++++ libs/ui/include/psemek/ui/monospace_font.hpp | 4 ++++ libs/ui/source/kerned_font.cpp | 13 ++++++++++++- libs/ui/source/monospace_font.cpp | 13 ++++++++++++- 5 files changed, 33 insertions(+), 2 deletions(-) diff --git a/libs/ui/include/psemek/ui/font.hpp b/libs/ui/include/psemek/ui/font.hpp index ad0d2ebe..f9c33912 100644 --- a/libs/ui/include/psemek/ui/font.hpp +++ b/libs/ui/include/psemek/ui/font.hpp @@ -58,6 +58,7 @@ namespace psemek::ui virtual util::span supported_characters() const = 0; virtual std::vector shape(std::string_view str, shape_options const & options) const = 0; + virtual std::vector shape(std::u32string_view str, shape_options const & options) const = 0; virtual gfx::texture_2d const & atlas() const = 0; diff --git a/libs/ui/include/psemek/ui/kerned_font.hpp b/libs/ui/include/psemek/ui/kerned_font.hpp index cf3d3548..a0f221af 100644 --- a/libs/ui/include/psemek/ui/kerned_font.hpp +++ b/libs/ui/include/psemek/ui/kerned_font.hpp @@ -32,6 +32,7 @@ namespace psemek::ui util::span supported_characters() const override { return ranges_; } std::vector shape(std::string_view str, shape_options const & options) const override; + std::vector shape(std::u32string_view str, shape_options const & options) const override; gfx::texture_2d const & atlas() const override { return atlas_; }; @@ -44,6 +45,9 @@ namespace psemek::ui int baseline_offset_; gfx::texture_2d atlas_; std::unordered_map glyphs_; + + template + std::vector shape_impl(String const & str, shape_options const & options) const; }; } diff --git a/libs/ui/include/psemek/ui/monospace_font.hpp b/libs/ui/include/psemek/ui/monospace_font.hpp index 2cfe5add..29b92966 100644 --- a/libs/ui/include/psemek/ui/monospace_font.hpp +++ b/libs/ui/include/psemek/ui/monospace_font.hpp @@ -20,6 +20,7 @@ namespace psemek::ui util::span supported_characters() const override { return {&range_, &range_ + 1}; } std::vector shape(std::string_view str, shape_options const & options) const override; + std::vector shape(std::u32string_view str, shape_options const & options) const override; gfx::texture_2d const & atlas() const override { return atlas_; }; @@ -31,6 +32,9 @@ namespace psemek::ui geom::vector size_; gfx::texture_2d atlas_; std::vector> texcoords_; + + template + std::vector shape_impl(String const & str, shape_options const & options) const; }; } diff --git a/libs/ui/source/kerned_font.cpp b/libs/ui/source/kerned_font.cpp index c9015d6c..5bce5933 100644 --- a/libs/ui/source/kerned_font.cpp +++ b/libs/ui/source/kerned_font.cpp @@ -51,6 +51,17 @@ namespace psemek::ui } std::vector kerned_font::shape(std::string_view str, shape_options const & options) const + { + return shape_impl(util::utf8_range(str), options); + } + + std::vector kerned_font::shape(std::u32string_view str, shape_options const & options) const + { + return shape_impl(str, options); + } + + template + std::vector kerned_font::shape_impl(String const & str, shape_options const & options) const { char32_t const unknown = supports_character(options.unknown_character) ? options.unknown_character : '?'; geom::vector const advance_mask = advance_dir(options.direction); @@ -58,7 +69,7 @@ namespace psemek::ui std::vector result; geom::vector pos{0.f, (size_[1] - baseline_offset_) * options.scale}; - for (char32_t c : util::utf8_range(str)) + for (char32_t c : str) { if (!supports_character(c)) c = unknown; diff --git a/libs/ui/source/monospace_font.cpp b/libs/ui/source/monospace_font.cpp index dbbab4aa..4b9bfb2f 100644 --- a/libs/ui/source/monospace_font.cpp +++ b/libs/ui/source/monospace_font.cpp @@ -38,6 +38,17 @@ namespace psemek::ui } std::vector monospace_font::shape(std::string_view str, shape_options const & options) const + { + return shape_impl(util::utf8_range(str), options); + } + + std::vector monospace_font::shape(std::u32string_view str, shape_options const & options) const + { + return shape_impl(str, options); + } + + template + std::vector monospace_font::shape_impl(String const & str, shape_options const & options) const { char32_t const unknown = supports_character(options.unknown_character) ? options.unknown_character : '?'; geom::vector const size = geom::cast(this->size()) * options.scale; @@ -46,7 +57,7 @@ namespace psemek::ui std::vector result; geom::vector pos{0.f, 0.f}; - for (char32_t c : util::utf8_range(str)) + for (char32_t c : str) { glyph g; if (std::isspace(c))