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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 parser, SkTDArray<FontFamily*> &families) | 54 FamilyData(XML_Parser parser, SkTDArray<FontFamily*> &families) |
55 : fParser(parser) | 55 : fParser(parser) |
56 , fFamilies(families) | 56 , fFamilies(families) |
57 , fCurrentFamily(NULL) | 57 , fCurrentFamily(NULL) |
58 , fCurrentFontInfo(NULL) | 58 , fCurrentFontInfo(NULL) |
59 , fCurrentTag(NO_TAG) | 59 , fCurrentTag(NO_TAG) |
60 { }; | 60 , fVersion(0) |
61 { } | |
61 | 62 |
62 XML_Parser fParser; // The expat parser doing the work , owned by caller | 63 XML_Parser fParser; // The expat parser doing the work , owned by caller |
63 SkTDArray<FontFamily*>& fFamilies; // The array to append families, o wned by caller | 64 SkTDArray<FontFamily*>& fFamilies; // The array to append families, o wned by caller |
64 SkAutoTDelete<FontFamily> fCurrentFamily; // The family being created, owned by this | 65 SkAutoTDelete<FontFamily> fCurrentFamily; // The family being created, owned by this |
65 FontFileInfo* fCurrentFontInfo; // The fontInfo being created, own ed by currentFamily | 66 FontFileInfo* fCurrentFontInfo; // The fontInfo being created, own ed by currentFamily |
66 int fCurrentTag; // Flag to indicate when we're in nameset/fileset tags | 67 int fCurrentTag; // Flag to indicate when we're in nameset/fileset tags |
68 int fVersion; // The version of the file parsed. | |
67 }; | 69 }; |
68 | 70 |
69 /** http://www.w3.org/TR/html-markup/datatypes.html#common.data.integer.non-nega tive-def */ | 71 /** http://www.w3.org/TR/html-markup/datatypes.html#common.data.integer.non-nega tive-def */ |
70 template <typename T> static bool parseNonNegativeInteger(const char* s, T* valu e) { | 72 template <typename T> static bool parseNonNegativeInteger(const char* s, T* valu e) { |
71 SK_COMPILE_ASSERT(std::numeric_limits<T>::is_integer, T_must_be_integer); | 73 SK_COMPILE_ASSERT(std::numeric_limits<T>::is_integer, T_must_be_integer); |
72 const T nMax = std::numeric_limits<T>::max() / 10; | 74 const T nMax = std::numeric_limits<T>::max() / 10; |
73 const T dMax = std::numeric_limits<T>::max() - (nMax * 10); | 75 const T dMax = std::numeric_limits<T>::max() - (nMax * 10); |
74 T n = 0; | 76 T n = 0; |
75 for (; *s; ++s) { | 77 for (; *s; ++s) { |
76 // Check if digit | 78 // Check if digit |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
324 for (size_t i = 0; atts[i] != NULL && | 326 for (size_t i = 0; atts[i] != NULL && |
325 atts[i+1] != NULL; i += 2) { | 327 atts[i+1] != NULL; i += 2) { |
326 size_t nameLen = strlen(atts[i]); | 328 size_t nameLen = strlen(atts[i]); |
327 if (nameLen == 7 && strncmp(atts[i], "version", nameLen)) continue; | 329 if (nameLen == 7 && strncmp(atts[i], "version", nameLen)) continue; |
328 const char* valueString = atts[i+1]; | 330 const char* valueString = atts[i+1]; |
329 int version; | 331 int version; |
330 if (parseNonNegativeInteger(valueString, &version) && (version >= 21 )) { | 332 if (parseNonNegativeInteger(valueString, &version) && (version >= 21 )) { |
331 XML_SetElementHandler(familyData->fParser, | 333 XML_SetElementHandler(familyData->fParser, |
332 lmpParser::startElementHandler, | 334 lmpParser::startElementHandler, |
333 lmpParser::endElementHandler); | 335 lmpParser::endElementHandler); |
336 familyData->fVersion = version; | |
334 } | 337 } |
335 } | 338 } |
336 } else if (len == 6 && strncmp(tag, "family", len) == 0) { | 339 } else if (len == 6 && strncmp(tag, "family", len) == 0) { |
337 familyData->fCurrentFamily.reset(new FontFamily()); | 340 familyData->fCurrentFamily.reset(new FontFamily()); |
338 // The Family tag has an optional "order" attribute with an integer valu e >= 0 | 341 // 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 | 342 // If this attribute does not exist, the default value is -1 |
340 for (size_t i = 0; atts[i] != NULL && | 343 for (size_t i = 0; atts[i] != NULL && |
341 atts[i+1] != NULL; i += 2) { | 344 atts[i+1] != NULL; i += 2) { |
342 const char* valueString = atts[i+1]; | 345 const char* valueString = atts[i+1]; |
343 int value; | 346 int value; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
380 familyData->fCurrentTag == FILESET_TAG)) { | 383 familyData->fCurrentTag == FILESET_TAG)) { |
381 // Disable the arbitrary text handler installed to load Name data | 384 // Disable the arbitrary text handler installed to load Name data |
382 XML_SetCharacterDataHandler(familyData->fParser, NULL); | 385 XML_SetCharacterDataHandler(familyData->fParser, NULL); |
383 } | 386 } |
384 } | 387 } |
385 | 388 |
386 } // namespace jbParser | 389 } // namespace jbParser |
387 | 390 |
388 /** | 391 /** |
389 * This function parses the given filename and stores the results in the given | 392 * This function parses the given filename and stores the results in the given |
390 * families array. | 393 * families array. Returns the version of the file, negative if the file does no t exist. |
391 */ | 394 */ |
392 static void parseConfigFile(const char* filename, SkTDArray<FontFamily*> &famili es) { | 395 static int parseConfigFile(const char* filename, SkTDArray<FontFamily*> &familie s) { |
393 | 396 |
394 FILE* file = fopen(filename, "r"); | 397 FILE* file = fopen(filename, "r"); |
395 | 398 |
396 // Some of the files we attempt to parse (in particular, /vendor/etc/fallbac k_fonts.xml) | 399 // Some of the files we attempt to parse (in particular, /vendor/etc/fallbac k_fonts.xml) |
397 // are optional - failure here is okay because one of these optional files m ay not exist. | 400 // are optional - failure here is okay because one of these optional files m ay not exist. |
398 if (NULL == file) { | 401 if (NULL == file) { |
399 return; | 402 return -1; |
400 } | 403 } |
401 | 404 |
402 XML_Parser parser = XML_ParserCreate(NULL); | 405 XML_Parser parser = XML_ParserCreate(NULL); |
403 FamilyData familyData(parser, families); | 406 FamilyData familyData(parser, families); |
404 XML_SetUserData(parser, &familyData); | 407 XML_SetUserData(parser, &familyData); |
405 // Start parsing oldschool; switch these in flight if we detect a newer vers ion of the file. | 408 // Start parsing oldschool; switch these in flight if we detect a newer vers ion of the file. |
406 XML_SetElementHandler(parser, jbParser::startElementHandler, jbParser::endEl ementHandler); | 409 XML_SetElementHandler(parser, jbParser::startElementHandler, jbParser::endEl ementHandler); |
407 | 410 |
408 char buffer[512]; | 411 char buffer[512]; |
409 bool done = false; | 412 bool done = false; |
410 while (!done) { | 413 while (!done) { |
411 fgets(buffer, sizeof(buffer), file); | 414 fgets(buffer, sizeof(buffer), file); |
412 size_t len = strlen(buffer); | 415 size_t len = strlen(buffer); |
413 if (feof(file) != 0) { | 416 if (feof(file) != 0) { |
414 done = true; | 417 done = true; |
415 } | 418 } |
416 XML_Parse(parser, buffer, len, done); | 419 XML_Parse(parser, buffer, len, done); |
417 } | 420 } |
418 XML_ParserFree(parser); | 421 XML_ParserFree(parser); |
419 fclose(file); | 422 fclose(file); |
423 return familyData.fVersion; | |
420 } | 424 } |
421 | 425 |
422 static void getSystemFontFamilies(SkTDArray<FontFamily*> &fontFamilies) { | 426 /** Returns the version of the system font file actually found, negative if none . */ |
427 static int appendSystemFontFamilies(SkTDArray<FontFamily*> &fontFamilies) { | |
mtklein
2015/02/02 16:55:49
Let's update to static_function_name_style and T&
bungeman-skia
2015/02/02 18:36:37
Done.
| |
423 int initialCount = fontFamilies.count(); | 428 int initialCount = fontFamilies.count(); |
424 parseConfigFile(LMP_SYSTEM_FONTS_FILE, fontFamilies); | 429 int version = parseConfigFile(LMP_SYSTEM_FONTS_FILE, fontFamilies); |
425 | 430 if (version < 0 || fontFamilies.count() == initialCount) { |
426 if (initialCount == fontFamilies.count()) { | 431 version = parseConfigFile(OLD_SYSTEM_FONTS_FILE, fontFamilies); |
427 parseConfigFile(OLD_SYSTEM_FONTS_FILE, fontFamilies); | |
428 } | 432 } |
433 return version; | |
429 } | 434 } |
430 | 435 |
431 /** | 436 /** |
432 * In some versions of Android prior to Android 4.2 (JellyBean MR1 at API | 437 * In some versions of Android prior to Android 4.2 (JellyBean MR1 at API |
433 * Level 17) the fallback fonts for certain locales were encoded in their own | 438 * Level 17) the fallback fonts for certain locales were encoded in their own |
434 * XML files with a suffix that identified the locale. We search the provided | 439 * XML files with a suffix that identified the locale. We search the provided |
435 * directory for those files,add all of their entries to the fallback chain, and | 440 * directory for those files,add all of their entries to the fallback chain, and |
436 * include the locale as part of each entry. | 441 * include the locale as part of each entry. |
437 */ | 442 */ |
438 static void getFallbackFontFamiliesForLocale(SkTDArray<FontFamily*> &fallbackFon ts, const char* dir) { | 443 static void appendFallbackFontFamiliesForLocale(SkTDArray<FontFamily*> &fallback Fonts, |
444 const char* dir) | |
445 { | |
439 #if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) | 446 #if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) |
440 // The framework is beyond Android 4.2 and can therefore skip this function | 447 // The framework is beyond Android 4.2 and can therefore skip this function |
441 return; | 448 return; |
442 #endif | 449 #endif |
443 | 450 |
444 DIR* fontDirectory = opendir(dir); | 451 DIR* fontDirectory = opendir(dir); |
445 if (fontDirectory != NULL){ | 452 if (fontDirectory != NULL){ |
446 struct dirent* dirEntry = readdir(fontDirectory); | 453 struct dirent* dirEntry = readdir(fontDirectory); |
447 while (dirEntry) { | 454 while (dirEntry) { |
448 | 455 |
(...skipping 26 matching lines...) Expand all Loading... | |
475 } | 482 } |
476 | 483 |
477 // proceed to the next entry in the directory | 484 // proceed to the next entry in the directory |
478 dirEntry = readdir(fontDirectory); | 485 dirEntry = readdir(fontDirectory); |
479 } | 486 } |
480 // cleanup the directory reference | 487 // cleanup the directory reference |
481 closedir(fontDirectory); | 488 closedir(fontDirectory); |
482 } | 489 } |
483 } | 490 } |
484 | 491 |
485 static void getFallbackFontFamilies(SkTDArray<FontFamily*> &fallbackFonts) { | 492 static void appendSystemFallbackFontFamilies(SkTDArray<FontFamily*> &fallbackFon ts) { |
493 parseConfigFile(FALLBACK_FONTS_FILE, fallbackFonts); | |
494 appendFallbackFontFamiliesForLocale(fallbackFonts, LOCALE_FALLBACK_FONTS_SYS TEM_DIR); | |
495 } | |
496 | |
497 static void mixinVendorFallbackFontFamilies(SkTDArray<FontFamily*> &fallbackFont s) { | |
486 SkTDArray<FontFamily*> vendorFonts; | 498 SkTDArray<FontFamily*> vendorFonts; |
487 parseConfigFile(FALLBACK_FONTS_FILE, fallbackFonts); | |
488 parseConfigFile(VENDOR_FONTS_FILE, vendorFonts); | 499 parseConfigFile(VENDOR_FONTS_FILE, vendorFonts); |
489 | 500 appendFallbackFontFamiliesForLocale(vendorFonts, LOCALE_FALLBACK_FONTS_VENDO R_DIR); |
490 getFallbackFontFamiliesForLocale(fallbackFonts, LOCALE_FALLBACK_FONTS_SYSTEM _DIR); | |
491 getFallbackFontFamiliesForLocale(vendorFonts, LOCALE_FALLBACK_FONTS_VENDOR_D IR); | |
492 | 501 |
493 // This loop inserts the vendor fallback fonts in the correct order in the | 502 // This loop inserts the vendor fallback fonts in the correct order in the |
494 // overall fallbacks list. | 503 // overall fallbacks list. |
495 int currentOrder = -1; | 504 int currentOrder = -1; |
496 for (int i = 0; i < vendorFonts.count(); ++i) { | 505 for (int i = 0; i < vendorFonts.count(); ++i) { |
497 FontFamily* family = vendorFonts[i]; | 506 FontFamily* family = vendorFonts[i]; |
498 int order = family->fOrder; | 507 int order = family->fOrder; |
499 if (order < 0) { | 508 if (order < 0) { |
500 if (currentOrder < 0) { | 509 if (currentOrder < 0) { |
501 // Default case - just add it to the end of the fallback list | 510 // Default case - just add it to the end of the fallback list |
(...skipping 10 matching lines...) Expand all Loading... | |
512 currentOrder = order + 1; | 521 currentOrder = order + 1; |
513 } | 522 } |
514 } | 523 } |
515 } | 524 } |
516 | 525 |
517 /** | 526 /** |
518 * Loads data on font families from various expected configuration files. The | 527 * Loads data on font families from various expected configuration files. The |
519 * resulting data is returned in the given fontFamilies array. | 528 * resulting data is returned in the given fontFamilies array. |
520 */ | 529 */ |
521 void SkFontConfigParser::GetFontFamilies(SkTDArray<FontFamily*> &fontFamilies) { | 530 void SkFontConfigParser::GetFontFamilies(SkTDArray<FontFamily*> &fontFamilies) { |
522 | 531 // Version 21 of the system font configuration does not need any fallback co nfiguration files. |
523 getSystemFontFamilies(fontFamilies); | 532 if (appendSystemFontFamilies(fontFamilies) >= 21) { |
533 return; | |
534 } | |
524 | 535 |
525 // Append all the fallback fonts to system fonts | 536 // Append all the fallback fonts to system fonts |
526 SkTDArray<FontFamily*> fallbackFonts; | 537 SkTDArray<FontFamily*> fallbackFonts; |
527 getFallbackFontFamilies(fallbackFonts); | 538 appendSystemFallbackFontFamilies(fallbackFonts); |
539 mixinVendorFallbackFontFamilies(fallbackFonts); | |
528 for (int i = 0; i < fallbackFonts.count(); ++i) { | 540 for (int i = 0; i < fallbackFonts.count(); ++i) { |
529 fallbackFonts[i]->fIsFallbackFont = true; | 541 fallbackFonts[i]->fIsFallbackFont = true; |
530 *fontFamilies.append() = fallbackFonts[i]; | 542 *fontFamilies.append() = fallbackFonts[i]; |
531 } | 543 } |
532 } | 544 } |
533 | 545 |
534 void SkFontConfigParser::GetTestFontFamilies(SkTDArray<FontFamily*> &fontFamilie s, | 546 void SkFontConfigParser::GetTestFontFamilies(SkTDArray<FontFamily*> &fontFamilie s, |
535 const char* testMainConfigFile, | 547 const char* testMainConfigFile, |
536 const char* testFallbackConfigFile) { | 548 const char* testFallbackConfigFile) { |
537 parseConfigFile(testMainConfigFile, fontFamilies); | 549 parseConfigFile(testMainConfigFile, fontFamilies); |
(...skipping 15 matching lines...) Expand all Loading... | |
553 const char* tag = fTag.c_str(); | 565 const char* tag = fTag.c_str(); |
554 | 566 |
555 // strip off the rightmost "-.*" | 567 // strip off the rightmost "-.*" |
556 const char* parentTagEnd = strrchr(tag, '-'); | 568 const char* parentTagEnd = strrchr(tag, '-'); |
557 if (parentTagEnd == NULL) { | 569 if (parentTagEnd == NULL) { |
558 return SkLanguage(); | 570 return SkLanguage(); |
559 } | 571 } |
560 size_t parentTagLen = parentTagEnd - tag; | 572 size_t parentTagLen = parentTagEnd - tag; |
561 return SkLanguage(tag, parentTagLen); | 573 return SkLanguage(tag, parentTagLen); |
562 } | 574 } |
OLD | NEW |