HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
text_shaper.hpp
1// Copyright Take Vos 2021-2022.
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 "text_shaper_char.hpp"
8#include "text_shaper_line.hpp"
9#include "text_cursor.hpp"
10#include "text_theme.hpp"
11#include "text.hpp"
12#include "../layout/box_constraints.hpp"
13#include "../font/module.hpp"
14#include "../geometry/module.hpp"
15#include "../unicode/module.hpp"
16#include <vector>
17#include <tuple>
18
19namespace hi::inline v1 {
20
35public:
37 using char_iterator = char_vector::iterator;
38 using char_const_iterator = char_vector::const_iterator;
39 using char_reference = char_vector::reference;
40 using char_const_reference = char_vector::const_reference;
42 using line_iterator = line_vector::iterator;
43 using line_const_iterator = line_vector::const_iterator;
44
45 constexpr text_shaper() noexcept = default;
46 constexpr text_shaper(text_shaper const&) noexcept = default;
47 constexpr text_shaper(text_shaper&&) noexcept = default;
48 constexpr text_shaper& operator=(text_shaper const&) noexcept = default;
49 constexpr text_shaper& operator=(text_shaper&&) noexcept = default;
50
77 [[nodiscard]] text_shaper(
78 hi::text const& text,
79 hi::text_theme const &text_theme,
80 hi::alignment alignment,
81 bool left_to_right) noexcept;
82
83 [[nodiscard]] bool empty() const noexcept
84 {
85 return _text.empty();
86 }
87
88 [[nodiscard]] size_t size() const noexcept
89 {
90 return _text.size();
91 }
92
93 [[nodiscard]] char_iterator begin() noexcept
94 {
95 return _text.begin();
96 }
97
98 [[nodiscard]] char_const_iterator begin() const noexcept
99 {
100 return _text.begin();
101 }
102
103 [[nodiscard]] char_const_iterator cbegin() const noexcept
104 {
105 return _text.cbegin();
106 }
107
108 [[nodiscard]] char_iterator end() noexcept
109 {
110 return _text.end();
111 }
112
113 [[nodiscard]] char_const_iterator end() const noexcept
114 {
115 return _text.end();
116 }
117
118 [[nodiscard]] char_const_iterator cend() const noexcept
119 {
120 return _text.cend();
121 }
122
123 auto const& lines() const noexcept
124 {
125 return _lines;
126 }
127
146 [[nodiscard]] aarectangle
147 bounding_rectangle(float maximum_line_width, float line_spacing = 1.0f, float paragraph_spacing = 1.5f) noexcept;
148
161 [[nodiscard]] void layout(
162 aarectangle rectangle,
163 float baseline,
164 extent2 sub_pixel_size,
165 float line_spacing = 1.0f,
166 float paragraph_spacing = 1.5f) noexcept;
167
170 [[nodiscard]] aarectangle rectangle() const noexcept
171 {
172 return _rectangle;
173 }
174
177 [[nodiscard]] unicode_bidi_class text_direction() const noexcept
178 {
179 return _text_direction;
180 }
181
187 [[nodiscard]] alignment resolved_alignment() const noexcept
188 {
189 return resolve(_alignment, _text_direction == unicode_bidi_class::L);
190 }
191
199 [[nodiscard]] char_const_iterator get_it(size_t index) const noexcept;
200
208 [[nodiscard]] char_const_iterator get_it(text_cursor cursor) const noexcept
209 {
210 return get_it(cursor.index());
211 }
212
221 [[nodiscard]] char_const_iterator get_it(size_t column, size_t row) const noexcept;
222
230 [[nodiscard]] char_const_iterator get_it(std::pair<size_t, size_t> column_row) const noexcept
231 {
232 return get_it(column_row.first, column_row.second);
233 }
234
240 [[nodiscard]] std::pair<size_t, size_t> get_column_line(text_shaper::char_const_iterator it) const noexcept;
241
247 [[nodiscard]] std::pair<size_t, size_t> get_column_line(size_t index) const noexcept
248 {
249 return get_column_line(get_it(index));
250 }
251
257 [[nodiscard]] std::pair<size_t, size_t> get_column_line(text_cursor cursor) const noexcept
258 {
259 return get_column_line(cursor.index());
260 }
261
267 [[nodiscard]] size_t get_index(text_shaper::char_const_iterator it) const noexcept;
268
273 [[nodiscard]] text_cursor get_begin_cursor() const noexcept;
274
279 [[nodiscard]] text_cursor get_end_cursor() const noexcept;
280
286 [[nodiscard]] text_cursor get_before_cursor(size_t index) const noexcept;
287
293 [[nodiscard]] text_cursor get_after_cursor(size_t index) const noexcept;
294
300 [[nodiscard]] text_cursor get_before_cursor(text_shaper::char_const_iterator it) const noexcept
301 {
302 return get_before_cursor(get_index(it));
303 }
304
310 [[nodiscard]] text_cursor get_after_cursor(text_shaper::char_const_iterator it) const noexcept
311 {
312 return get_after_cursor(get_index(it));
313 }
314
320 [[nodiscard]] text_cursor get_left_cursor(text_shaper::char_const_iterator it) const noexcept;
321
327 [[nodiscard]] text_cursor get_right_cursor(text_shaper::char_const_iterator it) const noexcept;
328
334 [[nodiscard]] bool is_on_left(text_cursor cursor) const noexcept;
335
341 [[nodiscard]] bool is_on_right(text_cursor cursor) const noexcept;
342
348 [[nodiscard]] text_cursor get_nearest_cursor(point2 point) const noexcept;
349
352 [[nodiscard]] std::pair<text_cursor, text_cursor> select_char(text_cursor cursor) const noexcept;
353
356 [[nodiscard]] std::pair<text_cursor, text_cursor> select_word(text_cursor cursor) const noexcept;
357
361
365
369
375 [[nodiscard]] char_const_iterator move_left_char(char_const_iterator it) const noexcept;
376
382 [[nodiscard]] char_const_iterator move_right_char(char_const_iterator it) const noexcept;
383
384 [[nodiscard]] text_cursor move_left_char(text_cursor cursor, bool overwrite_mode) const noexcept;
385 [[nodiscard]] text_cursor move_right_char(text_cursor cursor, bool overwrite_mode) const noexcept;
386 [[nodiscard]] text_cursor move_down_char(text_cursor cursor, float& x) const noexcept;
387 [[nodiscard]] text_cursor move_up_char(text_cursor cursor, float& x) const noexcept;
388 [[nodiscard]] text_cursor move_left_word(text_cursor cursor, bool overwrite_mode) const noexcept;
389 [[nodiscard]] text_cursor move_right_word(text_cursor cursor, bool overwrite_mode) const noexcept;
390 [[nodiscard]] text_cursor move_begin_line(text_cursor cursor) const noexcept;
391 [[nodiscard]] text_cursor move_end_line(text_cursor cursor) const noexcept;
392 [[nodiscard]] text_cursor move_begin_sentence(text_cursor cursor) const noexcept;
393 [[nodiscard]] text_cursor move_end_sentence(text_cursor cursor) const noexcept;
394 [[nodiscard]] text_cursor move_begin_paragraph(text_cursor cursor) const noexcept;
395 [[nodiscard]] text_cursor move_end_paragraph(text_cursor cursor) const noexcept;
396 [[nodiscard]] text_cursor move_begin_document(text_cursor cursor) const noexcept;
397 [[nodiscard]] text_cursor move_end_document(text_cursor cursor) const noexcept;
398
399private:
406 char_vector _text;
407
408 hi::alignment _alignment;
409
412 unicode_break_vector _line_break_opportunities;
413
416 std::vector<float> _line_break_widths;
417
420 unicode_break_vector _word_break_opportunities;
421
424 unicode_break_vector _sentence_break_opportunities;
425
428 unicode_bidi_context _bidi_context;
429
432 unicode_bidi_class _text_direction;
433
438 line_vector _lines;
439
442 font_metrics _initial_line_metrics;
443
446 aarectangle _rectangle;
447
456 [[nodiscard]] line_vector make_lines(
457 aarectangle rectangle,
458 float baseline,
459 extent2 sub_pixel_size,
460 float line_spacing,
461 float paragraph_spacing) noexcept;
462
469 void position_glyphs(aarectangle rectangle, extent2 sub_pixel_size) noexcept;
470
475 void resolve_font_and_widths(hi::text_theme const &text_theme) noexcept;
476
478 get_selection_from_break(text_cursor cursor, unicode_break_vector const& break_opportunities) const noexcept;
479
481 get_line_metrics(text_shaper::char_const_iterator first, text_shaper::char_const_iterator last) const noexcept;
482
489 [[nodiscard]] float get_text_height(std::vector<size_t> const& lines) const noexcept;
490};
491
492} // namespace hi::inline v1
DOXYGEN BUG.
Definition algorithm.hpp:13
The metrics of a font.
Definition font_metrics.hpp:15
Horizontal/Vertical alignment combination.
Definition alignment.hpp:231
A rectangle / parallelogram in 3D space.
Definition rectangle.hpp:20
A cursor-position in text.
Definition text_cursor.hpp:22
Text shaper.
Definition text_shaper.hpp:34
char_const_iterator get_it(size_t column, size_t row) const noexcept
Get the character at column and row in display order.
std::pair< text_cursor, text_cursor > select_paragraph(text_cursor cursor) const noexcept
Get the selection for a paragraph at the cursor.
std::pair< size_t, size_t > get_column_line(size_t index) const noexcept
Get the column and line of a character.
Definition text_shaper.hpp:247
char_const_iterator get_it(text_cursor cursor) const noexcept
Get the character at the cursor.
Definition text_shaper.hpp:208
std::pair< text_cursor, text_cursor > select_sentence(text_cursor cursor) const noexcept
Get the selection for the sentence at the cursor.
bool is_on_left(text_cursor cursor) const noexcept
Check if the cursor is on the left side of the character in display order.
bool is_on_right(text_cursor cursor) const noexcept
Check if the cursor is on the right side of the character in display order.
aarectangle bounding_rectangle(float maximum_line_width, float line_spacing=1.0f, float paragraph_spacing=1.5f) noexcept
Get bounding rectangle.
text_cursor get_after_cursor(text_shaper::char_const_iterator it) const noexcept
Get the cursor after the character in logical order.
Definition text_shaper.hpp:310
unicode_bidi_class text_direction() const noexcept
Get the text-direction as a whole.
Definition text_shaper.hpp:177
std::pair< text_cursor, text_cursor > select_char(text_cursor cursor) const noexcept
Get the selection for the character at the cursor.
std::pair< size_t, size_t > get_column_line(text_shaper::char_const_iterator it) const noexcept
Get the column and line of a character.
text_cursor get_left_cursor(text_shaper::char_const_iterator it) const noexcept
Get the cursor left of the character in display order.
std::pair< text_cursor, text_cursor > select_word(text_cursor cursor) const noexcept
Get the selection for the word at the cursor.
size_t get_index(text_shaper::char_const_iterator it) const noexcept
Get the index of the character in logical order.
char_const_iterator get_it(size_t index) const noexcept
Get the character at index in logical order.
std::pair< text_cursor, text_cursor > select_document(text_cursor cursor) const noexcept
Get the selection for a paragraph at the cursor.
text_cursor get_nearest_cursor(point2 point) const noexcept
find the nearest character.
char_const_iterator move_right_char(char_const_iterator it) const noexcept
Get the character to the right.
text_shaper(hi::text const &text, hi::text_theme const &text_theme, hi::alignment alignment, bool left_to_right) noexcept
Construct a text_shaper with a text and alignment.
char_const_iterator get_it(std::pair< size_t, size_t > column_row) const noexcept
Get the character at column and row in display order.
Definition text_shaper.hpp:230
text_cursor get_begin_cursor() const noexcept
Get the cursor at the beginning of the document.
alignment resolved_alignment() const noexcept
Get the resolved alignment of the text.
Definition text_shaper.hpp:187
std::pair< size_t, size_t > get_column_line(text_cursor cursor) const noexcept
Get the column and line of a character.
Definition text_shaper.hpp:257
text_cursor get_right_cursor(text_shaper::char_const_iterator it) const noexcept
Get the cursor right of the character in display order.
char_const_iterator move_left_char(char_const_iterator it) const noexcept
Get the character to the left.
Definition text_theme.hpp:16
Definition unicode_bidi.hpp:18
T begin(T... args)
T end(T... args)