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 "../numeric_array.hpp"
13#include "../recursive_iterator.hpp"
14#include <string_view>
15#include <optional>
16
17namespace tt {
18
19
23public:
25
27
28 alignment alignment;
29 aarect boundingBox;
30 float width;
31 f32x4 preferred_extent;
32
33private:
35
36public:
37 shaped_text() noexcept :
38 alignment(alignment::middle_center), boundingBox(), width(0.0f), preferred_extent(), lines() {}
39 shaped_text(shaped_text const &other) = default;
40 shaped_text(shaped_text &&other) noexcept = default;
41 shaped_text &operator=(shaped_text const &other) = default;
42 shaped_text &operator=(shaped_text &&other) noexcept = default;
43 ~shaped_text() = default;
44
68 float width,
69 tt::alignment const alignment=alignment::middle_center,
70 bool wrap=true
71 ) noexcept;
72
83 gstring const &text,
84 text_style const &style,
85 float width,
86 tt::alignment const alignment=alignment::middle_center,
87 bool wrap=true
88 ) noexcept;
89
100 std::u8string_view text,
101 text_style const &style,
102 float width,
103 tt::alignment const alignment=alignment::middle_center,
104 bool wrap=true
105 ) noexcept;
106
107 [[nodiscard]] size_t size() const noexcept {
108 ssize_t count = 0;
109 for (ttlet &line: lines) {
110 count += std::ssize(line);
111 }
112 return narrow_cast<size_t>(count);
113 }
114
115 [[nodiscard]] iterator begin() noexcept { return recursive_iterator_begin(lines); }
116 [[nodiscard]] const_iterator begin() const noexcept { return recursive_iterator_begin(lines); }
117 [[nodiscard]] const_iterator cbegin() const noexcept { return recursive_iterator_begin(lines); }
118
119 [[nodiscard]] iterator end() noexcept { return recursive_iterator_end(lines); }
120 [[nodiscard]] const_iterator end() const noexcept { return recursive_iterator_end(lines); }
121 [[nodiscard]] const_iterator cend() const noexcept { return recursive_iterator_end(lines); }
122
123 float topAccender() const noexcept {
124 return lines.front().ascender;
125 }
126
127 float bottomDescender() const noexcept {
128 return lines.back().descender;
129 }
130
131 float topCapHeight() const noexcept {
132 return lines.front().capHeight;
133 }
134
135 float bottomCapHeight() const noexcept {
136 return lines.back().capHeight;
137 }
138
141 float middleCapHeight() const noexcept {
142 if ((std::ssize(lines) % 2) == 1) {
143 return lines[std::ssize(lines) / 2].capHeight;
144 } else {
145 return (lines[std::ssize(lines) / 2 - 1].capHeight + lines[std::ssize(lines) / 2].capHeight) * 0.5f;
146 }
147 }
148
154 float baselineOffset(float height) noexcept {
155 if (alignment == vertical_alignment::top) {
156 return height - topAccender();
157 } else if (alignment == vertical_alignment::bottom) {
158 return bottomDescender();
159 } else if (alignment == vertical_alignment::middle) {
160 return height * 0.5f - middleCapHeight() * 0.5f;
161 } else {
162 tt_no_default();
163 }
164 }
165
171 float middleOffset(float height) const noexcept {
172 if (alignment == vertical_alignment::top) {
173 return height - topCapHeight() * 0.5f;
174 } else if (alignment == vertical_alignment::bottom) {
175 return height - bottomCapHeight() * 0.5f;
176 } else if (alignment == vertical_alignment::middle) {
177 return height - middleCapHeight() * 0.5f;
178 } else {
179 tt_no_default();
180 }
181 }
182
188 {
189 return translate2{position.x(), middleOffset(position.y())};
190 }
191
194 [[nodiscard]] const_iterator find(ssize_t position) const noexcept;
195
204 [[nodiscard]] aarect rectangleOfgrapheme(ssize_t index) const noexcept;
205
213 [[nodiscard]] aarect leftToRightCaret(ssize_t index, bool overwrite) const noexcept;
214
222 [[nodiscard]] std::vector<aarect> selectionRectangles(ssize_t first, ssize_t last) const noexcept;
223
228 [[nodiscard]] std::optional<ssize_t> indexOfCharAtCoordinate(f32x4 coordinate) const noexcept;
229
234 [[nodiscard]] std::optional<ssize_t> indexOfCharOnTheLeft(ssize_t logical_index) const noexcept;
235
240 [[nodiscard]] std::optional<ssize_t> indexOfCharOnTheRight(ssize_t logical_index) const noexcept;
241
246 [[nodiscard]] std::pair<ssize_t,ssize_t> indicesOfWord(ssize_t logical_index) const noexcept;
247
252 [[nodiscard]] std::pair<ssize_t,ssize_t> indicesOfParagraph(ssize_t logical_index) const noexcept;
253
258 [[nodiscard]] ssize_t indexAtRightSideOfWord(ssize_t logical_index) const noexcept;
259
264 [[nodiscard]] std::optional<ssize_t> indexOfWordOnTheLeft(ssize_t logical_index) const noexcept;
265
270 [[nodiscard]] std::optional<ssize_t> indexOfWordOnTheRight(ssize_t logical_index) const noexcept;
271
274 [[nodiscard]] graphic_path get_path() const noexcept;
275
276
283 [[nodiscard]] int indexFromCoordinate(f32x4 coordinate) const noexcept;
284
292 [[nodiscard]] std::vector<int> indicesFromCoordinates(f32x4 start, f32x4 current) const noexcept;
293};
294
295
296
297}
STL namespace.
A path is a vector graphics object.
Definition graphic_path.hpp:29
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:22
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:154
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.
std::vector< aarect > selectionRectangles(ssize_t first, ssize_t last) const noexcept
Return a list of merged rectangles to display for the selection.
float middleCapHeight() const noexcept
Get the capHeight of the middle line(s).
Definition shaped_text.hpp:141
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::vector< int > indicesFromCoordinates(f32x4 start, f32x4 current) const noexcept
Get the index into the text from a coordinate.
std::pair< ssize_t, ssize_t > indicesOfParagraph(ssize_t logical_index) const noexcept
Get the character right of the given character.
aarect rectangleOfgrapheme(ssize_t index) const noexcept
Get a rectangle for the grapheme.
translate2 translate_base_line(f32x4 position) noexcept
Get the translation for where to place the text.
Definition shaped_text.hpp:187
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:171
std::optional< ssize_t > indexOfCharAtCoordinate(f32x4 coordinate) const noexcept
Get the character close to a coordinate.
int indexFromCoordinate(f32x4 coordinate) const noexcept
Get the index into the text from a coordinate.
aarect leftToRightCaret(ssize_t index, bool overwrite) const noexcept
Return the cursor-carets.
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)