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 |
354 static bool find_dict_float(CFDictionaryRef dict, CFStringRef name, float* value
) { | 361 static bool find_dict_float(CFDictionaryRef dict, CFStringRef name, float* value
) { |
355 CFNumberRef num; | 362 CFNumberRef num; |
356 return CFDictionaryGetValueIfPresent(dict, name, (const void**)&num) | 363 return CFDictionaryGetValueIfPresent(dict, name, (const void**)&num) |
357 && CFNumberIsFloatType(num) | 364 && CFNumberIsFloatType(num) |
358 && CFNumberGetValue(num, kCFNumberFloatType, value); | 365 && CFNumberGetValue(num, kCFNumberFloatType, value); |
359 } | 366 } |
360 | 367 |
361 static int unit_weight_to_fontstyle(float unit) { | 368 static int unit_weight_to_fontstyle(float unit) { |
362 float value; | 369 float value; |
363 if (unit < 0) { | 370 if (unit < 0) { |
364 value = 100 + (1 + unit) * 300; | 371 value = 100 + (1 + unit) * 300; |
365 } else { | 372 } else { |
366 value = 400 + unit * 500; | 373 value = 400 + unit * 500; |
367 } | 374 } |
368 return sk_float_round2int(value); | 375 return sk_float_round2int(value); |
369 } | 376 } |
370 | 377 |
371 static int unit_width_to_fontstyle(float unit) { | 378 static int unit_width_to_fontstyle(float unit) { |
372 float value; | 379 float value; |
373 if (unit < 0) { | 380 if (unit < 0) { |
374 value = 1 + (1 + unit) * 4; | 381 value = 1 + (1 + unit) * 4; |
375 } else { | 382 } else { |
376 value = 5 + unit * 4; | 383 value = 5 + unit * 4; |
377 } | 384 } |
378 return sk_float_round2int(value); | 385 return sk_float_round2int(value); |
379 } | 386 } |
380 | 387 |
381 static SkFontStyle fontstyle_from_descriptor(CTFontDescriptorRef desc) { | 388 static SkFontStyle fontstyle_from_descriptor(CTFontDescriptorRef desc, bool* isF
ixedPitch) { |
382 AutoCFRelease<CFDictionaryRef> dict( | 389 AutoCFRelease<CFDictionaryRef> dict( |
383 (CFDictionaryRef)CTFontDescriptorCopyAttribute(desc, kCTFontTraitsAt
tribute)); | 390 (CFDictionaryRef)CTFontDescriptorCopyAttribute(desc, kCTFontTraitsAt
tribute)); |
384 if (NULL == dict.get()) { | 391 if (NULL == dict.get()) { |
385 return SkFontStyle(); | 392 return SkFontStyle(); |
386 } | 393 } |
387 | 394 |
| 395 CTFontSymbolicTraits traits; |
| 396 if (!find_dict_traits(dict, &traits)) { |
| 397 traits = 0; |
| 398 } |
| 399 if (isFixedPitch) { |
| 400 *isFixedPitch = SkToBool(traits & kCTFontMonoSpaceTrait); |
| 401 } |
| 402 |
388 float weight, width, slant; | 403 float weight, width, slant; |
389 if (!find_dict_float(dict, kCTFontWeightTrait, &weight)) { | 404 if (!find_dict_float(dict, kCTFontWeightTrait, &weight)) { |
390 weight = 0; | 405 weight = (traits & kCTFontBoldTrait) ? 0.5f : 0; |
391 } | 406 } |
392 if (!find_dict_float(dict, kCTFontWidthTrait, &width)) { | 407 if (!find_dict_float(dict, kCTFontWidthTrait, &width)) { |
393 width = 0; | 408 width = 0; |
394 } | 409 } |
395 if (!find_dict_float(dict, kCTFontSlantTrait, &slant)) { | 410 if (!find_dict_float(dict, kCTFontSlantTrait, &slant)) { |
396 slant = 0; | 411 slant = (traits & kCTFontItalicTrait) ? 0.5f : 0; |
397 } | 412 } |
398 | 413 |
399 return SkFontStyle(unit_weight_to_fontstyle(weight), | 414 return SkFontStyle(unit_weight_to_fontstyle(weight), |
400 unit_width_to_fontstyle(width), | 415 unit_width_to_fontstyle(width), |
401 slant ? SkFontStyle::kItalic_Slant | 416 slant ? SkFontStyle::kItalic_Slant |
402 : SkFontStyle::kUpright_Slant); | 417 : SkFontStyle::kUpright_Slant); |
403 } | 418 } |
404 | 419 |
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 | |
421 static SkFontID CTFontRef_to_SkFontID(CTFontRef fontRef) { | 420 static SkFontID CTFontRef_to_SkFontID(CTFontRef fontRef) { |
422 SkFontID id = 0; | 421 SkFontID id = 0; |
423 // CTFontGetPlatformFont and ATSFontRef are not supported on iOS, so we have to | 422 // CTFontGetPlatformFont and ATSFontRef are not supported on iOS, so we have to |
424 // bracket this to be Mac only. | 423 // bracket this to be Mac only. |
425 #ifdef SK_BUILD_FOR_MAC | 424 #ifdef SK_BUILD_FOR_MAC |
426 ATSFontRef ats = CTFontGetPlatformFont(fontRef, NULL); | 425 ATSFontRef ats = CTFontGetPlatformFont(fontRef, NULL); |
427 id = (SkFontID)ats; | 426 id = (SkFontID)ats; |
428 if (id != 0) { | 427 if (id != 0) { |
429 id &= 0x3FFFFFFF; // make top two bits 00 | 428 id &= 0x3FFFFFFF; // make top two bits 00 |
430 return id; | 429 return id; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 | 484 |
486 private: | 485 private: |
487 bool fIsLocalStream; | 486 bool fIsLocalStream; |
488 | 487 |
489 typedef SkTypeface INHERITED; | 488 typedef SkTypeface INHERITED; |
490 }; | 489 }; |
491 | 490 |
492 static SkTypeface* NewFromFontRef(CTFontRef fontRef, const char name[], bool isL
ocalStream) { | 491 static SkTypeface* NewFromFontRef(CTFontRef fontRef, const char name[], bool isL
ocalStream) { |
493 SkASSERT(fontRef); | 492 SkASSERT(fontRef); |
494 bool isFixedPitch; | 493 bool isFixedPitch; |
495 SkFontStyle style = SkFontStyle(computeStyleBits(fontRef, &isFixedPitch)); | 494 AutoCFRelease<CTFontDescriptorRef> desc(CTFontCopyFontDescriptor(fontRef)); |
| 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); | 2025 cacheRequest.fStyle = fontstyle_from_descriptor(desc, NULL); |
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 (void)computeStyleBits(ctFont, &isFixedPitch); | 2045 AutoCFRelease<CTFontDescriptorRef> ctFontDesc(CTFontCopyFontDescriptor(ctFon
t)); |
| 2046 (void)fontstyle_from_descriptor(ctFontDesc, &isFixedPitch); |
2046 SkFontID fontID = CTFontRef_to_SkFontID(ctFont); | 2047 SkFontID fontID = CTFontRef_to_SkFontID(ctFont); |
2047 | 2048 |
2048 face = SkNEW_ARGS(SkTypeface_Mac, (cacheRequest.fStyle, fontID, isFixedPitch
, | 2049 face = SkNEW_ARGS(SkTypeface_Mac, (cacheRequest.fStyle, fontID, isFixedPitch
, |
2049 ctFont, skFamilyName.c_str(), false)); | 2050 ctFont, skFamilyName.c_str(), false)); |
2050 SkTypefaceCache::Add(face, face->fontStyle()); | 2051 SkTypefaceCache::Add(face, face->fontStyle()); |
2051 return face; | 2052 return face; |
2052 } | 2053 } |
2053 | 2054 |
2054 class SkFontStyleSet_Mac : public SkFontStyleSet { | 2055 class SkFontStyleSet_Mac : public SkFontStyleSet { |
2055 public: | 2056 public: |
(...skipping 14 matching lines...) Expand all Loading... |
2070 } | 2071 } |
2071 | 2072 |
2072 virtual int count() SK_OVERRIDE { | 2073 virtual int count() SK_OVERRIDE { |
2073 return fCount; | 2074 return fCount; |
2074 } | 2075 } |
2075 | 2076 |
2076 virtual void getStyle(int index, SkFontStyle* style, SkString* name) SK_OVER
RIDE { | 2077 virtual void getStyle(int index, SkFontStyle* style, SkString* name) SK_OVER
RIDE { |
2077 SkASSERT((unsigned)index < (unsigned)fCount); | 2078 SkASSERT((unsigned)index < (unsigned)fCount); |
2078 CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(f
Array, index); | 2079 CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(f
Array, index); |
2079 if (style) { | 2080 if (style) { |
2080 *style = fontstyle_from_descriptor(desc); | 2081 *style = fontstyle_from_descriptor(desc, NULL); |
2081 } | 2082 } |
2082 if (name) { | 2083 if (name) { |
2083 if (!find_desc_str(desc, kCTFontStyleNameAttribute, name)) { | 2084 if (!find_desc_str(desc, kCTFontStyleNameAttribute, name)) { |
2084 name->reset(); | 2085 name->reset(); |
2085 } | 2086 } |
2086 } | 2087 } |
2087 } | 2088 } |
2088 | 2089 |
2089 virtual SkTypeface* createTypeface(int index) SK_OVERRIDE { | 2090 virtual SkTypeface* createTypeface(int index) SK_OVERRIDE { |
2090 SkASSERT((unsigned)index < (unsigned)CFArrayGetCount(fArray)); | 2091 SkASSERT((unsigned)index < (unsigned)CFArrayGetCount(fArray)); |
(...skipping 13 matching lines...) Expand all Loading... |
2104 CFArrayRef fArray; | 2105 CFArrayRef fArray; |
2105 CFStringRef fFamilyName; | 2106 CFStringRef fFamilyName; |
2106 int fCount; | 2107 int fCount; |
2107 | 2108 |
2108 CTFontDescriptorRef findMatchingDesc(const SkFontStyle& pattern) const { | 2109 CTFontDescriptorRef findMatchingDesc(const SkFontStyle& pattern) const { |
2109 int bestMetric = SK_MaxS32; | 2110 int bestMetric = SK_MaxS32; |
2110 CTFontDescriptorRef bestDesc = NULL; | 2111 CTFontDescriptorRef bestDesc = NULL; |
2111 | 2112 |
2112 for (int i = 0; i < fCount; ++i) { | 2113 for (int i = 0; i < fCount; ++i) { |
2113 CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtInd
ex(fArray, i); | 2114 CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtInd
ex(fArray, i); |
2114 int metric = compute_metric(pattern, fontstyle_from_descriptor(desc)
); | 2115 int metric = compute_metric(pattern, fontstyle_from_descriptor(desc,
NULL)); |
2115 if (0 == metric) { | 2116 if (0 == metric) { |
2116 return desc; | 2117 return desc; |
2117 } | 2118 } |
2118 if (metric < bestMetric) { | 2119 if (metric < bestMetric) { |
2119 bestMetric = metric; | 2120 bestMetric = metric; |
2120 bestDesc = desc; | 2121 bestDesc = desc; |
2121 } | 2122 } |
2122 } | 2123 } |
2123 SkASSERT(bestDesc); | 2124 SkASSERT(bestDesc); |
2124 return bestDesc; | 2125 return bestDesc; |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2241 } | 2242 } |
2242 return face; | 2243 return face; |
2243 } | 2244 } |
2244 }; | 2245 }; |
2245 | 2246 |
2246 /////////////////////////////////////////////////////////////////////////////// | 2247 /////////////////////////////////////////////////////////////////////////////// |
2247 | 2248 |
2248 SkFontMgr* SkFontMgr::Factory() { | 2249 SkFontMgr* SkFontMgr::Factory() { |
2249 return SkNEW(SkFontMgr_Mac); | 2250 return SkNEW(SkFontMgr_Mac); |
2250 } | 2251 } |
OLD | NEW |