Chromium Code Reviews| 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 |