reorderString method Null safety

void reorderString()

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.
}