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 |