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 #ifdef SK_BUILD_FOR_MAC | 9 #ifdef SK_BUILD_FOR_MAC |
10 #import <ApplicationServices/ApplicationServices.h> | 10 #import <ApplicationServices/ApplicationServices.h> |
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 id = (id & 0x3FFFFFFF) | 0x80000000; // make top two bits 10 | 443 id = (id & 0x3FFFFFFF) | 0x80000000; // make top two bits 10 |
444 } | 444 } |
445 return id; | 445 return id; |
446 } | 446 } |
447 | 447 |
448 #define WEIGHT_THRESHOLD ((SkFontStyle::kNormal_Weight + SkFontStyle::kBold_W
eight)/2) | 448 #define WEIGHT_THRESHOLD ((SkFontStyle::kNormal_Weight + SkFontStyle::kBold_W
eight)/2) |
449 | 449 |
450 class SkTypeface_Mac : public SkTypeface { | 450 class SkTypeface_Mac : public SkTypeface { |
451 public: | 451 public: |
452 SkTypeface_Mac(const SkFontStyle& fs, SkFontID fontID, bool isFixedPitch, | 452 SkTypeface_Mac(const SkFontStyle& fs, SkFontID fontID, bool isFixedPitch, |
453 CTFontRef fontRef, const char name[], bool isLocalStream) | 453 CTFontRef fontRef, const char requestedName[], bool isLocalSt
ream) |
454 : SkTypeface(fs, fontID, isFixedPitch) | 454 : SkTypeface(fs, fontID, isFixedPitch) |
455 , fName(name) | 455 , fRequestedName(requestedName) |
456 , fFontRef(fontRef) // caller has already called CFRetain for us | 456 , fFontRef(fontRef) // caller has already called CFRetain for us |
457 , fIsLocalStream(isLocalStream) | 457 , fIsLocalStream(isLocalStream) |
458 { | 458 { |
459 SkASSERT(fontRef); | 459 SkASSERT(fontRef); |
460 } | 460 } |
461 | 461 |
462 SkString fName; | 462 SkString fRequestedName; |
463 AutoCFRelease<CTFontRef> fFontRef; | 463 AutoCFRelease<CTFontRef> fFontRef; |
464 | 464 |
465 protected: | 465 protected: |
466 friend class SkFontHost; // to access our protected members for deprecate
d methods | 466 friend class SkFontHost; // to access our protected members for deprecate
d methods |
467 | 467 |
468 virtual int onGetUPEM() const SK_OVERRIDE; | 468 virtual int onGetUPEM() const SK_OVERRIDE; |
469 virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE; | 469 virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE; |
470 virtual void onGetFamilyName(SkString* familyName) const SK_OVERRIDE; | 470 virtual void onGetFamilyName(SkString* familyName) const SK_OVERRIDE; |
471 virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_
OVERRIDE; | 471 virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_
OVERRIDE; |
472 virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE; | 472 virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE; |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
579 SkTypefaceCache::Add(face, face->fontStyle()); | 579 SkTypefaceCache::Add(face, face->fontStyle()); |
580 // NewFromFontRef doesn't retain the parameter, but the typeface it | 580 // NewFromFontRef doesn't retain the parameter, but the typeface it |
581 // creates does release it in its destructor, so we balance that with | 581 // creates does release it in its destructor, so we balance that with |
582 // a retain call here. | 582 // a retain call here. |
583 CFRetain(fontRef); | 583 CFRetain(fontRef); |
584 } | 584 } |
585 SkASSERT(face->getRefCnt() > 1); | 585 SkASSERT(face->getRefCnt() > 1); |
586 return face; | 586 return face; |
587 } | 587 } |
588 | 588 |
589 struct NameStyleRec { | 589 struct NameStyle { |
590 const char* fName; | 590 const char* fName; |
591 SkFontStyle fStyle; | 591 SkFontStyle fStyle; |
592 }; | 592 }; |
593 | 593 |
594 static bool FindByNameStyle(SkTypeface* face, const SkFontStyle& style, void* ct
x) { | 594 static bool find_by_NameStyle(SkTypeface* cachedFace, const SkFontStyle& cachedS
tyle, void* ctx) { |
595 const SkTypeface_Mac* mface = reinterpret_cast<SkTypeface_Mac*>(face); | 595 const SkTypeface_Mac* cachedMacFace = static_cast<SkTypeface_Mac*>(cachedFac
e); |
596 const NameStyleRec* rec = reinterpret_cast<const NameStyleRec*>(ctx); | 596 const NameStyle* requested = static_cast<const NameStyle*>(ctx); |
597 | 597 |
598 return rec->fStyle == style && mface->fName.equals(rec->fName); | 598 return cachedStyle == requested->fStyle |
| 599 && cachedMacFace->fRequestedName.equals(requested->fName); |
599 } | 600 } |
600 | 601 |
601 static const char* map_css_names(const char* name) { | 602 static const char* map_css_names(const char* name) { |
602 static const struct { | 603 static const struct { |
603 const char* fFrom; // name the caller specified | 604 const char* fFrom; // name the caller specified |
604 const char* fTo; // "canonical" name we map to | 605 const char* fTo; // "canonical" name we map to |
605 } gPairs[] = { | 606 } gPairs[] = { |
606 { "sans-serif", "Helvetica" }, | 607 { "sans-serif", "Helvetica" }, |
607 { "serif", "Times" }, | 608 { "serif", "Times" }, |
608 { "monospace", "Courier" } | 609 { "monospace", "Courier" } |
(...skipping 1400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2009 return value * value; | 2010 return value * value; |
2010 } | 2011 } |
2011 | 2012 |
2012 // We normalize each axis (weight, width, italic) to be base-900 | 2013 // We normalize each axis (weight, width, italic) to be base-900 |
2013 static int compute_metric(const SkFontStyle& a, const SkFontStyle& b) { | 2014 static int compute_metric(const SkFontStyle& a, const SkFontStyle& b) { |
2014 return sqr(a.weight() - b.weight()) + | 2015 return sqr(a.weight() - b.weight()) + |
2015 sqr((a.width() - b.width()) * 100) + | 2016 sqr((a.width() - b.width()) * 100) + |
2016 sqr((a.isItalic() != b.isItalic()) * 900); | 2017 sqr((a.isItalic() != b.isItalic()) * 900); |
2017 } | 2018 } |
2018 | 2019 |
2019 struct NameFontStyleRec { | 2020 static SkTypeface* createFromDesc(CFStringRef cfFamilyName, CTFontDescriptorRef
desc) { |
2020 SkString fFamilyName; | 2021 NameStyle cacheRequest; |
2021 SkFontStyle fFontStyle; | 2022 SkString skFamilyName; |
2022 }; | 2023 CFStringToSkString(cfFamilyName, &skFamilyName); |
| 2024 cacheRequest.fName = skFamilyName.c_str(); |
| 2025 cacheRequest.fStyle = fontstyle_from_descriptor(desc, NULL); |
2023 | 2026 |
2024 static bool nameFontStyleProc(SkTypeface* face, const SkFontStyle&, void* ctx) { | 2027 SkTypeface* face = SkTypefaceCache::FindByProcAndRef(find_by_NameStyle, &cac
heRequest); |
2025 SkTypeface_Mac* macFace = (SkTypeface_Mac*)face; | |
2026 const NameFontStyleRec* rec = (const NameFontStyleRec*)ctx; | |
2027 | |
2028 return macFace->fontStyle() == rec->fFontStyle && | |
2029 macFace->fName == rec->fFamilyName; | |
2030 } | |
2031 | |
2032 static SkTypeface* createFromDesc(CFStringRef cfFamilyName, CTFontDescriptorRef
desc) { | |
2033 NameFontStyleRec rec; | |
2034 CFStringToSkString(cfFamilyName, &rec.fFamilyName); | |
2035 rec.fFontStyle = fontstyle_from_descriptor(desc, NULL); | |
2036 | |
2037 SkTypeface* face = SkTypefaceCache::FindByProcAndRef(nameFontStyleProc, &rec
); | |
2038 if (face) { | 2028 if (face) { |
2039 return face; | 2029 return face; |
2040 } | 2030 } |
2041 | 2031 |
2042 AutoCFRelease<CFDictionaryRef> fontFamilyNameDictionary( | 2032 AutoCFRelease<CFDictionaryRef> fontFamilyNameDictionary( |
2043 CFDictionaryCreate(kCFAllocatorDefault, | 2033 CFDictionaryCreate(kCFAllocatorDefault, |
2044 (const void**)&kCTFontFamilyNameAttribute, (const voi
d**)&cfFamilyName, | 2034 (const void**)&kCTFontFamilyNameAttribute, (const voi
d**)&cfFamilyName, |
2045 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionary
ValueCallBacks)); | 2035 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionary
ValueCallBacks)); |
2046 AutoCFRelease<CTFontDescriptorRef> fontDescriptor( | 2036 AutoCFRelease<CTFontDescriptorRef> fontDescriptor( |
2047 CTFontDescriptorCreateWithAttributes(fontFamilyNameDictionary)); | 2037 CTFontDescriptorCreateWithAttributes(fontFamilyNameDictionary)); |
2048 AutoCFRelease<CTFontRef> ctNamed(CTFontCreateWithFontDescriptor(fontDescript
or, 0, NULL)); | 2038 AutoCFRelease<CTFontRef> ctNamed(CTFontCreateWithFontDescriptor(fontDescript
or, 0, NULL)); |
2049 CTFontRef ctFont = CTFontCreateCopyWithAttributes(ctNamed, 1, NULL, desc); | 2039 CTFontRef ctFont = CTFontCreateCopyWithAttributes(ctNamed, 1, NULL, desc); |
2050 if (NULL == ctFont) { | 2040 if (NULL == ctFont) { |
2051 return NULL; | 2041 return NULL; |
2052 } | 2042 } |
2053 | 2043 |
2054 SkString str; | |
2055 CFStringToSkString(cfFamilyName, &str); | |
2056 | |
2057 bool isFixedPitch; | 2044 bool isFixedPitch; |
2058 AutoCFRelease<CTFontDescriptorRef> ctFontDesc(CTFontCopyFontDescriptor(ctFon
t)); | 2045 AutoCFRelease<CTFontDescriptorRef> ctFontDesc(CTFontCopyFontDescriptor(ctFon
t)); |
2059 (void)fontstyle_from_descriptor(ctFontDesc, &isFixedPitch); | 2046 (void)fontstyle_from_descriptor(ctFontDesc, &isFixedPitch); |
2060 SkFontID fontID = CTFontRef_to_SkFontID(ctFont); | 2047 SkFontID fontID = CTFontRef_to_SkFontID(ctFont); |
2061 | 2048 |
2062 face = SkNEW_ARGS(SkTypeface_Mac, (rec.fFontStyle, fontID, isFixedPitch, | 2049 face = SkNEW_ARGS(SkTypeface_Mac, (cacheRequest.fStyle, fontID, isFixedPitch
, |
2063 ctFont, str.c_str(), false)); | 2050 ctFont, skFamilyName.c_str(), false)); |
2064 SkTypefaceCache::Add(face, face->fontStyle()); | 2051 SkTypefaceCache::Add(face, face->fontStyle()); |
2065 return face; | 2052 return face; |
2066 } | 2053 } |
2067 | 2054 |
2068 class SkFontStyleSet_Mac : public SkFontStyleSet { | 2055 class SkFontStyleSet_Mac : public SkFontStyleSet { |
2069 public: | 2056 public: |
2070 SkFontStyleSet_Mac(CFStringRef familyName, CTFontDescriptorRef desc) | 2057 SkFontStyleSet_Mac(CFStringRef familyName, CTFontDescriptorRef desc) |
2071 : fArray(CTFontDescriptorCreateMatchingFontDescriptors(desc, NULL)) | 2058 : fArray(CTFontDescriptorCreateMatchingFontDescriptors(desc, NULL)) |
2072 , fFamilyName(familyName) | 2059 , fFamilyName(familyName) |
2073 , fCount(0) { | 2060 , fCount(0) { |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2234 | 2221 |
2235 SkFontStyle style = SkFontStyle((SkTypeface::Style)styleBits); | 2222 SkFontStyle style = SkFontStyle((SkTypeface::Style)styleBits); |
2236 if (familyName) { | 2223 if (familyName) { |
2237 familyName = map_css_names(familyName); | 2224 familyName = map_css_names(familyName); |
2238 } | 2225 } |
2239 | 2226 |
2240 if (!familyName || !*familyName) { | 2227 if (!familyName || !*familyName) { |
2241 familyName = FONT_DEFAULT_NAME; | 2228 familyName = FONT_DEFAULT_NAME; |
2242 } | 2229 } |
2243 | 2230 |
2244 NameStyleRec rec = { familyName, style }; | 2231 NameStyle cacheRequest = { familyName, style }; |
2245 SkTypeface* face = SkTypefaceCache::FindByProcAndRef(FindByNameStyle, &r
ec); | 2232 SkTypeface* face = SkTypefaceCache::FindByProcAndRef(find_by_NameStyle,
&cacheRequest); |
2246 | 2233 |
2247 if (NULL == face) { | 2234 if (NULL == face) { |
2248 face = NewFromName(familyName, style); | 2235 face = NewFromName(familyName, style); |
2249 if (face) { | 2236 if (face) { |
2250 SkTypefaceCache::Add(face, style); | 2237 SkTypefaceCache::Add(face, style); |
2251 } else { | 2238 } else { |
2252 face = GetDefaultFace(); | 2239 face = GetDefaultFace(); |
2253 face->ref(); | 2240 face->ref(); |
2254 } | 2241 } |
2255 } | 2242 } |
2256 return face; | 2243 return face; |
2257 } | 2244 } |
2258 }; | 2245 }; |
2259 | 2246 |
2260 /////////////////////////////////////////////////////////////////////////////// | 2247 /////////////////////////////////////////////////////////////////////////////// |
2261 | 2248 |
2262 SkFontMgr* SkFontMgr::Factory() { | 2249 SkFontMgr* SkFontMgr::Factory() { |
2263 return SkNEW(SkFontMgr_Mac); | 2250 return SkNEW(SkFontMgr_Mac); |
2264 } | 2251 } |
OLD | NEW |