Issue #2538 - Part 3: Bring ZWJ Awareness to ClusterReverseIterator

Additional patch to resolve a bug exposed while working on the Cluster issue.
This commit is contained in:
Andy 2024-06-27 18:29:23 -07:00 • committed by roytam1
commit 44f81b46b6

View file

@ -180,6 +180,8 @@ GetHangulSyllableType(uint32_t aCh)
return HSType(u_getIntPropertyValue(aCh, UCHAR_HANGUL_SYLLABLE_TYPE)); return HSType(u_getIntPropertyValue(aCh, UCHAR_HANGUL_SYLLABLE_TYPE));
} }
static const uint32_t kZWJ = 0x200d;
void void
ClusterIterator::Next() ClusterIterator::Next()
{ {
@ -233,7 +235,6 @@ ClusterIterator::Next()
} }
} }
const uint32_t kZWJ = 0x200d;
uint32_t aNextCh = 0; uint32_t aNextCh = 0;
if (mPos + 1 < mLimit) { if (mPos + 1 < mLimit) {
aNextCh = *mPos; aNextCh = *mPos;
@ -299,19 +300,55 @@ ClusterReverseIterator::Next()
} }
uint32_t ch; uint32_t ch;
do {
ch = *--mPos;
if (NS_IS_LOW_SURROGATE(ch) && mPos > mLimit && bool nextWasComponent = false;
NS_IS_HIGH_SURROGATE(*(mPos - 1))) { size_t tRel = 0;
ch = SURROGATE_TO_UCS4(*--mPos, ch); size_t tPos = 0;
size_t chLen = 0;
do {
tRel++;
ch = *(mPos - tRel);
if (NS_IS_LOW_SURROGATE(ch) && (mPos - tRel) > mLimit &&
NS_IS_HIGH_SURROGATE(*(mPos - (tRel + 1)))) {
tRel++;
ch = SURROGATE_TO_UCS4(*(mPos - tRel), ch);
if (chLen == 0) {
chLen = 2;
}
} else if (chLen == 0) {
chLen = 1;
} }
// TODO: Full extendCluster support. bool prevWillBeZwj = false;
if (!(IsClusterExtender(ch) || IsEmojiClusterExtender(ch))) { bool validEmoji =
(GetEmojiPresentation(ch) == EmojiDefault) ||
(GetEmojiPresentation(ch) == EmojiComponent) ||
((GetEmojiPresentation(ch) == TextDefault) && nextWasComponent);
if (validEmoji) {
tPos = tRel;
uint32_t aPrevCh = *(mPos - (tRel + 1));
if (NS_IS_LOW_SURROGATE(aPrevCh) && (mPos - (tRel + 1)) > mLimit) {
uint32_t aHighCh = *(mPos - (tRel + 2));
if (NS_IS_HIGH_SURROGATE(aHighCh)) {
aPrevCh = SURROGATE_TO_UCS4(aHighCh, aPrevCh);
}
}
prevWillBeZwj = (aPrevCh == kZWJ);
}
if (!(IsClusterExtender(ch) ||
IsEmojiClusterExtender(ch) ||
prevWillBeZwj)) {
if (tPos == 0) {
tPos = chLen;
}
break; break;
} }
} while (mPos > mLimit); nextWasComponent = (GetEmojiPresentation(ch) == EmojiComponent);
} while ((mPos - tRel) > mLimit);
mPos -= tPos;
// XXX May need to handle conjoining Jamo // XXX May need to handle conjoining Jamo