Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(653)

Side by Side Diff: src/ports/SkFontHost_mac.cpp

Issue 667023002: Revert of Replace SkTypeface::Style with SkFontStyle. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ports/SkFontHost_linux.cpp ('k') | src/ports/SkFontHost_win.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/ports/SkFontHost_linux.cpp ('k') | src/ports/SkFontHost_win.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698