| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 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 #include "SkDataTable.h" | 8 #include "SkDataTable.h" |
| 9 #include "SkFontDescriptor.h" | 9 #include "SkFontDescriptor.h" |
| 10 #include "SkFontHost_FreeType_common.h" | 10 #include "SkFontHost_FreeType_common.h" |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 if (FcGetVersion() < 21091) { | 89 if (FcGetVersion() < 21091) { |
| 90 gFCMutex.assertHeld(); | 90 gFCMutex.assertHeld(); |
| 91 } else { | 91 } else { |
| 92 SkASSERT(true == *THREAD_FC_LOCKED); | 92 SkASSERT(true == *THREAD_FC_LOCKED); |
| 93 } | 93 } |
| 94 ) } | 94 ) } |
| 95 }; | 95 }; |
| 96 | 96 |
| 97 } // namespace | 97 } // namespace |
| 98 | 98 |
| 99 template<typename T, void (*P)(T*)> void FcTDestroy(T* t) { | 99 template<typename T, void (*D)(T*)> void FcTDestroy(T* t) { |
| 100 FCLocker::AssertHeld(); | 100 FCLocker::AssertHeld(); |
| 101 P(t); | 101 D(t); |
| 102 } | 102 } |
| 103 template <typename T, void (*P)(T*)> class SkAutoFc | 103 template <typename T, T* (*C)(), void (*D)(T*)> class SkAutoFc |
| 104 : public SkAutoTCallVProc<T, FcTDestroy<T, P> > { | 104 : public SkAutoTCallVProc<T, FcTDestroy<T, D> > { |
| 105 public: | 105 public: |
| 106 SkAutoFc(T* obj) : SkAutoTCallVProc<T, FcTDestroy<T, P> >(obj) {} | 106 SkAutoFc() : SkAutoTCallVProc<T, FcTDestroy<T, D> >(C()) { |
| 107 T* obj = this->operator T*(); |
| 108 SK_ALWAYSBREAK(NULL != obj); |
| 109 } |
| 110 explicit SkAutoFc(T* obj) : SkAutoTCallVProc<T, FcTDestroy<T, D> >(obj) {} |
| 107 }; | 111 }; |
| 108 | 112 |
| 109 typedef SkAutoFc<FcConfig, FcConfigDestroy> SkAutoFcConfig; | 113 typedef SkAutoFc<FcCharSet, FcCharSetCreate, FcCharSetDestroy> SkAutoFcCharSet; |
| 110 typedef SkAutoFc<FcFontSet, FcFontSetDestroy> SkAutoFcFontSet; | 114 typedef SkAutoFc<FcConfig, FcConfigCreate, FcConfigDestroy> SkAutoFcConfig; |
| 111 typedef SkAutoFc<FcLangSet, FcLangSetDestroy> SkAutoFcLangSet; | 115 typedef SkAutoFc<FcFontSet, FcFontSetCreate, FcFontSetDestroy> SkAutoFcFontSet; |
| 112 typedef SkAutoFc<FcObjectSet, FcObjectSetDestroy> SkAutoFcObjectSet; | 116 typedef SkAutoFc<FcLangSet, FcLangSetCreate, FcLangSetDestroy> SkAutoFcLangSet; |
| 113 typedef SkAutoFc<FcPattern, FcPatternDestroy> SkAutoFcPattern; | 117 typedef SkAutoFc<FcObjectSet, FcObjectSetCreate, FcObjectSetDestroy> SkAutoFcObj
ectSet; |
| 118 typedef SkAutoFc<FcPattern, FcPatternCreate, FcPatternDestroy> SkAutoFcPattern; |
| 114 | 119 |
| 115 static int get_int(FcPattern* pattern, const char object[], int missing) { | 120 static int get_int(FcPattern* pattern, const char object[], int missing) { |
| 116 int value; | 121 int value; |
| 117 if (FcPatternGetInteger(pattern, object, 0, &value) != FcResultMatch) { | 122 if (FcPatternGetInteger(pattern, object, 0, &value) != FcResultMatch) { |
| 118 return missing; | 123 return missing; |
| 119 } | 124 } |
| 120 return value; | 125 return value; |
| 121 } | 126 } |
| 122 | 127 |
| 123 static const char* get_string(FcPattern* pattern, const char object[], const cha
r* missing = "") { | 128 static const char* get_string(FcPattern* pattern, const char object[], const cha
r* missing = "") { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 if (result != FcResultMatch) { | 168 if (result != FcResultMatch) { |
| 164 return kNoId_WeakReturn; | 169 return kNoId_WeakReturn; |
| 165 } | 170 } |
| 166 while (hasId) { | 171 while (hasId) { |
| 167 hasId = FcPatternRemove(minimal, object, 1); | 172 hasId = FcPatternRemove(minimal, object, 1); |
| 168 } | 173 } |
| 169 | 174 |
| 170 // Create a font set with two patterns. | 175 // Create a font set with two patterns. |
| 171 // 1. the same 'object' as minimal and a lang object with only 'nomatchlang'
. | 176 // 1. the same 'object' as minimal and a lang object with only 'nomatchlang'
. |
| 172 // 2. a different 'object' from minimal and a lang object with only 'matchla
ng'. | 177 // 2. a different 'object' from minimal and a lang object with only 'matchla
ng'. |
| 173 SkAutoFcFontSet fontSet(FcFontSetCreate()); | 178 SkAutoFcFontSet fontSet; |
| 174 | 179 |
| 175 SkAutoFcLangSet strongLangSet(FcLangSetCreate()); | 180 SkAutoFcLangSet strongLangSet; |
| 176 FcLangSetAdd(strongLangSet, (const FcChar8*)"nomatchlang"); | 181 FcLangSetAdd(strongLangSet, (const FcChar8*)"nomatchlang"); |
| 177 SkAutoFcPattern strong(FcPatternDuplicate(minimal)); | 182 SkAutoFcPattern strong(FcPatternDuplicate(minimal)); |
| 178 FcPatternAddLangSet(strong, FC_LANG, strongLangSet); | 183 FcPatternAddLangSet(strong, FC_LANG, strongLangSet); |
| 179 | 184 |
| 180 SkAutoFcLangSet weakLangSet(FcLangSetCreate()); | 185 SkAutoFcLangSet weakLangSet; |
| 181 FcLangSetAdd(weakLangSet, (const FcChar8*)"matchlang"); | 186 FcLangSetAdd(weakLangSet, (const FcChar8*)"matchlang"); |
| 182 SkAutoFcPattern weak(FcPatternCreate()); | 187 SkAutoFcPattern weak; |
| 183 FcPatternAddString(weak, object, (const FcChar8*)"nomatchstring"); | 188 FcPatternAddString(weak, object, (const FcChar8*)"nomatchstring"); |
| 184 FcPatternAddLangSet(weak, FC_LANG, weakLangSet); | 189 FcPatternAddLangSet(weak, FC_LANG, weakLangSet); |
| 185 | 190 |
| 186 FcFontSetAdd(fontSet, strong.detach()); | 191 FcFontSetAdd(fontSet, strong.detach()); |
| 187 FcFontSetAdd(fontSet, weak.detach()); | 192 FcFontSetAdd(fontSet, weak.detach()); |
| 188 | 193 |
| 189 // Add 'matchlang' to the copy of the pattern. | 194 // Add 'matchlang' to the copy of the pattern. |
| 190 FcPatternAddLangSet(minimal, FC_LANG, weakLangSet); | 195 FcPatternAddLangSet(minimal, FC_LANG, weakLangSet); |
| 191 | 196 |
| 192 // Run a match against the copy of the pattern. | 197 // Run a match against the copy of the pattern. |
| 193 // If the 'id' was weak, then we should match the pattern with 'matchlang'. | 198 // If the 'id' was weak, then we should match the pattern with 'matchlang'. |
| 194 // If the 'id' was strong, then we should match the pattern with 'nomatchlan
g'. | 199 // If the 'id' was strong, then we should match the pattern with 'nomatchlan
g'. |
| 195 | 200 |
| 196 // Note that this config is only used for FcFontRenderPrepare, which we don'
t even want. | 201 // Note that this config is only used for FcFontRenderPrepare, which we don'
t even want. |
| 197 // However, there appears to be no way to match/sort without it. | 202 // However, there appears to be no way to match/sort without it. |
| 198 SkAutoFcConfig config(FcConfigCreate()); | 203 SkAutoFcConfig config; |
| 199 FcFontSet* fontSets[1] = { fontSet }; | 204 FcFontSet* fontSets[1] = { fontSet }; |
| 200 SkAutoFcPattern match(FcFontSetMatch(config, fontSets, SK_ARRAY_COUNT(fontSe
ts), | 205 SkAutoFcPattern match(FcFontSetMatch(config, fontSets, SK_ARRAY_COUNT(fontSe
ts), |
| 201 minimal, &result)); | 206 minimal, &result)); |
| 202 | 207 |
| 203 FcLangSet* matchLangSet; | 208 FcLangSet* matchLangSet; |
| 204 FcPatternGetLangSet(match, FC_LANG, 0, &matchLangSet); | 209 FcPatternGetLangSet(match, FC_LANG, 0, &matchLangSet); |
| 205 return FcLangEqual == FcLangSetHasLang(matchLangSet, (const FcChar8*)"matchl
ang") | 210 return FcLangEqual == FcLangSetHasLang(matchLangSet, (const FcChar8*)"matchl
ang") |
| 206 ? kIsWeak_WeakReturn : kIsStrong_WeakReturn; | 211 ? kIsWeak_WeakReturn : kIsStrong_WeakReturn; |
| 207 } | 212 } |
| 208 | 213 |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 481 virtual SkTypeface* createTypeface(int index) SK_OVERRIDE { | 486 virtual SkTypeface* createTypeface(int index) SK_OVERRIDE { |
| 482 FCLocker lock; | 487 FCLocker lock; |
| 483 | 488 |
| 484 FcPattern* match = fFontSet->fonts[index]; | 489 FcPattern* match = fFontSet->fonts[index]; |
| 485 return fFontMgr->createTypefaceFromFcPattern(match); | 490 return fFontMgr->createTypefaceFromFcPattern(match); |
| 486 } | 491 } |
| 487 | 492 |
| 488 virtual SkTypeface* matchStyle(const SkFontStyle& style) SK_OVERRIDE { | 493 virtual SkTypeface* matchStyle(const SkFontStyle& style) SK_OVERRIDE { |
| 489 FCLocker lock; | 494 FCLocker lock; |
| 490 | 495 |
| 491 SkAutoFcPattern pattern(FcPatternCreate()); | 496 SkAutoFcPattern pattern; |
| 492 if (NULL == pattern) { | |
| 493 return NULL; | |
| 494 } | |
| 495 | |
| 496 fcpattern_from_skfontstyle(style, pattern); | 497 fcpattern_from_skfontstyle(style, pattern); |
| 497 FcConfigSubstitute(fFontMgr->fFC, pattern, FcMatchPattern); | 498 FcConfigSubstitute(fFontMgr->fFC, pattern, FcMatchPattern); |
| 498 FcDefaultSubstitute(pattern); | 499 FcDefaultSubstitute(pattern); |
| 499 | 500 |
| 500 FcResult result; | 501 FcResult result; |
| 501 FcFontSet* fontSets[1] = { fFontSet }; | 502 FcFontSet* fontSets[1] = { fFontSet }; |
| 502 SkAutoFcPattern match(FcFontSetMatch(fFontMgr->fFC, | 503 SkAutoFcPattern match(FcFontSetMatch(fFontMgr->fFC, |
| 503 fontSets, SK_ARRAY_COUNT(fontSe
ts), | 504 fontSets, SK_ARRAY_COUNT(fontSe
ts), |
| 504 pattern, &result)); | 505 pattern, &result)); |
| 505 if (NULL == match) { | 506 if (NULL == match) { |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 643 continue; | 644 continue; |
| 644 } | 645 } |
| 645 if (0 == FcStrCmpIgnoreCase(patternString, fontString)) { | 646 if (0 == FcStrCmpIgnoreCase(patternString, fontString)) { |
| 646 return true; | 647 return true; |
| 647 } | 648 } |
| 648 } | 649 } |
| 649 } | 650 } |
| 650 return false; | 651 return false; |
| 651 } | 652 } |
| 652 | 653 |
| 653 static bool ValidPattern(FcPattern* pattern) { | 654 static bool FontAccessible(FcPattern* font) { |
| 654 // FontConfig can return fonts which are unreadable. | 655 // FontConfig can return fonts which are unreadable. |
| 655 const char* filename = get_string(pattern, FC_FILE, NULL); | 656 const char* filename = get_string(font, FC_FILE, NULL); |
| 656 if (NULL == filename) { | 657 if (NULL == filename) { |
| 657 return false; | 658 return false; |
| 658 } | 659 } |
| 659 return sk_exists(filename, kRead_SkFILE_Flag); | 660 return sk_exists(filename, kRead_SkFILE_Flag); |
| 660 } | 661 } |
| 661 | 662 |
| 662 static bool FontMatches(FcPattern* font, FcPattern* pattern) { | 663 static bool FontFamilyNameMatches(FcPattern* font, FcPattern* pattern) { |
| 663 return ValidPattern(font) && AnyMatching(font, pattern, FC_FAMILY); | 664 return AnyMatching(font, pattern, FC_FAMILY); |
| 665 } |
| 666 |
| 667 static bool FontContainsCharacter(FcPattern* font, uint32_t character) { |
| 668 FcResult result; |
| 669 FcCharSet* matchCharSet; |
| 670 for (int charSetId = 0; ; ++charSetId) { |
| 671 result = FcPatternGetCharSet(font, FC_CHARSET, charSetId, &matchChar
Set); |
| 672 if (FcResultNoId == result) { |
| 673 break; |
| 674 } |
| 675 if (FcResultMatch != result) { |
| 676 continue; |
| 677 } |
| 678 if (FcCharSetHasChar(matchCharSet, character)) { |
| 679 return true; |
| 680 } |
| 681 } |
| 682 return false; |
| 664 } | 683 } |
| 665 | 684 |
| 666 virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVER
RIDE { | 685 virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVER
RIDE { |
| 667 FCLocker lock; | 686 FCLocker lock; |
| 668 | 687 |
| 669 SkAutoFcPattern pattern(FcPatternCreate()); | 688 SkAutoFcPattern pattern; |
| 670 if (NULL == pattern) { | |
| 671 return NULL; | |
| 672 } | |
| 673 | |
| 674 FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName); | 689 FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName); |
| 675 FcConfigSubstitute(fFC, pattern, FcMatchPattern); | 690 FcConfigSubstitute(fFC, pattern, FcMatchPattern); |
| 676 FcDefaultSubstitute(pattern); | 691 FcDefaultSubstitute(pattern); |
| 677 | 692 |
| 678 FcPattern* matchPattern; | 693 FcPattern* matchPattern; |
| 679 SkAutoFcPattern strongPattern(NULL); | 694 SkAutoFcPattern strongPattern(NULL); |
| 680 if (familyName) { | 695 if (familyName) { |
| 681 strongPattern.reset(FcPatternDuplicate(pattern)); | 696 strongPattern.reset(FcPatternDuplicate(pattern)); |
| 682 remove_weak(strongPattern, FC_FAMILY); | 697 remove_weak(strongPattern, FC_FAMILY); |
| 683 matchPattern = strongPattern; | 698 matchPattern = strongPattern; |
| 684 } else { | 699 } else { |
| 685 matchPattern = pattern; | 700 matchPattern = pattern; |
| 686 } | 701 } |
| 687 | 702 |
| 688 SkAutoFcFontSet matches(FcFontSetCreate()); | 703 SkAutoFcFontSet matches; |
| 689 // TODO: Some families have 'duplicates' due to symbolic links. | 704 // TODO: Some families have 'duplicates' due to symbolic links. |
| 690 // The patterns are exactly the same except for the FC_FILE. | 705 // The patterns are exactly the same except for the FC_FILE. |
| 691 // It should be possible to collapse these patterns by normalizing. | 706 // It should be possible to collapse these patterns by normalizing. |
| 692 static const FcSetName fcNameSet[] = { FcSetSystem, FcSetApplication }; | 707 static const FcSetName fcNameSet[] = { FcSetSystem, FcSetApplication }; |
| 693 for (int setIndex = 0; setIndex < (int)SK_ARRAY_COUNT(fcNameSet); ++setI
ndex) { | 708 for (int setIndex = 0; setIndex < (int)SK_ARRAY_COUNT(fcNameSet); ++setI
ndex) { |
| 694 // Return value of FcConfigGetFonts must not be destroyed. | 709 // Return value of FcConfigGetFonts must not be destroyed. |
| 695 FcFontSet* allFonts(FcConfigGetFonts(fFC, fcNameSet[setIndex])); | 710 FcFontSet* allFonts(FcConfigGetFonts(fFC, fcNameSet[setIndex])); |
| 696 if (NULL == allFonts) { | 711 if (NULL == allFonts) { |
| 697 continue; | 712 continue; |
| 698 } | 713 } |
| 699 | 714 |
| 700 for (int fontIndex = 0; fontIndex < allFonts->nfont; ++fontIndex) { | 715 for (int fontIndex = 0; fontIndex < allFonts->nfont; ++fontIndex) { |
| 701 if (FontMatches(allFonts->fonts[fontIndex], matchPattern)) { | 716 FcPattern* font = allFonts->fonts[fontIndex]; |
| 702 FcFontSetAdd(matches, | 717 if (FontAccessible(font) && FontFamilyNameMatches(font, matchPat
tern)) { |
| 703 FcFontRenderPrepare(fFC, pattern, allFonts->fon
ts[fontIndex])); | 718 FcFontSetAdd(matches, FcFontRenderPrepare(fFC, pattern, font
)); |
| 704 } | 719 } |
| 705 } | 720 } |
| 706 } | 721 } |
| 707 | 722 |
| 708 return SkNEW_ARGS(StyleSet, (this, matches.detach())); | 723 return SkNEW_ARGS(StyleSet, (this, matches.detach())); |
| 709 } | 724 } |
| 710 | 725 |
| 711 virtual SkTypeface* onMatchFamilyStyle(const char familyName[], | 726 virtual SkTypeface* onMatchFamilyStyle(const char familyName[], |
| 712 const SkFontStyle& style) const SK_OV
ERRIDE | 727 const SkFontStyle& style) const SK_OV
ERRIDE |
| 713 { | 728 { |
| 714 FCLocker lock; | 729 FCLocker lock; |
| 715 | 730 |
| 716 SkAutoFcPattern pattern(FcPatternCreate()); | 731 SkAutoFcPattern pattern; |
| 717 if (NULL == pattern) { | |
| 718 return NULL; | |
| 719 } | |
| 720 | |
| 721 FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName); | 732 FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName); |
| 722 fcpattern_from_skfontstyle(style, pattern); | 733 fcpattern_from_skfontstyle(style, pattern); |
| 723 FcConfigSubstitute(fFC, pattern, FcMatchPattern); | 734 FcConfigSubstitute(fFC, pattern, FcMatchPattern); |
| 724 FcDefaultSubstitute(pattern); | 735 FcDefaultSubstitute(pattern); |
| 725 | 736 |
| 726 // We really want to match strong (prefered) and same (acceptable) only
here. | 737 // We really want to match strong (prefered) and same (acceptable) only
here. |
| 727 // If a family name was specified, assume that any weak matches after th
e last strong match | 738 // If a family name was specified, assume that any weak matches after th
e last strong match |
| 728 // are weak (default) and ignore them. | 739 // are weak (default) and ignore them. |
| 729 // The reason for is that after substitution the pattern for 'sans-serif
' looks like | 740 // The reason for is that after substitution the pattern for 'sans-serif
' looks like |
| 730 // "wwwwwwwwwwwwwwswww" where there are many weak but preferred names, f
ollowed by defaults. | 741 // "wwwwwwwwwwwwwwswww" where there are many weak but preferred names, f
ollowed by defaults. |
| 731 // So it is possible to have weakly matching but preferred names. | 742 // So it is possible to have weakly matching but preferred names. |
| 732 // In aliases, bindings are weak by default, so this is easy and common. | 743 // In aliases, bindings are weak by default, so this is easy and common. |
| 733 // If no family name was specified, we'll probably only get weak matches
, but that's ok. | 744 // If no family name was specified, we'll probably only get weak matches
, but that's ok. |
| 734 FcPattern* matchPattern; | 745 FcPattern* matchPattern; |
| 735 SkAutoFcPattern strongPattern(NULL); | 746 SkAutoFcPattern strongPattern(NULL); |
| 736 if (familyName) { | 747 if (familyName) { |
| 737 strongPattern.reset(FcPatternDuplicate(pattern)); | 748 strongPattern.reset(FcPatternDuplicate(pattern)); |
| 738 remove_weak(strongPattern, FC_FAMILY); | 749 remove_weak(strongPattern, FC_FAMILY); |
| 739 matchPattern = strongPattern; | 750 matchPattern = strongPattern; |
| 740 } else { | 751 } else { |
| 741 matchPattern = pattern; | 752 matchPattern = pattern; |
| 742 } | 753 } |
| 743 | 754 |
| 744 FcResult result; | 755 FcResult result; |
| 745 SkAutoFcPattern match(FcFontMatch(fFC, pattern, &result)); | 756 SkAutoFcPattern font(FcFontMatch(fFC, pattern, &result)); |
| 746 if (NULL == match || !FontMatches(match, matchPattern)) { | 757 if (NULL == font || !FontAccessible(font) || !FontFamilyNameMatches(font
, matchPattern)) { |
| 747 return NULL; | 758 return NULL; |
| 748 } | 759 } |
| 749 | 760 |
| 750 return createTypefaceFromFcPattern(match); | 761 return createTypefaceFromFcPattern(font); |
| 762 } |
| 763 |
| 764 virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], |
| 765 const SkFontStyle& style, |
| 766 const char bpc47[], |
| 767 uint32_t character) const SK
_OVERRIDE |
| 768 { |
| 769 FCLocker lock; |
| 770 |
| 771 SkAutoFcPattern pattern; |
| 772 FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName); |
| 773 fcpattern_from_skfontstyle(style, pattern); |
| 774 |
| 775 SkAutoFcCharSet charSet; |
| 776 FcCharSetAddChar(charSet, character); |
| 777 FcPatternAddCharSet(pattern, FC_CHARSET, charSet); |
| 778 |
| 779 if (bpc47) { |
| 780 SkAutoFcLangSet langSet; |
| 781 FcLangSetAdd(langSet, (const FcChar8*)bpc47); |
| 782 FcPatternAddLangSet(pattern, FC_LANG, langSet); |
| 783 } |
| 784 |
| 785 FcConfigSubstitute(fFC, pattern, FcMatchPattern); |
| 786 FcDefaultSubstitute(pattern); |
| 787 |
| 788 FcResult result; |
| 789 SkAutoFcPattern font(FcFontMatch(fFC, pattern, &result)); |
| 790 if (NULL == font || !FontAccessible(font) || !FontContainsCharacter(font
, character)) { |
| 791 return NULL; |
| 792 } |
| 793 |
| 794 return createTypefaceFromFcPattern(font); |
| 751 } | 795 } |
| 752 | 796 |
| 753 virtual SkTypeface* onMatchFaceStyle(const SkTypeface* typeface, | 797 virtual SkTypeface* onMatchFaceStyle(const SkTypeface* typeface, |
| 754 const SkFontStyle& style) const SK_OVER
RIDE | 798 const SkFontStyle& style) const SK_OVER
RIDE |
| 755 { | 799 { |
| 756 //TODO: should the SkTypeface_fontconfig know its family? | 800 //TODO: should the SkTypeface_fontconfig know its family? |
| 757 const SkTypeface_fontconfig* fcTypeface = | 801 const SkTypeface_fontconfig* fcTypeface = |
| 758 static_cast<const SkTypeface_fontconfig*>(typeface); | 802 static_cast<const SkTypeface_fontconfig*>(typeface); |
| 759 return this->matchFamilyStyle(get_string(fcTypeface->fPattern, FC_FAMILY
), style); | 803 return this->matchFamilyStyle(get_string(fcTypeface->fPattern, FC_FAMILY
), style); |
| 760 } | 804 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 800 return typeface.detach(); | 844 return typeface.detach(); |
| 801 } | 845 } |
| 802 | 846 |
| 803 return this->matchFamilyStyle(NULL, style); | 847 return this->matchFamilyStyle(NULL, style); |
| 804 } | 848 } |
| 805 }; | 849 }; |
| 806 | 850 |
| 807 SkFontMgr* SkFontMgr::Factory() { | 851 SkFontMgr* SkFontMgr::Factory() { |
| 808 return SkNEW(SkFontMgr_fontconfig); | 852 return SkNEW(SkFontMgr_fontconfig); |
| 809 } | 853 } |
| OLD | NEW |