std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(pathName.c_str()); if (!stream) {
SkDEBUGF("Requested font file %s does not exist or cannot be opened.\n",
pathName.c_str()); continue;
}
constint ttcIndex = fontFile.fIndex;
SkString familyName;
SkFontStyle style; bool isFixedWidth;
SkFontScanner::AxisDefinitions axisDefinitions; if (!scanner->scanInstance(stream.get(), ttcIndex, 0,
&familyName, &style, &isFixedWidth, &axisDefinitions))
{
SkDEBUGF("Requested font file %s exists, but is not a valid font.\n",
pathName.c_str()); continue;
}
// The first specified family name overrides the family name found in the font. // TODO: SkTypeface_AndroidSystem::onCreateFamilyNameIterator should return // all of the specified family names in addition to the names found in the font. if (cannonicalFamilyName != nullptr) {
familyName = *cannonicalFamilyName;
}
/** On Android a single family can have many names, but our API assumes unique names. * Map names to the back end so that all names for a given family refer to the same * (non-replicated) set of typefaces. * SkTDict<> doesn't let us do index-based lookup, so we write our own mapping.
*/ struct NameToFamily {
SkString name;
SkFontStyleSet_Android* styleSet;
};
protected: /** Returns not how many families we have, but how many unique names * exist among the families.
*/ int onCountFamilies() const override { return fNameToFamilyMap.size();
}
sk_sp<SkFontStyleSet> onMatchFamily(constchar familyName[]) const override { if (!familyName) { return nullptr;
}
SkAutoAsciiToLC tolc(familyName); for (int i = 0; i < fNameToFamilyMap.size(); ++i) { if (fNameToFamilyMap[i].name.equals(tolc.lc())) { return sk_ref_sp(fNameToFamilyMap[i].styleSet);
}
} // TODO: eventually we should not need to name fallback families. for (int i = 0; i < fFallbackNameToFamilyMap.size(); ++i) { if (fFallbackNameToFamilyMap[i].name.equals(tolc.lc())) { return sk_ref_sp(fFallbackNameToFamilyMap[i].styleSet);
}
} return nullptr;
}
sk_sp<SkTypeface> onMatchFamilyStyleCharacter(constchar familyName[], const SkFontStyle& style, constchar* bcp47[], int bcp47Count,
SkUnichar character) const override { // The variant 'elegant' is 'not squashed', 'compact' is 'stays in ascent/descent'. // The variant 'default' means 'compact and elegant'. // As a result, it is not possible to know the variant context from the font alone. // TODO: add 'is_elegant' and 'is_compact' bits to 'style' request.
SkString familyNameString(familyName); for (const SkString& currentFamilyName : { familyNameString, SkString() }) { // The first time match anything elegant, second time anything not elegant. for (int elegant = 2; elegant --> 0;) { for (int bcp47Index = bcp47Count; bcp47Index --> 0;) {
SkLanguage lang(bcp47[bcp47Index]); while (!lang.getTag().isEmpty()) {
sk_sp<SkTypeface_AndroidSystem> matchingTypeface =
find_family_style_character(currentFamilyName, fFallbackNameToFamilyMap,
style, SkToBool(elegant),
lang.getTag(), character); if (matchingTypeface) { return matchingTypeface;
}
sk_sp<SkTypeface> onLegacyMakeTypeface(constchar familyName[], SkFontStyle style) constoverride { if (familyName) { // On Android, we must return nullptr when we can't find the requested // named typeface so that the system/app can provide their own recovery // mechanism. On other platforms we'd provide a typeface from the // default family instead. return sk_sp<SkTypeface>(this->onMatchFamilyStyle(familyName, style));
} if (fDefaultStyleSet) { return sk_sp<SkTypeface>(fDefaultStyleSet->matchStyle(style));
} return SkTypeface::MakeEmpty();
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.