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 #include <vector> | |
10 #ifdef SK_BUILD_FOR_MAC | 9 #ifdef SK_BUILD_FOR_MAC |
11 #import <ApplicationServices/ApplicationServices.h> | 10 #import <ApplicationServices/ApplicationServices.h> |
12 #endif | 11 #endif |
13 | 12 |
14 #ifdef SK_BUILD_FOR_IOS | 13 #ifdef SK_BUILD_FOR_IOS |
15 #include <CoreText/CoreText.h> | 14 #include <CoreText/CoreText.h> |
16 #include <CoreText/CTFontManager.h> | 15 #include <CoreText/CTFontManager.h> |
17 #include <CoreGraphics/CoreGraphics.h> | 16 #include <CoreGraphics/CoreGraphics.h> |
18 #include <CoreFoundation/CoreFoundation.h> | 17 #include <CoreFoundation/CoreFoundation.h> |
19 #endif | 18 #endif |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 } | 344 } |
346 }; | 345 }; |
347 | 346 |
348 Offscreen::Offscreen() : fRGBSpace(NULL), fCG(NULL), | 347 Offscreen::Offscreen() : fRGBSpace(NULL), fCG(NULL), |
349 fDoAA(false), fDoLCD(false) { | 348 fDoAA(false), fDoLCD(false) { |
350 fSize.set(0, 0); | 349 fSize.set(0, 0); |
351 } | 350 } |
352 | 351 |
353 /////////////////////////////////////////////////////////////////////////////// | 352 /////////////////////////////////////////////////////////////////////////////// |
354 | 353 |
355 static SkTypeface::Style computeStyleBits(CTFontRef font, bool* isFixedPitch) { | 354 static bool find_dict_traits(CFDictionaryRef dict, CTFontSymbolicTraits* traits)
{ |
356 unsigned style = SkTypeface::kNormal; | 355 CFNumberRef num; |
357 CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(font); | 356 return CFDictionaryGetValueIfPresent(dict, kCTFontSymbolicTrait, (const void
**)&num) |
| 357 && CFNumberIsFloatType(num) |
| 358 && CFNumberGetValue(num, kCFNumberSInt32Type, traits); |
| 359 } |
358 | 360 |
359 if (traits & kCTFontBoldTrait) { | 361 static bool find_dict_float(CFDictionaryRef dict, CFStringRef name, float* value
) { |
360 style |= SkTypeface::kBold; | 362 CFNumberRef num; |
| 363 return CFDictionaryGetValueIfPresent(dict, name, (const void**)&num) |
| 364 && CFNumberIsFloatType(num) |
| 365 && CFNumberGetValue(num, kCFNumberFloatType, value); |
| 366 } |
| 367 |
| 368 static int unit_weight_to_fontstyle(float unit) { |
| 369 float value; |
| 370 if (unit < 0) { |
| 371 value = 100 + (1 + unit) * 300; |
| 372 } else { |
| 373 value = 400 + unit * 500; |
361 } | 374 } |
362 if (traits & kCTFontItalicTrait) { | 375 return sk_float_round2int(value); |
363 style |= SkTypeface::kItalic; | 376 } |
| 377 |
| 378 static int unit_width_to_fontstyle(float unit) { |
| 379 float value; |
| 380 if (unit < 0) { |
| 381 value = 1 + (1 + unit) * 4; |
| 382 } else { |
| 383 value = 5 + unit * 4; |
| 384 } |
| 385 return sk_float_round2int(value); |
| 386 } |
| 387 |
| 388 static SkFontStyle fontstyle_from_descriptor(CTFontDescriptorRef desc, bool* isF
ixedPitch) { |
| 389 AutoCFRelease<CFDictionaryRef> dict( |
| 390 (CFDictionaryRef)CTFontDescriptorCopyAttribute(desc, kCTFontTraitsAt
tribute)); |
| 391 if (NULL == dict.get()) { |
| 392 return SkFontStyle(); |
| 393 } |
| 394 |
| 395 CTFontSymbolicTraits traits; |
| 396 if (!find_dict_traits(dict, &traits)) { |
| 397 traits = 0; |
364 } | 398 } |
365 if (isFixedPitch) { | 399 if (isFixedPitch) { |
366 *isFixedPitch = (traits & kCTFontMonoSpaceTrait) != 0; | 400 *isFixedPitch = SkToBool(traits & kCTFontMonoSpaceTrait); |
367 } | 401 } |
368 return (SkTypeface::Style)style; | 402 |
| 403 float weight, width, slant; |
| 404 if (!find_dict_float(dict, kCTFontWeightTrait, &weight)) { |
| 405 weight = (traits & kCTFontBoldTrait) ? 0.5f : 0; |
| 406 } |
| 407 if (!find_dict_float(dict, kCTFontWidthTrait, &width)) { |
| 408 width = 0; |
| 409 } |
| 410 if (!find_dict_float(dict, kCTFontSlantTrait, &slant)) { |
| 411 slant = (traits & kCTFontItalicTrait) ? 0.5f : 0; |
| 412 } |
| 413 |
| 414 return SkFontStyle(unit_weight_to_fontstyle(weight), |
| 415 unit_width_to_fontstyle(width), |
| 416 slant ? SkFontStyle::kItalic_Slant |
| 417 : SkFontStyle::kUpright_Slant); |
369 } | 418 } |
370 | 419 |
371 static SkFontID CTFontRef_to_SkFontID(CTFontRef fontRef) { | 420 static SkFontID CTFontRef_to_SkFontID(CTFontRef fontRef) { |
372 SkFontID id = 0; | 421 SkFontID id = 0; |
373 // 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 |
374 // bracket this to be Mac only. | 423 // bracket this to be Mac only. |
375 #ifdef SK_BUILD_FOR_MAC | 424 #ifdef SK_BUILD_FOR_MAC |
376 ATSFontRef ats = CTFontGetPlatformFont(fontRef, NULL); | 425 ATSFontRef ats = CTFontGetPlatformFont(fontRef, NULL); |
377 id = (SkFontID)ats; | 426 id = (SkFontID)ats; |
378 if (id != 0) { | 427 if (id != 0) { |
(...skipping 10 matching lines...) Expand all Loading... |
389 id = (id & 0x3FFFFFFF) | 0x40000000; // make top two bits 01 | 438 id = (id & 0x3FFFFFFF) | 0x40000000; // make top two bits 01 |
390 } | 439 } |
391 // well-formed fonts have checksums, but as a last resort, use the pointer. | 440 // well-formed fonts have checksums, but as a last resort, use the pointer. |
392 if (id == 0) { | 441 if (id == 0) { |
393 id = (SkFontID) (uintptr_t) fontRef; | 442 id = (SkFontID) (uintptr_t) fontRef; |
394 id = (id & 0x3FFFFFFF) | 0x80000000; // make top two bits 10 | 443 id = (id & 0x3FFFFFFF) | 0x80000000; // make top two bits 10 |
395 } | 444 } |
396 return id; | 445 return id; |
397 } | 446 } |
398 | 447 |
399 static SkFontStyle stylebits2fontstyle(SkTypeface::Style styleBits) { | |
400 return SkFontStyle((styleBits & SkTypeface::kBold) | |
401 ? SkFontStyle::kBold_Weight | |
402 : SkFontStyle::kNormal_Weight, | |
403 SkFontStyle::kNormal_Width, | |
404 (styleBits & SkTypeface::kItalic) | |
405 ? SkFontStyle::kItalic_Slant | |
406 : SkFontStyle::kUpright_Slant); | |
407 } | |
408 | |
409 #define WEIGHT_THRESHOLD ((SkFontStyle::kNormal_Weight + SkFontStyle::kBold_W
eight)/2) | 448 #define WEIGHT_THRESHOLD ((SkFontStyle::kNormal_Weight + SkFontStyle::kBold_W
eight)/2) |
410 | 449 |
411 static SkTypeface::Style fontstyle2stylebits(const SkFontStyle& fs) { | |
412 unsigned style = 0; | |
413 if (fs.width() >= WEIGHT_THRESHOLD) { | |
414 style |= SkTypeface::kBold; | |
415 } | |
416 if (fs.isItalic()) { | |
417 style |= SkTypeface::kItalic; | |
418 } | |
419 return (SkTypeface::Style)style; | |
420 } | |
421 | |
422 class SkTypeface_Mac : public SkTypeface { | 450 class SkTypeface_Mac : public SkTypeface { |
423 public: | 451 public: |
424 SkTypeface_Mac(SkTypeface::Style style, SkFontID fontID, bool isFixedPitch, | 452 SkTypeface_Mac(const SkFontStyle& fs, SkFontID fontID, bool isFixedPitch, |
425 CTFontRef fontRef, const char name[], bool isLocalStream) | 453 CTFontRef fontRef, const char name[], bool isLocalStream) |
426 : SkTypeface(style, fontID, isFixedPitch) | 454 : SkTypeface(fs, fontID, isFixedPitch) |
427 , fName(name) | 455 , fName(name) |
428 , fFontRef(fontRef) // caller has already called CFRetain for us | 456 , fFontRef(fontRef) // caller has already called CFRetain for us |
429 , fFontStyle(stylebits2fontstyle(style)) | |
430 , fIsLocalStream(isLocalStream) | 457 , fIsLocalStream(isLocalStream) |
431 { | 458 { |
432 SkASSERT(fontRef); | 459 SkASSERT(fontRef); |
433 } | |
434 | |
435 SkTypeface_Mac(const SkFontStyle& fs, SkFontID fontID, bool isFixedPitch, | |
436 CTFontRef fontRef, const char name[], bool isLocalStream) | |
437 : SkTypeface(fontstyle2stylebits(fs), fontID, isFixedPitch) | |
438 , fName(name) | |
439 , fFontRef(fontRef) // caller has already called CFRetain for us | |
440 , fFontStyle(fs) | |
441 , fIsLocalStream(isLocalStream) | |
442 { | |
443 SkASSERT(fontRef); | |
444 } | 460 } |
445 | 461 |
446 SkString fName; | 462 SkString fName; |
447 AutoCFRelease<CTFontRef> fFontRef; | 463 AutoCFRelease<CTFontRef> fFontRef; |
448 SkFontStyle fFontStyle; | |
449 | 464 |
450 protected: | 465 protected: |
451 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 |
452 | 467 |
453 virtual int onGetUPEM() const SK_OVERRIDE; | 468 virtual int onGetUPEM() const SK_OVERRIDE; |
454 virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE; | 469 virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE; |
455 virtual void onGetFamilyName(SkString* familyName) const SK_OVERRIDE; | 470 virtual void onGetFamilyName(SkString* familyName) const SK_OVERRIDE; |
456 virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_
OVERRIDE; | 471 virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_
OVERRIDE; |
457 virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE; | 472 virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE; |
458 virtual size_t onGetTableData(SkFontTableTag, size_t offset, | 473 virtual size_t onGetTableData(SkFontTableTag, size_t offset, |
(...skipping 10 matching lines...) Expand all Loading... |
469 | 484 |
470 private: | 485 private: |
471 bool fIsLocalStream; | 486 bool fIsLocalStream; |
472 | 487 |
473 typedef SkTypeface INHERITED; | 488 typedef SkTypeface INHERITED; |
474 }; | 489 }; |
475 | 490 |
476 static SkTypeface* NewFromFontRef(CTFontRef fontRef, const char name[], bool isL
ocalStream) { | 491 static SkTypeface* NewFromFontRef(CTFontRef fontRef, const char name[], bool isL
ocalStream) { |
477 SkASSERT(fontRef); | 492 SkASSERT(fontRef); |
478 bool isFixedPitch; | 493 bool isFixedPitch; |
479 SkTypeface::Style style = computeStyleBits(fontRef, &isFixedPitch); | 494 AutoCFRelease<CTFontDescriptorRef> desc(CTFontCopyFontDescriptor(fontRef)); |
| 495 SkFontStyle style = fontstyle_from_descriptor(desc, &isFixedPitch); |
480 SkFontID fontID = CTFontRef_to_SkFontID(fontRef); | 496 SkFontID fontID = CTFontRef_to_SkFontID(fontRef); |
481 | 497 |
482 return new SkTypeface_Mac(style, fontID, isFixedPitch, fontRef, name, isLoca
lStream); | 498 return new SkTypeface_Mac(style, fontID, isFixedPitch, fontRef, name, isLoca
lStream); |
483 } | 499 } |
484 | 500 |
485 static SkTypeface* NewFromName(const char familyName[], SkTypeface::Style theSty
le) { | 501 static SkTypeface* NewFromName(const char familyName[], const SkFontStyle& theSt
yle) { |
486 CTFontRef ctFont = NULL; | 502 CTFontRef ctFont = NULL; |
487 | 503 |
488 CTFontSymbolicTraits ctFontTraits = 0; | 504 CTFontSymbolicTraits ctFontTraits = 0; |
489 if (theStyle & SkTypeface::kBold) { | 505 if (theStyle.weight() >= SkFontStyle::kBold_Weight) { |
490 ctFontTraits |= kCTFontBoldTrait; | 506 ctFontTraits |= kCTFontBoldTrait; |
491 } | 507 } |
492 if (theStyle & SkTypeface::kItalic) { | 508 if (theStyle.slant() != SkFontStyle::kUpright_Slant) { |
493 ctFontTraits |= kCTFontItalicTrait; | 509 ctFontTraits |= kCTFontItalicTrait; |
494 } | 510 } |
495 | 511 |
| 512 //TODO: add weight width slant |
| 513 |
496 // Create the font info | 514 // Create the font info |
497 AutoCFRelease<CFStringRef> cfFontName(make_CFString(familyName)); | 515 AutoCFRelease<CFStringRef> cfFontName(make_CFString(familyName)); |
498 | 516 |
499 AutoCFRelease<CFNumberRef> cfFontTraits( | 517 AutoCFRelease<CFNumberRef> cfFontTraits( |
500 CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &ctFontTrai
ts)); | 518 CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &ctFontTrai
ts)); |
501 | 519 |
502 AutoCFRelease<CFMutableDictionaryRef> cfAttributes( | 520 AutoCFRelease<CFMutableDictionaryRef> cfAttributes( |
503 CFDictionaryCreateMutable(kCFAllocatorDefault, 0, | 521 CFDictionaryCreateMutable(kCFAllocatorDefault, 0, |
504 &kCFTypeDictionaryKeyCallBacks, | 522 &kCFTypeDictionaryKeyCallBacks, |
505 &kCFTypeDictionaryValueCallBacks)); | 523 &kCFTypeDictionaryValueCallBacks)); |
(...skipping 21 matching lines...) Expand all Loading... |
527 return ctFont ? NewFromFontRef(ctFont, familyName, false) : NULL; | 545 return ctFont ? NewFromFontRef(ctFont, familyName, false) : NULL; |
528 } | 546 } |
529 | 547 |
530 SK_DECLARE_STATIC_MUTEX(gGetDefaultFaceMutex); | 548 SK_DECLARE_STATIC_MUTEX(gGetDefaultFaceMutex); |
531 static SkTypeface* GetDefaultFace() { | 549 static SkTypeface* GetDefaultFace() { |
532 SkAutoMutexAcquire ma(gGetDefaultFaceMutex); | 550 SkAutoMutexAcquire ma(gGetDefaultFaceMutex); |
533 | 551 |
534 static SkTypeface* gDefaultFace; | 552 static SkTypeface* gDefaultFace; |
535 | 553 |
536 if (NULL == gDefaultFace) { | 554 if (NULL == gDefaultFace) { |
537 gDefaultFace = NewFromName(FONT_DEFAULT_NAME, SkTypeface::kNormal); | 555 gDefaultFace = NewFromName(FONT_DEFAULT_NAME, SkFontStyle()); |
538 SkTypefaceCache::Add(gDefaultFace, SkTypeface::kNormal); | 556 SkTypefaceCache::Add(gDefaultFace, SkFontStyle()); |
539 } | 557 } |
540 return gDefaultFace; | 558 return gDefaultFace; |
541 } | 559 } |
542 | 560 |
543 /////////////////////////////////////////////////////////////////////////////// | 561 /////////////////////////////////////////////////////////////////////////////// |
544 | 562 |
545 extern CTFontRef SkTypeface_GetCTFontRef(const SkTypeface* face); | 563 extern CTFontRef SkTypeface_GetCTFontRef(const SkTypeface* face); |
546 CTFontRef SkTypeface_GetCTFontRef(const SkTypeface* face) { | 564 CTFontRef SkTypeface_GetCTFontRef(const SkTypeface* face) { |
547 const SkTypeface_Mac* macface = (const SkTypeface_Mac*)face; | 565 const SkTypeface_Mac* macface = (const SkTypeface_Mac*)face; |
548 return macface ? macface->fFontRef.get() : NULL; | 566 return macface ? macface->fFontRef.get() : NULL; |
549 } | 567 } |
550 | 568 |
551 /* This function is visible on the outside. It first searches the cache, and if | 569 /* This function is visible on the outside. It first searches the cache, and if |
552 * not found, returns a new entry (after adding it to the cache). | 570 * not found, returns a new entry (after adding it to the cache). |
553 */ | 571 */ |
554 SkTypeface* SkCreateTypefaceFromCTFont(CTFontRef fontRef) { | 572 SkTypeface* SkCreateTypefaceFromCTFont(CTFontRef fontRef) { |
555 SkFontID fontID = CTFontRef_to_SkFontID(fontRef); | 573 SkFontID fontID = CTFontRef_to_SkFontID(fontRef); |
556 SkTypeface* face = SkTypefaceCache::FindByID(fontID); | 574 SkTypeface* face = SkTypefaceCache::FindByID(fontID); |
557 if (face) { | 575 if (face) { |
558 face->ref(); | 576 face->ref(); |
559 } else { | 577 } else { |
560 face = NewFromFontRef(fontRef, NULL, false); | 578 face = NewFromFontRef(fontRef, NULL, false); |
561 SkTypefaceCache::Add(face, face->style()); | 579 SkTypefaceCache::Add(face, face->fontStyle()); |
562 // NewFromFontRef doesn't retain the parameter, but the typeface it | 580 // NewFromFontRef doesn't retain the parameter, but the typeface it |
563 // 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 |
564 // a retain call here. | 582 // a retain call here. |
565 CFRetain(fontRef); | 583 CFRetain(fontRef); |
566 } | 584 } |
567 SkASSERT(face->getRefCnt() > 1); | 585 SkASSERT(face->getRefCnt() > 1); |
568 return face; | 586 return face; |
569 } | 587 } |
570 | 588 |
571 struct NameStyleRec { | 589 struct NameStyleRec { |
572 const char* fName; | 590 const char* fName; |
573 SkTypeface::Style fStyle; | 591 SkFontStyle fStyle; |
574 }; | 592 }; |
575 | 593 |
576 static bool FindByNameStyle(SkTypeface* face, SkTypeface::Style style, | 594 static bool FindByNameStyle(SkTypeface* face, const SkFontStyle& style, void* ct
x) { |
577 void* ctx) { | |
578 const SkTypeface_Mac* mface = reinterpret_cast<SkTypeface_Mac*>(face); | 595 const SkTypeface_Mac* mface = reinterpret_cast<SkTypeface_Mac*>(face); |
579 const NameStyleRec* rec = reinterpret_cast<const NameStyleRec*>(ctx); | 596 const NameStyleRec* rec = reinterpret_cast<const NameStyleRec*>(ctx); |
580 | 597 |
581 return rec->fStyle == style && mface->fName.equals(rec->fName); | 598 return rec->fStyle == style && mface->fName.equals(rec->fName); |
582 } | 599 } |
583 | 600 |
584 static const char* map_css_names(const char* name) { | 601 static const char* map_css_names(const char* name) { |
585 static const struct { | 602 static const struct { |
586 const char* fFrom; // name the caller specified | 603 const char* fFrom; // name the caller specified |
587 const char* fTo; // "canonical" name we map to | 604 const char* fTo; // "canonical" name we map to |
588 } gPairs[] = { | 605 } gPairs[] = { |
589 { "sans-serif", "Helvetica" }, | 606 { "sans-serif", "Helvetica" }, |
590 { "serif", "Times" }, | 607 { "serif", "Times" }, |
591 { "monospace", "Courier" } | 608 { "monospace", "Courier" } |
592 }; | 609 }; |
593 | 610 |
594 for (size_t i = 0; i < SK_ARRAY_COUNT(gPairs); i++) { | 611 for (size_t i = 0; i < SK_ARRAY_COUNT(gPairs); i++) { |
595 if (strcmp(name, gPairs[i].fFrom) == 0) { | 612 if (strcmp(name, gPairs[i].fFrom) == 0) { |
596 return gPairs[i].fTo; | 613 return gPairs[i].fTo; |
597 } | 614 } |
598 } | 615 } |
599 return name; // no change | 616 return name; // no change |
600 } | 617 } |
601 | 618 |
602 static SkTypeface* create_typeface(const SkTypeface* familyFace, | |
603 const char familyName[], | |
604 SkTypeface::Style style) { | |
605 if (familyName) { | |
606 familyName = map_css_names(familyName); | |
607 } | |
608 | |
609 // Clone an existing typeface | |
610 // TODO: only clone if style matches the familyFace's style... | |
611 if (familyName == NULL && familyFace != NULL) { | |
612 familyFace->ref(); | |
613 return const_cast<SkTypeface*>(familyFace); | |
614 } | |
615 | |
616 if (!familyName || !*familyName) { | |
617 familyName = FONT_DEFAULT_NAME; | |
618 } | |
619 | |
620 NameStyleRec rec = { familyName, style }; | |
621 SkTypeface* face = SkTypefaceCache::FindByProcAndRef(FindByNameStyle, &rec); | |
622 | |
623 if (NULL == face) { | |
624 face = NewFromName(familyName, style); | |
625 if (face) { | |
626 SkTypefaceCache::Add(face, style); | |
627 } else { | |
628 face = GetDefaultFace(); | |
629 face->ref(); | |
630 } | |
631 } | |
632 return face; | |
633 } | |
634 | |
635 /////////////////////////////////////////////////////////////////////////////// | 619 /////////////////////////////////////////////////////////////////////////////// |
636 | 620 |
637 /** GlyphRect is in FUnits (em space, y up). */ | 621 /** GlyphRect is in FUnits (em space, y up). */ |
638 struct GlyphRect { | 622 struct GlyphRect { |
639 int16_t fMinX; | 623 int16_t fMinX; |
640 int16_t fMinY; | 624 int16_t fMinY; |
641 int16_t fMaxX; | 625 int16_t fMaxX; |
642 int16_t fMaxY; | 626 int16_t fMaxY; |
643 }; | 627 }; |
644 | 628 |
(...skipping 1356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2001 // Odd to get here, as we expected CT to have returned true up front. | 1985 // Odd to get here, as we expected CT to have returned true up front. |
2002 return glyphCount; | 1986 return glyphCount; |
2003 } | 1987 } |
2004 | 1988 |
2005 int SkTypeface_Mac::onCountGlyphs() const { | 1989 int SkTypeface_Mac::onCountGlyphs() const { |
2006 return SkToInt(CTFontGetGlyphCount(fFontRef)); | 1990 return SkToInt(CTFontGetGlyphCount(fFontRef)); |
2007 } | 1991 } |
2008 | 1992 |
2009 /////////////////////////////////////////////////////////////////////////////// | 1993 /////////////////////////////////////////////////////////////////////////////// |
2010 /////////////////////////////////////////////////////////////////////////////// | 1994 /////////////////////////////////////////////////////////////////////////////// |
2011 #if 1 | |
2012 | 1995 |
2013 static bool find_desc_str(CTFontDescriptorRef desc, CFStringRef name, SkString*
value) { | 1996 static bool find_desc_str(CTFontDescriptorRef desc, CFStringRef name, SkString*
value) { |
2014 AutoCFRelease<CFStringRef> ref((CFStringRef)CTFontDescriptorCopyAttribute(de
sc, name)); | 1997 AutoCFRelease<CFStringRef> ref((CFStringRef)CTFontDescriptorCopyAttribute(de
sc, name)); |
2015 if (NULL == ref.get()) { | 1998 if (NULL == ref.get()) { |
2016 return false; | 1999 return false; |
2017 } | 2000 } |
2018 CFStringToSkString(ref, value); | 2001 CFStringToSkString(ref, value); |
2019 return true; | 2002 return true; |
2020 } | 2003 } |
2021 | 2004 |
2022 static bool find_dict_float(CFDictionaryRef dict, CFStringRef name, float* value
) { | |
2023 CFNumberRef num; | |
2024 return CFDictionaryGetValueIfPresent(dict, name, (const void**)&num) | |
2025 && CFNumberIsFloatType(num) | |
2026 && CFNumberGetValue(num, kCFNumberFloatType, value); | |
2027 } | |
2028 | |
2029 #include "SkFontMgr.h" | 2005 #include "SkFontMgr.h" |
2030 | 2006 |
2031 static int unit_weight_to_fontstyle(float unit) { | |
2032 float value; | |
2033 if (unit < 0) { | |
2034 value = 100 + (1 + unit) * 300; | |
2035 } else { | |
2036 value = 400 + unit * 500; | |
2037 } | |
2038 return sk_float_round2int(value); | |
2039 } | |
2040 | |
2041 static int unit_width_to_fontstyle(float unit) { | |
2042 float value; | |
2043 if (unit < 0) { | |
2044 value = 1 + (1 + unit) * 4; | |
2045 } else { | |
2046 value = 5 + unit * 4; | |
2047 } | |
2048 return sk_float_round2int(value); | |
2049 } | |
2050 | |
2051 static inline int sqr(int value) { | 2007 static inline int sqr(int value) { |
2052 SkASSERT(SkAbs32(value) < 0x7FFF); // check for overflow | 2008 SkASSERT(SkAbs32(value) < 0x7FFF); // check for overflow |
2053 return value * value; | 2009 return value * value; |
2054 } | 2010 } |
2055 | 2011 |
2056 // We normalize each axis (weight, width, italic) to be base-900 | 2012 // We normalize each axis (weight, width, italic) to be base-900 |
2057 static int compute_metric(const SkFontStyle& a, const SkFontStyle& b) { | 2013 static int compute_metric(const SkFontStyle& a, const SkFontStyle& b) { |
2058 return sqr(a.weight() - b.weight()) + | 2014 return sqr(a.weight() - b.weight()) + |
2059 sqr((a.width() - b.width()) * 100) + | 2015 sqr((a.width() - b.width()) * 100) + |
2060 sqr((a.isItalic() != b.isItalic()) * 900); | 2016 sqr((a.isItalic() != b.isItalic()) * 900); |
2061 } | 2017 } |
2062 | 2018 |
2063 static SkFontStyle desc2fontstyle(CTFontDescriptorRef desc) { | |
2064 AutoCFRelease<CFDictionaryRef> dict( | |
2065 (CFDictionaryRef)CTFontDescriptorCopyAttribute(desc, | |
2066 kCTFontTraitsAttribute)); | |
2067 if (NULL == dict.get()) { | |
2068 return SkFontStyle(); | |
2069 } | |
2070 | |
2071 float weight, width, slant; | |
2072 if (!find_dict_float(dict, kCTFontWeightTrait, &weight)) { | |
2073 weight = 0; | |
2074 } | |
2075 if (!find_dict_float(dict, kCTFontWidthTrait, &width)) { | |
2076 width = 0; | |
2077 } | |
2078 if (!find_dict_float(dict, kCTFontSlantTrait, &slant)) { | |
2079 slant = 0; | |
2080 } | |
2081 | |
2082 return SkFontStyle(unit_weight_to_fontstyle(weight), | |
2083 unit_width_to_fontstyle(width), | |
2084 slant ? SkFontStyle::kItalic_Slant | |
2085 : SkFontStyle::kUpright_Slant); | |
2086 } | |
2087 | |
2088 struct NameFontStyleRec { | 2019 struct NameFontStyleRec { |
2089 SkString fFamilyName; | 2020 SkString fFamilyName; |
2090 SkFontStyle fFontStyle; | 2021 SkFontStyle fFontStyle; |
2091 }; | 2022 }; |
2092 | 2023 |
2093 static bool nameFontStyleProc(SkTypeface* face, SkTypeface::Style, | 2024 static bool nameFontStyleProc(SkTypeface* face, const SkFontStyle&, void* ctx) { |
2094 void* ctx) { | |
2095 SkTypeface_Mac* macFace = (SkTypeface_Mac*)face; | 2025 SkTypeface_Mac* macFace = (SkTypeface_Mac*)face; |
2096 const NameFontStyleRec* rec = (const NameFontStyleRec*)ctx; | 2026 const NameFontStyleRec* rec = (const NameFontStyleRec*)ctx; |
2097 | 2027 |
2098 return macFace->fFontStyle == rec->fFontStyle && | 2028 return macFace->fontStyle() == rec->fFontStyle && |
2099 macFace->fName == rec->fFamilyName; | 2029 macFace->fName == rec->fFamilyName; |
2100 } | 2030 } |
2101 | 2031 |
2102 static SkTypeface* createFromDesc(CFStringRef cfFamilyName, | 2032 static SkTypeface* createFromDesc(CFStringRef cfFamilyName, CTFontDescriptorRef
desc) { |
2103 CTFontDescriptorRef desc) { | |
2104 NameFontStyleRec rec; | 2033 NameFontStyleRec rec; |
2105 CFStringToSkString(cfFamilyName, &rec.fFamilyName); | 2034 CFStringToSkString(cfFamilyName, &rec.fFamilyName); |
2106 rec.fFontStyle = desc2fontstyle(desc); | 2035 rec.fFontStyle = fontstyle_from_descriptor(desc, NULL); |
2107 | 2036 |
2108 SkTypeface* face = SkTypefaceCache::FindByProcAndRef(nameFontStyleProc, | 2037 SkTypeface* face = SkTypefaceCache::FindByProcAndRef(nameFontStyleProc, &rec
); |
2109 &rec); | |
2110 if (face) { | 2038 if (face) { |
2111 return face; | 2039 return face; |
2112 } | 2040 } |
2113 | 2041 |
2114 AutoCFRelease<CFDictionaryRef> fontFamilyNameDictionary( | 2042 AutoCFRelease<CFDictionaryRef> fontFamilyNameDictionary( |
2115 CFDictionaryCreate(kCFAllocatorDefault, | 2043 CFDictionaryCreate(kCFAllocatorDefault, |
2116 (const void**)&kCTFontFamilyNameAttribute, (const voi
d**)&cfFamilyName, | 2044 (const void**)&kCTFontFamilyNameAttribute, (const voi
d**)&cfFamilyName, |
2117 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionary
ValueCallBacks)); | 2045 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionary
ValueCallBacks)); |
2118 AutoCFRelease<CTFontDescriptorRef> fontDescriptor( | 2046 AutoCFRelease<CTFontDescriptorRef> fontDescriptor( |
2119 CTFontDescriptorCreateWithAttributes(fontFamilyNameDictionary)); | 2047 CTFontDescriptorCreateWithAttributes(fontFamilyNameDictionary)); |
2120 AutoCFRelease<CTFontRef> ctNamed(CTFontCreateWithFontDescriptor(fontDescript
or, 0, NULL)); | 2048 AutoCFRelease<CTFontRef> ctNamed(CTFontCreateWithFontDescriptor(fontDescript
or, 0, NULL)); |
2121 CTFontRef ctFont = CTFontCreateCopyWithAttributes(ctNamed, 1, NULL, desc); | 2049 CTFontRef ctFont = CTFontCreateCopyWithAttributes(ctNamed, 1, NULL, desc); |
2122 if (NULL == ctFont) { | 2050 if (NULL == ctFont) { |
2123 return NULL; | 2051 return NULL; |
2124 } | 2052 } |
2125 | 2053 |
2126 SkString str; | 2054 SkString str; |
2127 CFStringToSkString(cfFamilyName, &str); | 2055 CFStringToSkString(cfFamilyName, &str); |
2128 | 2056 |
2129 bool isFixedPitch; | 2057 bool isFixedPitch; |
2130 (void)computeStyleBits(ctFont, &isFixedPitch); | 2058 AutoCFRelease<CTFontDescriptorRef> ctFontDesc(CTFontCopyFontDescriptor(ctFon
t)); |
| 2059 (void)fontstyle_from_descriptor(ctFontDesc, &isFixedPitch); |
2131 SkFontID fontID = CTFontRef_to_SkFontID(ctFont); | 2060 SkFontID fontID = CTFontRef_to_SkFontID(ctFont); |
2132 | 2061 |
2133 face = SkNEW_ARGS(SkTypeface_Mac, (rec.fFontStyle, fontID, isFixedPitch, | 2062 face = SkNEW_ARGS(SkTypeface_Mac, (rec.fFontStyle, fontID, isFixedPitch, |
2134 ctFont, str.c_str(), false)); | 2063 ctFont, str.c_str(), false)); |
2135 SkTypefaceCache::Add(face, face->style()); | 2064 SkTypefaceCache::Add(face, face->fontStyle()); |
2136 return face; | 2065 return face; |
2137 } | 2066 } |
2138 | 2067 |
2139 class SkFontStyleSet_Mac : public SkFontStyleSet { | 2068 class SkFontStyleSet_Mac : public SkFontStyleSet { |
2140 public: | 2069 public: |
2141 SkFontStyleSet_Mac(CFStringRef familyName, CTFontDescriptorRef desc) | 2070 SkFontStyleSet_Mac(CFStringRef familyName, CTFontDescriptorRef desc) |
2142 : fArray(CTFontDescriptorCreateMatchingFontDescriptors(desc, NULL)) | 2071 : fArray(CTFontDescriptorCreateMatchingFontDescriptors(desc, NULL)) |
2143 , fFamilyName(familyName) | 2072 , fFamilyName(familyName) |
2144 , fCount(0) { | 2073 , fCount(0) { |
2145 CFRetain(familyName); | 2074 CFRetain(familyName); |
2146 if (NULL == fArray) { | 2075 if (NULL == fArray) { |
2147 fArray = CFArrayCreate(NULL, NULL, 0, NULL); | 2076 fArray = CFArrayCreate(NULL, NULL, 0, NULL); |
2148 } | 2077 } |
2149 fCount = SkToInt(CFArrayGetCount(fArray)); | 2078 fCount = SkToInt(CFArrayGetCount(fArray)); |
2150 } | 2079 } |
2151 | 2080 |
2152 virtual ~SkFontStyleSet_Mac() { | 2081 virtual ~SkFontStyleSet_Mac() { |
2153 CFRelease(fArray); | 2082 CFRelease(fArray); |
2154 CFRelease(fFamilyName); | 2083 CFRelease(fFamilyName); |
2155 } | 2084 } |
2156 | 2085 |
2157 virtual int count() SK_OVERRIDE { | 2086 virtual int count() SK_OVERRIDE { |
2158 return fCount; | 2087 return fCount; |
2159 } | 2088 } |
2160 | 2089 |
2161 virtual void getStyle(int index, SkFontStyle* style, | 2090 virtual void getStyle(int index, SkFontStyle* style, SkString* name) SK_OVER
RIDE { |
2162 SkString* name) SK_OVERRIDE { | |
2163 SkASSERT((unsigned)index < (unsigned)fCount); | 2091 SkASSERT((unsigned)index < (unsigned)fCount); |
2164 CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(f
Array, index); | 2092 CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(f
Array, index); |
2165 if (style) { | 2093 if (style) { |
2166 *style = desc2fontstyle(desc); | 2094 *style = fontstyle_from_descriptor(desc, NULL); |
2167 } | 2095 } |
2168 if (name) { | 2096 if (name) { |
2169 if (!find_desc_str(desc, kCTFontStyleNameAttribute, name)) { | 2097 if (!find_desc_str(desc, kCTFontStyleNameAttribute, name)) { |
2170 name->reset(); | 2098 name->reset(); |
2171 } | 2099 } |
2172 } | 2100 } |
2173 } | 2101 } |
2174 | 2102 |
2175 virtual SkTypeface* createTypeface(int index) SK_OVERRIDE { | 2103 virtual SkTypeface* createTypeface(int index) SK_OVERRIDE { |
2176 SkASSERT((unsigned)index < (unsigned)CFArrayGetCount(fArray)); | 2104 SkASSERT((unsigned)index < (unsigned)CFArrayGetCount(fArray)); |
(...skipping 13 matching lines...) Expand all Loading... |
2190 CFArrayRef fArray; | 2118 CFArrayRef fArray; |
2191 CFStringRef fFamilyName; | 2119 CFStringRef fFamilyName; |
2192 int fCount; | 2120 int fCount; |
2193 | 2121 |
2194 CTFontDescriptorRef findMatchingDesc(const SkFontStyle& pattern) const { | 2122 CTFontDescriptorRef findMatchingDesc(const SkFontStyle& pattern) const { |
2195 int bestMetric = SK_MaxS32; | 2123 int bestMetric = SK_MaxS32; |
2196 CTFontDescriptorRef bestDesc = NULL; | 2124 CTFontDescriptorRef bestDesc = NULL; |
2197 | 2125 |
2198 for (int i = 0; i < fCount; ++i) { | 2126 for (int i = 0; i < fCount; ++i) { |
2199 CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtInd
ex(fArray, i); | 2127 CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtInd
ex(fArray, i); |
2200 int metric = compute_metric(pattern, desc2fontstyle(desc)); | 2128 int metric = compute_metric(pattern, fontstyle_from_descriptor(desc,
NULL)); |
2201 if (0 == metric) { | 2129 if (0 == metric) { |
2202 return desc; | 2130 return desc; |
2203 } | 2131 } |
2204 if (metric < bestMetric) { | 2132 if (metric < bestMetric) { |
2205 bestMetric = metric; | 2133 bestMetric = metric; |
2206 bestDesc = desc; | 2134 bestDesc = desc; |
2207 } | 2135 } |
2208 } | 2136 } |
2209 SkASSERT(bestDesc); | 2137 SkASSERT(bestDesc); |
2210 return bestDesc; | 2138 return bestDesc; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2270 virtual SkTypeface* onMatchFamilyStyle(const char familyName[], | 2198 virtual SkTypeface* onMatchFamilyStyle(const char familyName[], |
2271 const SkFontStyle&) const SK_OVERRIDE
{ | 2199 const SkFontStyle&) const SK_OVERRIDE
{ |
2272 return NULL; | 2200 return NULL; |
2273 } | 2201 } |
2274 | 2202 |
2275 virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember, | 2203 virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember, |
2276 const SkFontStyle&) const SK_OVERRIDE { | 2204 const SkFontStyle&) const SK_OVERRIDE { |
2277 return NULL; | 2205 return NULL; |
2278 } | 2206 } |
2279 | 2207 |
2280 virtual SkTypeface* onCreateFromData(SkData* data, | 2208 virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OV
ERRIDE { |
2281 int ttcIndex) const SK_OVERRIDE { | |
2282 AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromData(data)); | 2209 AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromData(data)); |
2283 if (NULL == pr) { | 2210 if (NULL == pr) { |
2284 return NULL; | 2211 return NULL; |
2285 } | 2212 } |
2286 return create_from_dataProvider(pr); | 2213 return create_from_dataProvider(pr); |
2287 } | 2214 } |
2288 | 2215 |
2289 virtual SkTypeface* onCreateFromStream(SkStream* stream, | 2216 virtual SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const
SK_OVERRIDE { |
2290 int ttcIndex) const SK_OVERRIDE { | |
2291 AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromStream(strea
m)); | 2217 AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromStream(strea
m)); |
2292 if (NULL == pr) { | 2218 if (NULL == pr) { |
2293 return NULL; | 2219 return NULL; |
2294 } | 2220 } |
2295 return create_from_dataProvider(pr); | 2221 return create_from_dataProvider(pr); |
2296 } | 2222 } |
2297 | 2223 |
2298 virtual SkTypeface* onCreateFromFile(const char path[], | 2224 virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const
SK_OVERRIDE { |
2299 int ttcIndex) const SK_OVERRIDE { | |
2300 AutoCFRelease<CGDataProviderRef> pr(CGDataProviderCreateWithFilename(pat
h)); | 2225 AutoCFRelease<CGDataProviderRef> pr(CGDataProviderCreateWithFilename(pat
h)); |
2301 if (NULL == pr) { | 2226 if (NULL == pr) { |
2302 return NULL; | 2227 return NULL; |
2303 } | 2228 } |
2304 return create_from_dataProvider(pr); | 2229 return create_from_dataProvider(pr); |
2305 } | 2230 } |
2306 | 2231 |
2307 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], | 2232 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], |
2308 unsigned styleBits) const SK_OVER
RIDE { | 2233 unsigned styleBits) const SK_OVER
RIDE { |
2309 return create_typeface(NULL, familyName, (SkTypeface::Style)styleBits); | 2234 |
| 2235 SkFontStyle style = SkFontStyle((SkTypeface::Style)styleBits); |
| 2236 if (familyName) { |
| 2237 familyName = map_css_names(familyName); |
| 2238 } |
| 2239 |
| 2240 if (!familyName || !*familyName) { |
| 2241 familyName = FONT_DEFAULT_NAME; |
| 2242 } |
| 2243 |
| 2244 NameStyleRec rec = { familyName, style }; |
| 2245 SkTypeface* face = SkTypefaceCache::FindByProcAndRef(FindByNameStyle, &r
ec); |
| 2246 |
| 2247 if (NULL == face) { |
| 2248 face = NewFromName(familyName, style); |
| 2249 if (face) { |
| 2250 SkTypefaceCache::Add(face, style); |
| 2251 } else { |
| 2252 face = GetDefaultFace(); |
| 2253 face->ref(); |
| 2254 } |
| 2255 } |
| 2256 return face; |
2310 } | 2257 } |
2311 }; | 2258 }; |
2312 | 2259 |
2313 /////////////////////////////////////////////////////////////////////////////// | 2260 /////////////////////////////////////////////////////////////////////////////// |
2314 | 2261 |
2315 SkFontMgr* SkFontMgr::Factory() { | 2262 SkFontMgr* SkFontMgr::Factory() { |
2316 return SkNEW(SkFontMgr_Mac); | 2263 return SkNEW(SkFontMgr_Mac); |
2317 } | 2264 } |
2318 #endif | |
OLD | NEW |