| 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 |