Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(677)

Unified Diff: src/ports/SkFontConfigParser_android.cpp

Issue 14731025: Add a fontConfig interface for android. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: rebasing Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ports/SkFontConfigParser_android.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ports/SkFontConfigParser_android.cpp
diff --git a/src/ports/FontHostConfiguration_android.cpp b/src/ports/SkFontConfigParser_android.cpp
similarity index 64%
copy from src/ports/FontHostConfiguration_android.cpp
copy to src/ports/SkFontConfigParser_android.cpp
index ef5a742a18ab90eb22108be000d3d2641f1fef36..9214d1bf61484e8addc8198ca4753d840c61c234 100644
--- a/src/ports/FontHostConfiguration_android.cpp
+++ b/src/ports/SkFontConfigParser_android.cpp
@@ -5,9 +5,10 @@
* found in the LICENSE file.
*/
-#include "FontHostConfiguration_android.h"
-#include "SkString.h"
+#include "SkFontConfigParser_android.h"
#include "SkTDArray.h"
+#include "SkTypeface.h"
+
#include <expat.h>
#include <sys/system_properties.h>
@@ -15,7 +16,6 @@
#define FALLBACK_FONTS_FILE "/system/etc/fallback_fonts.xml"
#define VENDOR_FONTS_FILE "/vendor/etc/fallback_fonts.xml"
-
// These defines are used to determine the kind of tag that we're currently
// populating with data. We only care about the sibling tags nameset and fileset
// for now.
@@ -28,24 +28,25 @@
* can read these variables that are relevant to the current parsing.
*/
struct FamilyData {
- FamilyData(XML_Parser *parserRef, SkTDArray<FontFamily*> &familiesRef, const AndroidLocale &localeRef) :
- parser(parserRef), families(familiesRef), currentTag(NO_TAG),
- locale(localeRef), currentFamilyLangMatch(false), familyLangMatchCount(0) {}
+ FamilyData(XML_Parser *parserRef, SkTDArray<FontFamily*> &familiesRef) :
+ parser(parserRef),
+ families(familiesRef),
+ currentFamily(NULL),
+ currentFontInfo(NULL),
+ currentTag(NO_TAG) {};
XML_Parser *parser; // The expat parser doing the work
SkTDArray<FontFamily*> &families; // The array that each family is put into as it is parsed
FontFamily *currentFamily; // The current family being created
+ FontFileInfo *currentFontInfo; // The current fontInfo being created
int currentTag; // A flag to indicate whether we're in nameset/fileset tags
- const AndroidLocale &locale; // The locale to which we compare the "lang" attribute of File.
- bool currentFamilyLangMatch; // If currentFamily's File has a "lang" attribute and matches locale.
- int familyLangMatchCount; // Number of families containing File which has a "lang" attribute and matches locale.
};
/**
* 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 fFileNames arrays.
+ * or file tag. The resulting strings are put into the fNames or FontFileInfo arrays.
*/
-void textHandler(void *data, const char *s, int len) {
+static void textHandler(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->currentFamily &&
@@ -60,7 +61,9 @@ void textHandler(void *data, const char *s, int len) {
*(familyData->currentFamily->fNames.append()) = buff;
break;
case FILESET_TAG:
- *(familyData->currentFamily->fFileNames.append()) = buff;
+ if (familyData->currentFontInfo) {
+ familyData->currentFontInfo->fFileName = buff;
+ }
break;
default:
// Noop - don't care about any text that's not in the Fonts or Names list
@@ -70,10 +73,41 @@ 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) {
+ FontFileInfo* newFileInfo = new FontFileInfo();
+ if (attributes) {
+ int currentAttributeIndex = 0;
+ while (attributes[currentAttributeIndex]) {
+ const char* attributeName = attributes[currentAttributeIndex];
+ const char* attributeValue = attributes[currentAttributeIndex+1];
+ int nameLength = strlen(attributeName);
+ int valueLength = strlen(attributeValue);
+ if (strncmp(attributeName, "variant", nameLength) == 0) {
+ if (strncmp(attributeValue, "elegant", valueLength) == 0) {
+ newFileInfo->fPaintOptions.setFontVariant(SkPaintOptionsAndroid::kElegant_Variant);
+ } else if (strncmp(attributeValue, "compact", valueLength) == 0) {
+ newFileInfo->fPaintOptions.setFontVariant(SkPaintOptionsAndroid::kCompact_Variant);
+ }
+ } else if (strncmp(attributeName, "lang", nameLength) == 0) {
+ newFileInfo->fPaintOptions.setLanguage(attributeValue);
+ }
+ //each element is a pair of attributeName/attributeValue string pairs
+ currentAttributeIndex += 2;
+ }
+ }
+ *(familyData->currentFamily->fFontFiles.append()) = newFileInfo;
+ familyData->currentFontInfo = newFileInfo;
+ XML_SetCharacterDataHandler(*familyData->parser, textHandler);
+}
+
+/**
* Handler for the start of a tag. The only tags we expect are family, nameset,
* fileset, name, and file.
*/
-void startElementHandler(void *data, const char *tag, const char **atts) {
+static void startElementHandler(void *data, const char *tag, const char **atts) {
FamilyData *familyData = (FamilyData*) data;
int len = strlen(tag);
if (strncmp(tag, "family", len)== 0) {
@@ -89,32 +123,16 @@ void startElementHandler(void *data, const char *tag, const char **atts) {
familyData->currentFamily->order = value;
}
}
- } else if (len == 7 && strncmp(tag, "nameset", len)== 0) {
+ } else if (len == 7 && strncmp(tag, "nameset", len) == 0) {
familyData->currentTag = NAMESET_TAG;
} else if (len == 7 && strncmp(tag, "fileset", len) == 0) {
familyData->currentTag = FILESET_TAG;
} else if (strncmp(tag, "name", len) == 0 && familyData->currentTag == NAMESET_TAG) {
+ // If it's a Name, parse the text inside
XML_SetCharacterDataHandler(*familyData->parser, textHandler);
} else if (strncmp(tag, "file", len) == 0 && familyData->currentTag == FILESET_TAG) {
- // From JB MR1, the File tag has a "lang" attribute to specify a language specific font file
- // and the family entry has higher priority than the others without "lang" attribute.
- bool includeTheEntry = true;
- for (int i = 0; atts[i] != NULL; i += 2) {
- const char* attribute = atts[i];
- const char* value = atts[i+1];
- if (strncmp(attribute, "lang", 4) == 0) {
- if (strcmp(value, familyData->locale.language) == 0) {
- // Found matching "lang" attribute. The current Family will have higher priority in the family list.
- familyData->currentFamilyLangMatch = true;
- } else {
- // Don't include the entry if "lang" is specified but not matching.
- includeTheEntry = false;
- }
- }
- }
- if (includeTheEntry) {
- XML_SetCharacterDataHandler(*familyData->parser, textHandler);
- }
+ // If it's a file, parse the attributes, then parse the text inside
+ fontFileElementHandler(familyData, atts);
}
}
@@ -122,21 +140,16 @@ 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.
*/
-void endElementHandler(void *data, const char *tag) {
+static void endElementHandler(void *data, const char *tag) {
FamilyData *familyData = (FamilyData*) data;
int len = strlen(tag);
if (strncmp(tag, "family", len)== 0) {
// Done parsing a Family - store the created currentFamily in the families array
- if (familyData->currentFamilyLangMatch) {
- *familyData->families.insert(familyData->familyLangMatchCount++) = familyData->currentFamily;
- familyData->currentFamilyLangMatch = false;
- } else {
- *familyData->families.append() = familyData->currentFamily;
- }
+ *familyData->families.append() = familyData->currentFamily;
familyData->currentFamily = NULL;
- } else if (len == 7 && strncmp(tag, "nameset", len)== 0) {
+ } else if (len == 7 && strncmp(tag, "nameset", len) == 0) {
familyData->currentTag = NO_TAG;
- } else if (len == 7 && strncmp(tag, "fileset", len)== 0) {
+ } else if (len == 7 && strncmp(tag, "fileset", len) == 0) {
familyData->currentTag = NO_TAG;
} else if ((strncmp(tag, "name", len) == 0 && familyData->currentTag == NAMESET_TAG) ||
(strncmp(tag, "file", len) == 0 && familyData->currentTag == FILESET_TAG)) {
@@ -146,74 +159,15 @@ void endElementHandler(void *data, const char *tag) {
}
/**
- * Read the persistent locale.
- */
-void getLocale(AndroidLocale &locale)
-{
- 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");
- }
- }
- strncpy(locale.language, propLang, 2);
- locale.language[2] = '\0';
- strncpy(locale.region, propRegn, 2);
- locale.region[2] = '\0';
-}
-
-/**
- * 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, const AndroidLocale& locale) {
- FILE* file = 0;
- SkString basename;
- SkString filename;
-
- basename.set(origname);
- // 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
- filename.printf("%s-%s-%s.xml", basename.c_str(), locale.language, locale.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(), locale.language);
- file = fopen(filename.c_str(), "r");
-
- 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.
*/
-void parseConfigFile(const char *filename, SkTDArray<FontFamily*> &families) {
- AndroidLocale locale;
- getLocale(locale);
+static void parseConfigFile(const char *filename, SkTDArray<FontFamily*> &families) {
XML_Parser parser = XML_ParserCreate(NULL);
- FamilyData familyData(&parser, families, locale);
- XML_SetUserData(parser, &familyData);
+ FamilyData *familyData = new FamilyData(&parser, families);
+ XML_SetUserData(parser, familyData);
XML_SetElementHandler(parser, startElementHandler, endElementHandler);
- FILE *file = openLocalizedFile(filename, locale);
+ 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 (file == NULL) {
@@ -230,14 +184,13 @@ void parseConfigFile(const char *filename, SkTDArray<FontFamily*> &families) {
XML_Parse(parser, buffer, len, done);
}
fclose(file);
- XML_ParserFree(parser);
}
-void getSystemFontFamilies(SkTDArray<FontFamily*> &fontFamilies) {
+static void getSystemFontFamilies(SkTDArray<FontFamily*> &fontFamilies) {
parseConfigFile(SYSTEM_FONTS_FILE, fontFamilies);
}
-void getFallbackFontFamilies(SkTDArray<FontFamily*> &fallbackFonts) {
+static void getFallbackFontFamilies(SkTDArray<FontFamily*> &fallbackFonts) {
SkTDArray<FontFamily*> vendorFonts;
parseConfigFile(FALLBACK_FONTS_FILE, fallbackFonts);
parseConfigFile(VENDOR_FONTS_FILE, vendorFonts);
@@ -270,21 +223,22 @@ 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 getFontFamilies(SkTDArray<FontFamily*> &fontFamilies) {
- SkTDArray<FontFamily*> fallbackFonts;
+void SkFontConfigParser::GetFontFamilies(SkTDArray<FontFamily*> &fontFamilies) {
getSystemFontFamilies(fontFamilies);
- getFallbackFontFamilies(fallbackFonts);
- // Append all fallback fonts to system fonts
+ // Append all the fallback fonts to system fonts
+ SkTDArray<FontFamily*> fallbackFonts;
+ getFallbackFontFamilies(fallbackFonts);
for (int i = 0; i < fallbackFonts.count(); ++i) {
+ fallbackFonts[i]->fIsFallbackFont = true;
*fontFamilies.append() = fallbackFonts[i];
}
}
-void getTestFontFamilies(SkTDArray<FontFamily*> &fontFamilies,
- const char* testMainConfigFile,
- const char* testFallbackConfigFile) {
+void SkFontConfigParser::GetTestFontFamilies(SkTDArray<FontFamily*> &fontFamilies,
+ const char* testMainConfigFile,
+ const char* testFallbackConfigFile) {
parseConfigFile(testMainConfigFile, fontFamilies);
SkTDArray<FontFamily*> fallbackFonts;
@@ -292,6 +246,31 @@ void getTestFontFamilies(SkTDArray<FontFamily*> &fontFamilies,
// Append all fallback fonts to system fonts
for (int i = 0; i < fallbackFonts.count(); ++i) {
+ fallbackFonts[i]->fIsFallbackFont = true;
*fontFamilies.append() = fallbackFonts[i];
}
}
+
+/**
+ * Read the persistent locale.
+ */
+void SkFontConfigParser::GetLocale(AndroidLocale &locale)
+{
+ 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");
+ }
+ }
+ strncpy(locale.language, propLang, 2);
+ locale.language[2] = '\0';
+ strncpy(locale.region, propRegn, 2);
+ locale.region[2] = '\0';
+}
« no previous file with comments | « src/ports/SkFontConfigParser_android.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698