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
diff --git a/src/ports/SkFontConfigInterface_android.cpp b/src/ports/SkFontConfigInterface_android.cpp
index c9dc944..9a38261 100644
--- a/src/ports/SkFontConfigInterface_android.cpp
+++ b/src/ports/SkFontConfigInterface_android.cpp
@@ -55,8 +55,6 @@
SkRefPtr<SkTypeface> fTypeface;
SkString fFileName;
SkTypeface::Style fStyle;
- SkPaintOptionsAndroid fPaintOptions;
- bool fIsFallbackFont;
bool fIsValid;
FamilyRecID fFamilyRecID;
};
@@ -68,10 +66,12 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
}
}
-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 @@
fFallbackFontDict.set(languageTag.c_str(), customList);
}
SkASSERT(customList != NULL);
- customList->push(fontRecID);
+ customList->push(familyRecID);
}
@@ -502,7 +507,8 @@
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 @@
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 @@
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* 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++;