diff options
Diffstat (limited to 'src/ports')
-rw-r--r-- | src/ports/SkFontConfigParser_android.cpp | 48 | ||||
-rw-r--r-- | src/ports/SkFontConfigParser_android.h | 56 | ||||
-rw-r--r-- | src/ports/SkFontMgr_android.cpp | 15 |
3 files changed, 89 insertions, 30 deletions
diff --git a/src/ports/SkFontConfigParser_android.cpp b/src/ports/SkFontConfigParser_android.cpp index 658055d5a2..b38ec8cc4c 100644 --- a/src/ports/SkFontConfigParser_android.cpp +++ b/src/ports/SkFontConfigParser_android.cpp @@ -109,9 +109,9 @@ void familyElementHandler(FontFamily* family, const char** attributes) { } else if (nameLen == 7 && !strncmp("variant", name, nameLen)) { // Value should be either elegant or compact. if (valueLen == 7 && !strncmp("elegant", value, valueLen)) { - family->fVariant = SkPaintOptionsAndroid::kElegant_Variant; + family->fVariant = kElegant_FontVariant; } else if (valueLen == 7 && !strncmp("compact", value, valueLen)) { - family->fVariant = SkPaintOptionsAndroid::kCompact_Variant; + family->fVariant = kCompact_FontVariant; } } } @@ -122,13 +122,6 @@ void fontFileNameHandler(void* data, const char* s, int len) { familyData->currentFontInfo->fFileName.set(s, len); } -void familyElementEndHandler(FontFamily* family) { - for (int i = 0; i < family->fFonts.count(); i++) { - family->fFonts[i].fPaintOptions.setLanguage(family->fLanguage); - family->fFonts[i].fPaintOptions.setFontVariant(family->fVariant); - } -} - void fontElementHandler(XML_Parser* parser, FontFileInfo* file, const char** attributes) { // A <font> should have weight (integer) and style (normal, italic) attributes. // NOTE: we ignore the style. @@ -278,7 +271,6 @@ void endElementHandler(void* data, const char* tag) { if (len == 9 && strncmp(tag, "familyset", len) == 0) { familysetElementEndHandler(familyData); } else if (len == 6 && strncmp(tag, "family", len) == 0) { - familyElementEndHandler(familyData->currentFamily); *familyData->families.append() = familyData->currentFamily; familyData->currentFamily = NULL; } else if (len == 4 && !strncmp(tag, "font", len)) { @@ -332,14 +324,27 @@ static void fontFileElementHandler(FamilyData* familyData, const char** attribut size_t nameLength = strlen(attributeName); size_t valueLength = strlen(attributeValue); if (nameLength == 7 && strncmp(attributeName, "variant", nameLength) == 0) { + const FontVariant prevVariant = familyData->currentFamily->fVariant; if (valueLength == 7 && strncmp(attributeValue, "elegant", valueLength) == 0) { - newFileInfo.fPaintOptions.setFontVariant(SkPaintOptionsAndroid::kElegant_Variant); + familyData->currentFamily->fVariant = kElegant_FontVariant; } else if (valueLength == 7 && strncmp(attributeValue, "compact", valueLength) == 0) { - newFileInfo.fPaintOptions.setFontVariant(SkPaintOptionsAndroid::kCompact_Variant); + familyData->currentFamily->fVariant = kCompact_FontVariant; + } + if (familyData->currentFamily->fFonts.count() > 1 && + familyData->currentFamily->fVariant != prevVariant) { + SkDebugf("Every font file within a family must have identical variants"); + sk_throw(); } + } else if (nameLength == 4 && strncmp(attributeName, "lang", nameLength) == 0) { - newFileInfo.fPaintOptions.setLanguage(attributeValue); + SkLanguage prevLang = familyData->currentFamily->fLanguage; + familyData->currentFamily->fLanguage = SkLanguage(attributeValue); + if (familyData->currentFamily->fFonts.count() > 1 && + familyData->currentFamily->fLanguage != prevLang) { + SkDebugf("Every font file within a family must have identical languages"); + sk_throw(); + } } else if (nameLength == 5 && strncmp(attributeName, "index", nameLength) == 0) { int value; if (parseNonNegativeInteger(attributeValue, &value)) { @@ -514,9 +519,7 @@ static void getFallbackFontFamiliesForLocale(SkTDArray<FontFamily*> &fallbackFon for (int i = 0; i < langSpecificFonts.count(); ++i) { FontFamily* family = langSpecificFonts[i]; - for (int j = 0; j < family->fFonts.count(); ++j) { - family->fFonts[j].fPaintOptions.setLanguage(locale); - } + family->fLanguage = SkLanguage(locale); *fallbackFonts.append() = family; } } @@ -594,3 +597,16 @@ void SkFontConfigParser::GetTestFontFamilies(SkTDArray<FontFamily*> &fontFamilie *fontFamilies.append() = fallbackFonts[i]; } } + +SkLanguage SkLanguage::getParent() const { + SkASSERT(!fTag.isEmpty()); + const char* tag = fTag.c_str(); + + // strip off the rightmost "-.*" + const char* parentTagEnd = strrchr(tag, '-'); + if (parentTagEnd == NULL) { + return SkLanguage(); + } + size_t parentTagLen = parentTagEnd - tag; + return SkLanguage(tag, parentTagLen); +} diff --git a/src/ports/SkFontConfigParser_android.h b/src/ports/SkFontConfigParser_android.h index 40b645287a..117a1086fb 100644 --- a/src/ports/SkFontConfigParser_android.h +++ b/src/ports/SkFontConfigParser_android.h @@ -8,18 +8,62 @@ #ifndef SKFONTCONFIGPARSER_ANDROID_H_ #define SKFONTCONFIGPARSER_ANDROID_H_ -#include "SkTypes.h" - -#include "SkPaintOptionsAndroid.h" #include "SkString.h" #include "SkTDArray.h" +/** \class SkLanguage + + The SkLanguage class represents a human written language, and is used by + text draw operations to determine which glyph to draw when drawing + characters with variants (ie Han-derived characters). +*/ +class SkLanguage { +public: + SkLanguage() { } + SkLanguage(const SkString& tag) : fTag(tag) { } + SkLanguage(const char* tag) : fTag(tag) { } + SkLanguage(const char* tag, size_t len) : fTag(tag, len) { } + SkLanguage(const SkLanguage& b) : fTag(b.fTag) { } + + /** Gets a BCP 47 language identifier for this SkLanguage. + @return a BCP 47 language identifier representing this language + */ + const SkString& getTag() const { return fTag; } + + /** Performs BCP 47 fallback to return an SkLanguage one step more general. + @return an SkLanguage one step more general + */ + SkLanguage getParent() const; + + bool operator==(const SkLanguage& b) const { + return fTag == b.fTag; + } + bool operator!=(const SkLanguage& b) const { + return fTag != b.fTag; + } + SkLanguage& operator=(const SkLanguage& b) { + fTag = b.fTag; + return *this; + } + +private: + //! BCP 47 language identifier + SkString fTag; +}; + +enum FontVariants { + kDefault_FontVariant = 0x01, + kCompact_FontVariant = 0x02, + kElegant_FontVariant = 0x04, + kLast_FontVariant = kElegant_FontVariant, +}; +typedef uint32_t FontVariant; + struct FontFileInfo { FontFileInfo() : fIndex(0), fWeight(0) { } SkString fFileName; int fIndex; - SkPaintOptionsAndroid fPaintOptions; int fWeight; }; @@ -32,14 +76,14 @@ struct FontFileInfo { */ struct FontFamily { FontFamily() - : fVariant(SkPaintOptionsAndroid::kDefault_Variant) + : fVariant(kDefault_FontVariant) , fOrder(-1) , fIsFallbackFont(false) { } SkTArray<SkString> fNames; SkTArray<FontFileInfo> fFonts; SkLanguage fLanguage; - SkPaintOptionsAndroid::FontVariant fVariant; + FontVariant fVariant; int fOrder; // internal to SkFontConfigParser bool fIsFallbackFont; }; diff --git a/src/ports/SkFontMgr_android.cpp b/src/ports/SkFontMgr_android.cpp index b03185de63..e966c84f1f 100644 --- a/src/ports/SkFontMgr_android.cpp +++ b/src/ports/SkFontMgr_android.cpp @@ -67,7 +67,7 @@ public: bool isFixedPitch, const SkString familyName, const SkLanguage& lang, - uint32_t variantStyle) + FontVariant variantStyle) : INHERITED(index, style, isFixedPitch, familyName) , fPathName(pathName) , fLang(lang) @@ -88,7 +88,7 @@ public: const SkString fPathName; const SkLanguage fLang; - const uint32_t fVariantStyle; + const FontVariant fVariantStyle; typedef SkTypeface_Android INHERITED; }; @@ -163,11 +163,10 @@ public: continue; } - const SkLanguage& lang = fontFile.fPaintOptions.getLanguage(); - uint32_t variant = fontFile.fPaintOptions.getFontVariant(); - if (SkPaintOptionsAndroid::kDefault_Variant == variant) { - variant = SkPaintOptionsAndroid::kCompact_Variant | - SkPaintOptionsAndroid::kElegant_Variant; + const SkLanguage& lang = family.fLanguage; + uint32_t variant = family.fVariant; + if (kDefault_FontVariant == variant) { + variant = kCompact_FontVariant | kElegant_FontVariant; } // The first specified family name overrides the family name found in the font. @@ -353,7 +352,7 @@ protected: // TODO: add 'is_elegant' and 'is_compact' bits to 'style' request. // For compatibility, try 'elegant' fonts first in fallback. - uint32_t variantMask = SkPaintOptionsAndroid::kElegant_Variant; + uint32_t variantMask = kElegant_FontVariant; // The first time match anything in the mask, second time anything not in the mask. for (bool maskMatches = true; maskMatches != false; maskMatches = false) { |