7#include "ucd_grapheme_cluster_breaks.hpp"
8#include "unicode_break_opportunity.hpp"
11namespace hi {
inline namespace v1 {
15 unicode_grapheme_cluster_break previous = unicode_grapheme_cluster_break::Other;
17 bool first_character =
true;
18 bool in_extended_pictograph =
false;
20 constexpr void reset()
noexcept
22 previous = unicode_grapheme_cluster_break::Other;
24 first_character =
true;
25 in_extended_pictograph =
false;
37[[nodiscard]]
constexpr bool breaks_grapheme(unicode_grapheme_cluster_break cluster_break,
grapheme_break_state& state)
noexcept
39 using enum unicode_grapheme_cluster_break;
41 hilet lhs = state.previous;
42 hilet rhs = cluster_break;
44 enum class break_state {
50 break_state break_state = break_state::unknown;
53 bool GB1 = state.first_character;
54 if ((break_state == break_state::unknown) & GB1) {
55 break_state = break_state::do_break;
58 state.first_character =
false;
61 hilet GB3 = (lhs == CR) && (rhs == LF);
62 hilet GB4 = (lhs == Control) || (lhs == CR) || (lhs == LF);
63 hilet GB5 = (rhs == Control) || (rhs == CR) || (rhs == LF);
64 if (break_state == break_state::unknown) {
66 break_state = break_state::dont_break;
67 }
else if (GB4 || GB5) {
68 break_state = break_state::do_break;
73 hilet GB6 = (lhs == L) && ((rhs == L) || (rhs == V) || (rhs == LV) | (rhs == LVT));
74 hilet GB7 = ((lhs == LV) || (lhs == V)) && ((rhs == V) || (rhs == T));
75 hilet GB8 = ((lhs == LVT) || (lhs == T)) && (rhs == T);
76 if ((break_state == break_state::unknown) && (GB6 || GB7 || GB8)) {
77 break_state = break_state::dont_break;
81 hilet GB9 = ((rhs == Extend) || (rhs == ZWJ));
85 hilet GB9a = (rhs == SpacingMark);
86 hilet GB9b = (lhs == Prepend);
87 if ((break_state == break_state::unknown) & (GB9 || GB9a || GB9b)) {
88 break_state = break_state::dont_break;
92 hilet GB11 = state.in_extended_pictograph && (lhs == ZWJ) && (rhs == Extended_Pictographic);
93 if ((break_state == break_state::unknown) && GB11) {
94 break_state = break_state::dont_break;
97 if (rhs == Extended_Pictographic) {
98 state.in_extended_pictograph =
true;
99 }
else if (!((rhs == Extend) || (rhs == ZWJ))) {
100 state.in_extended_pictograph =
false;
106 hilet GB12_13 = (lhs == Regional_Indicator) && (rhs == Regional_Indicator) && ((state.RI_count % 2) == 1);
107 if ((break_state == break_state::unknown) && (GB12_13)) {
108 break_state = break_state::dont_break;
111 if (rhs == Regional_Indicator) {
118 if (break_state == break_state::unknown) {
119 break_state = break_state::do_break;
122 state.previous = rhs;
123 return break_state == break_state::do_break;
133[[nodiscard]]
constexpr bool breaks_grapheme(
char32_t code_point, grapheme_break_state& state)
noexcept
135 return breaks_grapheme(ucd_get_grapheme_cluster_break(code_point), state);
140template<
typename It,
typename ItEnd>
144 auto state = detail::grapheme_break_state{};
146 for (
auto it = first; it != last; ++it) {
147 hilet opportunity = detail::breaks_grapheme(*it, state) ? unicode_break_opportunity::yes : unicode_break_opportunity::no;
151 r.push_back(unicode_break_opportunity::yes);
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
DOXYGEN BUG.
Definition algorithm.hpp:13
geometry/margins.hpp
Definition cache.hpp:11
Definition unicode_grapheme_cluster_break.hpp:14