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

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

Issue 13312002: add matcher to fontstyleset (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « src/core/SkFontHost.cpp ('k') | 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 /* 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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/core/SkFontHost.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698