HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
shaped_text.hpp
1// Copyright Take Vos 2020-2021.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "attributed_glyph_line.hpp"
8#include "gstring.hpp"
9#include "../required.hpp"
10#include "../alignment.hpp"
11#include "../graphic_path.hpp"
12#include "../recursive_iterator.hpp"
13#include "../geometry/extent.hpp"
14#include "../geometry/point.hpp"
15#include <string_view>
16#include <optional>
17
18namespace tt {
19
20
24public:
26
28
29 alignment alignment;
30 aarectangle boundingBox;
31 float width;
32 extent2 preferred_extent;
33
34private:
36
37public:
38 shaped_text() noexcept :
39 alignment(alignment::middle_center), boundingBox(), width(0.0f), preferred_extent(), lines() {}
40 shaped_text(shaped_text const &other) = default;
41 shaped_text(shaped_text &&other) noexcept = default;
42 shaped_text &operator=(shaped_text const &other) = default;
43 shaped_text &operator=(shaped_text &&other) noexcept = default;
44 ~shaped_text() = default;
45
69 float width,
70 tt::alignment const alignment=alignment::middle_center,
71 bool wrap=true
72 ) noexcept;
73
84 gstring const &text,
85 text_style const &style,
86 float width,
87 tt::alignment const alignment=alignment::middle_center,
88 bool wrap=true
89 ) noexcept;
90
101 std::u8string_view text,
102 text_style const &style,
103 float width,
104 tt::alignment const alignment=alignment::middle_center,
105 bool wrap=true
106 ) noexcept;
107
108 [[nodiscard]] size_t size() const noexcept {
109 ssize_t count = 0;
110 for (ttlet &line: lines) {
111 count += std::ssize(line);
112 }
113 return narrow_cast<size_t>(count);
114 }
115
116 [[nodiscard]] iterator begin() noexcept { return recursive_iterator_begin(lines); }
117 [[nodiscard]] const_iterator begin() const noexcept { return recursive_iterator_begin(lines); }
118 [[nodiscard]] const_iterator cbegin() const noexcept { return recursive_iterator_begin(lines); }
119
120 [[nodiscard]] iterator end() noexcept { return recursive_iterator_end(lines); }
121 [[nodiscard]] const_iterator end() const noexcept { return recursive_iterator_end(lines); }
122 [[nodiscard]] const_iterator cend() const noexcept { return recursive_iterator_end(lines); }
123
124 float topAccender() const noexcept {
125 return lines.front().ascender;
126 }
127
128 float bottomDescender() const noexcept {
129 return lines.back().descender;
130 }
131
132 float topCapHeight() const noexcept {
133 return lines.front().capHeight;
134 }
135
136 float bottomCapHeight() const noexcept {
137 return lines.back().capHeight;
138 }
139
142 float middleCapHeight() const noexcept {
143 if ((std::ssize(lines) % 2) == 1) {
144 return lines[std::ssize(lines) / 2].capHeight;
145 } else {
146 return (lines[std::ssize(lines) / 2 - 1].capHeight + lines[std::ssize(lines) / 2].capHeight) * 0.5f;
147 }
148 }
149
155 float baselineOffset(float height) noexcept {
156 if (alignment == vertical_alignment::top) {
157 return height - topAccender();
158 } else if (alignment == vertical_alignment::bottom) {
159 return bottomDescender();
160 } else if (alignment == vertical_alignment::middle) {
161 return height * 0.5f - middleCapHeight() * 0.5f;
162 } else {
163 tt_no_default();
164 }
165 }
166
172 float middleOffset(float height) const noexcept {
173 if (alignment == vertical_alignment::top) {
174 return height - topCapHeight() * 0.5f;
175 } else if (alignment == vertical_alignment::bottom) {
176 return height - bottomCapHeight() * 0.5f;
177 } else if (alignment == vertical_alignment::middle) {
178 return height - middleCapHeight() * 0.5f;
179 } else {
180 tt_no_default();
181 }
182 }
183
189 {
190 return translate2{position.x(), middleOffset(position.y())};
191 }
192
195 [[nodiscard]] const_iterator find(ssize_t position) const noexcept;
196
205 [[nodiscard]] aarectangle rectangleOfgrapheme(ssize_t index) const noexcept;
206
214 [[nodiscard]] aarectangle leftToRightCaret(ssize_t index, bool overwrite) const noexcept;
215
223 [[nodiscard]] std::vector<aarectangle> selectionRectangles(ssize_t first, ssize_t last) const noexcept;
224
229 [[nodiscard]] std::optional<ssize_t> indexOfCharAtCoordinate(point2 coordinate) const noexcept;
230
235 [[nodiscard]] std::optional<ssize_t> indexOfCharOnTheLeft(ssize_t logical_index) const noexcept;
236
241 [[nodiscard]] std::optional<ssize_t> indexOfCharOnTheRight(ssize_t logical_index) const noexcept;
242
247 [[nodiscard]] std::pair<ssize_t,ssize_t> indicesOfWord(ssize_t logical_index) const noexcept;
248
253 [[nodiscard]] std::pair<ssize_t,ssize_t> indicesOfParagraph(ssize_t logical_index) const noexcept;
254
259 [[nodiscard]] ssize_t indexAtRightSideOfWord(ssize_t logical_index) const noexcept;
260
265 [[nodiscard]] std::optional<ssize_t> indexOfWordOnTheLeft(ssize_t logical_index) const noexcept;
266
271 [[nodiscard]] std::optional<ssize_t> indexOfWordOnTheRight(ssize_t logical_index) const noexcept;
272
275 [[nodiscard]] graphic_path get_path() const noexcept;
276
277
284 [[nodiscard]] int indexFromCoordinate(point2 coordinate) const noexcept;
285
293 [[nodiscard]] std::vector<int> indicesFromCoordinates(point2 start, point2 current) const noexcept;
294};
295
296
297
298}
STL namespace.
Class which represents an axis-aligned rectangle.
Definition axis_aligned_rectangle.hpp:18
A path is a vector graphics object.
Definition graphic_path.hpp:28
An iterator which recursively iterates through nested containers.
Definition recursive_iterator.hpp:18
Definition gstring.hpp:13
shaped_text represent a piece of text shaped to be displayed.
Definition shaped_text.hpp:23
shaped_text(std::vector< attributed_grapheme > const &text, float width, tt::alignment const alignment=alignment::middle_center, bool wrap=true) noexcept
Create shaped text from attributed text.
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 shaped_text.hpp:155
std::vector< int > indicesFromCoordinates(point2 start, point2 current) const noexcept
Get the index into the text from a coordinate.
std::optional< ssize_t > indexOfWordOnTheLeft(ssize_t logical_index) const noexcept
Get the first character of the word on the left.
std::optional< ssize_t > indexOfCharOnTheRight(ssize_t logical_index) const noexcept
Get the character right of the given character.
std::optional< ssize_t > indexOfWordOnTheRight(ssize_t logical_index) const noexcept
Get the last character of the word on the right.
float middleCapHeight() const noexcept
Get the capHeight of the middle line(s).
Definition shaped_text.hpp:142
std::vector< aarectangle > selectionRectangles(ssize_t first, ssize_t last) const noexcept
Return a list of merged rectangles to display for the selection.
translate2 translate_base_line(point2 position) noexcept
Get the translation for where to place the text.
Definition shaped_text.hpp:188
graphic_path get_path() const noexcept
Convert the whole shaped text into a layered path.
std::pair< ssize_t, ssize_t > indicesOfWord(ssize_t logical_index) const noexcept
Get the word with the given character.
std::pair< ssize_t, ssize_t > indicesOfParagraph(ssize_t logical_index) const noexcept
Get the character right of the given character.
aarectangle leftToRightCaret(ssize_t index, bool overwrite) const noexcept
Return the cursor-carets.
std::optional< ssize_t > indexOfCharAtCoordinate(point2 coordinate) const noexcept
Get the character close to a coordinate.
ssize_t indexAtRightSideOfWord(ssize_t logical_index) const noexcept
Get the character right of the given character.
const_iterator find(ssize_t position) const noexcept
Find a glyph that corresponds to position.
float middleOffset(float height) const noexcept
Get the offset of the middle of a line.
Definition shaped_text.hpp:172
aarectangle rectangleOfgrapheme(ssize_t index) const noexcept
Get a rectangle for the grapheme.
int indexFromCoordinate(point2 coordinate) const noexcept
Get the index into the text from a coordinate.
std::optional< ssize_t > indexOfCharOnTheLeft(ssize_t logical_index) const noexcept
Get the character left of the given character.
Definition text_style.hpp:16
T back(T... args)
T front(T... args)