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