HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
unicode_bidi.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 "unicode_bidi_class.hpp"
8#include "unicode_description.hpp"
9
10namespace hi::inline v1 {
11
13 enum class mode_type : uint8_t { LTR, RTL, auto_LTR, auto_RTL };
14
15 mode_type direction_mode = mode_type::auto_LTR;
16 bool enable_mirrored_brackets = true;
17 bool enable_line_separator = true;
18 bool move_lf_and_ps_to_end_of_line = false;
19};
20
21namespace detail {
22
27
31
35 char32_t code_point;
36
41
45 unicode_bidi_class direction;
46
50 unicode_bidi_class bidi_class;
51
52 [[nodiscard]] unicode_bidi_char_info(std::size_t index, unicode_description const &description) noexcept :
53 index(index),
54 description(&description),
55 code_point(description.code_point()),
56 embedding_level(0),
57 direction(description.bidi_class()),
58 bidi_class(description.bidi_class())
59 {
60 }
61
65 [[nodiscard]] unicode_bidi_char_info(std::size_t index, unicode_bidi_class bidi_class) noexcept :
66 index(index),
67 code_point(U'\ufffd'),
68 direction(bidi_class),
69 bidi_class(bidi_class),
70 embedding_level(0),
71 description(nullptr)
72 {
73 }
74};
75
76using unicode_bidi_char_info_vector = std::vector<unicode_bidi_char_info>;
77using unicode_bidi_char_info_iterator = unicode_bidi_char_info_vector::iterator;
78using unicode_bidi_char_info_const_iterator = unicode_bidi_char_info_vector::const_iterator;
79
82
83 characters_type characters;
84
85 template<typename... Args>
86 void emplace_character(Args &&...args) noexcept
87 {
88 characters.emplace_back(std::forward<Args>(args)...);
89 }
90};
91
92template<typename OutputIt, typename SetCodePoint, typename SetTextDirection>
93static void unicode_bidi_L4(
94 unicode_bidi_char_info_iterator first,
95 unicode_bidi_char_info_iterator last,
96 OutputIt output_it,
97 SetCodePoint set_code_point,
98 SetTextDirection set_text_direction) noexcept
99{
100 for (auto it = first; it != last; ++it, ++output_it) {
101 hilet text_direction = it->embedding_level % 2 == 0 ? unicode_bidi_class::L : unicode_bidi_class::R;
102 set_text_direction(*output_it, text_direction);
103 if (it->direction == unicode_bidi_class::R && it->description->bidi_bracket_type() != unicode_bidi_bracket_type::n) {
104 set_code_point(*output_it, it->description->bidi_mirrored_glyph());
105 }
106 }
107}
108
110 unicode_bidi_char_info_iterator first,
111 unicode_bidi_char_info_iterator last,
112 unicode_bidi_context const &context = {}) noexcept;
113
114} // namespace detail
115
142template<typename It, typename GetDescription, typename SetCodePoint, typename SetTextDirection>
144 It first,
145 It last,
146 GetDescription get_description,
147 SetCodePoint set_code_point,
148 SetTextDirection set_text_direction,
149 unicode_bidi_context const &context = {})
150{
151 auto proxy = detail::unicode_bidi_char_info_vector{};
152 proxy.reserve(std::distance(first, last));
153
154 std::size_t index = 0;
155 for (auto it = first; it != last; ++it) {
156 proxy.emplace_back(index++, get_description(*it));
157 }
158
159 auto [proxy_last, paragraph_directions] = detail::unicode_bidi_P1(begin(proxy), end(proxy), context);
160 last = shuffle_by_index(first, last, begin(proxy), proxy_last, [](hilet &item) {
161 return item.index;
162 });
163
164 detail::unicode_bidi_L4(
165 begin(proxy),
166 proxy_last,
167 first,
168 std::forward<SetCodePoint>(set_code_point),
169 std::forward<SetTextDirection>(set_text_direction));
170 return {last, std::move(paragraph_directions)};
171}
172
183template<typename It, typename EndIt, typename DescriptionFunc>
184It unicode_bidi_control_filter(It first, EndIt last, DescriptionFunc const &description_func)
185{
186 return std::remove_if(first, last, [&](hilet &item) {
187 return is_control(description_func(item).bidi_class());
188 });
189}
190
191
192} // namespace hi::inline v1
#define hilet
Invariant should be the default for variables.
Definition required.hpp:23
Definition unicode_bidi.hpp:12
Definition unicode_bidi.hpp:23
unicode_bidi_class direction
Current computed direction of the code-point.
Definition unicode_bidi.hpp:45
unicode_description const * description
Description of the code-point.
Definition unicode_bidi.hpp:30
int8_t embedding_level
The embedding level.
Definition unicode_bidi.hpp:40
unicode_bidi_class bidi_class
The original bidi class of the code-point.
Definition unicode_bidi.hpp:50
std::size_t index
Index from the first character in the original list.
Definition unicode_bidi.hpp:26
char32_t code_point
The current code point.
Definition unicode_bidi.hpp:35
unicode_bidi_char_info(std::size_t index, unicode_bidi_class bidi_class) noexcept
Constructor for testing to bypass normal initialization.
Definition unicode_bidi.hpp:65
Definition unicode_bidi.hpp:80
Description of a unicode code point.
Definition unicode_description.hpp:79
constexpr unicode_bidi_class bidi_class() const noexcept
The bidi class of this code-point This function is used by the bidirectional algorithm to figure out ...
Definition unicode_description.hpp:249
constexpr char32_t code_point() const noexcept
The code point of the description.
Definition unicode_description.hpp:185
T begin(T... args)
T distance(T... args)
T emplace_back(T... args)
T end(T... args)
T move(T... args)
T remove_if(T... args)