private StringBuilder InternalDecompose(ArrayList char_lengths) { StringBuilder target = new StringBuilder(); StringBuilder buffer = new StringBuilder(); _hasArabic = false; _hasNSMs = false; for (int i = 0; i < _text.Length; ++i) { BidiCharacterType ct = UnicodeCharacterDataResolver.GetBidiCharacterType(_text[i]); _hasArabic |= ((ct == BidiCharacterType.AL) || (ct == BidiCharacterType.AN)); _hasNSMs |= (ct == BidiCharacterType.NSM); buffer.Length = 0; GetRecursiveDecomposition(false, _text[i], buffer); char_lengths.Add(1 - buffer.Length); // add all of the characters in the decomposition. // (may be just the original character, if there was // no decomposition mapping) char ch; for (int j = 0; j < buffer.Length; ++j) { ch = buffer[j]; UnicodeCanonicalClass chClass = UnicodeCharacterDataResolver.GetUnicodeCanonicalClass(ch); int k = target.Length; // insertion point if (chClass != UnicodeCanonicalClass.NR) { // bubble-sort combining marks as necessary char ch2; for (; k > 0; --k) { ch2 = target[k - 1]; if (UnicodeCharacterDataResolver.GetUnicodeCanonicalClass(ch2) <= chClass) { break; } } } target.Insert(k, ch); } } return(target); }
private void InternalCompose(StringBuilder target, ArrayList char_lengths) { if (target.Length == 0) { return; } int starterPos = 0; int compPos = 1; int text_idx = 0; char starterCh = target[0]; char_lengths[starterPos] = (int)char_lengths[starterPos] + 1; UnicodeCanonicalClass lastClass = UnicodeCharacterDataResolver.GetUnicodeCanonicalClass(starterCh); if (lastClass != UnicodeCanonicalClass.NR) { lastClass = (UnicodeCanonicalClass)256; // fix for strings staring with a combining mark } int oldLen = target.Length; // Loop on the decomposed characters, combining where possible char ch; for (int decompPos = compPos; decompPos < target.Length; ++decompPos) { ch = target[decompPos]; UnicodeCanonicalClass chClass = UnicodeCharacterDataResolver.GetUnicodeCanonicalClass(ch); char composite = GetPairwiseComposition(starterCh, ch); UnicodeDecompositionType composeType = UnicodeCharacterDataResolver.GetUnicodeDecompositionType(composite); if (composeType == UnicodeDecompositionType.None && composite != BidiChars.NotAChar && (lastClass < chClass || lastClass == UnicodeCanonicalClass.NR)) { target[starterPos] = composite; char_lengths[starterPos] = (int)char_lengths[starterPos] + 1; // we know that we will only be replacing non-supplementaries by non-supplementaries // so we don't have to adjust the decompPos starterCh = composite; } else { if (chClass == UnicodeCanonicalClass.NR) { starterPos = compPos; starterCh = ch; text_idx++; } lastClass = chClass; target[compPos] = ch; //char_lengths[compPos] = (int)char_lengths[compPos] + 1; int chkPos = compPos; if ((int)char_lengths[chkPos] < 0) { while ((int)char_lengths[chkPos] < 0) { char_lengths[chkPos] = (int)char_lengths[chkPos] + 1; char_lengths.Insert(compPos, 0); chkPos++; } } else { char_lengths[chkPos] = (int)char_lengths[chkPos] + 1; } if (target.Length != oldLen) // MAY HAVE TO ADJUST! { decompPos += target.Length - oldLen; oldLen = target.Length; } ++compPos; } } target.Length = compPos; char_lengths.RemoveRange(compPos, char_lengths.Count - compPos); }