Index: src/ports/SkFontConfigInterface_android.cpp |
diff --git a/src/ports/SkFontConfigInterface_android.cpp b/src/ports/SkFontConfigInterface_android.cpp |
index c9dc944f81d6df75687743a34874c97f42cfd6b7..9a38261e80262789788e545dd9d86cbb5d1d9825 100644 |
--- a/src/ports/SkFontConfigInterface_android.cpp |
+++ b/src/ports/SkFontConfigInterface_android.cpp |
@@ -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++; |