performShaping method Null safety
3.5 Shaping Implements rules R1-R7 and rules L1-L3 of section 8.2 (Persian) of the Unicode standard.
Implementation
// TODO - this code is very special-cased.
List<int> performShaping(List<int> text) {
_ShapeJoiningType lastJt = _ShapeJoiningType.U;
_LetterForm lastForm = _LetterForm.Isolated;
int lastPos = 0;
var lastChar = _BidiChars.NotAChar;
final letterForms =
List<_LetterForm>.filled(text.length, _LetterForm.Initial);
for (int currPos = 0; currPos < text.length; ++currPos) {
var ch = text[currPos];
//string chStr = (ch).toString("X4");
final jt = _getShapeJoiningType(ch);
if ((jt == _ShapeJoiningType.R ||
jt == _ShapeJoiningType.D ||
jt == _ShapeJoiningType.C) &&
(lastJt == _ShapeJoiningType.L ||
lastJt == _ShapeJoiningType.D ||
lastJt == _ShapeJoiningType.C)) {
if (lastForm == _LetterForm.Isolated &&
(lastJt == _ShapeJoiningType.D || lastJt == _ShapeJoiningType.L)) {
letterForms[lastPos] = _LetterForm.Initial;
} else if (lastForm == _LetterForm.Final &&
lastJt == _ShapeJoiningType.D) {
letterForms[lastPos] = _LetterForm.Medial;
}
letterForms[currPos] = _LetterForm.Final;
lastForm = _LetterForm.Final;
lastJt = jt;
lastPos = currPos;
lastChar = ch;
} else if (jt != _ShapeJoiningType.T) {
letterForms[currPos] = _LetterForm.Isolated;
lastForm = _LetterForm.Isolated;
lastJt = jt;
lastPos = currPos;
lastChar = ch;
} else {
letterForms[currPos] = _LetterForm.Isolated;
}
}
lastChar = _BidiChars.NotAChar;
lastPos = 0;
int insertPos = 0;
final sb = <int>[];
for (int currPos = 0; currPos < text.length; ++currPos) {
var ch = text[currPos];
//string chStr = (ch).toString("X4");
final jt = _getShapeJoiningType(ch);
if (lastChar == _BidiChars.ARABIC_LAM &&
ch != _BidiChars.ARABIC_ALEF &&
ch != _BidiChars.ARABIC_ALEF_MADDA_ABOVE &&
ch != _BidiChars.ARABIC_ALEF_HAMZA_ABOVE &&
ch != _BidiChars.ARABIC_ALEF_HAMZA_BELOW &&
jt != _ShapeJoiningType.T) {
lastChar = _BidiChars.NotAChar;
} else if (ch == _BidiChars.ARABIC_LAM) {
lastChar = ch;
lastPos = currPos;
insertPos = sb.length;
}
if (lastChar == _BidiChars.ARABIC_LAM) {
if (letterForms[lastPos] == _LetterForm.Medial) {
switch (ch) {
case _BidiChars.ARABIC_ALEF:
sb[insertPos] = _BidiChars.ARABIC_LAM_ALEF_FINAL;
_charLengths.removeAt(insertPos);
continue;
case _BidiChars.ARABIC_ALEF_MADDA_ABOVE:
sb[insertPos] = _BidiChars.ARABIC_LAM_ALEF_MADDA_ABOVE_FINAL;
_charLengths.removeAt(insertPos);
_charLengths[insertPos] = _charLengths[insertPos] + 1;
continue;
case _BidiChars.ARABIC_ALEF_HAMZA_ABOVE:
sb[insertPos] = _BidiChars.ARABIC_LAM_ALEF_HAMZA_ABOVE_FINAL;
_charLengths.removeAt(insertPos);
continue;
case _BidiChars.ARABIC_ALEF_HAMZA_BELOW:
sb[insertPos] = _BidiChars.ARABIC_LAM_ALEF_HAMZA_BELOW_FINAL;
_charLengths.removeAt(insertPos);
continue;
}
} else if (letterForms[lastPos] == _LetterForm.Initial) {
switch (ch) {
case _BidiChars.ARABIC_ALEF:
sb[insertPos] = _BidiChars.ARABIC_LAM_ALEF_ISOLATED;
_charLengths.removeAt(insertPos);
continue;
case _BidiChars.ARABIC_ALEF_MADDA_ABOVE:
sb[insertPos] = _BidiChars.ARABIC_LAM_ALEF_MADDA_ABOVE_ISOLATED;
_charLengths.removeAt(insertPos);
_charLengths[insertPos] = _charLengths[insertPos] + 1;
continue;
case _BidiChars.ARABIC_ALEF_HAMZA_ABOVE:
sb[insertPos] = _BidiChars.ARABIC_LAM_ALEF_HAMZA_ABOVE_ISOLATED;
_charLengths.removeAt(insertPos);
continue;
case _BidiChars.ARABIC_ALEF_HAMZA_BELOW:
sb[insertPos] = _BidiChars.ARABIC_LAM_ALEF_HAMZA_BELOW_ISOLATED;
_charLengths.removeAt(insertPos);
continue;
}
}
}
sb.add(_getCharacterByLetterForm(ch, letterForms[currPos]));
}
return sb;
}