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

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

Issue 353993003: Fix SkTypeface::serialize() on Mac by properly indicating local fonts (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: style nits Created 6 years, 5 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 | « no previous file | tests/FontHostStreamTest.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 #include <vector>
10 #ifdef SK_BUILD_FOR_MAC 10 #ifdef SK_BUILD_FOR_MAC
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 } 419 }
420 if (fs.isItalic()) { 420 if (fs.isItalic()) {
421 style |= SkTypeface::kItalic; 421 style |= SkTypeface::kItalic;
422 } 422 }
423 return (SkTypeface::Style)style; 423 return (SkTypeface::Style)style;
424 } 424 }
425 425
426 class SkTypeface_Mac : public SkTypeface { 426 class SkTypeface_Mac : public SkTypeface {
427 public: 427 public:
428 SkTypeface_Mac(SkTypeface::Style style, SkFontID fontID, bool isFixedPitch, 428 SkTypeface_Mac(SkTypeface::Style style, SkFontID fontID, bool isFixedPitch,
429 CTFontRef fontRef, const char name[]) 429 CTFontRef fontRef, const char name[], bool isLocalStream)
430 : SkTypeface(style, fontID, isFixedPitch) 430 : SkTypeface(style, fontID, isFixedPitch)
431 , fName(name) 431 , fName(name)
432 , fFontRef(fontRef) // caller has already called CFRetain for us 432 , fFontRef(fontRef) // caller has already called CFRetain for us
433 , fFontStyle(stylebits2fontstyle(style)) 433 , fFontStyle(stylebits2fontstyle(style))
434 , fIsLocalStream(isLocalStream)
434 { 435 {
435 SkASSERT(fontRef); 436 SkASSERT(fontRef);
436 } 437 }
437 438
438 SkTypeface_Mac(const SkFontStyle& fs, SkFontID fontID, bool isFixedPitch, 439 SkTypeface_Mac(const SkFontStyle& fs, SkFontID fontID, bool isFixedPitch,
439 CTFontRef fontRef, const char name[]) 440 CTFontRef fontRef, const char name[], bool isLocalStream)
440 : SkTypeface(fontstyle2stylebits(fs), fontID, isFixedPitch) 441 : SkTypeface(fontstyle2stylebits(fs), fontID, isFixedPitch)
441 , fName(name) 442 , fName(name)
442 , fFontRef(fontRef) // caller has already called CFRetain for us 443 , fFontRef(fontRef) // caller has already called CFRetain for us
443 , fFontStyle(fs) 444 , fFontStyle(fs)
445 , fIsLocalStream(isLocalStream)
444 { 446 {
445 SkASSERT(fontRef); 447 SkASSERT(fontRef);
446 } 448 }
447 449
448 SkString fName; 450 SkString fName;
449 AutoCFRelease<CTFontRef> fFontRef; 451 AutoCFRelease<CTFontRef> fFontRef;
450 SkFontStyle fFontStyle; 452 SkFontStyle fFontStyle;
451 453
452 protected: 454 protected:
453 friend class SkFontHost; // to access our protected members for deprecate d methods 455 friend class SkFontHost; // to access our protected members for deprecate d methods
454 456
455 virtual int onGetUPEM() const SK_OVERRIDE; 457 virtual int onGetUPEM() const SK_OVERRIDE;
456 virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE; 458 virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE;
457 virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_ OVERRIDE; 459 virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_ OVERRIDE;
458 virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE; 460 virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE;
459 virtual size_t onGetTableData(SkFontTableTag, size_t offset, 461 virtual size_t onGetTableData(SkFontTableTag, size_t offset,
460 size_t length, void* data) const SK_OVERRIDE; 462 size_t length, void* data) const SK_OVERRIDE;
461 virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK _OVERRIDE; 463 virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK _OVERRIDE;
462 virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE; 464 virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE;
463 virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE ; 465 virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE ;
464 virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics( 466 virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
465 SkAdvancedTypefaceMetrics::PerGlyphInfo, 467 SkAdvancedTypefaceMetrics::PerGlyphInfo,
466 const uint32_t*, uint32_t) const SK_OVERRIDE; 468 const uint32_t*, uint32_t) const SK_OVERRIDE;
467 virtual int onCharsToGlyphs(const void* chars, Encoding, uint16_t glyphs[], 469 virtual int onCharsToGlyphs(const void* chars, Encoding, uint16_t glyphs[],
468 int glyphCount) const SK_OVERRIDE; 470 int glyphCount) const SK_OVERRIDE;
469 virtual int onCountGlyphs() const SK_OVERRIDE; 471 virtual int onCountGlyphs() const SK_OVERRIDE;
470 472
471 private: 473 private:
474 bool fIsLocalStream;
472 475
473 typedef SkTypeface INHERITED; 476 typedef SkTypeface INHERITED;
474 }; 477 };
475 478
476 static SkTypeface* NewFromFontRef(CTFontRef fontRef, const char name[]) { 479 static SkTypeface* NewFromFontRef(CTFontRef fontRef, const char name[], bool isL ocalStream) {
477 SkASSERT(fontRef); 480 SkASSERT(fontRef);
478 bool isFixedPitch; 481 bool isFixedPitch;
479 SkTypeface::Style style = computeStyleBits(fontRef, &isFixedPitch); 482 SkTypeface::Style style = computeStyleBits(fontRef, &isFixedPitch);
480 SkFontID fontID = CTFontRef_to_SkFontID(fontRef); 483 SkFontID fontID = CTFontRef_to_SkFontID(fontRef);
481 484
482 return new SkTypeface_Mac(style, fontID, isFixedPitch, fontRef, name); 485 return new SkTypeface_Mac(style, fontID, isFixedPitch, fontRef, name, isLoca lStream);
483 } 486 }
484 487
485 static SkTypeface* NewFromName(const char familyName[], SkTypeface::Style theSty le) { 488 static SkTypeface* NewFromName(const char familyName[], SkTypeface::Style theSty le) {
486 CTFontRef ctFont = NULL; 489 CTFontRef ctFont = NULL;
487 490
488 CTFontSymbolicTraits ctFontTraits = 0; 491 CTFontSymbolicTraits ctFontTraits = 0;
489 if (theStyle & SkTypeface::kBold) { 492 if (theStyle & SkTypeface::kBold) {
490 ctFontTraits |= kCTFontBoldTrait; 493 ctFontTraits |= kCTFontBoldTrait;
491 } 494 }
492 if (theStyle & SkTypeface::kItalic) { 495 if (theStyle & SkTypeface::kItalic) {
(...skipping 24 matching lines...) Expand all
517 CFDictionaryAddValue(cfAttributes, kCTFontTraitsAttribute, cfTraits); 520 CFDictionaryAddValue(cfAttributes, kCTFontTraitsAttribute, cfTraits);
518 521
519 AutoCFRelease<CTFontDescriptorRef> ctFontDesc( 522 AutoCFRelease<CTFontDescriptorRef> ctFontDesc(
520 CTFontDescriptorCreateWithAttributes(cfAttributes)); 523 CTFontDescriptorCreateWithAttributes(cfAttributes));
521 524
522 if (ctFontDesc != NULL) { 525 if (ctFontDesc != NULL) {
523 ctFont = CTFontCreateWithFontDescriptor(ctFontDesc, 0, NULL); 526 ctFont = CTFontCreateWithFontDescriptor(ctFontDesc, 0, NULL);
524 } 527 }
525 } 528 }
526 529
527 return ctFont ? NewFromFontRef(ctFont, familyName) : NULL; 530 return ctFont ? NewFromFontRef(ctFont, familyName, false) : NULL;
528 } 531 }
529 532
530 static SkTypeface* GetDefaultFace() { 533 static SkTypeface* GetDefaultFace() {
531 SK_DECLARE_STATIC_MUTEX(gMutex); 534 SK_DECLARE_STATIC_MUTEX(gMutex);
532 SkAutoMutexAcquire ma(gMutex); 535 SkAutoMutexAcquire ma(gMutex);
533 536
534 static SkTypeface* gDefaultFace; 537 static SkTypeface* gDefaultFace;
535 538
536 if (NULL == gDefaultFace) { 539 if (NULL == gDefaultFace) {
537 gDefaultFace = NewFromName(FONT_DEFAULT_NAME, SkTypeface::kNormal); 540 gDefaultFace = NewFromName(FONT_DEFAULT_NAME, SkTypeface::kNormal);
538 SkTypefaceCache::Add(gDefaultFace, SkTypeface::kNormal); 541 SkTypefaceCache::Add(gDefaultFace, SkTypeface::kNormal);
539 } 542 }
540 return gDefaultFace; 543 return gDefaultFace;
541 } 544 }
542 545
543 /////////////////////////////////////////////////////////////////////////////// 546 ///////////////////////////////////////////////////////////////////////////////
544 547
545 extern CTFontRef SkTypeface_GetCTFontRef(const SkTypeface* face); 548 extern CTFontRef SkTypeface_GetCTFontRef(const SkTypeface* face);
546 CTFontRef SkTypeface_GetCTFontRef(const SkTypeface* face) { 549 CTFontRef SkTypeface_GetCTFontRef(const SkTypeface* face) {
547 const SkTypeface_Mac* macface = (const SkTypeface_Mac*)face; 550 const SkTypeface_Mac* macface = (const SkTypeface_Mac*)face;
548 return macface ? macface->fFontRef.get() : NULL; 551 return macface ? macface->fFontRef.get() : NULL;
549 } 552 }
550 553
551 /* This function is visible on the outside. It first searches the cache, and if 554 static SkTypeface* internalCreateTypefaceFromCTFont(CTFontRef fontRef, bool isLo calStream) {
552 * not found, returns a new entry (after adding it to the cache).
553 */
554 SkTypeface* SkCreateTypefaceFromCTFont(CTFontRef fontRef) {
555 SkFontID fontID = CTFontRef_to_SkFontID(fontRef); 555 SkFontID fontID = CTFontRef_to_SkFontID(fontRef);
556 SkTypeface* face = SkTypefaceCache::FindByID(fontID); 556 SkTypeface* face = SkTypefaceCache::FindByID(fontID);
557 if (face) { 557 if (face) {
558 face->ref(); 558 face->ref();
559 } else { 559 } else {
560 face = NewFromFontRef(fontRef, NULL); 560 face = NewFromFontRef(fontRef, NULL, isLocalStream);
561 SkTypefaceCache::Add(face, face->style()); 561 SkTypefaceCache::Add(face, face->style());
562 // NewFromFontRef doesn't retain the parameter, but the typeface it 562 // NewFromFontRef doesn't retain the parameter, but the typeface it
563 // 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
564 // a retain call here. 564 // a retain call here.
565 CFRetain(fontRef); 565 CFRetain(fontRef);
566 } 566 }
567 SkASSERT(face->getRefCnt() > 1); 567 SkASSERT(face->getRefCnt() > 1);
568 return face; 568 return face;
569 } 569 }
570 570
571 /* This function is visible on the outside. It first searches the cache, and if
572 * not found, returns a new entry (after adding it to the cache).
573 */
574 SkTypeface* SkCreateTypefaceFromCTFont(CTFontRef fontRef) {
575 return internalCreateTypefaceFromCTFont(fontRef, false);
576 }
577
571 struct NameStyleRec { 578 struct NameStyleRec {
572 const char* fName; 579 const char* fName;
573 SkTypeface::Style fStyle; 580 SkTypeface::Style fStyle;
574 }; 581 };
575 582
576 static bool FindByNameStyle(SkTypeface* face, SkTypeface::Style style, 583 static bool FindByNameStyle(SkTypeface* face, SkTypeface::Style style,
577 void* ctx) { 584 void* ctx) {
578 const SkTypeface_Mac* mface = reinterpret_cast<SkTypeface_Mac*>(face); 585 const SkTypeface_Mac* mface = reinterpret_cast<SkTypeface_Mac*>(face);
579 const NameStyleRec* rec = reinterpret_cast<const NameStyleRec*>(ctx); 586 const NameStyleRec* rec = reinterpret_cast<const NameStyleRec*>(ctx);
580 587
(...skipping 850 matching lines...) Expand 10 before | Expand all | Expand 10 after
1431 /////////////////////////////////////////////////////////////////////////////// 1438 ///////////////////////////////////////////////////////////////////////////////
1432 1439
1433 // Returns NULL on failure 1440 // Returns NULL on failure
1434 // Call must still manage its ownership of provider 1441 // Call must still manage its ownership of provider
1435 static SkTypeface* create_from_dataProvider(CGDataProviderRef provider) { 1442 static SkTypeface* create_from_dataProvider(CGDataProviderRef provider) {
1436 AutoCFRelease<CGFontRef> cg(CGFontCreateWithDataProvider(provider)); 1443 AutoCFRelease<CGFontRef> cg(CGFontCreateWithDataProvider(provider));
1437 if (NULL == cg) { 1444 if (NULL == cg) {
1438 return NULL; 1445 return NULL;
1439 } 1446 }
1440 CTFontRef ct = CTFontCreateWithGraphicsFont(cg, 0, NULL, NULL); 1447 CTFontRef ct = CTFontCreateWithGraphicsFont(cg, 0, NULL, NULL);
1441 return cg ? SkCreateTypefaceFromCTFont(ct) : NULL; 1448 return cg ? internalCreateTypefaceFromCTFont(ct, true) : NULL;
bungeman-skia 2014/06/30 15:10:23 I think this is incorrect, in that stream based ty
1442 } 1449 }
1443 1450
1444 // Web fonts added to the the CTFont registry do not return their character set. 1451 // Web fonts added to the the CTFont registry do not return their character set.
1445 // Iterate through the font in this case. The existing caller caches the result, 1452 // Iterate through the font in this case. The existing caller caches the result,
1446 // so the performance impact isn't too bad. 1453 // so the performance impact isn't too bad.
1447 static void populate_glyph_to_unicode_slow(CTFontRef ctFont, CFIndex glyphCount, 1454 static void populate_glyph_to_unicode_slow(CTFontRef ctFont, CFIndex glyphCount,
1448 SkTDArray<SkUnichar>* glyphToUnicode) { 1455 SkTDArray<SkUnichar>* glyphToUnicode) {
1449 glyphToUnicode->setCount(SkToInt(glyphCount)); 1456 glyphToUnicode->setCount(SkToInt(glyphCount));
1450 SkUnichar* out = glyphToUnicode->begin(); 1457 SkUnichar* out = glyphToUnicode->begin();
1451 sk_bzero(out, glyphCount * sizeof(SkUnichar)); 1458 sk_bzero(out, glyphCount * sizeof(SkUnichar));
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
1901 return str->c_str(); 1908 return str->c_str();
1902 } 1909 }
1903 1910
1904 void SkTypeface_Mac::onGetFontDescriptor(SkFontDescriptor* desc, 1911 void SkTypeface_Mac::onGetFontDescriptor(SkFontDescriptor* desc,
1905 bool* isLocalStream) const { 1912 bool* isLocalStream) const {
1906 SkString tmpStr; 1913 SkString tmpStr;
1907 1914
1908 desc->setFamilyName(get_str(CTFontCopyFamilyName(fFontRef), &tmpStr)); 1915 desc->setFamilyName(get_str(CTFontCopyFamilyName(fFontRef), &tmpStr));
1909 desc->setFullName(get_str(CTFontCopyFullName(fFontRef), &tmpStr)); 1916 desc->setFullName(get_str(CTFontCopyFullName(fFontRef), &tmpStr));
1910 desc->setPostscriptName(get_str(CTFontCopyPostScriptName(fFontRef), &tmpStr) ); 1917 desc->setPostscriptName(get_str(CTFontCopyPostScriptName(fFontRef), &tmpStr) );
1911 // TODO: need to add support for local-streams (here and openStream) 1918 *isLocalStream = fIsLocalStream;
1912 *isLocalStream = false;
1913 } 1919 }
1914 1920
1915 int SkTypeface_Mac::onCharsToGlyphs(const void* chars, Encoding encoding, 1921 int SkTypeface_Mac::onCharsToGlyphs(const void* chars, Encoding encoding,
1916 uint16_t glyphs[], int glyphCount) const 1922 uint16_t glyphs[], int glyphCount) const
1917 { 1923 {
1918 // Undocumented behavior of CTFontGetGlyphsForCharacters with non-bmp code p oints: 1924 // Undocumented behavior of CTFontGetGlyphsForCharacters with non-bmp code p oints:
1919 // When a surrogate pair is detected, the glyph index used is the index of t he high surrogate. 1925 // When a surrogate pair is detected, the glyph index used is the index of t he high surrogate.
1920 // It is documented that if a mapping is unavailable, the glyph will be set to 0. 1926 // It is documented that if a mapping is unavailable, the glyph will be set to 0.
1921 1927
1922 SkAutoSTMalloc<1024, UniChar> charStorage; 1928 SkAutoSTMalloc<1024, UniChar> charStorage;
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
2121 } 2127 }
2122 2128
2123 SkString str; 2129 SkString str;
2124 CFStringToSkString(cfFamilyName, &str); 2130 CFStringToSkString(cfFamilyName, &str);
2125 2131
2126 bool isFixedPitch; 2132 bool isFixedPitch;
2127 (void)computeStyleBits(ctFont, &isFixedPitch); 2133 (void)computeStyleBits(ctFont, &isFixedPitch);
2128 SkFontID fontID = CTFontRef_to_SkFontID(ctFont); 2134 SkFontID fontID = CTFontRef_to_SkFontID(ctFont);
2129 2135
2130 face = SkNEW_ARGS(SkTypeface_Mac, (rec.fFontStyle, fontID, isFixedPitch, 2136 face = SkNEW_ARGS(SkTypeface_Mac, (rec.fFontStyle, fontID, isFixedPitch,
2131 ctFont, str.c_str())); 2137 ctFont, str.c_str(), false));
2132 SkTypefaceCache::Add(face, face->style()); 2138 SkTypefaceCache::Add(face, face->style());
2133 return face; 2139 return face;
2134 } 2140 }
2135 2141
2136 class SkFontStyleSet_Mac : public SkFontStyleSet { 2142 class SkFontStyleSet_Mac : public SkFontStyleSet {
2137 public: 2143 public:
2138 SkFontStyleSet_Mac(CFStringRef familyName, CTFontDescriptorRef desc) 2144 SkFontStyleSet_Mac(CFStringRef familyName, CTFontDescriptorRef desc)
2139 : fArray(CTFontDescriptorCreateMatchingFontDescriptors(desc, NULL)) 2145 : fArray(CTFontDescriptorCreateMatchingFontDescriptors(desc, NULL))
2140 , fFamilyName(familyName) 2146 , fFamilyName(familyName)
2141 , fCount(0) { 2147 , fCount(0) {
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
2306 return create_typeface(NULL, familyName, (SkTypeface::Style)styleBits); 2312 return create_typeface(NULL, familyName, (SkTypeface::Style)styleBits);
2307 } 2313 }
2308 }; 2314 };
2309 2315
2310 /////////////////////////////////////////////////////////////////////////////// 2316 ///////////////////////////////////////////////////////////////////////////////
2311 2317
2312 SkFontMgr* SkFontMgr::Factory() { 2318 SkFontMgr* SkFontMgr::Factory() {
2313 return SkNEW(SkFontMgr_Mac); 2319 return SkNEW(SkFontMgr_Mac);
2314 } 2320 }
2315 #endif 2321 #endif
OLDNEW
« no previous file with comments | « no previous file | tests/FontHostStreamTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698