15 using iterator = vector_type::iterator;
16 using const_iterator = vector_type::const_iterator;
17 using value_type = vector_type::value_type;
31 line(), width(0.0f), ascender(0.0f), descender(0.0f), lineGap(0.0f), capHeight(0.0f), xHeight(0.0f)
37 calculateLineMetrics();
40 [[nodiscard]]
bool shouldWrap(
float maximum_width)
noexcept {
41 tt_axiom(std::ssize(line) >= 1);
43 width > maximum_width &&
44 std::ssize(line) >= (line.
back().isParagraphSeparator() ? 3 : 2);
48 tt_axiom(shouldWrap(maximum_width));
50 auto word_end = line.
begin();
51 auto line_width = 0.0f;
52 auto line_valid_width = 0.0f;
54 auto i = line.
begin();
55 for (; i != line.
end(); ++i) {
56 line_width += i->metrics.advance.x();
58 line_valid_width = line_width;
61 if (line_valid_width > maximum_width) {
65 }
else if (i->isWhiteSpace()) {
72 (word_end != line.
begin()) ? word_end :
73 (i != line.begin()) ? i :
78 calculateLineMetrics();
82 [[nodiscard]] aarectangle boundingBox() const noexcept {
83 tt_axiom(std::ssize(line) >= 1);
86 line.
front().position.x(),
87 line.
front().position.y() - descender
91 line.
back().position.x() + line.
back().metrics.advance.x(),
92 line.
back().position.y() + ascender
95 return aarectangle{p0, p3};
98 [[nodiscard]]
bool contains(point2 coordinate)
const noexcept {
99 return boundingBox().
contains(coordinate);
102 [[nodiscard]] const_iterator find(point2 coordinate)
const noexcept
104 auto bbox = boundingBox();
106 if (coordinate.y() < bbox.bottom() || coordinate.y() > bbox.top()) {
110 if (coordinate.x() < bbox.left()) {
114 if (coordinate.x() > bbox.right()) {
118 return std::lower_bound(cbegin(), cend(), coordinate.x(), [](ttlet &a, ttlet &b) {
119 return (a.position.x() + a.metrics.advance.x()) < b;
123 [[nodiscard]]
size_t size() const noexcept {
return line.
size(); }
125 [[nodiscard]] iterator begin() noexcept {
return line.
begin(); }
126 [[nodiscard]] const_iterator begin() const noexcept {
return line.
cbegin(); }
127 [[nodiscard]] const_iterator cbegin() const noexcept {
return line.
cbegin(); }
129 [[nodiscard]] iterator end() noexcept {
return line.
end(); }
130 [[nodiscard]] const_iterator end() const noexcept {
return line.
cend(); }
131 [[nodiscard]] const_iterator cend() const noexcept {
return line.
cend(); }
133 void positionGlyphs(point2 position)
noexcept {
135 for (
auto &&g: line) {
136 g.position = position;
137 position += g.metrics.advance;
142 void calculateLineMetrics() noexcept {
149 auto totalWidth = 0.0f;
150 auto validWidth = 0.0f;
151 for (ttlet &g: line) {
152 totalWidth += g.metrics.advance.x();
153 ascender =
std::max(ascender, g.metrics.ascender);
154 descender =
std::max(descender, g.metrics.descender);
155 lineGap =
std::max(lineGap, g.metrics.lineGap);
156 capHeight += g.metrics.capHeight;
157 xHeight += g.metrics.xHeight;
161 validWidth = totalWidth;
164 capHeight /= narrow_cast<float>(std::ssize(line));
165 xHeight /= narrow_cast<float>(std::ssize(line));
attributed_glyph_line(iterator first, iterator last) noexcept
This constructor will move the data from first to last.
Definition attributed_glyph_line.hpp:30