diff options
Diffstat (limited to 'src/ports')
-rw-r--r-- | src/ports/SkFontConfigParser_android.cpp | 92 | ||||
-rw-r--r-- | src/ports/SkFontConfigParser_android.h | 4 |
2 files changed, 53 insertions, 43 deletions
diff --git a/src/ports/SkFontConfigParser_android.cpp b/src/ports/SkFontConfigParser_android.cpp index 2e9054d36d..90450a9940 100644 --- a/src/ports/SkFontConfigParser_android.cpp +++ b/src/ports/SkFontConfigParser_android.cpp @@ -16,8 +16,6 @@ #include <limits> - - // From Android version LMP onwards, all font files collapse into // /system/etc/fonts.xml. Instead of trying to detect which version // we're on, try to open fonts.xml; if that fails, fall back to the @@ -51,23 +49,25 @@ * can read these variables that are relevant to the current parsing. */ struct FamilyData { - FamilyData(XML_Parser parser, SkTDArray<FontFamily*> &families) + FamilyData(XML_Parser parser, SkTDArray<FontFamily*>& families) : fParser(parser) , fFamilies(families) , fCurrentFamily(NULL) , fCurrentFontInfo(NULL) , fCurrentTag(NO_TAG) - { }; + , fVersion(0) + { } XML_Parser fParser; // The expat parser doing the work, owned by caller SkTDArray<FontFamily*>& fFamilies; // The array to append families, owned by caller SkAutoTDelete<FontFamily> fCurrentFamily; // The family being created, owned by this FontFileInfo* fCurrentFontInfo; // The fontInfo being created, owned by currentFamily int fCurrentTag; // Flag to indicate when we're in nameset/fileset tags + int fVersion; // The version of the file parsed. }; /** http://www.w3.org/TR/html-markup/datatypes.html#common.data.integer.non-negative-def */ -template <typename T> static bool parseNonNegativeInteger(const char* s, T* value) { +template <typename T> static bool parse_non_negative_integer(const char* s, T* value) { SK_COMPILE_ASSERT(std::numeric_limits<T>::is_integer, T_must_be_integer); const T nMax = std::numeric_limits<T>::max() / 10; const T dMax = std::numeric_limits<T>::max() - (nMax * 10); @@ -133,7 +133,7 @@ void fontElementHandler(XML_Parser parser, FontFileInfo* file, const char** attr const char* value = attributes[i+1]; size_t nameLen = strlen(name); if (nameLen == 6 && !strncmp("weight", name, nameLen)) { - if (!parseNonNegativeInteger(value, &file->fWeight)) { + if (!parse_non_negative_integer(value, &file->fWeight)) { SkDebugf("---- Font weight %s (INVALID)", value); file->fWeight = 0; } @@ -178,7 +178,7 @@ void aliasElementHandler(FamilyData* familyData, const char** attributes) { } else if (nameLen == 2 && !strncmp("to", name, nameLen)) { to.set(value); } else if (nameLen == 6 && !strncmp("weight", name, nameLen)) { - parseNonNegativeInteger(value, &weight); + parse_non_negative_integer(value, &weight); } } @@ -237,7 +237,7 @@ namespace jbParser { * Handler for arbitrary text. This is used to parse the text inside each name * or file tag. The resulting strings are put into the fNames or FontFileInfo arrays. */ -static void textHandler(void* data, const char* s, int len) { +static void text_handler(void* data, const char* s, int len) { FamilyData* familyData = (FamilyData*) data; // Make sure we're in the right state to store this name information if (familyData->fCurrentFamily.get() && @@ -264,7 +264,7 @@ static void textHandler(void* data, const char* s, int len) { * Handler for font files. This processes the attributes for language and * variants then lets textHandler handle the actual file name */ -static void fontFileElementHandler(FamilyData* familyData, const char** attributes) { +static void font_file_element_handler(FamilyData* familyData, const char** attributes) { FontFileInfo& newFileInfo = familyData->fCurrentFamily->fFonts.push_back(); if (attributes) { size_t currentAttributeIndex = 0; @@ -298,7 +298,7 @@ static void fontFileElementHandler(FamilyData* familyData, const char** attribut } } else if (nameLength == 5 && strncmp(attributeName, "index", nameLength) == 0) { int value; - if (parseNonNegativeInteger(attributeValue, &value)) { + if (parse_non_negative_integer(attributeValue, &value)) { newFileInfo.fIndex = value; } else { SkDebugf("---- SystemFonts index=%s (INVALID)", attributeValue); @@ -309,14 +309,14 @@ static void fontFileElementHandler(FamilyData* familyData, const char** attribut } } familyData->fCurrentFontInfo = &newFileInfo; - XML_SetCharacterDataHandler(familyData->fParser, textHandler); + XML_SetCharacterDataHandler(familyData->fParser, text_handler); } /** * Handler for the start of a tag. The only tags we expect are familyset, family, * nameset, fileset, name, and file. */ -static void startElementHandler(void* data, const char* tag, const char** atts) { +static void start_element_handler(void* data, const char* tag, const char** atts) { FamilyData* familyData = (FamilyData*) data; size_t len = strlen(tag); if (len == 9 && strncmp(tag, "familyset", len) == 0) { @@ -327,10 +327,11 @@ static void startElementHandler(void* data, const char* tag, const char** atts) if (nameLen == 7 && strncmp(atts[i], "version", nameLen)) continue; const char* valueString = atts[i+1]; int version; - if (parseNonNegativeInteger(valueString, &version) && (version >= 21)) { + if (parse_non_negative_integer(valueString, &version) && (version >= 21)) { XML_SetElementHandler(familyData->fParser, lmpParser::startElementHandler, lmpParser::endElementHandler); + familyData->fVersion = version; } } } else if (len == 6 && strncmp(tag, "family", len) == 0) { @@ -341,7 +342,7 @@ static void startElementHandler(void* data, const char* tag, const char** atts) atts[i+1] != NULL; i += 2) { const char* valueString = atts[i+1]; int value; - if (parseNonNegativeInteger(valueString, &value)) { + if (parse_non_negative_integer(valueString, &value)) { familyData->fCurrentFamily->fOrder = value; } } @@ -351,10 +352,10 @@ static void startElementHandler(void* data, const char* tag, const char** atts) familyData->fCurrentTag = FILESET_TAG; } else if (len == 4 && strncmp(tag, "name", len) == 0 && familyData->fCurrentTag == NAMESET_TAG) { // If it's a Name, parse the text inside - XML_SetCharacterDataHandler(familyData->fParser, textHandler); + XML_SetCharacterDataHandler(familyData->fParser, text_handler); } else if (len == 4 && strncmp(tag, "file", len) == 0 && familyData->fCurrentTag == FILESET_TAG) { // If it's a file, parse the attributes, then parse the text inside - fontFileElementHandler(familyData, atts); + font_file_element_handler(familyData, atts); } } @@ -362,7 +363,7 @@ static void startElementHandler(void* data, const char* tag, const char** atts) * Handler for the end of tags. We only care about family, nameset, fileset, * name, and file. */ -static void endElementHandler(void* data, const char* tag) { +static void end_element_handler(void* data, const char* tag) { FamilyData* familyData = (FamilyData*) data; size_t len = strlen(tag); if (len == 6 && strncmp(tag, "family", len)== 0) { @@ -387,23 +388,23 @@ static void endElementHandler(void* data, const char* tag) { /** * This function parses the given filename and stores the results in the given - * families array. + * families array. Returns the version of the file, negative if the file does not exist. */ -static void parseConfigFile(const char* filename, SkTDArray<FontFamily*> &families) { +static int parse_config_file(const char* filename, SkTDArray<FontFamily*>& families) { FILE* file = fopen(filename, "r"); // Some of the files we attempt to parse (in particular, /vendor/etc/fallback_fonts.xml) // are optional - failure here is okay because one of these optional files may not exist. if (NULL == file) { - return; + return -1; } XML_Parser parser = XML_ParserCreate(NULL); FamilyData familyData(parser, families); XML_SetUserData(parser, &familyData); // Start parsing oldschool; switch these in flight if we detect a newer version of the file. - XML_SetElementHandler(parser, jbParser::startElementHandler, jbParser::endElementHandler); + XML_SetElementHandler(parser, jbParser::start_element_handler, jbParser::end_element_handler); char buffer[512]; bool done = false; @@ -417,15 +418,17 @@ static void parseConfigFile(const char* filename, SkTDArray<FontFamily*> &famili } XML_ParserFree(parser); fclose(file); + return familyData.fVersion; } -static void getSystemFontFamilies(SkTDArray<FontFamily*> &fontFamilies) { +/** Returns the version of the system font file actually found, negative if none. */ +static int append_system_font_families(SkTDArray<FontFamily*>& fontFamilies) { int initialCount = fontFamilies.count(); - parseConfigFile(LMP_SYSTEM_FONTS_FILE, fontFamilies); - - if (initialCount == fontFamilies.count()) { - parseConfigFile(OLD_SYSTEM_FONTS_FILE, fontFamilies); + int version = parse_config_file(LMP_SYSTEM_FONTS_FILE, fontFamilies); + if (version < 0 || fontFamilies.count() == initialCount) { + version = parse_config_file(OLD_SYSTEM_FONTS_FILE, fontFamilies); } + return version; } /** @@ -435,7 +438,9 @@ static void getSystemFontFamilies(SkTDArray<FontFamily*> &fontFamilies) { * directory for those files,add all of their entries to the fallback chain, and * include the locale as part of each entry. */ -static void getFallbackFontFamiliesForLocale(SkTDArray<FontFamily*> &fallbackFonts, const char* dir) { +static void append_fallback_font_families_for_locale(SkTDArray<FontFamily*>& fallbackFonts, + const char* dir) +{ #if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) // The framework is beyond Android 4.2 and can therefore skip this function return; @@ -465,7 +470,7 @@ static void getFallbackFontFamiliesForLocale(SkTDArray<FontFamily*> &fallbackFon absoluteFilename.printf("%s/%s", dir, fileName.c_str()); SkTDArray<FontFamily*> langSpecificFonts; - parseConfigFile(absoluteFilename.c_str(), langSpecificFonts); + parse_config_file(absoluteFilename.c_str(), langSpecificFonts); for (int i = 0; i < langSpecificFonts.count(); ++i) { FontFamily* family = langSpecificFonts[i]; @@ -482,13 +487,15 @@ static void getFallbackFontFamiliesForLocale(SkTDArray<FontFamily*> &fallbackFon } } -static void getFallbackFontFamilies(SkTDArray<FontFamily*> &fallbackFonts) { - SkTDArray<FontFamily*> vendorFonts; - parseConfigFile(FALLBACK_FONTS_FILE, fallbackFonts); - parseConfigFile(VENDOR_FONTS_FILE, vendorFonts); +static void append_system_fallback_font_families(SkTDArray<FontFamily*>& fallbackFonts) { + parse_config_file(FALLBACK_FONTS_FILE, fallbackFonts); + append_fallback_font_families_for_locale(fallbackFonts, LOCALE_FALLBACK_FONTS_SYSTEM_DIR); +} - getFallbackFontFamiliesForLocale(fallbackFonts, LOCALE_FALLBACK_FONTS_SYSTEM_DIR); - getFallbackFontFamiliesForLocale(vendorFonts, LOCALE_FALLBACK_FONTS_VENDOR_DIR); +static void mixin_vendor_fallback_font_families(SkTDArray<FontFamily*>& fallbackFonts) { + SkTDArray<FontFamily*> vendorFonts; + parse_config_file(VENDOR_FONTS_FILE, vendorFonts); + append_fallback_font_families_for_locale(vendorFonts, LOCALE_FALLBACK_FONTS_VENDOR_DIR); // This loop inserts the vendor fallback fonts in the correct order in the // overall fallbacks list. @@ -518,27 +525,30 @@ static void getFallbackFontFamilies(SkTDArray<FontFamily*> &fallbackFonts) { * Loads data on font families from various expected configuration files. The * resulting data is returned in the given fontFamilies array. */ -void SkFontConfigParser::GetFontFamilies(SkTDArray<FontFamily*> &fontFamilies) { - - getSystemFontFamilies(fontFamilies); +void SkFontConfigParser::GetFontFamilies(SkTDArray<FontFamily*>& fontFamilies) { + // Version 21 of the system font configuration does not need any fallback configuration files. + if (append_system_font_families(fontFamilies) >= 21) { + return; + } // Append all the fallback fonts to system fonts SkTDArray<FontFamily*> fallbackFonts; - getFallbackFontFamilies(fallbackFonts); + append_system_fallback_font_families(fallbackFonts); + mixin_vendor_fallback_font_families(fallbackFonts); for (int i = 0; i < fallbackFonts.count(); ++i) { fallbackFonts[i]->fIsFallbackFont = true; *fontFamilies.append() = fallbackFonts[i]; } } -void SkFontConfigParser::GetTestFontFamilies(SkTDArray<FontFamily*> &fontFamilies, +void SkFontConfigParser::GetTestFontFamilies(SkTDArray<FontFamily*>& fontFamilies, const char* testMainConfigFile, const char* testFallbackConfigFile) { - parseConfigFile(testMainConfigFile, fontFamilies); + parse_config_file(testMainConfigFile, fontFamilies); SkTDArray<FontFamily*> fallbackFonts; if (testFallbackConfigFile) { - parseConfigFile(testFallbackConfigFile, fallbackFonts); + parse_config_file(testFallbackConfigFile, fallbackFonts); } // Append all fallback fonts to system fonts diff --git a/src/ports/SkFontConfigParser_android.h b/src/ports/SkFontConfigParser_android.h index 117a1086fb..5ce53e7777 100644 --- a/src/ports/SkFontConfigParser_android.h +++ b/src/ports/SkFontConfigParser_android.h @@ -94,13 +94,13 @@ namespace SkFontConfigParser { * Parses all system font configuration files and returns the results in an * array of FontFamily structures. */ -void GetFontFamilies(SkTDArray<FontFamily*> &fontFamilies); +void GetFontFamilies(SkTDArray<FontFamily*>& fontFamilies); /** * Parses all test font configuration files and returns the results in an * array of FontFamily structures. */ -void GetTestFontFamilies(SkTDArray<FontFamily*> &fontFamilies, +void GetTestFontFamilies(SkTDArray<FontFamily*>& fontFamilies, const char* testMainConfigFile, const char* testFallbackConfigFile); |