HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
ShapedText.hpp
1// Copyright 2020 Pokitec
2// All rights reserved.
3
4#pragma once
5
6#include "TTauri/Text/AttributedGlyphLine.hpp"
7#include "TTauri/Text/gstring.hpp"
8#include "TTauri/Foundation/required.hpp"
9#include "TTauri/Foundation/attributes.hpp"
10#include "TTauri/Foundation/Path.hpp"
11#include "TTauri/Foundation/vec.hpp"
12#include "TTauri/Foundation/nested_vector_iterator.hpp"
13#include <string_view>
14#include <optional>
15
16namespace tt {
17
18
22public:
24 std::vector<AttributedGlyphLine>::const_iterator,
25 std::vector<AttributedGlyphLine>::iterator,
26 AttributedGlyphLine::iterator>;
27
29 std::vector<AttributedGlyphLine>::const_iterator,
30 std::vector<AttributedGlyphLine>::const_iterator,
31 AttributedGlyphLine::const_iterator>;
32
33 Alignment alignment;
34 aarect boundingBox;
35 float width;
36 vec preferredExtent;
37
38private:
40
41public:
42 ShapedText() noexcept :
43 alignment(Alignment::MiddleCenter), boundingBox(), width(0.0f), preferredExtent(), lines() {}
44 ShapedText(ShapedText const &other) = default;
45 ShapedText(ShapedText &&other) noexcept = default;
46 ShapedText &operator=(ShapedText const &other) = default;
47 ShapedText &operator=(ShapedText &&other) noexcept = default;
48 ~ShapedText() = default;
49
73 float width,
74 Alignment const alignment=Alignment::MiddleCenter,
75 bool wrap=true
76 ) noexcept;
77
88 gstring const &text,
89 TextStyle const &style,
90 float width,
91 Alignment const alignment=Alignment::MiddleCenter,
92 bool wrap=true
93 ) noexcept;
94
105 std::string_view text,
106 TextStyle const &style,
107 float width,
108 Alignment const alignment=Alignment::MiddleCenter,
109 bool wrap=true
110 ) noexcept;
111
112 [[nodiscard]] size_t size() const noexcept {
113 ssize_t count = 0;
114 for (ttlet &line: lines) {
115 count += ssize(line);
116 }
117 return numeric_cast<size_t>(count);
118 }
119
120 [[nodiscard]] iterator begin() noexcept { return nested_vector_iterator_begin(lines); }
121 [[nodiscard]] const_iterator begin() const noexcept { return nested_vector_iterator_cbegin(lines); }
122 [[nodiscard]] const_iterator cbegin() const noexcept { return nested_vector_iterator_cbegin(lines); }
123
124 [[nodiscard]] iterator end() noexcept { return nested_vector_iterator_end(lines); }
125 [[nodiscard]] const_iterator end() const noexcept { return nested_vector_iterator_cend(lines); }
126 [[nodiscard]] const_iterator cend() const noexcept { return nested_vector_iterator_cend(lines); }
127
128 float topAccender() const noexcept {
129 return lines.front().ascender;
130 }
131
132 float bottomDescender() const noexcept {
133 return lines.back().descender;
134 }
135
136 float topCapHeight() const noexcept {
137 return lines.front().capHeight;
138 }
139
140 float bottomCapHeight() const noexcept {
141 return lines.back().capHeight;
142 }
143
146 float middleCapHeight() const noexcept {
147 if ((ssize(lines) % 2) == 1) {
148 return lines[ssize(lines) / 2].capHeight;
149 } else {
150 return (lines[ssize(lines) / 2 - 1].capHeight + lines[ssize(lines) / 2].capHeight) * 0.5f;
151 }
152 }
153
159 float baselineOffset(float height) noexcept {
160 if (alignment == VerticalAlignment::Top) {
161 return height - topAccender();
162 } else if (alignment == VerticalAlignment::Bottom) {
163 return bottomDescender();
164 } else if (alignment == VerticalAlignment::Middle) {
165 return height * 0.5f - middleCapHeight() * 0.5f;
166 } else {
167 tt_no_default;
168 }
169 }
170
176 float middleOffset(float height) const noexcept {
177 if (alignment == VerticalAlignment::Top) {
178 return height - topCapHeight() * 0.5f;
179 } else if (alignment == VerticalAlignment::Bottom) {
180 return height - bottomCapHeight() * 0.5f;
181 } else if (alignment == VerticalAlignment::Middle) {
182 return height - middleCapHeight() * 0.5f;
183 } else {
184 tt_no_default;
185 }
186 }
187
193 mat::T2 T(aarect rectangle) noexcept {
194 return {
195 rectangle.x(),
196 rectangle.y() + baselineOffset(rectangle.height())
197 };
198 }
199
204 mat::T2 TMiddle(vec position) noexcept {
205 return {
206 position.x(),
207 middleOffset(position.y())
208 };
209 }
210
211
214 [[nodiscard]] const_iterator find(ssize_t position) const noexcept;
215
224 [[nodiscard]] aarect rectangleOfGrapheme(ssize_t index) const noexcept;
225
233 [[nodiscard]] aarect leftToRightCaret(ssize_t index, bool overwrite) const noexcept;
234
242 [[nodiscard]] std::vector<aarect> selectionRectangles(ssize_t first, ssize_t last) const noexcept;
243
248 [[nodiscard]] std::optional<ssize_t> indexOfCharAtCoordinate(vec coordinate) const noexcept;
249
254 [[nodiscard]] std::optional<ssize_t> indexOfCharOnTheLeft(ssize_t logicalIndex) const noexcept;
255
260 [[nodiscard]] std::optional<ssize_t> indexOfCharOnTheRight(ssize_t logicalIndex) const noexcept;
261
264 [[nodiscard]] std::pair<ssize_t,ssize_t> indicesOfWord(ssize_t logicalIndex) const noexcept;
265
268 [[nodiscard]] std::pair<ssize_t,ssize_t> indicesOfParagraph(ssize_t logicalIndex) const noexcept;
269
272 [[nodiscard]] ssize_t indexAtRightSideOfWord(ssize_t logicalIndex) const noexcept;
273
278 [[nodiscard]] std::optional<ssize_t> indexOfWordOnTheLeft(ssize_t logicalIndex) const noexcept;
279
284 [[nodiscard]] std::optional<ssize_t> indexOfWordOnTheRight(ssize_t logicalIndex) const noexcept;
285
288 [[nodiscard]] Path get_path() const noexcept;
289
290
297 [[nodiscard]] int indexFromCoordinate(vec coordinate) const noexcept;
298
306 [[nodiscard]] std::vector<int> indicesFromCoordinates(vec start, vec current) const noexcept;
307};
308
309
310
311}
STL namespace.
Class which represents an axis-aligned rectangle.
Definition aarect.hpp:13
Optimized 2D translate matrix.
Definition mat.hpp:184
An iterator for a vector inside another vector.
Definition nested_vector_iterator.hpp:24
Definition Path.hpp:29
A 4D vector.
Definition vec.hpp:37
Definition gstring.hpp:12
ShapedText represent a piece of text shaped to be displayed.
Definition ShapedText.hpp:21
std::pair< ssize_t, ssize_t > indicesOfWord(ssize_t logicalIndex) const noexcept
Return the index at the left side and right side of a word.
int indexFromCoordinate(vec coordinate) const noexcept
Get the index into the text from a coordinate.
mat::T2 T(aarect rectangle) noexcept
Get the translation for where to place the text.
Definition ShapedText.hpp:193
mat::T2 TMiddle(vec position) noexcept
Get the translation for where to place the text.
Definition ShapedText.hpp:204
float middleCapHeight() const noexcept
Get the capHeight of the middle line(s).
Definition ShapedText.hpp:146
std::optional< ssize_t > indexOfCharOnTheRight(ssize_t logicalIndex) const noexcept
Return the index of the character to the right.
Path get_path() const noexcept
Convert the whole shaped text into a layered path.
float baselineOffset(float height) noexcept
Get the offset of the baseline The offset of the baseline when the text needs to be rendered inside a...
Definition ShapedText.hpp:159
const_iterator find(ssize_t position) const noexcept
Find a glyph that corresponds to position.
aarect leftToRightCaret(ssize_t index, bool overwrite) const noexcept
Return the cursor-carets.
ShapedText(std::vector< AttributedGrapheme > const &text, float width, Alignment const alignment=Alignment::MiddleCenter, bool wrap=true) noexcept
Create shaped text from attributed text.
std::pair< ssize_t, ssize_t > indicesOfParagraph(ssize_t logicalIndex) const noexcept
Return the index at the left side and right side of a paragraph.
std::vector< aarect > selectionRectangles(ssize_t first, ssize_t last) const noexcept
Return a list of merged rectangles to display for the selection.
std::optional< ssize_t > indexOfCharOnTheLeft(ssize_t logicalIndex) const noexcept
Return the index of the character to the left.
float middleOffset(float height) const noexcept
Get the offset of the middle of a line.
Definition ShapedText.hpp:176
aarect rectangleOfGrapheme(ssize_t index) const noexcept
Get a rectangle for the grapheme.
std::optional< ssize_t > indexOfWordOnTheRight(ssize_t logicalIndex) const noexcept
Return the index of the word to the right.
ssize_t indexAtRightSideOfWord(ssize_t logicalIndex) const noexcept
Return the index at the left side of a word.
std::optional< ssize_t > indexOfCharAtCoordinate(vec coordinate) const noexcept
Return the index of the character .
std::vector< int > indicesFromCoordinates(vec start, vec current) const noexcept
Get the index into the text from a coordinate.
std::optional< ssize_t > indexOfWordOnTheLeft(ssize_t logicalIndex) const noexcept
Return the index of the word to the left.
Definition TextStyle.hpp:15
T back(T... args)
T front(T... args)