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

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

Issue 488143002: Replace SkTypeface::Style with SkFontStyle. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Add expectations, remove whitespace. 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>
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
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
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
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
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
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
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
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
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