зеркало из https://github.com/mozilla/moz-skia.git
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:
Родитель
e15d9ecef8
Коммит
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++;
|
||||
|
|
Загрузка…
Ссылка в новой задаче