| 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 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 344 } | 344 } |
| 345 }; | 345 }; |
| 346 | 346 |
| 347 Offscreen::Offscreen() : fRGBSpace(NULL), fCG(NULL), | 347 Offscreen::Offscreen() : fRGBSpace(NULL), fCG(NULL), |
| 348 fDoAA(false), fDoLCD(false) { | 348 fDoAA(false), fDoLCD(false) { |
| 349 fSize.set(0, 0); | 349 fSize.set(0, 0); |
| 350 } | 350 } |
| 351 | 351 |
| 352 /////////////////////////////////////////////////////////////////////////////// | 352 /////////////////////////////////////////////////////////////////////////////// |
| 353 | 353 |
| 354 static bool find_dict_traits(CFDictionaryRef dict, CTFontSymbolicTraits* traits)
{ | |
| 355 CFNumberRef num; | |
| 356 return CFDictionaryGetValueIfPresent(dict, kCTFontSymbolicTrait, (const void
**)&num) | |
| 357 && CFNumberIsFloatType(num) | |
| 358 && CFNumberGetValue(num, kCFNumberSInt32Type, traits); | |
| 359 } | |
| 360 | |
| 361 static bool find_dict_float(CFDictionaryRef dict, CFStringRef name, float* value
) { | 354 static bool find_dict_float(CFDictionaryRef dict, CFStringRef name, float* value
) { |
| 362 CFNumberRef num; | 355 CFNumberRef num; |
| 363 return CFDictionaryGetValueIfPresent(dict, name, (const void**)&num) | 356 return CFDictionaryGetValueIfPresent(dict, name, (const void**)&num) |
| 364 && CFNumberIsFloatType(num) | 357 && CFNumberIsFloatType(num) |
| 365 && CFNumberGetValue(num, kCFNumberFloatType, value); | 358 && CFNumberGetValue(num, kCFNumberFloatType, value); |
| 366 } | 359 } |
| 367 | 360 |
| 368 static int unit_weight_to_fontstyle(float unit) { | 361 static int unit_weight_to_fontstyle(float unit) { |
| 369 float value; | 362 float value; |
| 370 if (unit < 0) { | 363 if (unit < 0) { |
| 371 value = 100 + (1 + unit) * 300; | 364 value = 100 + (1 + unit) * 300; |
| 372 } else { | 365 } else { |
| 373 value = 400 + unit * 500; | 366 value = 400 + unit * 500; |
| 374 } | 367 } |
| 375 return sk_float_round2int(value); | 368 return sk_float_round2int(value); |
| 376 } | 369 } |
| 377 | 370 |
| 378 static int unit_width_to_fontstyle(float unit) { | 371 static int unit_width_to_fontstyle(float unit) { |
| 379 float value; | 372 float value; |
| 380 if (unit < 0) { | 373 if (unit < 0) { |
| 381 value = 1 + (1 + unit) * 4; | 374 value = 1 + (1 + unit) * 4; |
| 382 } else { | 375 } else { |
| 383 value = 5 + unit * 4; | 376 value = 5 + unit * 4; |
| 384 } | 377 } |
| 385 return sk_float_round2int(value); | 378 return sk_float_round2int(value); |
| 386 } | 379 } |
| 387 | 380 |
| 388 static SkFontStyle fontstyle_from_descriptor(CTFontDescriptorRef desc, bool* isF
ixedPitch) { | 381 static SkFontStyle fontstyle_from_descriptor(CTFontDescriptorRef desc) { |
| 389 AutoCFRelease<CFDictionaryRef> dict( | 382 AutoCFRelease<CFDictionaryRef> dict( |
| 390 (CFDictionaryRef)CTFontDescriptorCopyAttribute(desc, kCTFontTraitsAt
tribute)); | 383 (CFDictionaryRef)CTFontDescriptorCopyAttribute(desc, kCTFontTraitsAt
tribute)); |
| 391 if (NULL == dict.get()) { | 384 if (NULL == dict.get()) { |
| 392 return SkFontStyle(); | 385 return SkFontStyle(); |
| 393 } | 386 } |
| 394 | 387 |
| 395 CTFontSymbolicTraits traits; | |
| 396 if (!find_dict_traits(dict, &traits)) { | |
| 397 traits = 0; | |
| 398 } | |
| 399 if (isFixedPitch) { | |
| 400 *isFixedPitch = SkToBool(traits & kCTFontMonoSpaceTrait); | |
| 401 } | |
| 402 | |
| 403 float weight, width, slant; | 388 float weight, width, slant; |
| 404 if (!find_dict_float(dict, kCTFontWeightTrait, &weight)) { | 389 if (!find_dict_float(dict, kCTFontWeightTrait, &weight)) { |
| 405 weight = (traits & kCTFontBoldTrait) ? 0.5f : 0; | 390 weight = 0; |
| 406 } | 391 } |
| 407 if (!find_dict_float(dict, kCTFontWidthTrait, &width)) { | 392 if (!find_dict_float(dict, kCTFontWidthTrait, &width)) { |
| 408 width = 0; | 393 width = 0; |
| 409 } | 394 } |
| 410 if (!find_dict_float(dict, kCTFontSlantTrait, &slant)) { | 395 if (!find_dict_float(dict, kCTFontSlantTrait, &slant)) { |
| 411 slant = (traits & kCTFontItalicTrait) ? 0.5f : 0; | 396 slant = 0; |
| 412 } | 397 } |
| 413 | 398 |
| 414 return SkFontStyle(unit_weight_to_fontstyle(weight), | 399 return SkFontStyle(unit_weight_to_fontstyle(weight), |
| 415 unit_width_to_fontstyle(width), | 400 unit_width_to_fontstyle(width), |
| 416 slant ? SkFontStyle::kItalic_Slant | 401 slant ? SkFontStyle::kItalic_Slant |
| 417 : SkFontStyle::kUpright_Slant); | 402 : SkFontStyle::kUpright_Slant); |
| 418 } | 403 } |
| 419 | 404 |
| 405 static SkTypeface::Style computeStyleBits(CTFontRef font, bool* isFixedPitch) { |
| 406 unsigned style = SkTypeface::kNormal; |
| 407 CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(font); |
| 408 |
| 409 if (traits & kCTFontBoldTrait) { |
| 410 style |= SkTypeface::kBold; |
| 411 } |
| 412 if (traits & kCTFontItalicTrait) { |
| 413 style |= SkTypeface::kItalic; |
| 414 } |
| 415 if (isFixedPitch) { |
| 416 *isFixedPitch = (traits & kCTFontMonoSpaceTrait) != 0; |
| 417 } |
| 418 return (SkTypeface::Style)style; |
| 419 } |
| 420 |
| 420 static SkFontID CTFontRef_to_SkFontID(CTFontRef fontRef) { | 421 static SkFontID CTFontRef_to_SkFontID(CTFontRef fontRef) { |
| 421 SkFontID id = 0; | 422 SkFontID id = 0; |
| 422 // CTFontGetPlatformFont and ATSFontRef are not supported on iOS, so we have to | 423 // CTFontGetPlatformFont and ATSFontRef are not supported on iOS, so we have to |
| 423 // bracket this to be Mac only. | 424 // bracket this to be Mac only. |
| 424 #ifdef SK_BUILD_FOR_MAC | 425 #ifdef SK_BUILD_FOR_MAC |
| 425 ATSFontRef ats = CTFontGetPlatformFont(fontRef, NULL); | 426 ATSFontRef ats = CTFontGetPlatformFont(fontRef, NULL); |
| 426 id = (SkFontID)ats; | 427 id = (SkFontID)ats; |
| 427 if (id != 0) { | 428 if (id != 0) { |
| 428 id &= 0x3FFFFFFF; // make top two bits 00 | 429 id &= 0x3FFFFFFF; // make top two bits 00 |
| 429 return id; | 430 return id; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 484 | 485 |
| 485 private: | 486 private: |
| 486 bool fIsLocalStream; | 487 bool fIsLocalStream; |
| 487 | 488 |
| 488 typedef SkTypeface INHERITED; | 489 typedef SkTypeface INHERITED; |
| 489 }; | 490 }; |
| 490 | 491 |
| 491 static SkTypeface* NewFromFontRef(CTFontRef fontRef, const char name[], bool isL
ocalStream) { | 492 static SkTypeface* NewFromFontRef(CTFontRef fontRef, const char name[], bool isL
ocalStream) { |
| 492 SkASSERT(fontRef); | 493 SkASSERT(fontRef); |
| 493 bool isFixedPitch; | 494 bool isFixedPitch; |
| 494 AutoCFRelease<CTFontDescriptorRef> desc(CTFontCopyFontDescriptor(fontRef)); | 495 SkFontStyle style = SkFontStyle(computeStyleBits(fontRef, &isFixedPitch)); |
| 495 SkFontStyle style = fontstyle_from_descriptor(desc, &isFixedPitch); | |
| 496 SkFontID fontID = CTFontRef_to_SkFontID(fontRef); | 496 SkFontID fontID = CTFontRef_to_SkFontID(fontRef); |
| 497 | 497 |
| 498 return new SkTypeface_Mac(style, fontID, isFixedPitch, fontRef, name, isLoca
lStream); | 498 return new SkTypeface_Mac(style, fontID, isFixedPitch, fontRef, name, isLoca
lStream); |
| 499 } | 499 } |
| 500 | 500 |
| 501 static SkTypeface* NewFromName(const char familyName[], const SkFontStyle& theSt
yle) { | 501 static SkTypeface* NewFromName(const char familyName[], const SkFontStyle& theSt
yle) { |
| 502 CTFontRef ctFont = NULL; | 502 CTFontRef ctFont = NULL; |
| 503 | 503 |
| 504 CTFontSymbolicTraits ctFontTraits = 0; | 504 CTFontSymbolicTraits ctFontTraits = 0; |
| 505 if (theStyle.weight() >= SkFontStyle::kBold_Weight) { | 505 if (theStyle.weight() >= SkFontStyle::kBold_Weight) { |
| (...skipping 1509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2015 return sqr(a.weight() - b.weight()) + | 2015 return sqr(a.weight() - b.weight()) + |
| 2016 sqr((a.width() - b.width()) * 100) + | 2016 sqr((a.width() - b.width()) * 100) + |
| 2017 sqr((a.isItalic() != b.isItalic()) * 900); | 2017 sqr((a.isItalic() != b.isItalic()) * 900); |
| 2018 } | 2018 } |
| 2019 | 2019 |
| 2020 static SkTypeface* createFromDesc(CFStringRef cfFamilyName, CTFontDescriptorRef
desc) { | 2020 static SkTypeface* createFromDesc(CFStringRef cfFamilyName, CTFontDescriptorRef
desc) { |
| 2021 NameStyle cacheRequest; | 2021 NameStyle cacheRequest; |
| 2022 SkString skFamilyName; | 2022 SkString skFamilyName; |
| 2023 CFStringToSkString(cfFamilyName, &skFamilyName); | 2023 CFStringToSkString(cfFamilyName, &skFamilyName); |
| 2024 cacheRequest.fName = skFamilyName.c_str(); | 2024 cacheRequest.fName = skFamilyName.c_str(); |
| 2025 cacheRequest.fStyle = fontstyle_from_descriptor(desc, NULL); | 2025 cacheRequest.fStyle = fontstyle_from_descriptor(desc); |
| 2026 | 2026 |
| 2027 SkTypeface* face = SkTypefaceCache::FindByProcAndRef(find_by_NameStyle, &cac
heRequest); | 2027 SkTypeface* face = SkTypefaceCache::FindByProcAndRef(find_by_NameStyle, &cac
heRequest); |
| 2028 if (face) { | 2028 if (face) { |
| 2029 return face; | 2029 return face; |
| 2030 } | 2030 } |
| 2031 | 2031 |
| 2032 AutoCFRelease<CFDictionaryRef> fontFamilyNameDictionary( | 2032 AutoCFRelease<CFDictionaryRef> fontFamilyNameDictionary( |
| 2033 CFDictionaryCreate(kCFAllocatorDefault, | 2033 CFDictionaryCreate(kCFAllocatorDefault, |
| 2034 (const void**)&kCTFontFamilyNameAttribute, (const voi
d**)&cfFamilyName, | 2034 (const void**)&kCTFontFamilyNameAttribute, (const voi
d**)&cfFamilyName, |
| 2035 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionary
ValueCallBacks)); | 2035 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionary
ValueCallBacks)); |
| 2036 AutoCFRelease<CTFontDescriptorRef> fontDescriptor( | 2036 AutoCFRelease<CTFontDescriptorRef> fontDescriptor( |
| 2037 CTFontDescriptorCreateWithAttributes(fontFamilyNameDictionary)); | 2037 CTFontDescriptorCreateWithAttributes(fontFamilyNameDictionary)); |
| 2038 AutoCFRelease<CTFontRef> ctNamed(CTFontCreateWithFontDescriptor(fontDescript
or, 0, NULL)); | 2038 AutoCFRelease<CTFontRef> ctNamed(CTFontCreateWithFontDescriptor(fontDescript
or, 0, NULL)); |
| 2039 CTFontRef ctFont = CTFontCreateCopyWithAttributes(ctNamed, 1, NULL, desc); | 2039 CTFontRef ctFont = CTFontCreateCopyWithAttributes(ctNamed, 1, NULL, desc); |
| 2040 if (NULL == ctFont) { | 2040 if (NULL == ctFont) { |
| 2041 return NULL; | 2041 return NULL; |
| 2042 } | 2042 } |
| 2043 | 2043 |
| 2044 bool isFixedPitch; | 2044 bool isFixedPitch; |
| 2045 AutoCFRelease<CTFontDescriptorRef> ctFontDesc(CTFontCopyFontDescriptor(ctFon
t)); | 2045 (void)computeStyleBits(ctFont, &isFixedPitch); |
| 2046 (void)fontstyle_from_descriptor(ctFontDesc, &isFixedPitch); | |
| 2047 SkFontID fontID = CTFontRef_to_SkFontID(ctFont); | 2046 SkFontID fontID = CTFontRef_to_SkFontID(ctFont); |
| 2048 | 2047 |
| 2049 face = SkNEW_ARGS(SkTypeface_Mac, (cacheRequest.fStyle, fontID, isFixedPitch
, | 2048 face = SkNEW_ARGS(SkTypeface_Mac, (cacheRequest.fStyle, fontID, isFixedPitch
, |
| 2050 ctFont, skFamilyName.c_str(), false)); | 2049 ctFont, skFamilyName.c_str(), false)); |
| 2051 SkTypefaceCache::Add(face, face->fontStyle()); | 2050 SkTypefaceCache::Add(face, face->fontStyle()); |
| 2052 return face; | 2051 return face; |
| 2053 } | 2052 } |
| 2054 | 2053 |
| 2055 class SkFontStyleSet_Mac : public SkFontStyleSet { | 2054 class SkFontStyleSet_Mac : public SkFontStyleSet { |
| 2056 public: | 2055 public: |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2071 } | 2070 } |
| 2072 | 2071 |
| 2073 virtual int count() SK_OVERRIDE { | 2072 virtual int count() SK_OVERRIDE { |
| 2074 return fCount; | 2073 return fCount; |
| 2075 } | 2074 } |
| 2076 | 2075 |
| 2077 virtual void getStyle(int index, SkFontStyle* style, SkString* name) SK_OVER
RIDE { | 2076 virtual void getStyle(int index, SkFontStyle* style, SkString* name) SK_OVER
RIDE { |
| 2078 SkASSERT((unsigned)index < (unsigned)fCount); | 2077 SkASSERT((unsigned)index < (unsigned)fCount); |
| 2079 CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(f
Array, index); | 2078 CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(f
Array, index); |
| 2080 if (style) { | 2079 if (style) { |
| 2081 *style = fontstyle_from_descriptor(desc, NULL); | 2080 *style = fontstyle_from_descriptor(desc); |
| 2082 } | 2081 } |
| 2083 if (name) { | 2082 if (name) { |
| 2084 if (!find_desc_str(desc, kCTFontStyleNameAttribute, name)) { | 2083 if (!find_desc_str(desc, kCTFontStyleNameAttribute, name)) { |
| 2085 name->reset(); | 2084 name->reset(); |
| 2086 } | 2085 } |
| 2087 } | 2086 } |
| 2088 } | 2087 } |
| 2089 | 2088 |
| 2090 virtual SkTypeface* createTypeface(int index) SK_OVERRIDE { | 2089 virtual SkTypeface* createTypeface(int index) SK_OVERRIDE { |
| 2091 SkASSERT((unsigned)index < (unsigned)CFArrayGetCount(fArray)); | 2090 SkASSERT((unsigned)index < (unsigned)CFArrayGetCount(fArray)); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2105 CFArrayRef fArray; | 2104 CFArrayRef fArray; |
| 2106 CFStringRef fFamilyName; | 2105 CFStringRef fFamilyName; |
| 2107 int fCount; | 2106 int fCount; |
| 2108 | 2107 |
| 2109 CTFontDescriptorRef findMatchingDesc(const SkFontStyle& pattern) const { | 2108 CTFontDescriptorRef findMatchingDesc(const SkFontStyle& pattern) const { |
| 2110 int bestMetric = SK_MaxS32; | 2109 int bestMetric = SK_MaxS32; |
| 2111 CTFontDescriptorRef bestDesc = NULL; | 2110 CTFontDescriptorRef bestDesc = NULL; |
| 2112 | 2111 |
| 2113 for (int i = 0; i < fCount; ++i) { | 2112 for (int i = 0; i < fCount; ++i) { |
| 2114 CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtInd
ex(fArray, i); | 2113 CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtInd
ex(fArray, i); |
| 2115 int metric = compute_metric(pattern, fontstyle_from_descriptor(desc,
NULL)); | 2114 int metric = compute_metric(pattern, fontstyle_from_descriptor(desc)
); |
| 2116 if (0 == metric) { | 2115 if (0 == metric) { |
| 2117 return desc; | 2116 return desc; |
| 2118 } | 2117 } |
| 2119 if (metric < bestMetric) { | 2118 if (metric < bestMetric) { |
| 2120 bestMetric = metric; | 2119 bestMetric = metric; |
| 2121 bestDesc = desc; | 2120 bestDesc = desc; |
| 2122 } | 2121 } |
| 2123 } | 2122 } |
| 2124 SkASSERT(bestDesc); | 2123 SkASSERT(bestDesc); |
| 2125 return bestDesc; | 2124 return bestDesc; |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2242 } | 2241 } |
| 2243 return face; | 2242 return face; |
| 2244 } | 2243 } |
| 2245 }; | 2244 }; |
| 2246 | 2245 |
| 2247 /////////////////////////////////////////////////////////////////////////////// | 2246 /////////////////////////////////////////////////////////////////////////////// |
| 2248 | 2247 |
| 2249 SkFontMgr* SkFontMgr::Factory() { | 2248 SkFontMgr* SkFontMgr::Factory() { |
| 2250 return SkNEW(SkFontMgr_Mac); | 2249 return SkNEW(SkFontMgr_Mac); |
| 2251 } | 2250 } |
| OLD | NEW |