| Index: src/ports/SkFontConfigParser_android.cpp
|
| diff --git a/src/ports/SkFontConfigParser_android.cpp b/src/ports/SkFontConfigParser_android.cpp
|
| index d1169b99fb60759b5ecfedf8e224f2085fbaea82..10212e8a07e7fdc420da6c51d4fe5c2a2812fffc 100644
|
| --- a/src/ports/SkFontConfigParser_android.cpp
|
| +++ b/src/ports/SkFontConfigParser_android.cpp
|
| @@ -11,8 +11,8 @@
|
| #include "SkTypeface.h"
|
|
|
| #include <expat.h>
|
| +#include <dirent.h>
|
| #include <stdio.h>
|
| -#include <sys/system_properties.h>
|
|
|
| #include <limits>
|
|
|
| @@ -20,6 +20,11 @@
|
| #define FALLBACK_FONTS_FILE "/system/etc/fallback_fonts.xml"
|
| #define VENDOR_FONTS_FILE "/vendor/etc/fallback_fonts.xml"
|
|
|
| +#define LOCALE_FALLBACK_FONTS_SYSTEM_DIR "/system/etc"
|
| +#define LOCALE_FALLBACK_FONTS_VENDOR_DIR "/vendor/etc"
|
| +#define LOCALE_FALLBACK_FONTS_PREFIX "fallback_fonts-"
|
| +#define LOCALE_FALLBACK_FONTS_SUFFIX ".xml"
|
| +
|
| /**
|
| * This file contains TWO parsers: one for JB and earlier (system_fonts.xml /
|
| * fallback_fonts.xml), one for LMP and later (fonts.xml).
|
| @@ -411,39 +416,7 @@ static void endElementHandler(void *data, const char *tag) {
|
| */
|
| static void parseConfigFile(const char *filename, SkTDArray<FontFamily*> &families) {
|
|
|
| - FILE* file = NULL;
|
| -
|
| -#if !defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
|
| - // if we are using a version of Android prior to Android 4.2 (JellyBean MR1
|
| - // at API Level 17) then we need to look for files with a different suffix.
|
| - char sdkVersion[PROP_VALUE_MAX];
|
| - __system_property_get("ro.build.version.sdk", sdkVersion);
|
| - const int sdkVersionInt = atoi(sdkVersion);
|
| -
|
| - if (0 != *sdkVersion && sdkVersionInt < 17) {
|
| - SkString basename;
|
| - SkString updatedFilename;
|
| - SkString locale = SkFontConfigParser::GetLocale();
|
| -
|
| - basename.set(filename);
|
| - // Remove the .xml suffix. We'll add it back in a moment.
|
| - if (basename.endsWith(".xml")) {
|
| - basename.resize(basename.size()-4);
|
| - }
|
| - // Try first with language and region
|
| - updatedFilename.printf("%s-%s.xml", basename.c_str(), locale.c_str());
|
| - file = fopen(updatedFilename.c_str(), "r");
|
| - if (!file) {
|
| - // If not found, try next with just language
|
| - updatedFilename.printf("%s-%.2s.xml", basename.c_str(), locale.c_str());
|
| - file = fopen(updatedFilename.c_str(), "r");
|
| - }
|
| - }
|
| -#endif
|
| -
|
| - if (NULL == file) {
|
| - file = fopen(filename, "r");
|
| - }
|
| + 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.
|
| @@ -475,11 +448,70 @@ static void getSystemFontFamilies(SkTDArray<FontFamily*> &fontFamilies) {
|
| parseConfigFile(SYSTEM_FONTS_FILE, fontFamilies);
|
| }
|
|
|
| +/**
|
| + * In some versions of Android prior to Android 4.2 (JellyBean MR1 at API
|
| + * Level 17) the fallback fonts for certain locales were encoded in their own
|
| + * XML files with a suffix that identified the locale. We search the provided
|
| + * 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) {
|
| +#if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
|
| + // The framework is beyond Android 4.2 and can therefore skip this function
|
| + return;
|
| +#endif
|
| +
|
| + DIR* fontDirectory = opendir(dir);
|
| + if (fontDirectory != NULL){
|
| + struct dirent* dirEntry = readdir(fontDirectory);
|
| + while (dirEntry) {
|
| +
|
| + // The size of both the prefix, suffix, and a minimum valid language code
|
| + static const int minSize = strlen(LOCALE_FALLBACK_FONTS_PREFIX) +
|
| + strlen(LOCALE_FALLBACK_FONTS_SUFFIX) + 2;
|
| +
|
| + SkString fileName(dirEntry->d_name);
|
| + if (fileName.size() >= minSize &&
|
| + fileName.startsWith(LOCALE_FALLBACK_FONTS_PREFIX) &&
|
| + fileName.endsWith(LOCALE_FALLBACK_FONTS_SUFFIX)) {
|
| +
|
| + static const int fixedLen = strlen(LOCALE_FALLBACK_FONTS_PREFIX) -
|
| + strlen(LOCALE_FALLBACK_FONTS_SUFFIX);
|
| +
|
| + SkString locale(fileName.c_str() - strlen(LOCALE_FALLBACK_FONTS_PREFIX),
|
| + fileName.size() - fixedLen);
|
| +
|
| + SkString absoluteFilename;
|
| + absoluteFilename.printf("%s/%s", dir, fileName.c_str());
|
| +
|
| + SkTDArray<FontFamily*> langSpecificFonts;
|
| + parseConfigFile(absoluteFilename.c_str(), langSpecificFonts);
|
| +
|
| + for (int i = 0; i < langSpecificFonts.count(); ++i) {
|
| + FontFamily* family = langSpecificFonts[i];
|
| + for (int j = 0; j < family->fFontFiles.count(); ++j) {
|
| + family->fFontFiles[j].fPaintOptions.setLanguage(locale);
|
| + }
|
| + *fallbackFonts.append() = family;
|
| + }
|
| + }
|
| +
|
| + // proceed to the next entry in the directory
|
| + dirEntry = readdir(fontDirectory);
|
| + }
|
| + // cleanup the directory reference
|
| + closedir(fontDirectory);
|
| + }
|
| +}
|
| +
|
| static void getFallbackFontFamilies(SkTDArray<FontFamily*> &fallbackFonts) {
|
| SkTDArray<FontFamily*> vendorFonts;
|
| parseConfigFile(FALLBACK_FONTS_FILE, fallbackFonts);
|
| parseConfigFile(VENDOR_FONTS_FILE, vendorFonts);
|
|
|
| + getFallbackFontFamiliesForLocale(fallbackFonts, LOCALE_FALLBACK_FONTS_SYSTEM_DIR);
|
| + getFallbackFontFamiliesForLocale(vendorFonts, LOCALE_FALLBACK_FONTS_VENDOR_DIR);
|
| +
|
| // This loop inserts the vendor fallback fonts in the correct order in the
|
| // overall fallbacks list.
|
| int currentOrder = -1;
|
| @@ -537,33 +569,3 @@ void SkFontConfigParser::GetTestFontFamilies(SkTDArray<FontFamily*> &fontFamilie
|
| *fontFamilies.append() = fallbackFonts[i];
|
| }
|
| }
|
| -
|
| -/**
|
| - * Read the persistent locale.
|
| - */
|
| -SkString SkFontConfigParser::GetLocale()
|
| -{
|
| - char propLang[PROP_VALUE_MAX], propRegn[PROP_VALUE_MAX];
|
| - __system_property_get("persist.sys.language", propLang);
|
| - __system_property_get("persist.sys.country", propRegn);
|
| -
|
| - if (*propLang == 0 && *propRegn == 0) {
|
| - /* Set to ro properties, default is en_US */
|
| - __system_property_get("ro.product.locale.language", propLang);
|
| - __system_property_get("ro.product.locale.region", propRegn);
|
| - if (*propLang == 0 && *propRegn == 0) {
|
| - strcpy(propLang, "en");
|
| - strcpy(propRegn, "US");
|
| - }
|
| - }
|
| -
|
| - SkString locale(6);
|
| - char* localeCStr = locale.writable_str();
|
| -
|
| - strncpy(localeCStr, propLang, 2);
|
| - localeCStr[2] = '-';
|
| - strncpy(&localeCStr[3], propRegn, 2);
|
| - localeCStr[5] = '\0';
|
| -
|
| - return locale;
|
| -}
|
|
|