external/harfbuzz_ng/src/hb-ot-shape-normalize.cc 中有一段话
- When a font does not support a character but supports its decomposition,
well, use the decomposition (preferring the canonical decomposition, but
falling back to the compatibility decomposition if necessary). The
compatibility decomposition is really nice to have, for characters like
ellipsis, or various-sized space characters.
当一个字体库不支持一个字符显示的时候,但是这个字符可以转换为另外一个字符显示。
decompose_compatibility
git:platform/frameworks/minikin
const FontCollection::FontInstance* FontCollection::getInstanceForChar(uint32_t ch,
FontLanguage lang, int variant) const {
if (ch >= mMaxChar) {
return NULL;
}
const Range& range = mRanges[ch >> kLogCharsPerPage];
#ifdef VERBOSE_DEBUG
ALOGD("querying range %d:%d\n", range.start, range.end);
#endif
const FontInstance* bestInstance = NULL;
int bestScore = -1;
for (size_t i = range.start; i < range.end; i++) {
const FontInstance* instance = mInstanceVec[i];
if (instance->mCoverage->get(ch)) {
FontFamily* family = instance->mFamily;
// First font family in collection always matches
if (mInstances[0].mFamily == family) {
return instance;
}
int score = lang.match(family->lang()) * 2;
if (variant != 0 && variant == family->variant()) {
score++;
}
if (score > bestScore) {
bestScore = score;
bestInstance = instance;
}
}
}
if (bestInstance == NULL && !mInstanceVec.empty()) {
UErrorCode errorCode = U_ZERO_ERROR;
const UNormalizer2* normalizer = unorm2_getNFDInstance(&errorCode);
if (U_SUCCESS(errorCode)) {
UChar decomposed[4];
int len = unorm2_getRawDecomposition(normalizer, ch, decomposed, 4, &errorCode);
if (U_SUCCESS(errorCode) && len > 0) {
int off = 0;
U16_NEXT_UNSAFE(decomposed, off, ch);
return getInstanceForChar(ch, lang, variant);
}
}
//************************xia yu edit ************/
UChar decomp[4];
errorCode = U_ZERO_ERROR;
int len = unorm_normalize((UChar *) &ch, 1, UNORM_NFKD, 0, decomp, 4,
&errorCode);
if (U_SUCCESS(errorCode) && len > 0) {
int off = 0;
U16_NEXT_UNSAFE(decomp, off, ch);
return getInstanceForChar(ch, lang, variant);
}
/*************************************/
bestInstance = &mInstances[0];
}
return bestInstance;
}