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 "glyph_metrics.hpp"
11#include "font_metrics.hpp"
12#include "text_style.hpp"
13#include "glyph_ids.hpp"
14#include "font.hpp"
15#include "../layout/box_constraints.hpp"
17#include "../unicode/unicode_description.hpp"
18#include "../unicode/unicode_break_opportunity.hpp"
19#include "../unicode/unicode_bidi.hpp"
20#include "../unicode/grapheme.hpp"
21#include "../unicode/gstring.hpp"
22#include <vector>
23#include <tuple>
24
25namespace hi::inline v1 {
26class font_book;
27
42public:
44 using char_iterator = char_vector::iterator;
45 using char_const_iterator = char_vector::const_iterator;
46 using char_reference = char_vector::reference;
47 using char_const_reference = char_vector::const_reference;
49 using line_iterator = line_vector::iterator;
50 using line_const_iterator = line_vector::const_iterator;
51
52 constexpr text_shaper() noexcept = default;
53 constexpr text_shaper(text_shaper const&) noexcept = default;
54 constexpr text_shaper(text_shaper&&) noexcept = default;
55 constexpr text_shaper& operator=(text_shaper const&) noexcept = default;
56 constexpr text_shaper& operator=(text_shaper&&) noexcept = default;
57
85 [[nodiscard]] text_shaper(
86 hi::font_book& font_book,
87 gstring const& text,
88 text_style const& style,
89 float dpi_scale,
90 hi::alignment alignment,
91 unicode_bidi_class text_direction,
92 unicode_script script = unicode_script::Common) noexcept;
93
94 [[nodiscard]] text_shaper(
95 hi::font_book& font_book,
96 std::string_view text,
97 text_style const& style,
98 float dpi_scale,
99 hi::alignment alignment,
100 unicode_bidi_class text_direction,
101 unicode_script script = unicode_script::Common) noexcept;
102
103 [[nodiscard]] bool empty() const noexcept
104 {
105 return _text.empty();
106 }
107
108 [[nodiscard]] size_t size() const noexcept
109 {
110 return _text.size();
111 }
112
113 [[nodiscard]] char_iterator begin() noexcept
114 {
115 return _text.begin();
116 }
117
118 [[nodiscard]] char_const_iterator begin() const noexcept
119 {
120 return _text.begin();
121 }
122
123 [[nodiscard]] char_const_iterator cbegin() const noexcept
124 {
125 return _text.cbegin();
126 }
127
128 [[nodiscard]] char_iterator end() noexcept
129 {
130 return _text.end();
131 }
132
133 [[nodiscard]] char_const_iterator end() const noexcept
134 {
135 return _text.end();
136 }
137
138 [[nodiscard]] char_const_iterator cend() const noexcept
139 {
140 return _text.cend();
141 }
142
143 auto const& lines() const noexcept
144 {
145 return _lines;
146 }
147
166 [[nodiscard]] aarectangle
167 bounding_rectangle(float maximum_line_width, float line_spacing = 1.0f, float paragraph_spacing = 1.5f) noexcept;
168
189 [[nodiscard]] void layout(
190 aarectangle rectangle,
191 float baseline,
192 extent2 sub_pixel_size,
193 float line_spacing = 1.0f,
194 float paragraph_spacing = 1.5f) noexcept;
195
198 [[nodiscard]] aarectangle rectangle() const noexcept
199 {
200 return _rectangle;
201 }
202
205 [[nodiscard]] unicode_bidi_class text_direction() const noexcept
206 {
207 return _text_direction;
208 }
209
215 [[nodiscard]] alignment resolved_alignment() const noexcept
216 {
217 return resolve(_alignment, _text_direction == unicode_bidi_class::L);
218 }
219
227 [[nodiscard]] char_const_iterator get_it(size_t index) const noexcept;
228
236 [[nodiscard]] char_const_iterator get_it(text_cursor cursor) const noexcept
237 {
238 return get_it(cursor.index());
239 }
240
249 [[nodiscard]] char_const_iterator get_it(size_t column, size_t row) const noexcept;
250
258 [[nodiscard]] char_const_iterator get_it(std::pair<size_t, size_t> column_row) const noexcept
259 {
260 return get_it(column_row.first, column_row.second);
261 }
262
268 [[nodiscard]] std::pair<size_t, size_t> get_column_line(text_shaper::char_const_iterator it) const noexcept;
269
275 [[nodiscard]] std::pair<size_t, size_t> get_column_line(size_t index) const noexcept
276 {
277 return get_column_line(get_it(index));
278 }
279
285 [[nodiscard]] std::pair<size_t, size_t> get_column_line(text_cursor cursor) const noexcept
286 {
287 return get_column_line(cursor.index());
288 }
289
295 [[nodiscard]] size_t get_index(text_shaper::char_const_iterator it) const noexcept;
296
301 [[nodiscard]] text_cursor get_begin_cursor() const noexcept;
302
307 [[nodiscard]] text_cursor get_end_cursor() const noexcept;
308
314 [[nodiscard]] text_cursor get_before_cursor(size_t index) const noexcept;
315
321 [[nodiscard]] text_cursor get_after_cursor(size_t index) const noexcept;
322
328 [[nodiscard]] text_cursor get_before_cursor(text_shaper::char_const_iterator it) const noexcept
329 {
330 return get_before_cursor(get_index(it));
331 }
332
338 [[nodiscard]] text_cursor get_after_cursor(text_shaper::char_const_iterator it) const noexcept
339 {
340 return get_after_cursor(get_index(it));
341 }
342
348 [[nodiscard]] text_cursor get_left_cursor(text_shaper::char_const_iterator it) const noexcept;
349
355 [[nodiscard]] text_cursor get_right_cursor(text_shaper::char_const_iterator it) const noexcept;
356
362 [[nodiscard]] bool is_on_left(text_cursor cursor) const noexcept;
363
369 [[nodiscard]] bool is_on_right(text_cursor cursor) const noexcept;
370
376 [[nodiscard]] text_cursor get_nearest_cursor(point2 point) const noexcept;
377
380 [[nodiscard]] std::pair<text_cursor, text_cursor> select_char(text_cursor cursor) const noexcept;
381
384 [[nodiscard]] std::pair<text_cursor, text_cursor> select_word(text_cursor cursor) const noexcept;
385
389
393
397
403 [[nodiscard]] char_const_iterator move_left_char(char_const_iterator it) const noexcept;
404
410 [[nodiscard]] char_const_iterator move_right_char(char_const_iterator it) const noexcept;
411
412 [[nodiscard]] text_cursor move_left_char(text_cursor cursor, bool overwrite_mode) const noexcept;
413 [[nodiscard]] text_cursor move_right_char(text_cursor cursor, bool overwrite_mode) const noexcept;
414 [[nodiscard]] text_cursor move_down_char(text_cursor cursor, float& x) const noexcept;
415 [[nodiscard]] text_cursor move_up_char(text_cursor cursor, float& x) const noexcept;
416 [[nodiscard]] text_cursor move_left_word(text_cursor cursor, bool overwrite_mode) const noexcept;
417 [[nodiscard]] text_cursor move_right_word(text_cursor cursor, bool overwrite_mode) const noexcept;
418 [[nodiscard]] text_cursor move_begin_line(text_cursor cursor) const noexcept;
419 [[nodiscard]] text_cursor move_end_line(text_cursor cursor) const noexcept;
420 [[nodiscard]] text_cursor move_begin_sentence(text_cursor cursor) const noexcept;
421 [[nodiscard]] text_cursor move_end_sentence(text_cursor cursor) const noexcept;
422 [[nodiscard]] text_cursor move_begin_paragraph(text_cursor cursor) const noexcept;
423 [[nodiscard]] text_cursor move_end_paragraph(text_cursor cursor) const noexcept;
424 [[nodiscard]] text_cursor move_begin_document(text_cursor cursor) const noexcept;
425 [[nodiscard]] text_cursor move_end_document(text_cursor cursor) const noexcept;
426
427private:
428 font_book *_font_book = nullptr;
429
432 float _dpi_scale;
433
440 char_vector _text;
441
442 hi::alignment _alignment;
443
446 unicode_break_vector _line_break_opportunities;
447
450 std::vector<float> _line_break_widths;
451
454 unicode_break_vector _word_break_opportunities;
455
458 unicode_break_vector _sentence_break_opportunities;
459
462 unicode_bidi_context _bidi_context;
463
466 unicode_bidi_class _text_direction;
467
470 unicode_script _script;
471
476 line_vector _lines;
477
480 font_metrics _initial_line_metrics;
481
484 aarectangle _rectangle;
485
494 [[nodiscard]] line_vector make_lines(
495 aarectangle rectangle,
496 float baseline,
497 extent2 sub_pixel_size,
498 float line_spacing,
499 float paragraph_spacing) noexcept;
500
507 void position_glyphs(aarectangle rectangle, extent2 sub_pixel_size) noexcept;
508
511 void resolve_script() noexcept;
512
513 [[nodiscard]] std::pair<text_cursor, text_cursor>
514 get_selection_from_break(text_cursor cursor, unicode_break_vector const& break_opportunities) const noexcept;
515
516 [[nodiscard]] std::pair<font_metrics, unicode_general_category>
517 get_line_metrics(text_shaper::char_const_iterator first, text_shaper::char_const_iterator last) const noexcept;
518
525 [[nodiscard]] float get_text_height(std::vector<size_t> const& lines) const noexcept;
526};
527
528} // namespace hi::inline v1
types and utilities for alignment.
STL namespace.
DOXYGEN BUG.
Definition algorithm.hpp:15
unicode_bidi_class
Bidirectional class Unicode Standard Annex #9: https://unicode.org/reports/tr9/.
Definition unicode_bidi_class.hpp:17
Horizontal/Vertical alignment combination.
Definition alignment.hpp:232
A rectangle / parallelogram in 3D space.
Definition rectangle.hpp:20
A variant of text.
Definition label.hpp:36
font_book keeps track of multiple fonts.
Definition font_book.hpp:31
The metrics of a font.
Definition font_metrics.hpp:15
A cursor-position in text.
Definition text_cursor.hpp:25
Text shaper.
Definition text_shaper.hpp:41
text_shaper(hi::font_book &font_book, gstring const &text, text_style const &style, float dpi_scale, hi::alignment alignment, unicode_bidi_class text_direction, unicode_script script=unicode_script::Common) noexcept
Construct a text_shaper with a text and alignment.
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:275
char_const_iterator get_it(text_cursor cursor) const noexcept
Get the character at the cursor.
Definition text_shaper.hpp:236
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:338
unicode_bidi_class text_direction() const noexcept
Get the text-direction as a whole.
Definition text_shaper.hpp:205
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.
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:258
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:215
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:285
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_style.hpp:176
Definition unicode_bidi.hpp:13
T begin(T... args)
T end(T... args)