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

Side by Side Diff: src/ports/SkFontConfigParser_android.cpp

Issue 880783003: Do not add indirection to XML_Parser. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Build locally after rebasing all the changes. Created 5 years, 10 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2011 The Android Open Source Project 2 * Copyright 2011 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkFontConfigParser_android.h" 8 #include "SkFontConfigParser_android.h"
9 #include "SkTDArray.h" 9 #include "SkTDArray.h"
10 #include "SkTSearch.h" 10 #include "SkTSearch.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 // for now. 44 // for now.
45 #define NO_TAG 0 45 #define NO_TAG 0
46 #define NAMESET_TAG 1 46 #define NAMESET_TAG 1
47 #define FILESET_TAG 2 47 #define FILESET_TAG 2
48 48
49 /** 49 /**
50 * The FamilyData structure is passed around by the parser so that each handler 50 * The FamilyData structure is passed around by the parser so that each handler
51 * can read these variables that are relevant to the current parsing. 51 * can read these variables that are relevant to the current parsing.
52 */ 52 */
53 struct FamilyData { 53 struct FamilyData {
54 FamilyData(XML_Parser* parserRef, SkTDArray<FontFamily*> &familiesRef) : 54 FamilyData(XML_Parser parserRef, SkTDArray<FontFamily*> &familiesRef) :
55 parser(parserRef), 55 parser(parserRef),
56 families(familiesRef), 56 families(familiesRef),
57 currentFamily(NULL), 57 currentFamily(NULL),
58 currentFontInfo(NULL), 58 currentFontInfo(NULL),
59 currentTag(NO_TAG) {}; 59 currentTag(NO_TAG) {};
60 60
61 XML_Parser* parser; // The expat parser doing the work 61 XML_Parser parser; // The expat parser doing the work, owned by caller
62 SkTDArray<FontFamily*> &families; // The array that each family is put into as it is parsed 62 SkTDArray<FontFamily*>& families; // The array to append families, owned by caller
63 FontFamily* currentFamily; // The current family being created 63 FontFamily* currentFamily; // The current family being created, owne d by this
64 FontFileInfo* currentFontInfo; // The current fontInfo being created 64 FontFileInfo* currentFontInfo; // The current fontInfo being created, ow ned by currentFamily
65 int currentTag; // A flag to indicate whether we're in na meset/fileset tags 65 int currentTag; // A flag to indicate whether we're in na meset/fileset tags
66 }; 66 };
67 67
68 /** http://www.w3.org/TR/html-markup/datatypes.html#common.data.integer.non-nega tive-def */ 68 /** http://www.w3.org/TR/html-markup/datatypes.html#common.data.integer.non-nega tive-def */
69 template <typename T> static bool parseNonNegativeInteger(const char* s, T* valu e) { 69 template <typename T> static bool parseNonNegativeInteger(const char* s, T* valu e) {
70 SK_COMPILE_ASSERT(std::numeric_limits<T>::is_integer, T_must_be_integer); 70 SK_COMPILE_ASSERT(std::numeric_limits<T>::is_integer, T_must_be_integer);
71 const T nMax = std::numeric_limits<T>::max() / 10; 71 const T nMax = std::numeric_limits<T>::max() / 10;
72 const T dMax = std::numeric_limits<T>::max() - (nMax * 10); 72 const T dMax = std::numeric_limits<T>::max() - (nMax * 10);
73 T n = 0; 73 T n = 0;
74 for (; *s; ++s) { 74 for (; *s; ++s) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 } 115 }
116 } 116 }
117 } 117 }
118 } 118 }
119 119
120 void fontFileNameHandler(void* data, const char* s, int len) { 120 void fontFileNameHandler(void* data, const char* s, int len) {
121 FamilyData* familyData = (FamilyData*) data; 121 FamilyData* familyData = (FamilyData*) data;
122 familyData->currentFontInfo->fFileName.set(s, len); 122 familyData->currentFontInfo->fFileName.set(s, len);
123 } 123 }
124 124
125 void fontElementHandler(XML_Parser* parser, FontFileInfo* file, const char** att ributes) { 125 void fontElementHandler(XML_Parser parser, FontFileInfo* file, const char** attr ibutes) {
126 // A <font> should have weight (integer) and style (normal, italic) attribut es. 126 // A <font> should have weight (integer) and style (normal, italic) attribut es.
127 // NOTE: we ignore the style. 127 // NOTE: we ignore the style.
128 // The element should contain a filename. 128 // The element should contain a filename.
129 for (size_t i = 0; attributes[i] != NULL && 129 for (size_t i = 0; attributes[i] != NULL &&
130 attributes[i+1] != NULL; i += 2) { 130 attributes[i+1] != NULL; i += 2) {
131 const char* name = attributes[i]; 131 const char* name = attributes[i];
132 const char* value = attributes[i+1]; 132 const char* value = attributes[i+1];
133 size_t nameLen = strlen(name); 133 size_t nameLen = strlen(name);
134 if (nameLen == 6 && !strncmp("weight", name, nameLen)) { 134 if (nameLen == 6 && !strncmp("weight", name, nameLen)) {
135 if (!parseNonNegativeInteger(value, &file->fWeight)) { 135 if (!parseNonNegativeInteger(value, &file->fWeight)) {
136 SkDebugf("---- Font weight %s (INVALID)", value); 136 SkDebugf("---- Font weight %s (INVALID)", value);
137 file->fWeight = 0; 137 file->fWeight = 0;
138 } 138 }
139 } 139 }
140 } 140 }
141 XML_SetCharacterDataHandler(*parser, fontFileNameHandler); 141 XML_SetCharacterDataHandler(parser, fontFileNameHandler);
142 } 142 }
143 143
144 FontFamily* findFamily(FamilyData* familyData, const char* familyName) { 144 FontFamily* findFamily(FamilyData* familyData, const char* familyName) {
145 size_t nameLen = strlen(familyName); 145 size_t nameLen = strlen(familyName);
146 for (int i = 0; i < familyData->families.count(); i++) { 146 for (int i = 0; i < familyData->families.count(); i++) {
147 FontFamily* candidate = familyData->families[i]; 147 FontFamily* candidate = familyData->families[i];
148 for (int j = 0; j < candidate->fNames.count(); j++) { 148 for (int j = 0; j < candidate->fNames.count(); j++) {
149 if (!strncmp(candidate->fNames[j].c_str(), familyName, nameLen) && 149 if (!strncmp(candidate->fNames[j].c_str(), familyName, nameLen) &&
150 nameLen == strlen(candidate->fNames[j].c_str())) { 150 nameLen == strlen(candidate->fNames[j].c_str())) {
151 return candidate; 151 return candidate;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 } 218 }
219 } 219 }
220 220
221 void endElementHandler(void* data, const char* tag) { 221 void endElementHandler(void* data, const char* tag) {
222 FamilyData* familyData = (FamilyData*) data; 222 FamilyData* familyData = (FamilyData*) data;
223 size_t len = strlen(tag); 223 size_t len = strlen(tag);
224 if (len == 6 && strncmp(tag, "family", len) == 0) { 224 if (len == 6 && strncmp(tag, "family", len) == 0) {
225 *familyData->families.append() = familyData->currentFamily; 225 *familyData->families.append() = familyData->currentFamily;
226 familyData->currentFamily = NULL; 226 familyData->currentFamily = NULL;
227 } else if (len == 4 && !strncmp(tag, "font", len)) { 227 } else if (len == 4 && !strncmp(tag, "font", len)) {
228 XML_SetCharacterDataHandler(*familyData->parser, NULL); 228 XML_SetCharacterDataHandler(familyData->parser, NULL);
229 } 229 }
230 } 230 }
231 231
232 } // lmpParser 232 } // lmpParser
233 233
234 namespace jbParser { 234 namespace jbParser {
235 235
236 /** 236 /**
237 * Handler for arbitrary text. This is used to parse the text inside each name 237 * Handler for arbitrary text. This is used to parse the text inside each name
238 * or file tag. The resulting strings are put into the fNames or FontFileInfo ar rays. 238 * or file tag. The resulting strings are put into the fNames or FontFileInfo ar rays.
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 newFileInfo.fIndex = value; 302 newFileInfo.fIndex = value;
303 } else { 303 } else {
304 SkDebugf("---- SystemFonts index=%s (INVALID)", attributeVal ue); 304 SkDebugf("---- SystemFonts index=%s (INVALID)", attributeVal ue);
305 } 305 }
306 } 306 }
307 //each element is a pair of attributeName/attributeValue string pair s 307 //each element is a pair of attributeName/attributeValue string pair s
308 currentAttributeIndex += 2; 308 currentAttributeIndex += 2;
309 } 309 }
310 } 310 }
311 familyData->currentFontInfo = &newFileInfo; 311 familyData->currentFontInfo = &newFileInfo;
312 XML_SetCharacterDataHandler(*familyData->parser, textHandler); 312 XML_SetCharacterDataHandler(familyData->parser, textHandler);
313 } 313 }
314 314
315 /** 315 /**
316 * Handler for the start of a tag. The only tags we expect are familyset, family , 316 * Handler for the start of a tag. The only tags we expect are familyset, family ,
317 * nameset, fileset, name, and file. 317 * nameset, fileset, name, and file.
318 */ 318 */
319 static void startElementHandler(void* data, const char* tag, const char** atts) { 319 static void startElementHandler(void* data, const char* tag, const char** atts) {
320 FamilyData* familyData = (FamilyData*) data; 320 FamilyData* familyData = (FamilyData*) data;
321 size_t len = strlen(tag); 321 size_t len = strlen(tag);
322 if (len == 9 && strncmp(tag, "familyset", len) == 0) { 322 if (len == 9 && strncmp(tag, "familyset", len) == 0) {
323 // The familyset tag has an optional "version" attribute with an integer value >= 0 323 // The familyset tag has an optional "version" attribute with an integer value >= 0
324 for (size_t i = 0; atts[i] != NULL && 324 for (size_t i = 0; atts[i] != NULL &&
325 atts[i+1] != NULL; i += 2) { 325 atts[i+1] != NULL; i += 2) {
326 size_t nameLen = strlen(atts[i]); 326 size_t nameLen = strlen(atts[i]);
327 if (nameLen == 7 && strncmp(atts[i], "version", nameLen)) continue; 327 if (nameLen == 7 && strncmp(atts[i], "version", nameLen)) continue;
328 const char* valueString = atts[i+1]; 328 const char* valueString = atts[i+1];
329 int version; 329 int version;
330 if (parseNonNegativeInteger(valueString, &version) && (version >= 21 )) { 330 if (parseNonNegativeInteger(valueString, &version) && (version >= 21 )) {
331 XML_SetElementHandler(*familyData->parser, 331 XML_SetElementHandler(familyData->parser,
332 lmpParser::startElementHandler, 332 lmpParser::startElementHandler,
333 lmpParser::endElementHandler); 333 lmpParser::endElementHandler);
334 } 334 }
335 } 335 }
336 } else if (len == 6 && strncmp(tag, "family", len) == 0) { 336 } else if (len == 6 && strncmp(tag, "family", len) == 0) {
337 familyData->currentFamily = new FontFamily(); 337 familyData->currentFamily = new FontFamily();
338 // The Family tag has an optional "order" attribute with an integer valu e >= 0 338 // The Family tag has an optional "order" attribute with an integer valu e >= 0
339 // If this attribute does not exist, the default value is -1 339 // If this attribute does not exist, the default value is -1
340 for (size_t i = 0; atts[i] != NULL && 340 for (size_t i = 0; atts[i] != NULL &&
341 atts[i+1] != NULL; i += 2) { 341 atts[i+1] != NULL; i += 2) {
342 const char* valueString = atts[i+1]; 342 const char* valueString = atts[i+1];
343 int value; 343 int value;
344 if (parseNonNegativeInteger(valueString, &value)) { 344 if (parseNonNegativeInteger(valueString, &value)) {
345 familyData->currentFamily->fOrder = value; 345 familyData->currentFamily->fOrder = value;
346 } 346 }
347 } 347 }
348 } else if (len == 7 && strncmp(tag, "nameset", len) == 0) { 348 } else if (len == 7 && strncmp(tag, "nameset", len) == 0) {
349 familyData->currentTag = NAMESET_TAG; 349 familyData->currentTag = NAMESET_TAG;
350 } else if (len == 7 && strncmp(tag, "fileset", len) == 0) { 350 } else if (len == 7 && strncmp(tag, "fileset", len) == 0) {
351 familyData->currentTag = FILESET_TAG; 351 familyData->currentTag = FILESET_TAG;
352 } else if (len == 4 && strncmp(tag, "name", len) == 0 && familyData->current Tag == NAMESET_TAG) { 352 } else if (len == 4 && strncmp(tag, "name", len) == 0 && familyData->current Tag == NAMESET_TAG) {
353 // If it's a Name, parse the text inside 353 // If it's a Name, parse the text inside
354 XML_SetCharacterDataHandler(*familyData->parser, textHandler); 354 XML_SetCharacterDataHandler(familyData->parser, textHandler);
355 } else if (len == 4 && strncmp(tag, "file", len) == 0 && familyData->current Tag == FILESET_TAG) { 355 } else if (len == 4 && strncmp(tag, "file", len) == 0 && familyData->current Tag == FILESET_TAG) {
356 // If it's a file, parse the attributes, then parse the text inside 356 // If it's a file, parse the attributes, then parse the text inside
357 fontFileElementHandler(familyData, atts); 357 fontFileElementHandler(familyData, atts);
358 } 358 }
359 } 359 }
360 360
361 /** 361 /**
362 * Handler for the end of tags. We only care about family, nameset, fileset, 362 * Handler for the end of tags. We only care about family, nameset, fileset,
363 * name, and file. 363 * name, and file.
364 */ 364 */
365 static void endElementHandler(void* data, const char* tag) { 365 static void endElementHandler(void* data, const char* tag) {
366 FamilyData* familyData = (FamilyData*) data; 366 FamilyData* familyData = (FamilyData*) data;
367 size_t len = strlen(tag); 367 size_t len = strlen(tag);
368 if (len == 6 && strncmp(tag, "family", len)== 0) { 368 if (len == 6 && strncmp(tag, "family", len)== 0) {
369 // Done parsing a Family - store the created currentFamily in the famili es array 369 // Done parsing a Family - store the created currentFamily in the famili es array
370 *familyData->families.append() = familyData->currentFamily; 370 *familyData->families.append() = familyData->currentFamily;
371 familyData->currentFamily = NULL; 371 familyData->currentFamily = NULL;
372 } else if (len == 7 && strncmp(tag, "nameset", len) == 0) { 372 } else if (len == 7 && strncmp(tag, "nameset", len) == 0) {
373 familyData->currentTag = NO_TAG; 373 familyData->currentTag = NO_TAG;
374 } else if (len == 7 && strncmp(tag, "fileset", len) == 0) { 374 } else if (len == 7 && strncmp(tag, "fileset", len) == 0) {
375 familyData->currentTag = NO_TAG; 375 familyData->currentTag = NO_TAG;
376 } else if ((len == 4 && 376 } else if ((len == 4 &&
377 strncmp(tag, "name", len) == 0 && 377 strncmp(tag, "name", len) == 0 &&
378 familyData->currentTag == NAMESET_TAG) || 378 familyData->currentTag == NAMESET_TAG) ||
379 (len == 4 && 379 (len == 4 &&
380 strncmp(tag, "file", len) == 0 && 380 strncmp(tag, "file", len) == 0 &&
381 familyData->currentTag == FILESET_TAG)) { 381 familyData->currentTag == FILESET_TAG)) {
382 // Disable the arbitrary text handler installed to load Name data 382 // Disable the arbitrary text handler installed to load Name data
383 XML_SetCharacterDataHandler(*familyData->parser, NULL); 383 XML_SetCharacterDataHandler(familyData->parser, NULL);
384 } 384 }
385 } 385 }
386 386
387 } // namespace jbParser 387 } // namespace jbParser
388 388
389 /** 389 /**
390 * This function parses the given filename and stores the results in the given 390 * This function parses the given filename and stores the results in the given
391 * families array. 391 * families array.
392 */ 392 */
393 static void parseConfigFile(const char* filename, SkTDArray<FontFamily*> &famili es) { 393 static void parseConfigFile(const char* filename, SkTDArray<FontFamily*> &famili es) {
394 394
395 FILE* file = fopen(filename, "r"); 395 FILE* file = fopen(filename, "r");
396 396
397 // Some of the files we attempt to parse (in particular, /vendor/etc/fallbac k_fonts.xml) 397 // Some of the files we attempt to parse (in particular, /vendor/etc/fallbac k_fonts.xml)
398 // are optional - failure here is okay because one of these optional files m ay not exist. 398 // are optional - failure here is okay because one of these optional files m ay not exist.
399 if (NULL == file) { 399 if (NULL == file) {
400 return; 400 return;
401 } 401 }
402 402
403 XML_Parser parser = XML_ParserCreate(NULL); 403 XML_Parser parser = XML_ParserCreate(NULL);
404 FamilyData* familyData = new FamilyData(&parser, families); 404 FamilyData* familyData = new FamilyData(parser, families);
405 XML_SetUserData(parser, familyData); 405 XML_SetUserData(parser, familyData);
406 // Start parsing oldschool; switch these in flight if we detect a newer vers ion of the file. 406 // Start parsing oldschool; switch these in flight if we detect a newer vers ion of the file.
407 XML_SetElementHandler(parser, jbParser::startElementHandler, jbParser::endEl ementHandler); 407 XML_SetElementHandler(parser, jbParser::startElementHandler, jbParser::endEl ementHandler);
408 408
409 char buffer[512]; 409 char buffer[512];
410 bool done = false; 410 bool done = false;
411 while (!done) { 411 while (!done) {
412 fgets(buffer, sizeof(buffer), file); 412 fgets(buffer, sizeof(buffer), file);
413 size_t len = strlen(buffer); 413 size_t len = strlen(buffer);
414 if (feof(file) != 0) { 414 if (feof(file) != 0) {
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 const char* tag = fTag.c_str(); 554 const char* tag = fTag.c_str();
555 555
556 // strip off the rightmost "-.*" 556 // strip off the rightmost "-.*"
557 const char* parentTagEnd = strrchr(tag, '-'); 557 const char* parentTagEnd = strrchr(tag, '-');
558 if (parentTagEnd == NULL) { 558 if (parentTagEnd == NULL) {
559 return SkLanguage(); 559 return SkLanguage();
560 } 560 }
561 size_t parentTagLen = parentTagEnd - tag; 561 size_t parentTagLen = parentTagEnd - tag;
562 return SkLanguage(tag, parentTagLen); 562 return SkLanguage(tag, parentTagLen);
563 } 563 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698