in platform/cc/shaper/FontRunIterator.cc [26:93]
void FontRunIterator::consume() {
const char* clusterStart = fCurrent;
const char* clusterEnd = fBegin + ubrk_following(fGraphemeIter.get(), clusterStart - fBegin);
UErrorCode status = U_ZERO_ERROR;
// If the starting typeface can handle this character, use it.
if (can_handle_cluster(fFont.getTypeface(), clusterStart, clusterEnd)) {
fCurrentFont = &fFont;
// If the current fallback can handle this character, use it.
} else if (fFallbackFont.getTypeface() && can_handle_cluster(fFallbackFont.getTypeface(), clusterStart, clusterEnd)) {
fCurrentFont = &fFallbackFont;
// If not, try to find a fallback typeface
} else {
const char* language = fLanguage ? fLanguage->currentLanguage() : nullptr;
int languageCount = fLanguage ? 1 : 0;
const char *ptr = clusterStart;
fCurrentFont = &fFont;
while (ptr < clusterEnd) {
SkUnichar u = SkUTF::NextUTF8(&ptr, clusterEnd);
u = u < 0 ? 0xFFFD : u;
sk_sp<SkTypeface> candidate(fFallbackMgr->matchFamilyStyleCharacter(fRequestName, fRequestStyle, &language, languageCount, u));
if (candidate && can_handle_cluster(candidate.get(), clusterStart, clusterEnd)) {
fFallbackFont.setTypeface(std::move(candidate));
fCurrentFont = &fFallbackFont;
break;
}
}
}
while (clusterStart < fEnd) {
clusterStart = clusterEnd;
clusterEnd = fBegin + ubrk_following(fGraphemeIter.get(), clusterStart - fBegin);
const char* ptr = clusterStart;
SkUnichar u = utf8_next(&ptr, clusterEnd);
// Do not switch font on control, whitespace or punct
if (ptr == clusterEnd
&& fCurrentFont->getTypeface()->unicharToGlyph(u) != 0
&& (u_iscntrl(u)
|| (fApproximateSpaces && u_isWhitespace(u))
|| (fApproximatePunctuation && u_ispunct(u))))
continue;
// End run if not using initial typeface and initial typeface has this character.
if (fCurrentFont->getTypeface() != fFont.getTypeface() && can_handle_cluster(fFont.getTypeface(), clusterStart, clusterEnd)) {
fCurrent = clusterStart;
return;
}
// End run if current typeface does not have this character and some other font does.
if (!can_handle_cluster(fCurrentFont->getTypeface(), clusterStart, clusterEnd)) {
const char* language = fLanguage ? fLanguage->currentLanguage() : nullptr;
int languageCount = fLanguage ? 1 : 0;
const char *ptr = clusterStart;
while (ptr < clusterEnd) {
SkUnichar u = SkUTF::NextUTF8(&ptr, clusterEnd);
u = u < 0 ? 0xFFFD : u;
sk_sp<SkTypeface> candidate(fFallbackMgr->matchFamilyStyleCharacter(fRequestName, fRequestStyle, &language, languageCount, u));
if (candidate && can_handle_cluster(candidate.get(), clusterStart, clusterEnd)) {
fCurrent = clusterStart;
return;
}
}
}
}
fCurrent = clusterStart;
}