Support shaping utf32-text directly in ui::font

This commit is contained in:
Nikita Lisitsa 2022-04-01 17:38:39 +03:00
parent 53b706a29b
commit 11b3e960d5
5 changed files with 33 additions and 2 deletions

View file

@ -58,6 +58,7 @@ namespace psemek::ui
virtual util::span<character_range const> supported_characters() const = 0;
virtual std::vector<glyph> shape(std::string_view str, shape_options const & options) const = 0;
virtual std::vector<glyph> shape(std::u32string_view str, shape_options const & options) const = 0;
virtual gfx::texture_2d const & atlas() const = 0;

View file

@ -32,6 +32,7 @@ namespace psemek::ui
util::span<character_range const> supported_characters() const override { return ranges_; }
std::vector<glyph> shape(std::string_view str, shape_options const & options) const override;
std::vector<glyph> 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<char32_t, glyph_data> glyphs_;
template <typename String>
std::vector<glyph> shape_impl(String const & str, shape_options const & options) const;
};
}

View file

@ -20,6 +20,7 @@ namespace psemek::ui
util::span<character_range const> supported_characters() const override { return {&range_, &range_ + 1}; }
std::vector<glyph> shape(std::string_view str, shape_options const & options) const override;
std::vector<glyph> 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<int, 2> size_;
gfx::texture_2d atlas_;
std::vector<geom::box<float, 2>> texcoords_;
template <typename String>
std::vector<glyph> shape_impl(String const & str, shape_options const & options) const;
};
}

View file

@ -51,6 +51,17 @@ namespace psemek::ui
}
std::vector<glyph> kerned_font::shape(std::string_view str, shape_options const & options) const
{
return shape_impl(util::utf8_range(str), options);
}
std::vector<glyph> kerned_font::shape(std::u32string_view str, shape_options const & options) const
{
return shape_impl(str, options);
}
template <typename String>
std::vector<glyph> 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<float, 2> const advance_mask = advance_dir(options.direction);
@ -58,7 +69,7 @@ namespace psemek::ui
std::vector<glyph> result;
geom::vector<float, 2> 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;

View file

@ -38,6 +38,17 @@ namespace psemek::ui
}
std::vector<glyph> monospace_font::shape(std::string_view str, shape_options const & options) const
{
return shape_impl(util::utf8_range(str), options);
}
std::vector<glyph> monospace_font::shape(std::u32string_view str, shape_options const & options) const
{
return shape_impl(str, options);
}
template <typename String>
std::vector<glyph> 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<float, 2> const size = geom::cast<float>(this->size()) * options.scale;
@ -46,7 +57,7 @@ namespace psemek::ui
std::vector<glyph> result;
geom::vector<float, 2> pos{0.f, 0.f};
for (char32_t c : util::utf8_range(str))
for (char32_t c : str)
{
glyph g;
if (std::isspace(c))