reorderString method Null safety
3.4 Reordering Resolved Levels
Implementation
void reorderString() {
//L1. On each line, reset the embedding level of the following characters to the paragraph embedding level:
// 1. Segment separators,
// 2. Paragraph separators,
// 3. Any sequence of whitespace characters preceding a segment separator or paragraph separator, and
// 4. Any sequence of white space characters at the end of the line.
int l1Start = 0;
for (int i = 0; i < _textData.length; ++i) {
if (_textData[i]._ct == _BidiCharacterType.S ||
_textData[i]._ct == _BidiCharacterType.B) {
for (int j = l1Start; j <= i; ++j) {
_textData[j]._el = _embeddingLevel;
}
}
if (_textData[i]._ct != _BidiCharacterType.WS) {
l1Start = i + 1;
}
}
for (int j = l1Start; j < _textData.length; ++j) {
_textData[j]._el = _embeddingLevel;
}
// L2. From the highest level found in the text to the lowest odd level on each
// line, including intermediate levels not actually present in the text,
// reverse any contiguous sequence of characters that are at that level or
// higher.
int highest = 0;
int lowestOdd = 63;
for (_CharData cd in _textData) {
if (cd._el > highest) highest = cd._el;
if ((cd._el & 1) == 1 && cd._el < lowestOdd) lowestOdd = cd._el;
}
for (var el = highest; el >= lowestOdd; --el) {
for (int i = 0; i < _textData.length; ++i) {
if (_textData[i]._el >= el) {
// find range of text at or above this level
int l2Start = i;
int limit = i + 1;
while (limit < _textData.length && _textData[limit]._el >= el) {
++limit;
}
// reverse run
for (int j = l2Start, k = limit - 1; j < k; ++j, --k) {
_CharData tempCd = _textData[j];
_textData[j] = _textData[k];
_textData[k] = tempCd;
}
// skip to end of level run
i = limit;
}
}
}
// TODO - L3. Combining marks applied to a right-to-left base character will at this point precede their base
// character. If the rendering engine expects them to follow the base characters in the final display process,
// then the ordering of the marks and the base character must be reversed.
}