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 bool supports_character(char32_t c) const = 0;
|
||||||
virtual util::span<character_range const> supported_characters() 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::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) 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;
|
virtual gfx::texture_2d const & atlas() const = 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,8 @@ namespace psemek::ui
|
||||||
bool supports_character(char32_t c) const override;
|
bool supports_character(char32_t c) const override;
|
||||||
util::span<character_range const> supported_characters() const override { return ranges_; }
|
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::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) 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_; };
|
gfx::texture_2d const & atlas() const override { return atlas_; };
|
||||||
|
|
||||||
|
|
@ -47,7 +47,7 @@ namespace psemek::ui
|
||||||
std::unordered_map<char32_t, glyph_data> glyphs_;
|
std::unordered_map<char32_t, glyph_data> glyphs_;
|
||||||
|
|
||||||
template <typename String>
|
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;
|
bool supports_character(char32_t c) const override;
|
||||||
util::span<character_range const> supported_characters() const override { return {&range_, &range_ + 1}; }
|
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::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) 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_; };
|
gfx::texture_2d const & atlas() const override { return atlas_; };
|
||||||
|
|
||||||
|
|
@ -34,7 +34,7 @@ namespace psemek::ui
|
||||||
std::vector<geom::box<float, 2>> texcoords_;
|
std::vector<geom::box<float, 2>> texcoords_;
|
||||||
|
|
||||||
template <typename String>
|
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);
|
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>
|
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 : '?';
|
char32_t const unknown = supports_character(options.unknown_character) ? options.unknown_character : '?';
|
||||||
geom::vector<float, 2> const advance_mask = advance_dir(options.direction);
|
geom::vector<float, 2> const advance_mask = advance_dir(options.direction);
|
||||||
|
|
||||||
std::vector<glyph> result;
|
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)
|
for (char32_t c : str)
|
||||||
{
|
{
|
||||||
if (!supports_character(c))
|
if (!supports_character(c))
|
||||||
|
|
@ -82,15 +82,15 @@ namespace psemek::ui
|
||||||
|
|
||||||
glyph g;
|
glyph g;
|
||||||
g.character = c;
|
g.character = c;
|
||||||
g.position[0].min = pos[0] + data.offset_x * options.scale;
|
g.position[0].min = pen[0] + data.offset_x * options.scale;
|
||||||
g.position[1].min = pos[1] - (data.offset_y + data.size_y) * options.scale;
|
g.position[1].min = pen[1] + offset_to_baseline - (data.offset_y + data.size_y) * options.scale;
|
||||||
g.position[0].max = pos[0] + (data.offset_x + data.size_x) * options.scale;
|
g.position[0].max = pen[0] + (data.offset_x + data.size_x) * options.scale;
|
||||||
g.position[1].max = pos[1] - data.offset_y * options.scale;
|
g.position[1].max = pen[1] + offset_to_baseline - data.offset_y * options.scale;
|
||||||
result.push_back(g);
|
result.push_back(g);
|
||||||
|
|
||||||
geom::vector<float, 2> advance{data.advance * options.scale, size_[1] * options.scale};
|
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;
|
return result;
|
||||||
|
|
|
||||||
|
|
@ -37,18 +37,18 @@ namespace psemek::ui
|
||||||
return std::isspace(c) || (c >= range_.begin && c < range_.end);
|
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>
|
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 : '?';
|
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;
|
geom::vector<float, 2> const size = geom::cast<float>(this->size()) * options.scale;
|
||||||
|
|
@ -56,22 +56,21 @@ namespace psemek::ui
|
||||||
|
|
||||||
std::vector<glyph> result;
|
std::vector<glyph> result;
|
||||||
|
|
||||||
geom::vector<float, 2> pos{0.f, 0.f};
|
|
||||||
for (char32_t c : str)
|
for (char32_t c : str)
|
||||||
{
|
{
|
||||||
glyph g;
|
glyph g;
|
||||||
if (std::isspace(c))
|
if (std::isspace(c))
|
||||||
{
|
{
|
||||||
g.character = 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
|
else
|
||||||
{
|
{
|
||||||
g.character = supports_character(c) ? c : unknown;
|
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);
|
result.push_back(g);
|
||||||
pos += advance;
|
pen += advance;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue