diff --git a/libs/ui/include/psemek/ui/font.hpp b/libs/ui/include/psemek/ui/font.hpp index f9c33912..ac0a9bd4 100644 --- a/libs/ui/include/psemek/ui/font.hpp +++ b/libs/ui/include/psemek/ui/font.hpp @@ -57,8 +57,20 @@ namespace psemek::ui virtual bool supports_character(char32_t c) const = 0; 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 std::vector shape(std::string_view str, shape_options const & options, geom::point & pen) const = 0; + virtual std::vector shape(std::u32string_view str, shape_options const & options, geom::point & pen) const = 0; + + virtual std::vector shape(std::string_view str, shape_options const & options) const + { + geom::point pen{0.f, 0.f}; + return shape(str, options, pen); + } + + virtual std::vector shape(std::u32string_view str, shape_options const & options) const + { + geom::point pen{0.f, 0.f}; + return shape(str, options, pen); + } 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 a0f221af..e0be7fd0 100644 --- a/libs/ui/include/psemek/ui/kerned_font.hpp +++ b/libs/ui/include/psemek/ui/kerned_font.hpp @@ -31,8 +31,8 @@ namespace psemek::ui bool supports_character(char32_t c) const override; 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; + std::vector shape(std::string_view str, shape_options const & options, geom::point & pen) const override; + std::vector shape(std::u32string_view str, shape_options const & options, geom::point & pen) const override; gfx::texture_2d const & atlas() const override { return atlas_; }; @@ -47,7 +47,7 @@ namespace psemek::ui std::unordered_map glyphs_; template - std::vector shape_impl(String const & str, shape_options const & options) const; + std::vector shape_impl(String const & str, shape_options const & options, geom::point & pen) const; }; } diff --git a/libs/ui/include/psemek/ui/monospace_font.hpp b/libs/ui/include/psemek/ui/monospace_font.hpp index 29b92966..1bd07d1e 100644 --- a/libs/ui/include/psemek/ui/monospace_font.hpp +++ b/libs/ui/include/psemek/ui/monospace_font.hpp @@ -19,8 +19,8 @@ namespace psemek::ui bool supports_character(char32_t c) const override; 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; + std::vector shape(std::string_view str, shape_options const & options, geom::point & pen) const override; + std::vector shape(std::u32string_view str, shape_options const & options, geom::point & pen) const override; gfx::texture_2d const & atlas() const override { return atlas_; }; @@ -34,7 +34,7 @@ namespace psemek::ui std::vector> texcoords_; template - std::vector shape_impl(String const & str, shape_options const & options) const; + std::vector shape_impl(String const & str, shape_options const & options, geom::point & pen) const; }; } diff --git a/libs/ui/source/kerned_font.cpp b/libs/ui/source/kerned_font.cpp index 5bce5933..59acf0a6 100644 --- a/libs/ui/source/kerned_font.cpp +++ b/libs/ui/source/kerned_font.cpp @@ -50,25 +50,25 @@ namespace psemek::ui return std::isspace(c) || glyphs_.contains(c); } - std::vector kerned_font::shape(std::string_view str, shape_options const & options) const + std::vector kerned_font::shape(std::string_view str, shape_options const & options, geom::point & pen) const { - return shape_impl(util::utf8_range(str), options); + return shape_impl(util::utf8_range(str), options, pen); } - std::vector kerned_font::shape(std::u32string_view str, shape_options const & options) const + std::vector kerned_font::shape(std::u32string_view str, shape_options const & options, geom::point & pen) const { - return shape_impl(str, options); + return shape_impl(str, options, pen); } template - std::vector kerned_font::shape_impl(String const & str, shape_options const & options) const + std::vector kerned_font::shape_impl(String const & str, shape_options const & options, geom::point & pen) const { char32_t const unknown = supports_character(options.unknown_character) ? options.unknown_character : '?'; geom::vector const advance_mask = advance_dir(options.direction); std::vector result; - geom::vector pos{0.f, (size_[1] - baseline_offset_) * options.scale}; + float const offset_to_baseline = (size_[1] - baseline_offset_) * options.scale; for (char32_t c : str) { if (!supports_character(c)) @@ -82,15 +82,15 @@ namespace psemek::ui glyph g; g.character = c; - g.position[0].min = pos[0] + data.offset_x * options.scale; - g.position[1].min = pos[1] - (data.offset_y + data.size_y) * options.scale; - g.position[0].max = pos[0] + (data.offset_x + data.size_x) * options.scale; - g.position[1].max = pos[1] - data.offset_y * options.scale; + g.position[0].min = pen[0] + data.offset_x * options.scale; + g.position[1].min = pen[1] + offset_to_baseline - (data.offset_y + data.size_y) * options.scale; + g.position[0].max = pen[0] + (data.offset_x + data.size_x) * options.scale; + g.position[1].max = pen[1] + offset_to_baseline - data.offset_y * options.scale; result.push_back(g); geom::vector advance{data.advance * options.scale, size_[1] * options.scale}; - pos += geom::pointwise_mult(advance_mask, advance); + pen += geom::pointwise_mult(advance_mask, advance); } return result; diff --git a/libs/ui/source/monospace_font.cpp b/libs/ui/source/monospace_font.cpp index 4b9bfb2f..1cace335 100644 --- a/libs/ui/source/monospace_font.cpp +++ b/libs/ui/source/monospace_font.cpp @@ -37,18 +37,18 @@ namespace psemek::ui return std::isspace(c) || (c >= range_.begin && c < range_.end); } - std::vector monospace_font::shape(std::string_view str, shape_options const & options) const + std::vector monospace_font::shape(std::string_view str, shape_options const & options, geom::point & pen) const { - return shape_impl(util::utf8_range(str), options); + return shape_impl(util::utf8_range(str), options, pen); } - std::vector monospace_font::shape(std::u32string_view str, shape_options const & options) const + std::vector monospace_font::shape(std::u32string_view str, shape_options const & options, geom::point & pen) const { - return shape_impl(str, options); + return shape_impl(str, options, pen); } template - std::vector monospace_font::shape_impl(String const & str, shape_options const & options) const + std::vector monospace_font::shape_impl(String const & str, shape_options const & options, geom::point & pen) const { char32_t const unknown = supports_character(options.unknown_character) ? options.unknown_character : '?'; geom::vector const size = geom::cast(this->size()) * options.scale; @@ -56,22 +56,21 @@ namespace psemek::ui std::vector result; - geom::vector pos{0.f, 0.f}; for (char32_t c : str) { glyph g; if (std::isspace(c)) { g.character = c; - g.position = {{{pos[0], pos[0]}, {pos[1], pos[1]}}}; + g.position = {{{pen[0], pen[0]}, {pen[1], pen[1]}}}; } else { g.character = supports_character(c) ? c : unknown; - g.position = {{{pos[0], pos[0] + size[0]}, {pos[1], pos[1] + size[1]}}}; + g.position = {{{pen[0], pen[0] + size[0]}, {pen[1], pen[1] + size[1]}}}; } result.push_back(g); - pos += advance; + pen += advance; } return result;