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

Unified Diff: src/ports/SkFontConfigParser_android.cpp

Issue 439813002: Test and generalize font configuration parser (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Safety tweak to attribute comparisons Created 6 years, 4 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
Index: src/ports/SkFontConfigParser_android.cpp
diff --git a/src/ports/SkFontConfigParser_android.cpp b/src/ports/SkFontConfigParser_android.cpp
index cc2ca8cad92f7fe4fcc7e4e66a0c24833081635a..1ba25f5ac58f4e1a30ed45e6064b9a5901b3db50 100644
--- a/src/ports/SkFontConfigParser_android.cpp
+++ b/src/ports/SkFontConfigParser_android.cpp
@@ -20,6 +20,13 @@
#define FALLBACK_FONTS_FILE "/system/etc/fallback_fonts.xml"
#define VENDOR_FONTS_FILE "/vendor/etc/fallback_fonts.xml"
+/**
+ * This file contains TWO parsers: one for JB and earlier (system_fonts.xml /
+ * fallback_fonts.xml), one for LMP and later (fonts.xml).
+ * We start with the JB parser, and if we detect a <familyset> tag with
+ * version 21 or higher we switch to the LMP parser.
+ */
+
// 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.
@@ -46,6 +53,45 @@ struct FamilyData {
int currentTag; // A flag to indicate whether we're in nameset/fileset tags
};
+/** 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) {
tomhudson 2014/08/04 17:33:48 Moved to start of file so everybody can see it.
+ 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);
+ T n = 0;
+ for (; *s; ++s) {
+ // Check if digit
+ if (*s < '0' || '9' < *s) {
+ return false;
+ }
+ int d = *s - '0';
+ // Check for overflow
+ if (n > nMax || (n == nMax && d > dMax)) {
+ return false;
+ }
+ n = (n * 10) + d;
+ }
+ *value = n;
+ return true;
+}
+
+namespace lmpParser {
tomhudson 2014/08/04 17:33:48 Will fill in with cleaned-up version of prototype
djsollen 2014/08/04 18:13:35 I'm ok with putting both of them in this file for
tomhudson 2014/08/04 21:03:56 Acknowledged.
+
+void startElementHandler(void* data, const char* tag,
+ const char** attributes) {
+ //SkDebugf("lmp started %s", tag);
+}
+
+void endElementHandler(void* data, const char* tag) {
+
+ //SkDebugf("lmp ended %s", tag);
+
+}
+
+} // lmpParser
+
+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.
@@ -61,11 +107,11 @@ static void textHandler(void *data, const char *s, int len) {
familyData->currentFamily->fNames.push_back().set(tolc.lc(), len);
break;
}
- case FILESET_TAG:
+ case FILESET_TAG: {
bungeman-skia 2014/08/04 18:02:12 nit: The extra braces seem extraneous, normally th
tomhudson 2014/08/04 21:03:56 Done.
if (familyData->currentFontInfo) {
familyData->currentFontInfo->fFileName.set(s, len);
}
- break;
+ } break;
default:
// Noop - don't care about any text that's not in the Fonts or Names list
break;
@@ -73,34 +119,11 @@ static void textHandler(void *data, const char *s, int len) {
}
}
-/** 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) {
- 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);
- T n = 0;
- for (; *s; ++s) {
- // Check if digit
- if (*s < '0' || '9' < *s) {
- return false;
- }
- int d = *s - '0';
- // Check for overflow
- if (n > nMax || (n == nMax && d > dMax)) {
- return false;
- }
- n = (n * 10) + d;
- }
- *value = n;
- return true;
-}
-
/**
* 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 = familyData->currentFamily->fFontFiles.push_back();
if (attributes) {
int currentAttributeIndex = 0;
@@ -134,13 +157,27 @@ static void fontFileElementHandler(FamilyData *familyData, const char **attribut
}
/**
- * Handler for the start of a tag. The only tags we expect are family, nameset,
- * fileset, name, and file.
+ * 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) {
FamilyData *familyData = (FamilyData*) data;
int len = strlen(tag);
- if (strncmp(tag, "family", len)== 0) {
+ if (len == 9 && strncmp(tag, "familyset", len) == 0) {
tomhudson 2014/08/04 17:33:48 Note to self: remember to check len explicitly, ot
bungeman-skia 2014/08/04 18:02:12 This is an interesting quirk, in that with strncmp
tomhudson 2014/08/04 18:14:49 The len == MAGIC && !strncmp() pattern was present
+ // The familyset tag has an optional "version" attribute with an integer value >= 0
+ for (int i = 0; atts[i] != NULL; i += 2) {
+ int nameLen = strlen(atts[i]);
+ if (strncmp(atts[i], "version", nameLen)) continue;
bungeman-skia 2014/08/04 18:02:12 Add the 'nameLen = strlen("version")' thing here t
tomhudson 2014/08/04 21:03:56 Done. Added it to every strlen() in the file, inc
+ const char* valueString = atts[i+1];
+ int version;
+ int len = sscanf(valueString, "%d", &version);
bungeman-skia 2014/08/04 18:02:12 It seems you put parseNonNegativeInteger up top in
tomhudson 2014/08/04 18:14:49 qv <family> order=; for some reason the previous v
tomhudson 2014/08/04 21:03:56 Done.
+ if (len > 0 && version >= 21) {
+ XML_SetElementHandler(*familyData->parser,
+ lmpParser::startElementHandler,
+ lmpParser::endElementHandler);
+ }
+ }
+ } else if (len == 6 && strncmp(tag, "family", len) == 0) {
familyData->currentFamily = new FontFamily();
familyData->currentFamily->order = -1;
// The Family tag has an optional "order" attribute with an integer value >= 0
@@ -188,6 +225,8 @@ static void endElementHandler(void *data, const char *tag) {
}
}
+} // namespace jbParser
+
/**
* This function parses the given filename and stores the results in the given
* families array.
@@ -237,7 +276,8 @@ static void parseConfigFile(const char *filename, SkTDArray<FontFamily*> &famili
XML_Parser parser = XML_ParserCreate(NULL);
FamilyData *familyData = new FamilyData(&parser, families);
XML_SetUserData(parser, familyData);
- XML_SetElementHandler(parser, startElementHandler, endElementHandler);
+ // Start parsing oldschool; switch these in flight if we detect a newer version of the file.
+ XML_SetElementHandler(parser, jbParser::startElementHandler, jbParser::endElementHandler);
char buffer[512];
bool done = false;
@@ -309,7 +349,9 @@ void SkFontConfigParser::GetTestFontFamilies(SkTDArray<FontFamily*> &fontFamilie
parseConfigFile(testMainConfigFile, fontFamilies);
SkTDArray<FontFamily*> fallbackFonts;
- parseConfigFile(testFallbackConfigFile, fallbackFonts);
+ if (NULL != testFallbackConfigFile) {
tomhudson 2014/08/04 17:33:48 For v22, we only have one file; instead of adding
djsollen 2014/08/04 18:13:35 Acknowledged.
+ parseConfigFile(testFallbackConfigFile, fallbackFonts);
+ }
// Append all fallback fonts to system fonts
for (int i = 0; i < fallbackFonts.count(); ++i) {

Powered by Google App Engine
This is Rietveld 408576698