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
30 aarectangle boundingBox;
31 float width;
32
33private:
35 extent2 _preferred_extent;
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::string_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]] extent2 minimum_size() const noexcept
117 {
118 return _preferred_extent;
119 }
120
121 [[nodiscard]] extent2 preferred_size() const noexcept
122 {
123 return _preferred_extent;
124 }
125
126 [[nodiscard]] extent2 maximum_size() const noexcept
127 {
128 return _preferred_extent;
129 }
130
131 [[nodiscard]] iterator begin() noexcept { return recursive_iterator_begin(lines); }
132 [[nodiscard]] const_iterator begin() const noexcept { return recursive_iterator_begin(lines); }
133 [[nodiscard]] const_iterator cbegin() const noexcept { return recursive_iterator_begin(lines); }
134
135 [[nodiscard]] iterator end() noexcept { return recursive_iterator_end(lines); }
136 [[nodiscard]] const_iterator end() const noexcept { return recursive_iterator_end(lines); }
137 [[nodiscard]] const_iterator cend() const noexcept { return recursive_iterator_end(lines); }
138
139 float topAccender() const noexcept {
140 return lines.front().ascender;
141 }
142
143 float bottomDescender() const noexcept {
144 return lines.back().descender;
145 }
146
147 float topCapHeight() const noexcept {
148 return lines.front().capHeight;
149 }
150
151 float bottomCapHeight() const noexcept {
152 return lines.back().capHeight;
153 }
154
157 float middleCapHeight() const noexcept {
158 if ((std::ssize(lines) % 2) == 1) {
159 return lines[std::ssize(lines) / 2].capHeight;
160 } else {
161 return (lines[std::ssize(lines) / 2 - 1].capHeight + lines[std::ssize(lines) / 2].capHeight) * 0.5f;
162 }
163 }
164
170 float baselineOffset(float height) noexcept {
171 if (alignment == vertical_alignment::top) {
172 return height - topAccender();
173 } else if (alignment == vertical_alignment::bottom) {
174 return bottomDescender();
175 } else if (alignment == vertical_alignment::middle) {
176 return height * 0.5f - middleCapHeight() * 0.5f;
177 } else {
178 tt_no_default();
179 }
180 }
181
187 float middleOffset(float height) const noexcept {
188 if (alignment == vertical_alignment::top) {
189 return height - topCapHeight() * 0.5f;
190 } else if (alignment == vertical_alignment::bottom) {
191 return height - bottomCapHeight() * 0.5f;
192 } else if (alignment == vertical_alignment::middle) {
193 return height - middleCapHeight() * 0.5f;
194 } else {
195 tt_no_default();
196 }
197 }
198
204 {
205 return translate2{position.x(), middleOffset(position.y())};
206 }
207
210 [[nodiscard]] const_iterator find(ssize_t position) const noexcept;
211
220 [[nodiscard]] aarectangle rectangleOfgrapheme(ssize_t index) const noexcept;
221
229 [[nodiscard]] aarectangle left_to_right_caret(ssize_t index, bool overwrite) const noexcept;
230
238 [[nodiscard]] std::vector<aarectangle> selection_rectangles(ssize_t first, ssize_t last) const noexcept;
239
244 [[nodiscard]] std::optional<ssize_t> index_of_grapheme_at_coordinate(point2 coordinate) const noexcept;
245
250 [[nodiscard]] std::optional<ssize_t> indexOfCharOnTheLeft(ssize_t logical_index) const noexcept;
251
256 [[nodiscard]] std::optional<ssize_t> indexOfCharOnTheRight(ssize_t logical_index) const noexcept;
257
262 [[nodiscard]] std::pair<ssize_t,ssize_t> indices_of_word(ssize_t logical_index) const noexcept;
263
268 [[nodiscard]] std::pair<ssize_t,ssize_t> indices_of_paragraph(ssize_t logical_index) const noexcept;
269
274 [[nodiscard]] ssize_t indexAtRightSideOfWord(ssize_t logical_index) const noexcept;
275
280 [[nodiscard]] std::optional<ssize_t> indexOfWordOnTheLeft(ssize_t logical_index) const noexcept;
281
286 [[nodiscard]] std::optional<ssize_t> indexOfWordOnTheRight(ssize_t logical_index) const noexcept;
287
290 [[nodiscard]] graphic_path get_path() const noexcept;
291
292
299 [[nodiscard]] int indexFromCoordinate(point2 coordinate) const noexcept;
300
308 [[nodiscard]] std::vector<int> indicesFromCoordinates(point2 start, point2 current) const noexcept;
309};
310
311
312
313}
alignment
Vertical and horizontal alignment.
Definition alignment.hpp:47
STL namespace.
Class which represents an axis-aligned rectangle.
Definition axis_aligned_rectangle.hpp:20
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:170
std::vector< int > indicesFromCoordinates(point2 start, point2 current) const noexcept
Get the index into the text from a coordinate.
std::optional< ssize_t > index_of_grapheme_at_coordinate(point2 coordinate) const noexcept
Get the character close to a coordinate.
std::vector< aarectangle > selection_rectangles(ssize_t first, ssize_t last) const noexcept
Return a list of merged rectangles to display for the selection.
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.
aarectangle left_to_right_caret(ssize_t index, bool overwrite) const noexcept
Return the cursor-carets.
float middleCapHeight() const noexcept
Get the capHeight of the middle line(s).
Definition shaped_text.hpp:157
translate2 translate_base_line(point2 position) noexcept
Get the translation for where to place the text.
Definition shaped_text.hpp:203
graphic_path get_path() const noexcept
Convert the whole shaped text into a layered path.
std::pair< ssize_t, ssize_t > indices_of_word(ssize_t logical_index) const noexcept
Get the word with the given character.
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:187
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::pair< ssize_t, ssize_t > indices_of_paragraph(ssize_t logical_index) const noexcept
Get the character right of the given character.
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)