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 |