Support setting initial pen position & retrieving final pen position in font text shaping
This commit is contained in:
parent
a9de6232de
commit
98b8a324d0
5 changed files with 39 additions and 28 deletions
|
|
@ -57,8 +57,20 @@ namespace psemek::ui
|
|||
virtual bool supports_character(char32_t c) const = 0;
|
||||
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 std::vector<glyph> shape(std::string_view str, shape_options const & options, geom::point<float, 2> & pen) const = 0;
|
||||
virtual std::vector<glyph> shape(std::u32string_view str, shape_options const & options, geom::point<float, 2> & pen) const = 0;
|
||||
|
||||
virtual std::vector<glyph> shape(std::string_view str, shape_options const & options) const
|
||||
{
|
||||
geom::point<float, 2> pen{0.f, 0.f};
|
||||
return shape(str, options, pen);
|
||||
}
|
||||
|
||||
virtual std::vector<glyph> shape(std::u32string_view str, shape_options const & options) const
|
||||
{
|
||||
geom::point<float, 2> pen{0.f, 0.f};
|
||||
return shape(str, options, pen);
|
||||
}
|
||||
|
||||
virtual gfx::texture_2d const & atlas() const = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ namespace psemek::ui
|
|||
bool supports_character(char32_t c) const override;
|
||||
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;
|
||||
std::vector<glyph> shape(std::string_view str, shape_options const & options, geom::point<float, 2> & pen) const override;
|
||||
std::vector<glyph> shape(std::u32string_view str, shape_options const & options, geom::point<float, 2> & pen) const override;
|
||||
|
||||
gfx::texture_2d const & atlas() const override { return atlas_; };
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ namespace psemek::ui
|
|||
std::unordered_map<char32_t, glyph_data> glyphs_;
|
||||
|
||||
template <typename String>
|
||||
std::vector<glyph> shape_impl(String const & str, shape_options const & options) const;
|
||||
std::vector<glyph> shape_impl(String const & str, shape_options const & options, geom::point<float, 2> & pen) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ namespace psemek::ui
|
|||
bool supports_character(char32_t c) const override;
|
||||
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;
|
||||
std::vector<glyph> shape(std::string_view str, shape_options const & options, geom::point<float, 2> & pen) const override;
|
||||
std::vector<glyph> shape(std::u32string_view str, shape_options const & options, geom::point<float, 2> & pen) const override;
|
||||
|
||||
gfx::texture_2d const & atlas() const override { return atlas_; };
|
||||
|
||||
|
|
@ -34,7 +34,7 @@ namespace psemek::ui
|
|||
std::vector<geom::box<float, 2>> texcoords_;
|
||||
|
||||
template <typename String>
|
||||
std::vector<glyph> shape_impl(String const & str, shape_options const & options) const;
|
||||
std::vector<glyph> shape_impl(String const & str, shape_options const & options, geom::point<float, 2> & pen) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,25 +50,25 @@ namespace psemek::ui
|
|||
return std::isspace(c) || glyphs_.contains(c);
|
||||
}
|
||||
|
||||
std::vector<glyph> kerned_font::shape(std::string_view str, shape_options const & options) const
|
||||
std::vector<glyph> kerned_font::shape(std::string_view str, shape_options const & options, geom::point<float, 2> & pen) const
|
||||
{
|
||||
return shape_impl(util::utf8_range(str), options);
|
||||
return shape_impl(util::utf8_range(str), options, pen);
|
||||
}
|
||||
|
||||
std::vector<glyph> kerned_font::shape(std::u32string_view str, shape_options const & options) const
|
||||
std::vector<glyph> kerned_font::shape(std::u32string_view str, shape_options const & options, geom::point<float, 2> & pen) const
|
||||
{
|
||||
return shape_impl(str, options);
|
||||
return shape_impl(str, options, pen);
|
||||
}
|
||||
|
||||
template <typename String>
|
||||
std::vector<glyph> kerned_font::shape_impl(String const & str, shape_options const & options) const
|
||||
std::vector<glyph> kerned_font::shape_impl(String const & str, shape_options const & options, geom::point<float, 2> & pen) const
|
||||
{
|
||||
char32_t const unknown = supports_character(options.unknown_character) ? options.unknown_character : '?';
|
||||
geom::vector<float, 2> const advance_mask = advance_dir(options.direction);
|
||||
|
||||
std::vector<glyph> result;
|
||||
|
||||
geom::vector<float, 2> 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<float, 2> 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;
|
||||
|
|
|
|||
|
|
@ -37,18 +37,18 @@ namespace psemek::ui
|
|||
return std::isspace(c) || (c >= range_.begin && c < range_.end);
|
||||
}
|
||||
|
||||
std::vector<glyph> monospace_font::shape(std::string_view str, shape_options const & options) const
|
||||
std::vector<glyph> monospace_font::shape(std::string_view str, shape_options const & options, geom::point<float, 2> & pen) const
|
||||
{
|
||||
return shape_impl(util::utf8_range(str), options);
|
||||
return shape_impl(util::utf8_range(str), options, pen);
|
||||
}
|
||||
|
||||
std::vector<glyph> monospace_font::shape(std::u32string_view str, shape_options const & options) const
|
||||
std::vector<glyph> monospace_font::shape(std::u32string_view str, shape_options const & options, geom::point<float, 2> & pen) const
|
||||
{
|
||||
return shape_impl(str, options);
|
||||
return shape_impl(str, options, pen);
|
||||
}
|
||||
|
||||
template <typename String>
|
||||
std::vector<glyph> monospace_font::shape_impl(String const & str, shape_options const & options) const
|
||||
std::vector<glyph> monospace_font::shape_impl(String const & str, shape_options const & options, geom::point<float, 2> & pen) 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;
|
||||
|
|
@ -56,22 +56,21 @@ namespace psemek::ui
|
|||
|
||||
std::vector<glyph> result;
|
||||
|
||||
geom::vector<float, 2> 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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue