fix regression in fallback chain where we don't account for the original font style.
This CL also enforces that the language and variant are the same for all fonts within a given fallback family. R=reed@google.com Review URL: https://codereview.chromium.org/23670009 git-svn-id: http://skia.googlecode.com/svn/trunk@11128 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
e15d9ecef8
commit
b27eba7c28
@ -55,8 +55,6 @@ struct FontRec {
|
||||
SkRefPtr<SkTypeface> fTypeface;
|
||||
SkString fFileName;
|
||||
SkTypeface::Style fStyle;
|
||||
SkPaintOptionsAndroid fPaintOptions;
|
||||
bool fIsFallbackFont;
|
||||
bool fIsValid;
|
||||
FamilyRecID fFamilyRecID;
|
||||
};
|
||||
@ -68,10 +66,12 @@ struct FamilyRec {
|
||||
|
||||
static const int FONT_STYLE_COUNT = 4;
|
||||
FontRecID fFontRecID[FONT_STYLE_COUNT];
|
||||
bool fIsFallbackFont;
|
||||
SkPaintOptionsAndroid fPaintOptions;
|
||||
};
|
||||
|
||||
|
||||
typedef SkTDArray<FontRecID> FallbackFontList;
|
||||
typedef SkTDArray<FamilyRecID> FallbackFontList;
|
||||
|
||||
class SkFontConfigInterfaceAndroid : public SkFontConfigInterface {
|
||||
public:
|
||||
@ -105,7 +105,7 @@ public:
|
||||
const SkPaintOptionsAndroid& options);
|
||||
|
||||
private:
|
||||
void addFallbackFont(FontRecID fontRecID);
|
||||
void addFallbackFamily(FamilyRecID fontRecID);
|
||||
SkTypeface* getTypefaceForFontRec(FontRecID fontRecID);
|
||||
FallbackFontList* getCurrentLocaleFallbackFontList();
|
||||
FallbackFontList* findFallbackFontList(const SkLanguage& lang, bool isOriginal = true);
|
||||
@ -227,8 +227,6 @@ SkFontConfigInterfaceAndroid::SkFontConfigInterfaceAndroid(SkTDArray<FontFamily*
|
||||
FontRec& fontRec = fFonts.push_back();
|
||||
fontRec.fFileName = filename;
|
||||
fontRec.fStyle = SkTypeface::kNormal;
|
||||
fontRec.fPaintOptions = family->fFontFiles[j]->fPaintOptions;
|
||||
fontRec.fIsFallbackFont = family->fIsFallbackFont;
|
||||
fontRec.fIsValid = false;
|
||||
fontRec.fFamilyRecID = familyRecID;
|
||||
|
||||
@ -241,7 +239,7 @@ SkFontConfigInterfaceAndroid::SkFontConfigInterfaceAndroid(SkTDArray<FontFamily*
|
||||
fontRec.fIsValid = find_name_and_attributes(stream.get(), &name,
|
||||
&fontRec.fStyle, &isFixedWidth);
|
||||
} else {
|
||||
if (!fontRec.fIsFallbackFont) {
|
||||
if (!family->fIsFallbackFont) {
|
||||
SkDebugf("---- failed to open <%s> as a font\n", filename.c_str());
|
||||
}
|
||||
}
|
||||
@ -261,6 +259,18 @@ SkFontConfigInterfaceAndroid::SkFontConfigInterfaceAndroid(SkTDArray<FontFamily*
|
||||
familyRec = &fFontFamilies.push_back();
|
||||
familyRecID = fFontFamilies.count() - 1;
|
||||
fontRec.fFamilyRecID = familyRecID;
|
||||
|
||||
familyRec->fIsFallbackFont = family->fIsFallbackFont;
|
||||
familyRec->fPaintOptions = family->fFontFiles[j]->fPaintOptions;
|
||||
|
||||
// if this is a fallback font then add it to the appropriate fallback chains
|
||||
if (familyRec->fIsFallbackFont) {
|
||||
addFallbackFamily(familyRecID);
|
||||
}
|
||||
} else if (familyRec->fPaintOptions != family->fFontFiles[j]->fPaintOptions) {
|
||||
SkDebugf("Every font file within a family must have identical"
|
||||
"language and variant attributes");
|
||||
sk_throw();
|
||||
}
|
||||
|
||||
// add this font to the current familyRec
|
||||
@ -271,21 +281,16 @@ SkFontConfigInterfaceAndroid::SkFontConfigInterfaceAndroid(SkTDArray<FontFamily*
|
||||
}
|
||||
familyRec->fFontRecID[fontRec.fStyle] = fontRecID;
|
||||
|
||||
// if this is a fallback font then add it to the appropriate fallback chains
|
||||
if (fontRec.fIsFallbackFont) {
|
||||
addFallbackFont(fontRecID);
|
||||
}
|
||||
|
||||
// add the fallback file name to the name dictionary. This is needed
|
||||
// by getFallbackFamilyNameForChar() so that fallback families can be
|
||||
// requested by the filenames of the fonts they contain.
|
||||
if (family->fIsFallbackFont && familyRec) {
|
||||
if (familyRec && familyRec->fIsFallbackFont) {
|
||||
insert_into_name_dict(fFamilyNameDict, fontRec.fFileName.c_str(), familyRecID);
|
||||
}
|
||||
}
|
||||
|
||||
// add the names that map to this family to the dictionary for easy lookup
|
||||
if (familyRec && !family->fIsFallbackFont) {
|
||||
if (familyRec && !familyRec->fIsFallbackFont) {
|
||||
SkTDArray<const char*> names = family->fNames;
|
||||
if (names.isEmpty()) {
|
||||
SkDEBUGFAIL("ERROR: non-fallback font with no name");
|
||||
@ -314,10 +319,10 @@ SkFontConfigInterfaceAndroid::SkFontConfigInterfaceAndroid(SkTDArray<FontFamily*
|
||||
const char* fallbackLang = iter.next(&fallbackList);
|
||||
while(fallbackLang != NULL) {
|
||||
for (int i = 0; i < fDefaultFallbackList.count(); i++) {
|
||||
FontRecID fontRecID = fDefaultFallbackList[i];
|
||||
const SkString& fontLang = fFonts[fontRecID].fPaintOptions.getLanguage().getTag();
|
||||
FamilyRecID familyRecID = fDefaultFallbackList[i];
|
||||
const SkString& fontLang = fFontFamilies[familyRecID].fPaintOptions.getLanguage().getTag();
|
||||
if (strcmp(fallbackLang, fontLang.c_str()) != 0) {
|
||||
fallbackList->push(fontRecID);
|
||||
fallbackList->push(familyRecID);
|
||||
}
|
||||
}
|
||||
// move to the next fallback list in the dictionary
|
||||
@ -334,16 +339,16 @@ SkFontConfigInterfaceAndroid::~SkFontConfigInterfaceAndroid() {
|
||||
}
|
||||
}
|
||||
|
||||
void SkFontConfigInterfaceAndroid::addFallbackFont(FontRecID fontRecID) {
|
||||
SkASSERT(fontRecID < fFonts.count());
|
||||
const FontRec& fontRec = fFonts[fontRecID];
|
||||
SkASSERT(fontRec.fIsFallbackFont);
|
||||
void SkFontConfigInterfaceAndroid::addFallbackFamily(FamilyRecID familyRecID) {
|
||||
SkASSERT(familyRecID < fFontFamilies.count());
|
||||
const FamilyRec& familyRec = fFontFamilies[familyRecID];
|
||||
SkASSERT(familyRec.fIsFallbackFont);
|
||||
|
||||
// add to the default fallback list
|
||||
fDefaultFallbackList.push(fontRecID);
|
||||
fDefaultFallbackList.push(familyRecID);
|
||||
|
||||
// stop here if it is the default language tag
|
||||
const SkString& languageTag = fontRec.fPaintOptions.getLanguage().getTag();
|
||||
const SkString& languageTag = familyRec.fPaintOptions.getLanguage().getTag();
|
||||
if (languageTag.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@ -356,7 +361,7 @@ void SkFontConfigInterfaceAndroid::addFallbackFont(FontRecID fontRecID) {
|
||||
fFallbackFontDict.set(languageTag.c_str(), customList);
|
||||
}
|
||||
SkASSERT(customList != NULL);
|
||||
customList->push(fontRecID);
|
||||
customList->push(familyRecID);
|
||||
}
|
||||
|
||||
|
||||
@ -502,7 +507,8 @@ SkTypeface* SkFontConfigInterfaceAndroid::getTypefaceForFontRec(FontRecID fontRe
|
||||
bool SkFontConfigInterfaceAndroid::getFallbackFamilyNameForChar(SkUnichar uni, SkString* name) {
|
||||
FallbackFontList* fallbackFontList = this->getCurrentLocaleFallbackFontList();
|
||||
for (int i = 0; i < fallbackFontList->count(); i++) {
|
||||
FontRecID fontRecID = fallbackFontList->getAt(i);
|
||||
FamilyRecID familyRecID = fallbackFontList->getAt(i);
|
||||
FontRecID fontRecID = find_best_style(fFontFamilies[familyRecID], SkTypeface::kNormal);
|
||||
SkTypeface* face = this->getTypefaceForFontRec(fontRecID);
|
||||
|
||||
SkPaint paint;
|
||||
@ -593,6 +599,12 @@ SkTypeface* SkFontConfigInterfaceAndroid::nextLogicalTypeface(SkFontID currFontI
|
||||
FallbackFontList* currentFallbackList = findFallbackFontList(opts.getLanguage());
|
||||
SkASSERT(currentFallbackList);
|
||||
|
||||
SkTypeface::Style origStyle = SkTypeface::kNormal;
|
||||
const SkTypeface* origTypeface = SkTypefaceCache::FindByID(origFontID);
|
||||
if (NULL != origTypeface) {
|
||||
origStyle = origTypeface->style();
|
||||
}
|
||||
|
||||
// we must convert currTypeface into a FontRecID
|
||||
FontRecID currFontRecID = INVALID_FONT_REC_ID;
|
||||
const SkTypeface* currTypeface = SkTypefaceCache::FindByID(currFontID);
|
||||
@ -603,8 +615,13 @@ SkTypeface* SkFontConfigInterfaceAndroid::nextLogicalTypeface(SkFontID currFontI
|
||||
SkASSERT(INVALID_FONT_REC_ID != currFontRecID);
|
||||
}
|
||||
|
||||
FamilyRecID currFamilyRecID = INVALID_FAMILY_REC_ID;
|
||||
if (INVALID_FONT_REC_ID != currFontRecID) {
|
||||
currFamilyRecID = fFonts[currFontRecID].fFamilyRecID;
|
||||
}
|
||||
|
||||
// lookup the index next font in the chain
|
||||
int currFallbackFontIndex = currentFallbackList->find(currFontRecID);
|
||||
int currFallbackFontIndex = currentFallbackList->find(currFamilyRecID);
|
||||
// We add 1 to the returned index for 2 reasons: (1) if find succeeds it moves
|
||||
// our index to the next entry in the list; (2) if find() fails it returns
|
||||
// -1 and incrementing it will set our starting index to 0 (the head of the list)
|
||||
@ -625,9 +642,10 @@ SkTypeface* SkFontConfigInterfaceAndroid::nextLogicalTypeface(SkFontID currFontI
|
||||
|
||||
SkTypeface* nextLogicalTypeface = 0;
|
||||
while (nextFallbackFontIndex < currentFallbackList->count()) {
|
||||
FontRecID fontRecID = currentFallbackList->getAt(nextFallbackFontIndex);
|
||||
if ((fFonts[fontRecID].fPaintOptions.getFontVariant() & acceptedVariants) != 0) {
|
||||
nextLogicalTypeface = this->getTypefaceForFontRec(fontRecID);
|
||||
FamilyRecID familyRecID = currentFallbackList->getAt(nextFallbackFontIndex);
|
||||
if ((fFontFamilies[familyRecID].fPaintOptions.getFontVariant() & acceptedVariants) != 0) {
|
||||
FontRecID matchedFont = find_best_style(fFontFamilies[familyRecID], origStyle);
|
||||
nextLogicalTypeface = this->getTypefaceForFontRec(matchedFont);
|
||||
break;
|
||||
}
|
||||
nextFallbackFontIndex++;
|
||||
|
Loading…
Reference in New Issue
Block a user