| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2009-2015 Google Inc. | 2 * Copyright 2009-2015 Google Inc. |
| 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 /* migrated from chrome/src/skia/ext/SkFontHost_fontconfig_direct.cpp */ | 8 /* migrated from chrome/src/skia/ext/SkFontHost_fontconfig_direct.cpp */ |
| 9 | 9 |
| 10 #include "SkBuffer.h" | 10 #include "SkBuffer.h" |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 SkASSERT(iden0 == iden1); | 154 SkASSERT(iden0 == iden1); |
| 155 | 155 |
| 156 test_writeToMemory(iden0, 0); | 156 test_writeToMemory(iden0, 0); |
| 157 test_writeToMemory(iden0, 0); | 157 test_writeToMemory(iden0, 0); |
| 158 } | 158 } |
| 159 #endif | 159 #endif |
| 160 | 160 |
| 161 /////////////////////////////////////////////////////////////////////////////// | 161 /////////////////////////////////////////////////////////////////////////////// |
| 162 | 162 |
| 163 // Returns the string from the pattern, or nullptr | 163 // Returns the string from the pattern, or nullptr |
| 164 static const char* get_name(FcPattern* pattern, const char field[], | 164 static const char* get_string(FcPattern* pattern, const char field[], int index
= 0) { |
| 165 int index = 0) { | |
| 166 const char* name; | 165 const char* name; |
| 167 if (FcPatternGetString(pattern, field, index, | 166 if (FcPatternGetString(pattern, field, index, (FcChar8**)&name) != FcResultM
atch) { |
| 168 (FcChar8**)&name) != FcResultMatch) { | |
| 169 name = nullptr; | 167 name = nullptr; |
| 170 } | 168 } |
| 171 return name; | 169 return name; |
| 172 } | 170 } |
| 173 | 171 |
| 174 /////////////////////////////////////////////////////////////////////////////// | 172 /////////////////////////////////////////////////////////////////////////////// |
| 175 | 173 |
| 176 namespace { | 174 namespace { |
| 177 | 175 |
| 178 // Equivalence classes, used to match the Liberation and other fonts | 176 // Equivalence classes, used to match the Liberation and other fonts |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 } | 511 } |
| 514 | 512 |
| 515 bool SkFontConfigInterfaceDirect::isAccessible(const char* filename) { | 513 bool SkFontConfigInterfaceDirect::isAccessible(const char* filename) { |
| 516 if (access(filename, R_OK) != 0) { | 514 if (access(filename, R_OK) != 0) { |
| 517 return false; | 515 return false; |
| 518 } | 516 } |
| 519 return true; | 517 return true; |
| 520 } | 518 } |
| 521 | 519 |
| 522 bool SkFontConfigInterfaceDirect::isValidPattern(FcPattern* pattern) { | 520 bool SkFontConfigInterfaceDirect::isValidPattern(FcPattern* pattern) { |
| 523 #ifdef SK_FONT_CONFIG_ONLY_ALLOW_SCALABLE_FONTS | |
| 524 FcBool is_scalable; | |
| 525 if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &is_scalable) != FcResultMatch | |
| 526 || !is_scalable) { | |
| 527 return false; | |
| 528 } | |
| 529 #endif | |
| 530 | |
| 531 #ifdef SK_FONT_CONFIG_INTERFACE_ONLY_ALLOW_SFNT_FONTS | 521 #ifdef SK_FONT_CONFIG_INTERFACE_ONLY_ALLOW_SFNT_FONTS |
| 532 const char* font_format = get_name(pattern, FC_FONTFORMAT); | 522 const char* font_format = get_string(pattern, FC_FONTFORMAT); |
| 533 if (font_format | 523 if (font_format |
| 534 && strcmp(font_format, kFontFormatTrueType) != 0 | 524 && strcmp(font_format, kFontFormatTrueType) != 0 |
| 535 && strcmp(font_format, kFontFormatCFF) != 0) | 525 && strcmp(font_format, kFontFormatCFF) != 0) |
| 536 { | 526 { |
| 537 return false; | 527 return false; |
| 538 } | 528 } |
| 539 #endif | 529 #endif |
| 540 | 530 |
| 541 // fontconfig can also return fonts which are unreadable | 531 // fontconfig can also return fonts which are unreadable |
| 542 const char* c_filename = get_name(pattern, FC_FILE); | 532 const char* c_filename = get_string(pattern, FC_FILE); |
| 543 if (!c_filename) { | 533 if (!c_filename) { |
| 544 return false; | 534 return false; |
| 545 } | 535 } |
| 546 return this->isAccessible(c_filename); | 536 return this->isAccessible(c_filename); |
| 547 } | 537 } |
| 548 | 538 |
| 549 // Find matching font from |font_set| for the given font family. | 539 // Find matching font from |font_set| for the given font family. |
| 550 FcPattern* SkFontConfigInterfaceDirect::MatchFont(FcFontSet* font_set, | 540 FcPattern* SkFontConfigInterfaceDirect::MatchFont(FcFontSet* font_set, |
| 551 const char* post_config_family
, | 541 const char* post_config_family
, |
| 552 const SkString& family) { | 542 const SkString& family) { |
| 553 // Older versions of fontconfig have a bug where they cannot select | 543 // Older versions of fontconfig have a bug where they cannot select |
| 554 // only scalable fonts so we have to manually filter the results. | 544 // only scalable fonts so we have to manually filter the results. |
| 555 FcPattern* match = nullptr; | 545 FcPattern* match = nullptr; |
| 556 for (int i = 0; i < font_set->nfont; ++i) { | 546 for (int i = 0; i < font_set->nfont; ++i) { |
| 557 FcPattern* current = font_set->fonts[i]; | 547 FcPattern* current = font_set->fonts[i]; |
| 558 if (this->isValidPattern(current)) { | 548 if (this->isValidPattern(current)) { |
| 559 match = current; | 549 match = current; |
| 560 break; | 550 break; |
| 561 } | 551 } |
| 562 } | 552 } |
| 563 | 553 |
| 564 if (match && !IsFallbackFontAllowed(family)) { | 554 if (match && !IsFallbackFontAllowed(family)) { |
| 565 bool acceptable_substitute = false; | 555 bool acceptable_substitute = false; |
| 566 for (int id = 0; id < 255; ++id) { | 556 for (int id = 0; id < 255; ++id) { |
| 567 const char* post_match_family = get_name(match, FC_FAMILY, id); | 557 const char* post_match_family = get_string(match, FC_FAMILY, id); |
| 568 if (!post_match_family) | 558 if (!post_match_family) |
| 569 break; | 559 break; |
| 570 acceptable_substitute = | 560 acceptable_substitute = |
| 571 (strcasecmp(post_config_family, post_match_family) == 0 || | 561 (strcasecmp(post_config_family, post_match_family) == 0 || |
| 572 // Workaround for Issue 12530: | 562 // Workaround for Issue 12530: |
| 573 // requested family: "Bitstream Vera Sans" | 563 // requested family: "Bitstream Vera Sans" |
| 574 // post_config_family: "Arial" | 564 // post_config_family: "Arial" |
| 575 // post_match_family: "Bitstream Vera Sans" | 565 // post_match_family: "Bitstream Vera Sans" |
| 576 // -> We should treat this case as a good match. | 566 // -> We should treat this case as a good match. |
| 577 strcasecmp(family.c_str(), post_match_family) == 0) || | 567 strcasecmp(family.c_str(), post_match_family) == 0) || |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 637 // -> good match | 627 // -> good match |
| 638 // | 628 // |
| 639 // and for a missing font: | 629 // and for a missing font: |
| 640 // requested family: "Monaco" | 630 // requested family: "Monaco" |
| 641 // post_config_family: "Monaco" | 631 // post_config_family: "Monaco" |
| 642 // post_match_family: "Times New Roman" | 632 // post_match_family: "Times New Roman" |
| 643 // -> BAD match | 633 // -> BAD match |
| 644 // | 634 // |
| 645 // However, we special-case fallback fonts; see IsFallbackFontAllowed(). | 635 // However, we special-case fallback fonts; see IsFallbackFontAllowed(). |
| 646 | 636 |
| 647 const char* post_config_family = get_name(pattern, FC_FAMILY); | 637 const char* post_config_family = get_string(pattern, FC_FAMILY); |
| 648 if (!post_config_family) { | 638 if (!post_config_family) { |
| 649 // we can just continue with an empty name, e.g. default font | 639 // we can just continue with an empty name, e.g. default font |
| 650 post_config_family = ""; | 640 post_config_family = ""; |
| 651 } | 641 } |
| 652 | 642 |
| 653 FcResult result; | 643 FcResult result; |
| 654 FcFontSet* font_set = FcFontSort(nullptr, pattern, 0, nullptr, &result); | 644 FcFontSet* font_set = FcFontSort(nullptr, pattern, 0, nullptr, &result); |
| 655 if (!font_set) { | 645 if (!font_set) { |
| 656 FcPatternDestroy(pattern); | 646 FcPatternDestroy(pattern); |
| 657 return false; | 647 return false; |
| 658 } | 648 } |
| 659 | 649 |
| 660 FcPattern* match = this->MatchFont(font_set, post_config_family, familyStr); | 650 FcPattern* match = this->MatchFont(font_set, post_config_family, familyStr); |
| 661 if (!match) { | 651 if (!match) { |
| 662 FcPatternDestroy(pattern); | 652 FcPatternDestroy(pattern); |
| 663 FcFontSetDestroy(font_set); | 653 FcFontSetDestroy(font_set); |
| 664 return false; | 654 return false; |
| 665 } | 655 } |
| 666 | 656 |
| 667 FcPatternDestroy(pattern); | 657 FcPatternDestroy(pattern); |
| 668 | 658 |
| 669 // From here out we just extract our results from 'match' | 659 // From here out we just extract our results from 'match' |
| 670 | 660 |
| 671 post_config_family = get_name(match, FC_FAMILY); | 661 post_config_family = get_string(match, FC_FAMILY); |
| 672 if (!post_config_family) { | 662 if (!post_config_family) { |
| 673 FcFontSetDestroy(font_set); | 663 FcFontSetDestroy(font_set); |
| 674 return false; | 664 return false; |
| 675 } | 665 } |
| 676 | 666 |
| 677 const char* c_filename = get_name(match, FC_FILE); | 667 const char* c_filename = get_string(match, FC_FILE); |
| 678 if (!c_filename) { | 668 if (!c_filename) { |
| 679 FcFontSetDestroy(font_set); | 669 FcFontSetDestroy(font_set); |
| 680 return false; | 670 return false; |
| 681 } | 671 } |
| 682 | 672 |
| 683 int face_index; | 673 int face_index = get_int(match, FC_INDEX, 0); |
| 684 if (FcPatternGetInteger(match, FC_INDEX, 0, &face_index) != FcResultMatch) { | |
| 685 FcFontSetDestroy(font_set); | |
| 686 return false; | |
| 687 } | |
| 688 | 674 |
| 689 FcFontSetDestroy(font_set); | 675 FcFontSetDestroy(font_set); |
| 690 | 676 |
| 691 if (outIdentity) { | 677 if (outIdentity) { |
| 692 outIdentity->fTTCIndex = face_index; | 678 outIdentity->fTTCIndex = face_index; |
| 693 outIdentity->fString.set(c_filename); | 679 outIdentity->fString.set(c_filename); |
| 694 } | 680 } |
| 695 if (outFamilyName) { | 681 if (outFamilyName) { |
| 696 outFamilyName->set(post_config_family); | 682 outFamilyName->set(post_config_family); |
| 697 } | 683 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 735 FcFontSet* fs = FcFontList(nullptr, pat, os); | 721 FcFontSet* fs = FcFontList(nullptr, pat, os); |
| 736 SkAutoTCallVProc<FcFontSet, FcFontSetDestroy> autoDestroyFs(fs); | 722 SkAutoTCallVProc<FcFontSet, FcFontSetDestroy> autoDestroyFs(fs); |
| 737 if (nullptr == fs) { | 723 if (nullptr == fs) { |
| 738 return nullptr; | 724 return nullptr; |
| 739 } | 725 } |
| 740 | 726 |
| 741 SkTDArray<const char*> names; | 727 SkTDArray<const char*> names; |
| 742 SkTDArray<size_t> sizes; | 728 SkTDArray<size_t> sizes; |
| 743 for (int i = 0; i < fs->nfont; ++i) { | 729 for (int i = 0; i < fs->nfont; ++i) { |
| 744 FcPattern* match = fs->fonts[i]; | 730 FcPattern* match = fs->fonts[i]; |
| 745 const char* famName = get_name(match, FC_FAMILY); | 731 const char* famName = get_string(match, FC_FAMILY); |
| 746 if (famName && !find_name(names, famName)) { | 732 if (famName && !find_name(names, famName)) { |
| 747 *names.append() = famName; | 733 *names.append() = famName; |
| 748 *sizes.append() = strlen(famName) + 1; | 734 *sizes.append() = strlen(famName) + 1; |
| 749 } | 735 } |
| 750 } | 736 } |
| 751 | 737 |
| 752 return SkDataTable::MakeCopyArrays((const void*const*)names.begin(), | 738 return SkDataTable::MakeCopyArrays((const void*const*)names.begin(), |
| 753 sizes.begin(), names.count()); | 739 sizes.begin(), names.count()); |
| 754 } | 740 } |
| OLD | NEW |