MCPcopy Create free account
hub / github.com/crosspoint-reader/crosspoint-reader / computeVisualWordOrder

Function computeVisualWordOrder

lib/MiniBidi/BidiUtils.cpp:103–232  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

101}
102
103bool computeVisualWordOrder(const std::vector<std::string>& words, bool paragraphIsRtl,
104 std::vector<uint16_t>& visualOrder) {
105 visualOrder.clear();
106 const size_t nWords = words.size();
107 if (nWords <= 1 || nWords > BIDI_MAX_LINE) return false;
108
109 static bidi_char line[BIDI_MAX_LINE];
110 int count = 0;
111 bool truncated = false;
112
113 for (size_t w = 0; w < nWords && !truncated; w++) {
114 auto* p = reinterpret_cast<const unsigned char*>(words[w].c_str());
115 while (*p) {
116 if (count >= BIDI_MAX_LINE) {
117 truncated = true;
118 break;
119 }
120 const uint32_t cp = utf8NextCodepoint(&p);
121 if (!cp || cp == REPLACEMENT_GLYPH) break;
122 line[count].origwc = line[count].wc = cp;
123 line[count].index = static_cast<uint16_t>(w);
124 count++;
125 }
126
127 if (!truncated && w + 1 < nWords) {
128 if (count >= BIDI_MAX_LINE) {
129 truncated = true;
130 break;
131 }
132 line[count].origwc = line[count].wc = ' ';
133 line[count].index = static_cast<uint16_t>(nWords);
134 count++;
135 }
136 }
137
138 if (truncated || count == 0) return false;
139
140 // Fast-path for homogeneous lines: skip UAX#9 if there's no mixing.
141 bool hasL = false, hasR = false;
142 for (int i = 0; i < count; i++) {
143 uchar bc = bidi_class(line[i].wc);
144 if (bc == L || bc == EN || bc == AN)
145 hasL = true;
146 else if (bc == R || bc == AL)
147 hasR = true;
148 }
149
150 // Purely LTR line in RTL paragraph: identity order, but we might still need to reorder
151 // if some characters are mirrored or neutral resolution differs.
152 // Actually, UAX#9 rule L1/L2 says purely LTR in RTL para stays as is (identity).
153 // Purely RTL line: just reverse the words.
154 if (!hasL && hasR && paragraphIsRtl) {
155 visualOrder.reserve(nWords);
156 for (int i = static_cast<int>(nWords) - 1; i >= 0; i--) {
157 visualOrder.push_back(static_cast<uint16_t>(i));
158 }
159 return true;
160 }

Callers 1

extractLineMethod · 0.85

Calls 7

utf8NextCodepointFunction · 0.85
bidi_classFunction · 0.85
do_bidiFunction · 0.85
isNaturalDirectionClassFunction · 0.85
push_backMethod · 0.80
clearMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected