Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: src/ports/SkFontConfigInterface_direct.cpp

Issue 2345053005: Sane use of FcPatternGetXXX in SkFontConfigInterface. (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698