diff options
author | 2012-03-21 15:39:03 +0000 | |
---|---|---|
committer | 2012-03-21 15:39:03 +0000 | |
commit | e63793a2c8d2871bf7d95195be7b93ff669688d7 (patch) | |
tree | 5b3f833f7cbb71470a9e2aba50e8dc7b2078e04b /src/ports | |
parent | 0ffc56f6745e3c5d9a9baa15a3259da5fea0f88a (diff) |
Upstream changes from Android repository.
Review URL: https://codereview.appspot.com/5752055
git-svn-id: http://skia.googlecode.com/svn/trunk@3449 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/ports')
-rw-r--r-- | src/ports/FontHostConfiguration_android.cpp | 90 | ||||
-rw-r--r-- | src/ports/FontHostConfiguration_android.h | 17 | ||||
-rw-r--r-- | src/ports/SkFontHost_android.cpp | 132 |
3 files changed, 222 insertions, 17 deletions
diff --git a/src/ports/FontHostConfiguration_android.cpp b/src/ports/FontHostConfiguration_android.cpp index 475dc4af8b..d1164c800d 100644 --- a/src/ports/FontHostConfiguration_android.cpp +++ b/src/ports/FontHostConfiguration_android.cpp @@ -16,8 +16,12 @@ */ #include "FontHostConfiguration_android.h" -#include <expat.h> +#include "SkString.h" #include "SkTDArray.h" +#include <expat.h> +#if !defined(SK_BUILD_FOR_ANDROID_NDK) + #include <cutils/properties.h> +#endif #define SYSTEM_FONTS_FILE "/system/etc/system_fonts.xml" #define FALLBACK_FONTS_FILE "/system/etc/fallback_fonts.xml" @@ -127,6 +131,65 @@ void endElementHandler(void *data, const char *tag) { } } +#if !defined(SK_BUILD_FOR_ANDROID_NDK) +/** + * Read the persistent locale. + */ +void getLocale(char* language, char* region) +{ + char propLang[PROPERTY_VALUE_MAX], propRegn[PROPERTY_VALUE_MAX]; + + property_get("persist.sys.language", propLang, ""); + property_get("persist.sys.country", propRegn, ""); + if (*propLang == 0 && *propRegn == 0) { + /* Set to ro properties, default is en_US */ + property_get("ro.product.locale.language", propLang, "en"); + property_get("ro.product.locale.region", propRegn, "US"); + } + strncat(language, propLang, 2); + strncat(region, propRegn, 2); +} +#endif + +/** + * Use the current system locale (language and region) to open the best matching + * customization. For example, when the language is Japanese, the sequence might be: + * /system/etc/fallback_fonts-ja-JP.xml + * /system/etc/fallback_fonts-ja.xml + * /system/etc/fallback_fonts.xml + */ +FILE* openLocalizedFile(const char* origname) { + FILE* file = 0; + +#if !defined(SK_BUILD_FOR_ANDROID_NDK) + SkString basename; + SkString filename; + char language[3] = ""; + char region[3] = ""; + + basename.set(origname); + // Remove the .xml suffix. We'll add it back in a moment. + if (basename.endsWith(".xml")) { + basename.resize(basename.size()-4); + } + getLocale(language, region); + // Try first with language and region + filename.printf("%s-%s-%s.xml", basename.c_str(), language, region); + file = fopen(filename.c_str(), "r"); + if (!file) { + // If not found, try next with just language + filename.printf("%s-%s.xml", basename.c_str(), language); + file = fopen(filename.c_str(), "r"); + } +#endif + + if (!file) { + // If still not found, try just the original name + file = fopen(origname, "r"); + } + return file; +} + /** * This function parses the given filename and stores the results in the given * families array. @@ -136,7 +199,7 @@ void parseConfigFile(const char *filename, SkTDArray<FontFamily*> &families) { FamilyData *familyData = new FamilyData(&parser, families); XML_SetUserData(parser, familyData); XML_SetElementHandler(parser, startElementHandler, endElementHandler); - FILE *file = fopen(filename, "r"); + FILE *file = openLocalizedFile(filename); // 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 (file == NULL) { @@ -154,15 +217,12 @@ void parseConfigFile(const char *filename, SkTDArray<FontFamily*> &families) { } } -/** - * Loads data on font families from various expected configuration files. The - * resulting data is returned in the given fontFamilies array. - */ -void getFontFamilies(SkTDArray<FontFamily*> &fontFamilies) { +void getSystemFontFamilies(SkTDArray<FontFamily*> &fontFamilies) { + parseConfigFile(SYSTEM_FONTS_FILE, fontFamilies); +} - SkTDArray<FontFamily*> fallbackFonts; +void getFallbackFontFamilies(SkTDArray<FontFamily*> &fallbackFonts) { SkTDArray<FontFamily*> vendorFonts; - parseConfigFile(SYSTEM_FONTS_FILE, fontFamilies); parseConfigFile(FALLBACK_FONTS_FILE, fallbackFonts); parseConfigFile(VENDOR_FONTS_FILE, vendorFonts); @@ -188,6 +248,18 @@ void getFontFamilies(SkTDArray<FontFamily*> &fontFamilies) { currentOrder = order + 1; } } +} + +/** + * Loads data on font families from various expected configuration files. The + * resulting data is returned in the given fontFamilies array. + */ +void getFontFamilies(SkTDArray<FontFamily*> &fontFamilies) { + SkTDArray<FontFamily*> fallbackFonts; + + getSystemFontFamilies(fontFamilies); + getFallbackFontFamilies(fallbackFonts); + // Append all fallback fonts to system fonts for (int i = 0; i < fallbackFonts.count(); ++i) { *fontFamilies.append() = fallbackFonts[i]; diff --git a/src/ports/FontHostConfiguration_android.h b/src/ports/FontHostConfiguration_android.h index 010f0efc0f..2441f0e436 100644 --- a/src/ports/FontHostConfiguration_android.h +++ b/src/ports/FontHostConfiguration_android.h @@ -39,4 +39,21 @@ struct FontFamily { */ void getFontFamilies(SkTDArray<FontFamily*> &fontFamilies); +/** + * Parse only the core system font configuration file and return the results in + * an array of FontFamily structures. + */ +void getSystemFontFamilies(SkTDArray<FontFamily*> &fontFamilies); + + +/** + * Parse the fallback and vendor system font configuration files and return the + * results in an array of FontFamily structures. + */ +void getFallbackFontFamilies(SkTDArray<FontFamily*> &fallbackFonts); + +#if !defined(SK_BUILD_FOR_ANDROID_NDK) + void getLocale(char* language, char* region); +#endif + #endif /* FONTHOSTCONFIGURATION_ANDROID_H_ */ diff --git a/src/ports/SkFontHost_android.cpp b/src/ports/SkFontHost_android.cpp index 4da17deeb5..edbc0169af 100644 --- a/src/ports/SkFontHost_android.cpp +++ b/src/ports/SkFontHost_android.cpp @@ -16,6 +16,7 @@ */ #include "SkFontHost.h" +#include "SkGraphics.h" #include "SkDescriptor.h" #include "SkMMapStream.h" #include "SkPaint.h" @@ -26,6 +27,7 @@ #include "SkTypeface_android.h" #include "FontHostConfiguration_android.h" #include <stdio.h> +#include <string.h> #define FONT_CACHE_MEMORY_BUDGET (768 * 1024) @@ -73,6 +75,7 @@ static int32_t gUniqueFontID; // this is the mutex that protects gFamilyHead and GetNameList() SK_DECLARE_STATIC_MUTEX(gFamilyHeadAndNameListMutex); static FamilyRec* gFamilyHead; +static SkTDArray<NameFamilyPair> gFallbackFilenameList; static NameFamilyPairList& GetNameList() { /* @@ -265,7 +268,6 @@ public: : SkTypeface(style, sk_atomic_inc(&gUniqueFontID) + 1, isFixedWidth) { fIsSysFont = sysFont; - // our caller has acquired the gFamilyHeadAndNameListMutex so this is safe FamilyRec* rec = NULL; if (familyMember) { @@ -439,8 +441,6 @@ static const struct { static FontInitRec *gSystemFonts; static size_t gNumSystemFonts = 0; -#define SYSTEM_FONTS_FILE "/system/etc/system_fonts.cfg" - // these globals are assigned (once) by load_system_fonts() static FamilyRec* gDefaultFamily; static SkTypeface* gDefaultNormal; @@ -448,10 +448,66 @@ static char** gDefaultNames = NULL; static uint32_t *gFallbackFonts; static uint32_t *gFallbackScriptsMap; +static void dump_globals() { + SkDebugf("gDefaultNormal=%p id=%u refCnt=%d", gDefaultNormal, + gDefaultNormal ? gDefaultNormal->uniqueID() : 0, + gDefaultNormal ? gDefaultNormal->getRefCnt() : 0); + + if (gDefaultFamily) { + SkDebugf("gDefaultFamily=%p fFaces={%u,%u,%u,%u} refCnt={%d,%d,%d,%d}", + gDefaultFamily, + gDefaultFamily->fFaces[0] ? gDefaultFamily->fFaces[0]->uniqueID() : 0, + gDefaultFamily->fFaces[1] ? gDefaultFamily->fFaces[1]->uniqueID() : 0, + gDefaultFamily->fFaces[2] ? gDefaultFamily->fFaces[2]->uniqueID() : 0, + gDefaultFamily->fFaces[3] ? gDefaultFamily->fFaces[3]->uniqueID() : 0, + gDefaultFamily->fFaces[0] ? gDefaultFamily->fFaces[0]->getRefCnt() : 0, + gDefaultFamily->fFaces[1] ? gDefaultFamily->fFaces[1]->getRefCnt() : 0, + gDefaultFamily->fFaces[2] ? gDefaultFamily->fFaces[2]->getRefCnt() : 0, + gDefaultFamily->fFaces[3] ? gDefaultFamily->fFaces[3]->getRefCnt() : 0); + } else { + SkDebugf("gDefaultFamily=%p", gDefaultFamily); + } + + SkDebugf("gNumSystemFonts=%d gSystemFonts=%p gFallbackFonts=%p", + gNumSystemFonts, gSystemFonts, gFallbackFonts); + + for (size_t i = 0; i < gNumSystemFonts; ++i) { + SkDebugf("gSystemFonts[%d] fileName=%s", i, gSystemFonts[i].fFileName); + size_t namesIndex = 0; + if (gSystemFonts[i].fNames) + for (const char* fontName = gSystemFonts[i].fNames[namesIndex]; + fontName != 0; + fontName = gSystemFonts[i].fNames[++namesIndex]) { + SkDebugf(" name[%u]=%s", namesIndex, fontName); + } + } + + if (gFamilyHead) { + FamilyRec* rec = gFamilyHead; + int i=0; + while (rec) { + SkDebugf("gFamilyHead[%d]=%p fFaces={%u,%u,%u,%u} refCnt={%d,%d,%d,%d}", + i++, rec, + rec->fFaces[0] ? rec->fFaces[0]->uniqueID() : 0, + rec->fFaces[1] ? rec->fFaces[1]->uniqueID() : 0, + rec->fFaces[2] ? rec->fFaces[2]->uniqueID() : 0, + rec->fFaces[3] ? rec->fFaces[3]->uniqueID() : 0, + rec->fFaces[0] ? rec->fFaces[0]->getRefCnt() : 0, + rec->fFaces[1] ? rec->fFaces[1]->getRefCnt() : 0, + rec->fFaces[2] ? rec->fFaces[2]->getRefCnt() : 0, + rec->fFaces[3] ? rec->fFaces[3]->getRefCnt() : 0); + rec = rec->fNext; + } + } else { + SkDebugf("gFamilyHead=%p", gFamilyHead); + } + +} + + /* Load info from a configuration file that populates the system/fallback font structures */ static void load_font_info() { -// load_font_info_xml("/system/etc/system_fonts.xml"); SkTDArray<FontFamily*> fontFamilies; getFontFamilies(fontFamilies); @@ -513,9 +569,9 @@ static void load_font_info() { * * gFamilyHeadAndNameListMutex must already be acquired. */ -static void load_system_fonts() { - // check if we've already be called - if (NULL != gDefaultNormal) { +static void init_system_fonts() { + // check if we've already been called + if (gDefaultNormal) { return; } @@ -588,6 +644,65 @@ static void load_system_fonts() { gFallbackFonts[fallbackCount] = 0; } +static size_t find_uniqueID(const char* filename) { + // uniqueID is the index, offset by one, of the associated element in gSystemFonts[] + // return 0 if not found + const FontInitRec* rec = gSystemFonts; + for (size_t i = 0; i < gNumSystemFonts; i++) { + if (strcmp(rec[i].fFileName, filename) == 0) { + return i+1; + } + } + return 0; +} + +static void reload_fallback_fonts() { + SkGraphics::PurgeFontCache(); + + SkTDArray<FontFamily*> fallbackFamilies; + getFallbackFontFamilies(fallbackFamilies); + + for (int i = 0; i < fallbackFamilies.count(); ++i) { + FontFamily *family = fallbackFamilies[i]; + + for (int j = 0; j < family->fFileNames.count(); ++j) { + if (family->fFileNames[j]) { + size_t uniqueID = find_uniqueID(family->fFileNames[j]); + if (uniqueID != gFallbackFonts[i]) + gFallbackFonts[i] = uniqueID; + break; // The fallback set contains only the first font of each family + } + } + } +} + +static void load_system_fonts() { +#if !defined(SK_BUILD_FOR_ANDROID_NDK) + static char prevLanguage[3]; + static char prevRegion[3]; + char language[3] = ""; + char region[3] = ""; + + getLocale(language, region); + + if (!gDefaultNormal) { + strncpy(prevLanguage, language, 2); + strncpy(prevRegion, region, 2); + init_system_fonts(); + } else if (strncmp(language, prevLanguage, 2) || strncmp(region, prevRegion, 2)) { + strncpy(prevLanguage, language, 2); + strncpy(prevRegion, region, 2); + reload_fallback_fonts(); + } +#else + if (!gDefaultNormal) { + init_system_fonts(); + reload_fallback_fonts(); + } +#endif +} + + /////////////////////////////////////////////////////////////////////////////// void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) { @@ -706,7 +821,7 @@ SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace, tf = find_best_face(gDefaultFamily, style); } - // we ref(), since the symantic is to return a new instance + // we ref(), since the semantic is to return a new instance tf->ref(); return tf; } @@ -792,6 +907,7 @@ SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) { SkASSERT(origTypeface != 0); SkASSERT(currTypeface != 0); + SkASSERT(gFallbackFonts); // Our fallback list always stores the id of the plain in each fallback // family, so we transform currFontID to its plain equivalent. |