OLD | NEW |
---|---|
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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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, owned by caller | 61 XML_Parser parser; // The expat parser doing the work, owned by caller |
62 SkTDArray<FontFamily*>& families; // The array to append families, owned by caller | 62 SkTDArray<FontFamily*>& families; // The array to append families, ow ned by caller |
mtklein
2015/01/30 23:07:41
Who cleans up things we add here?
bungeman-skia
2015/01/30 23:14:56
This is completely owned by the caller (this is th
| |
63 FontFamily* currentFamily; // The current family being created, owne d by this | 63 SkAutoTDelete<FontFamily> currentFamily; // The family being created, owned by this |
mtklein
2015/01/30 23:07:41
So, uh.... we were just never deleting this? I ca
bungeman-skia
2015/01/30 23:14:56
This is the 'working' FontFamily. When we finish b
| |
64 FontFileInfo* currentFontInfo; // The current fontInfo being created, ow ned by currentFamily | 64 FontFileInfo* currentFontInfo; // The fontInfo being created, owne d by currentFamily |
65 int currentTag; // A flag to indicate whether we're in na meset/fileset tags | 65 int currentTag; // Flag to indicate when we're in n ameset/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) { |
75 // Check if digit | 75 // Check if digit |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
182 } | 182 } |
183 | 183 |
184 // Assumes that the named family is already declared | 184 // Assumes that the named family is already declared |
185 FontFamily* targetFamily = findFamily(familyData, to.c_str()); | 185 FontFamily* targetFamily = findFamily(familyData, to.c_str()); |
186 if (!targetFamily) { | 186 if (!targetFamily) { |
187 SkDebugf("---- Font alias target %s (NOT FOUND)", to.c_str()); | 187 SkDebugf("---- Font alias target %s (NOT FOUND)", to.c_str()); |
188 return; | 188 return; |
189 } | 189 } |
190 | 190 |
191 if (weight) { | 191 if (weight) { |
192 FontFamily* family = new FontFamily(); | 192 FontFamily* family = new FontFamily(); |
mtklein
2015/01/30 23:07:41
E.g. I'm curious who calls delete on this family.
bungeman-skia
2015/01/30 23:14:56
This is added to the set of families being appende
| |
193 family->fNames.push_back().set(aliasName); | 193 family->fNames.push_back().set(aliasName); |
194 | 194 |
195 for (int i = 0; i < targetFamily->fFonts.count(); i++) { | 195 for (int i = 0; i < targetFamily->fFonts.count(); i++) { |
196 if (targetFamily->fFonts[i].fWeight == weight) { | 196 if (targetFamily->fFonts[i].fWeight == weight) { |
197 family->fFonts.push_back(targetFamily->fFonts[i]); | 197 family->fFonts.push_back(targetFamily->fFonts[i]); |
198 } | 198 } |
199 } | 199 } |
200 *familyData->families.append() = family; | 200 *familyData->families.append() = family; |
201 } else { | 201 } else { |
202 targetFamily->fNames.push_back().set(aliasName); | 202 targetFamily->fNames.push_back().set(aliasName); |
203 } | 203 } |
204 } | 204 } |
205 | 205 |
206 void startElementHandler(void* data, const char* tag, const char** attributes) { | 206 void startElementHandler(void* data, const char* tag, const char** attributes) { |
207 FamilyData* familyData = (FamilyData*) data; | 207 FamilyData* familyData = (FamilyData*) data; |
208 size_t len = strlen(tag); | 208 size_t len = strlen(tag); |
209 if (len == 6 && !strncmp(tag, "family", len)) { | 209 if (len == 6 && !strncmp(tag, "family", len)) { |
210 familyData->currentFamily = new FontFamily(); | 210 familyData->currentFamily.reset(new FontFamily()); |
211 familyElementHandler(familyData->currentFamily, attributes); | 211 familyElementHandler(familyData->currentFamily, attributes); |
212 } else if (len == 4 && !strncmp(tag, "font", len)) { | 212 } else if (len == 4 && !strncmp(tag, "font", len)) { |
213 FontFileInfo* file = &familyData->currentFamily->fFonts.push_back(); | 213 FontFileInfo* file = &familyData->currentFamily->fFonts.push_back(); |
214 familyData->currentFontInfo = file; | 214 familyData->currentFontInfo = file; |
215 fontElementHandler(familyData->parser, file, attributes); | 215 fontElementHandler(familyData->parser, file, attributes); |
216 } else if (len == 5 && !strncmp(tag, "alias", len)) { | 216 } else if (len == 5 && !strncmp(tag, "alias", len)) { |
217 aliasElementHandler(familyData, attributes); | 217 aliasElementHandler(familyData, attributes); |
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.detach(); |
226 familyData->currentFamily = NULL; | |
227 } else if (len == 4 && !strncmp(tag, "font", len)) { | 226 } else if (len == 4 && !strncmp(tag, "font", len)) { |
228 XML_SetCharacterDataHandler(familyData->parser, NULL); | 227 XML_SetCharacterDataHandler(familyData->parser, NULL); |
229 } | 228 } |
230 } | 229 } |
231 | 230 |
232 } // lmpParser | 231 } // lmpParser |
233 | 232 |
234 namespace jbParser { | 233 namespace jbParser { |
235 | 234 |
236 /** | 235 /** |
237 * Handler for arbitrary text. This is used to parse the text inside each name | 236 * 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. | 237 * or file tag. The resulting strings are put into the fNames or FontFileInfo ar rays. |
239 */ | 238 */ |
240 static void textHandler(void* data, const char* s, int len) { | 239 static void textHandler(void* data, const char* s, int len) { |
241 FamilyData* familyData = (FamilyData*) data; | 240 FamilyData* familyData = (FamilyData*) data; |
242 // Make sure we're in the right state to store this name information | 241 // Make sure we're in the right state to store this name information |
243 if (familyData->currentFamily && | 242 if (familyData->currentFamily.get() && |
244 (familyData->currentTag == NAMESET_TAG || familyData->currentTag == FILESET_TAG)) { | 243 (familyData->currentTag == NAMESET_TAG || familyData->currentTag == FILESET_TAG)) { |
245 switch (familyData->currentTag) { | 244 switch (familyData->currentTag) { |
246 case NAMESET_TAG: { | 245 case NAMESET_TAG: { |
247 SkAutoAsciiToLC tolc(s, len); | 246 SkAutoAsciiToLC tolc(s, len); |
248 familyData->currentFamily->fNames.push_back().set(tolc.lc(), len); | 247 familyData->currentFamily->fNames.push_back().set(tolc.lc(), len); |
249 break; | 248 break; |
250 } | 249 } |
251 case FILESET_TAG: | 250 case FILESET_TAG: |
252 if (familyData->currentFontInfo) { | 251 if (familyData->currentFontInfo) { |
253 familyData->currentFontInfo->fFileName.set(s, len); | 252 familyData->currentFontInfo->fFileName.set(s, len); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
327 if (nameLen == 7 && strncmp(atts[i], "version", nameLen)) continue; | 326 if (nameLen == 7 && strncmp(atts[i], "version", nameLen)) continue; |
328 const char* valueString = atts[i+1]; | 327 const char* valueString = atts[i+1]; |
329 int version; | 328 int version; |
330 if (parseNonNegativeInteger(valueString, &version) && (version >= 21 )) { | 329 if (parseNonNegativeInteger(valueString, &version) && (version >= 21 )) { |
331 XML_SetElementHandler(familyData->parser, | 330 XML_SetElementHandler(familyData->parser, |
332 lmpParser::startElementHandler, | 331 lmpParser::startElementHandler, |
333 lmpParser::endElementHandler); | 332 lmpParser::endElementHandler); |
334 } | 333 } |
335 } | 334 } |
336 } else if (len == 6 && strncmp(tag, "family", len) == 0) { | 335 } else if (len == 6 && strncmp(tag, "family", len) == 0) { |
337 familyData->currentFamily = new FontFamily(); | 336 familyData->currentFamily.reset(new FontFamily()); |
338 // The Family tag has an optional "order" attribute with an integer valu e >= 0 | 337 // 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 | 338 // If this attribute does not exist, the default value is -1 |
340 for (size_t i = 0; atts[i] != NULL && | 339 for (size_t i = 0; atts[i] != NULL && |
341 atts[i+1] != NULL; i += 2) { | 340 atts[i+1] != NULL; i += 2) { |
342 const char* valueString = atts[i+1]; | 341 const char* valueString = atts[i+1]; |
343 int value; | 342 int value; |
344 if (parseNonNegativeInteger(valueString, &value)) { | 343 if (parseNonNegativeInteger(valueString, &value)) { |
345 familyData->currentFamily->fOrder = value; | 344 familyData->currentFamily->fOrder = value; |
346 } | 345 } |
347 } | 346 } |
(...skipping 12 matching lines...) Expand all Loading... | |
360 | 359 |
361 /** | 360 /** |
362 * Handler for the end of tags. We only care about family, nameset, fileset, | 361 * Handler for the end of tags. We only care about family, nameset, fileset, |
363 * name, and file. | 362 * name, and file. |
364 */ | 363 */ |
365 static void endElementHandler(void* data, const char* tag) { | 364 static void endElementHandler(void* data, const char* tag) { |
366 FamilyData* familyData = (FamilyData*) data; | 365 FamilyData* familyData = (FamilyData*) data; |
367 size_t len = strlen(tag); | 366 size_t len = strlen(tag); |
368 if (len == 6 && strncmp(tag, "family", len)== 0) { | 367 if (len == 6 && strncmp(tag, "family", len)== 0) { |
369 // Done parsing a Family - store the created currentFamily in the famili es array | 368 // Done parsing a Family - store the created currentFamily in the famili es array |
370 *familyData->families.append() = familyData->currentFamily; | 369 *familyData->families.append() = familyData->currentFamily.detach(); |
371 familyData->currentFamily = NULL; | |
372 } else if (len == 7 && strncmp(tag, "nameset", len) == 0) { | 370 } else if (len == 7 && strncmp(tag, "nameset", len) == 0) { |
373 familyData->currentTag = NO_TAG; | 371 familyData->currentTag = NO_TAG; |
374 } else if (len == 7 && strncmp(tag, "fileset", len) == 0) { | 372 } else if (len == 7 && strncmp(tag, "fileset", len) == 0) { |
375 familyData->currentTag = NO_TAG; | 373 familyData->currentTag = NO_TAG; |
376 } else if ((len == 4 && | 374 } else if ((len == 4 && |
377 strncmp(tag, "name", len) == 0 && | 375 strncmp(tag, "name", len) == 0 && |
378 familyData->currentTag == NAMESET_TAG) || | 376 familyData->currentTag == NAMESET_TAG) || |
379 (len == 4 && | 377 (len == 4 && |
380 strncmp(tag, "file", len) == 0 && | 378 strncmp(tag, "file", len) == 0 && |
381 familyData->currentTag == FILESET_TAG)) { | 379 familyData->currentTag == FILESET_TAG)) { |
(...skipping 12 matching lines...) Expand all Loading... | |
394 | 392 |
395 FILE* file = fopen(filename, "r"); | 393 FILE* file = fopen(filename, "r"); |
396 | 394 |
397 // Some of the files we attempt to parse (in particular, /vendor/etc/fallbac k_fonts.xml) | 395 // 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. | 396 // are optional - failure here is okay because one of these optional files m ay not exist. |
399 if (NULL == file) { | 397 if (NULL == file) { |
400 return; | 398 return; |
401 } | 399 } |
402 | 400 |
403 XML_Parser parser = XML_ParserCreate(NULL); | 401 XML_Parser parser = XML_ParserCreate(NULL); |
404 FamilyData* familyData = new FamilyData(parser, families); | 402 FamilyData familyData(parser, families); |
405 XML_SetUserData(parser, familyData); | 403 XML_SetUserData(parser, &familyData); |
406 // Start parsing oldschool; switch these in flight if we detect a newer vers ion of the file. | 404 // 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); | 405 XML_SetElementHandler(parser, jbParser::startElementHandler, jbParser::endEl ementHandler); |
408 | 406 |
409 char buffer[512]; | 407 char buffer[512]; |
410 bool done = false; | 408 bool done = false; |
411 while (!done) { | 409 while (!done) { |
412 fgets(buffer, sizeof(buffer), file); | 410 fgets(buffer, sizeof(buffer), file); |
413 size_t len = strlen(buffer); | 411 size_t len = strlen(buffer); |
414 if (feof(file) != 0) { | 412 if (feof(file) != 0) { |
415 done = true; | 413 done = true; |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
554 const char* tag = fTag.c_str(); | 552 const char* tag = fTag.c_str(); |
555 | 553 |
556 // strip off the rightmost "-.*" | 554 // strip off the rightmost "-.*" |
557 const char* parentTagEnd = strrchr(tag, '-'); | 555 const char* parentTagEnd = strrchr(tag, '-'); |
558 if (parentTagEnd == NULL) { | 556 if (parentTagEnd == NULL) { |
559 return SkLanguage(); | 557 return SkLanguage(); |
560 } | 558 } |
561 size_t parentTagLen = parentTagEnd - tag; | 559 size_t parentTagLen = parentTagEnd - tag; |
562 return SkLanguage(tag, parentTagLen); | 560 return SkLanguage(tag, parentTagLen); |
563 } | 561 } |
OLD | NEW |