OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include <vector> | 9 #include <vector> |
10 #ifdef SK_BUILD_FOR_MAC | 10 #ifdef SK_BUILD_FOR_MAC |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 return *this; | 89 return *this; |
90 } | 90 } |
91 | 91 |
92 operator CFRef() const { return fCFRef; } | 92 operator CFRef() const { return fCFRef; } |
93 CFRef get() const { return fCFRef; } | 93 CFRef get() const { return fCFRef; } |
94 | 94 |
95 private: | 95 private: |
96 CFRef fCFRef; | 96 CFRef fCFRef; |
97 }; | 97 }; |
98 | 98 |
| 99 static CFStringRef make_CFString(const char str[]) { |
| 100 return CFStringCreateWithCString(NULL, str, kCFStringEncodingUTF8); |
| 101 } |
| 102 |
99 template<typename T> class AutoCGTable : SkNoncopyable { | 103 template<typename T> class AutoCGTable : SkNoncopyable { |
100 public: | 104 public: |
101 AutoCGTable(CGFontRef font) | 105 AutoCGTable(CGFontRef font) |
102 //Undocumented: the tag parameter in this call is expected in machine order
and not BE order. | 106 //Undocumented: the tag parameter in this call is expected in machine order
and not BE order. |
103 : fCFData(CGFontCopyTableForTag(font, SkSetFourByteTag(T::TAG0, T::TAG1, T::
TAG2, T::TAG3))) | 107 : fCFData(CGFontCopyTableForTag(font, SkSetFourByteTag(T::TAG0, T::TAG1, T::
TAG2, T::TAG3))) |
104 , fData(fCFData ? reinterpret_cast<const T*>(CFDataGetBytePtr(fCFData)) : NU
LL) | 108 , fData(fCFData ? reinterpret_cast<const T*>(CFDataGetBytePtr(fCFData)) : NU
LL) |
105 { } | 109 { } |
106 | 110 |
107 const T* operator->() const { return fData; } | 111 const T* operator->() const { return fData; } |
108 | 112 |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 | 495 |
492 CTFontSymbolicTraits ctFontTraits = 0; | 496 CTFontSymbolicTraits ctFontTraits = 0; |
493 if (theStyle & SkTypeface::kBold) { | 497 if (theStyle & SkTypeface::kBold) { |
494 ctFontTraits |= kCTFontBoldTrait; | 498 ctFontTraits |= kCTFontBoldTrait; |
495 } | 499 } |
496 if (theStyle & SkTypeface::kItalic) { | 500 if (theStyle & SkTypeface::kItalic) { |
497 ctFontTraits |= kCTFontItalicTrait; | 501 ctFontTraits |= kCTFontItalicTrait; |
498 } | 502 } |
499 | 503 |
500 // Create the font info | 504 // Create the font info |
501 AutoCFRelease<CFStringRef> cfFontName( | 505 AutoCFRelease<CFStringRef> cfFontName(make_CFString(familyName)); |
502 CFStringCreateWithCString(NULL, familyName, kCFStringEncodingUTF8)); | |
503 | 506 |
504 AutoCFRelease<CFNumberRef> cfFontTraits( | 507 AutoCFRelease<CFNumberRef> cfFontTraits( |
505 CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &ctFontTrai
ts)); | 508 CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &ctFontTrai
ts)); |
506 | 509 |
507 AutoCFRelease<CFMutableDictionaryRef> cfAttributes( | 510 AutoCFRelease<CFMutableDictionaryRef> cfAttributes( |
508 CFDictionaryCreateMutable(kCFAllocatorDefault, 0, | 511 CFDictionaryCreateMutable(kCFAllocatorDefault, 0, |
509 &kCFTypeDictionaryKeyCallBacks, | 512 &kCFTypeDictionaryKeyCallBacks, |
510 &kCFTypeDictionaryValueCallBacks)); | 513 &kCFTypeDictionaryValueCallBacks)); |
511 | 514 |
512 AutoCFRelease<CFMutableDictionaryRef> cfTraits( | 515 AutoCFRelease<CFMutableDictionaryRef> cfTraits( |
(...skipping 1393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1906 static int unit_width_to_fontstyle(float unit) { | 1909 static int unit_width_to_fontstyle(float unit) { |
1907 float value; | 1910 float value; |
1908 if (unit < 0) { | 1911 if (unit < 0) { |
1909 value = 1 + (1 + unit) * 4; | 1912 value = 1 + (1 + unit) * 4; |
1910 } else { | 1913 } else { |
1911 value = 5 + unit * 4; | 1914 value = 5 + unit * 4; |
1912 } | 1915 } |
1913 return sk_float_round2int(value); | 1916 return sk_float_round2int(value); |
1914 } | 1917 } |
1915 | 1918 |
| 1919 static inline int sqr(int value) { |
| 1920 SkASSERT(SkAbs32(value) < 0x7FFF); // check for overflow |
| 1921 return value * value; |
| 1922 } |
| 1923 |
| 1924 // We normalize each axis (weight, width, italic) to be base-900 |
| 1925 static int compute_metric(const SkFontStyle& a, const SkFontStyle& b) { |
| 1926 return sqr(a.weight() - b.weight()) + |
| 1927 sqr((a.width() - b.width()) * 100) + |
| 1928 sqr((a.isItalic() != b.isItalic()) * 900); |
| 1929 } |
| 1930 |
1916 static SkFontStyle desc2fontstyle(CTFontDescriptorRef desc) { | 1931 static SkFontStyle desc2fontstyle(CTFontDescriptorRef desc) { |
1917 AutoCFRelease<CFDictionaryRef> dict( | 1932 AutoCFRelease<CFDictionaryRef> dict( |
1918 (CFDictionaryRef)CTFontDescriptorCopyAttribute(desc, | 1933 (CFDictionaryRef)CTFontDescriptorCopyAttribute(desc, |
1919 kCTFontTraitsAttribute)); | 1934 kCTFontTraitsAttribute)); |
1920 if (NULL == dict.get()) { | 1935 if (NULL == dict.get()) { |
1921 return SkFontStyle(); | 1936 return SkFontStyle(); |
1922 } | 1937 } |
1923 | 1938 |
1924 float weight, width, slant; | 1939 float weight, width, slant; |
1925 if (!find_dict_float(dict, kCTFontWeightTrait, &weight)) { | 1940 if (!find_dict_float(dict, kCTFontWeightTrait, &weight)) { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2019 } | 2034 } |
2020 } | 2035 } |
2021 | 2036 |
2022 virtual SkTypeface* createTypeface(int index) SK_OVERRIDE { | 2037 virtual SkTypeface* createTypeface(int index) SK_OVERRIDE { |
2023 SkASSERT((unsigned)index < (unsigned)CFArrayGetCount(fArray)); | 2038 SkASSERT((unsigned)index < (unsigned)CFArrayGetCount(fArray)); |
2024 CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(f
Array, index); | 2039 CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(f
Array, index); |
2025 | 2040 |
2026 return createFromDesc(fFamilyName, desc); | 2041 return createFromDesc(fFamilyName, desc); |
2027 } | 2042 } |
2028 | 2043 |
| 2044 virtual SkTypeface* matchStyle(const SkFontStyle& pattern) SK_OVERRIDE { |
| 2045 if (0 == fCount) { |
| 2046 return NULL; |
| 2047 } |
| 2048 return createFromDesc(fFamilyName, findMatchingDesc(pattern)); |
| 2049 } |
| 2050 |
2029 private: | 2051 private: |
2030 CFArrayRef fArray; | 2052 CFArrayRef fArray; |
2031 CFStringRef fFamilyName; | 2053 CFStringRef fFamilyName; |
2032 int fCount; | 2054 int fCount; |
| 2055 |
| 2056 CTFontDescriptorRef findMatchingDesc(const SkFontStyle& pattern) const { |
| 2057 int bestMetric = SK_MaxS32; |
| 2058 CTFontDescriptorRef bestDesc = NULL; |
| 2059 |
| 2060 for (int i = 0; i < fCount; ++i) { |
| 2061 CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtInd
ex(fArray, i); |
| 2062 int metric = compute_metric(pattern, desc2fontstyle(desc)); |
| 2063 if (0 == metric) { |
| 2064 return desc; |
| 2065 } |
| 2066 if (metric < bestMetric) { |
| 2067 bestMetric = metric; |
| 2068 bestDesc = desc; |
| 2069 } |
| 2070 } |
| 2071 SkASSERT(bestDesc); |
| 2072 return bestDesc; |
| 2073 } |
2033 }; | 2074 }; |
2034 | 2075 |
2035 class SkFontMgr_Mac : public SkFontMgr { | 2076 class SkFontMgr_Mac : public SkFontMgr { |
2036 int fCount; | 2077 int fCount; |
2037 CFArrayRef fNames; | 2078 CFArrayRef fNames; |
2038 | 2079 |
2039 CFStringRef stringAt(int index) const { | 2080 CFStringRef stringAt(int index) const { |
2040 SkASSERT((unsigned)index < (unsigned)fCount); | 2081 SkASSERT((unsigned)index < (unsigned)fCount); |
2041 return (CFStringRef)CFArrayGetValueAtIndex(fNames, index); | 2082 return (CFStringRef)CFArrayGetValueAtIndex(fNames, index); |
2042 } | 2083 } |
2043 | 2084 |
2044 void lazyInit() { | 2085 void lazyInit() { |
2045 if (NULL == fNames) { | 2086 if (NULL == fNames) { |
2046 fNames = SkCTFontManagerCopyAvailableFontFamilyNames(); | 2087 fNames = SkCTFontManagerCopyAvailableFontFamilyNames(); |
2047 fCount = fNames ? CFArrayGetCount(fNames) : 0; | 2088 fCount = fNames ? CFArrayGetCount(fNames) : 0; |
2048 } | 2089 } |
2049 } | 2090 } |
2050 | 2091 |
| 2092 static SkFontStyleSet* CreateSet(CFStringRef cfFamilyName) { |
| 2093 AutoCFRelease<CFMutableDictionaryRef> cfAttr( |
| 2094 CFDictionaryCreateMutable(kCFAllocatorDefault, 0, |
| 2095 &kCFTypeDictionaryKeyCallBacks, |
| 2096 &kCFTypeDictionaryValueCallBacks)); |
| 2097 |
| 2098 CFDictionaryAddValue(cfAttr, kCTFontFamilyNameAttribute, cfFamilyName); |
| 2099 |
| 2100 AutoCFRelease<CTFontDescriptorRef> desc( |
| 2101 CTFontDescriptorCreateWithAttributes(cfAttr)); |
| 2102 return SkNEW_ARGS(SkFontStyleSet_Mac, (cfFamilyName, desc)); |
| 2103 } |
| 2104 |
2051 public: | 2105 public: |
2052 SkFontMgr_Mac() : fCount(0), fNames(NULL) {} | 2106 SkFontMgr_Mac() : fCount(0), fNames(NULL) {} |
2053 | 2107 |
2054 virtual ~SkFontMgr_Mac() { | 2108 virtual ~SkFontMgr_Mac() { |
2055 CFSafeRelease(fNames); | 2109 CFSafeRelease(fNames); |
2056 } | 2110 } |
2057 | 2111 |
2058 protected: | 2112 protected: |
2059 virtual int onCountFamilies() SK_OVERRIDE { | 2113 virtual int onCountFamilies() SK_OVERRIDE { |
2060 this->lazyInit(); | 2114 this->lazyInit(); |
2061 return fCount; | 2115 return fCount; |
2062 } | 2116 } |
2063 | 2117 |
2064 virtual void onGetFamilyName(int index, SkString* familyName) SK_OVERRIDE { | 2118 virtual void onGetFamilyName(int index, SkString* familyName) SK_OVERRIDE { |
2065 this->lazyInit(); | 2119 this->lazyInit(); |
2066 if ((unsigned)index < (unsigned)fCount) { | 2120 if ((unsigned)index < (unsigned)fCount) { |
2067 CFStringToSkString(this->stringAt(index), familyName); | 2121 CFStringToSkString(this->stringAt(index), familyName); |
2068 } else { | 2122 } else { |
2069 familyName->reset(); | 2123 familyName->reset(); |
2070 } | 2124 } |
2071 } | 2125 } |
2072 | 2126 |
2073 virtual SkFontStyleSet* onCreateStyleSet(int index) SK_OVERRIDE { | 2127 virtual SkFontStyleSet* onCreateStyleSet(int index) SK_OVERRIDE { |
2074 this->lazyInit(); | 2128 this->lazyInit(); |
2075 if ((unsigned)index >= (unsigned)fCount) { | 2129 if ((unsigned)index >= (unsigned)fCount) { |
2076 return NULL; | 2130 return NULL; |
2077 } | 2131 } |
2078 | 2132 return CreateSet(this->stringAt(index)); |
2079 AutoCFRelease<CFMutableDictionaryRef> cfAttr( | |
2080 CFDictionaryCreateMutable(kCFAllocatorDefault, 0, | |
2081 &kCFTypeDictionaryKeyCallBacks, | |
2082 &kCFTypeDictionaryValueCallBacks)); | |
2083 | |
2084 CFDictionaryAddValue(cfAttr, kCTFontFamilyNameAttribute, | |
2085 this->stringAt(index)); | |
2086 | |
2087 AutoCFRelease<CTFontDescriptorRef> desc( | |
2088 CTFontDescriptorCreateWithAttributes(cfAttr)); | |
2089 return SkNEW_ARGS(SkFontStyleSet_Mac, (this->stringAt(index), desc)); | |
2090 } | 2133 } |
2091 | 2134 |
| 2135 virtual SkFontStyleSet* onMatchFamily(const char familyName[]) SK_OVERRIDE { |
| 2136 AutoCFRelease<CFStringRef> cfName(make_CFString(familyName)); |
| 2137 return CreateSet(cfName); |
| 2138 } |
| 2139 |
2092 virtual SkTypeface* onMatchFamilyStyle(const char familyName[], | 2140 virtual SkTypeface* onMatchFamilyStyle(const char familyName[], |
2093 const SkFontStyle&) SK_OVERRIDE { | 2141 const SkFontStyle&) SK_OVERRIDE { |
2094 return NULL; | 2142 return NULL; |
2095 } | 2143 } |
2096 | 2144 |
2097 virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember, | 2145 virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember, |
2098 const SkFontStyle&) SK_OVERRIDE { | 2146 const SkFontStyle&) SK_OVERRIDE { |
2099 return NULL; | 2147 return NULL; |
2100 } | 2148 } |
2101 | 2149 |
(...skipping 22 matching lines...) Expand all Loading... |
2124 return NULL; | 2172 return NULL; |
2125 } | 2173 } |
2126 return create_from_dataProvider(pr); | 2174 return create_from_dataProvider(pr); |
2127 } | 2175 } |
2128 }; | 2176 }; |
2129 | 2177 |
2130 SkFontMgr* SkFontMgr::Factory() { | 2178 SkFontMgr* SkFontMgr::Factory() { |
2131 return SkNEW(SkFontMgr_Mac); | 2179 return SkNEW(SkFontMgr_Mac); |
2132 } | 2180 } |
2133 #endif | 2181 #endif |
OLD | NEW |