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

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

Issue 1139123008: Revert of Font variations. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 7 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/SkFontMgr_android.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 "SkTypes.h" // Keep this before any #ifdef ... 9 #include "SkTypes.h" // Keep this before any #ifdef ...
10 10
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 // Being an enum value it is not guarded by version macros, but old SDKs must st ill be supported. 421 // Being an enum value it is not guarded by version macros, but old SDKs must st ill be supported.
422 #if defined(__MAC_10_7) || defined(__IPHONE_4_3) 422 #if defined(__MAC_10_7) || defined(__IPHONE_4_3)
423 static const uint32_t SkCTFontColorGlyphsTrait = kCTFontColorGlyphsTrait; 423 static const uint32_t SkCTFontColorGlyphsTrait = kCTFontColorGlyphsTrait;
424 #else 424 #else
425 static const uint32_t SkCTFontColorGlyphsTrait = (1 << 13); 425 static const uint32_t SkCTFontColorGlyphsTrait = (1 << 13);
426 #endif 426 #endif
427 427
428 class SkTypeface_Mac : public SkTypeface { 428 class SkTypeface_Mac : public SkTypeface {
429 public: 429 public:
430 SkTypeface_Mac(const SkFontStyle& fs, bool isFixedPitch, 430 SkTypeface_Mac(const SkFontStyle& fs, bool isFixedPitch,
431 CTFontRef fontRef, const char requestedName[], bool isLocalSt ream, 431 CTFontRef fontRef, const char requestedName[], bool isLocalSt ream)
432 CGFontRef originatingCGFontRef = NULL)
433 : SkTypeface(fs, SkTypefaceCache::NewFontID(), isFixedPitch) 432 : SkTypeface(fs, SkTypefaceCache::NewFontID(), isFixedPitch)
434 , fRequestedName(requestedName) 433 , fRequestedName(requestedName)
435 , fFontRef(fontRef) // caller has already called CFRetain for us 434 , fFontRef(fontRef) // caller has already called CFRetain for us
436 , fOriginatingCGFontRef(originatingCGFontRef)
437 , fHasColorGlyphs(SkToBool(CTFontGetSymbolicTraits(fFontRef) & SkCTFontC olorGlyphsTrait)) 435 , fHasColorGlyphs(SkToBool(CTFontGetSymbolicTraits(fFontRef) & SkCTFontC olorGlyphsTrait))
438 , fIsLocalStream(isLocalStream) 436 , fIsLocalStream(isLocalStream)
439 { 437 {
440 SkASSERT(fontRef); 438 SkASSERT(fontRef);
441 } 439 }
442 440
443 SkString fRequestedName; 441 SkString fRequestedName;
444 AutoCFRelease<CTFontRef> fFontRef; 442 AutoCFRelease<CTFontRef> fFontRef;
445 AutoCFRelease<CGFontRef> fOriginatingCGFontRef;
446 const bool fHasColorGlyphs; 443 const bool fHasColorGlyphs;
447 444
448 protected: 445 protected:
449 int onGetUPEM() const override; 446 int onGetUPEM() const override;
450 SkStreamAsset* onOpenStream(int* ttcIndex) const override; 447 SkStreamAsset* onOpenStream(int* ttcIndex) const override;
451 SkFontData* onCreateFontData() const override;
452 void onGetFamilyName(SkString* familyName) const override; 448 void onGetFamilyName(SkString* familyName) const override;
453 SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override; 449 SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override;
454 int onGetTableTags(SkFontTableTag tags[]) const override; 450 int onGetTableTags(SkFontTableTag tags[]) const override;
455 virtual size_t onGetTableData(SkFontTableTag, size_t offset, 451 virtual size_t onGetTableData(SkFontTableTag, size_t offset,
456 size_t length, void* data) const override; 452 size_t length, void* data) const override;
457 SkScalerContext* onCreateScalerContext(const SkDescriptor*) const override; 453 SkScalerContext* onCreateScalerContext(const SkDescriptor*) const override;
458 void onFilterRec(SkScalerContextRec*) const override; 454 void onFilterRec(SkScalerContextRec*) const override;
459 void onGetFontDescriptor(SkFontDescriptor*, bool*) const override; 455 void onGetFontDescriptor(SkFontDescriptor*, bool*) const override;
460 virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics( 456 virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
461 PerGlyphInfo, 457 PerGlyphInfo,
462 const uint32_t*, uint32_t) const override; 458 const uint32_t*, uint32_t) const override;
463 virtual int onCharsToGlyphs(const void* chars, Encoding, uint16_t glyphs[], 459 virtual int onCharsToGlyphs(const void* chars, Encoding, uint16_t glyphs[],
464 int glyphCount) const override; 460 int glyphCount) const override;
465 int onCountGlyphs() const override; 461 int onCountGlyphs() const override;
466 462
467 private: 463 private:
468 bool fIsLocalStream; 464 bool fIsLocalStream;
469 465
470 typedef SkTypeface INHERITED; 466 typedef SkTypeface INHERITED;
471 }; 467 };
472 468
473 /** Creates a typeface without searching the cache. Takes ownership of the CTFon tRef. */ 469 /** Creates a typeface without searching the cache. Takes ownership of the CTFon tRef. */
474 static SkTypeface* NewFromFontRef(CTFontRef fontRef, const char name[], bool isL ocalStream, 470 static SkTypeface* NewFromFontRef(CTFontRef fontRef, const char name[], bool isL ocalStream) {
475 CGFontRef originatingCGFontRef = NULL)
476 {
477 SkASSERT(fontRef); 471 SkASSERT(fontRef);
478 bool isFixedPitch; 472 bool isFixedPitch;
479 SkFontStyle style = SkFontStyle(computeStyleBits(fontRef, &isFixedPitch)); 473 SkFontStyle style = SkFontStyle(computeStyleBits(fontRef, &isFixedPitch));
480 474
481 return new SkTypeface_Mac(style, isFixedPitch, fontRef, name, isLocalStream, 475 return new SkTypeface_Mac(style, isFixedPitch, fontRef, name, isLocalStream) ;
482 originatingCGFontRef);
483 } 476 }
484 477
485 static bool find_by_CTFontRef(SkTypeface* cached, const SkFontStyle&, void* cont ext) { 478 static bool find_by_CTFontRef(SkTypeface* cached, const SkFontStyle&, void* cont ext) {
486 CTFontRef self = (CTFontRef)context; 479 CTFontRef self = (CTFontRef)context;
487 CTFontRef other = ((SkTypeface_Mac*)cached)->fFontRef; 480 CTFontRef other = ((SkTypeface_Mac*)cached)->fFontRef;
488 481
489 return CFEqual(self, other); 482 return CFEqual(self, other);
490 } 483 }
491 484
492 /** Creates a typeface from a name, searching the cache. */ 485 /** Creates a typeface from a name, searching the cache. */
(...skipping 1259 matching lines...) Expand 10 before | Expand all | Expand 10 after
1752 entry->logicalLength = SkEndian_SwapBE32(SkToU32(tableSize)); 1745 entry->logicalLength = SkEndian_SwapBE32(SkToU32(tableSize));
1753 1746
1754 dataPtr += (tableSize + 3) & ~3; 1747 dataPtr += (tableSize + 3) & ~3;
1755 ++entry; 1748 ++entry;
1756 } 1749 }
1757 1750
1758 *ttcIndex = 0; 1751 *ttcIndex = 0;
1759 return stream; 1752 return stream;
1760 } 1753 }
1761 1754
1762 struct NonDefaultAxesContext {
1763 SkFixed* axisValue;
1764 CFArrayRef cgAxes;
1765 };
1766 static void set_non_default_axes(CFTypeRef key, CFTypeRef value, void* context) {
1767 NonDefaultAxesContext* self = static_cast<NonDefaultAxesContext*>(context);
1768
1769 if (CFGetTypeID(key) != CFStringGetTypeID() || CFGetTypeID(value) != CFNumbe rGetTypeID()) {
1770 return;
1771 }
1772
1773 // The key is a CFString which is a string from the 'name' table.
1774 // Search the cgAxes for an axis with this name, and use its index to store the value.
1775 CFIndex keyIndex = -1;
1776 CFStringRef keyString = static_cast<CFStringRef>(key);
1777 for (CFIndex i = 0; i < CFArrayGetCount(self->cgAxes); ++i) {
1778 CFTypeRef cgAxis = CFArrayGetValueAtIndex(self->cgAxes, i);
1779 if (CFGetTypeID(cgAxis) != CFDictionaryGetTypeID()) {
1780 continue;
1781 }
1782
1783 CFDictionaryRef cgAxisDict = static_cast<CFDictionaryRef>(cgAxis);
1784 CFTypeRef cgAxisName = CFDictionaryGetValue(cgAxisDict, kCGFontVariation AxisName);
1785 if (!cgAxisName || CFGetTypeID(cgAxisName) != CFStringGetTypeID()) {
1786 continue;
1787 }
1788 CFStringRef cgAxisNameString = static_cast<CFStringRef>(cgAxisName);
1789 if (CFStringCompare(keyString, cgAxisNameString, 0) == kCFCompareEqualTo ) {
1790 keyIndex = i;
1791 break;
1792 }
1793 }
1794 if (keyIndex == -1) {
1795 return;
1796 }
1797
1798 CFNumberRef valueNumber = static_cast<CFNumberRef>(value);
1799 double valueDouble;
1800 if (!CFNumberGetValue(valueNumber, kCFNumberDoubleType, &valueDouble) ||
1801 valueDouble < SkFixedToDouble(SK_FixedMin) || SkFixedToDouble(SK_FixedMa x) < valueDouble)
1802 {
1803 return;
1804 }
1805 self->axisValue[keyIndex] = SkDoubleToFixed(valueDouble);
1806 }
1807 static bool get_variations(CTFontRef fFontRef, CFIndex* cgAxisCount,
1808 SkAutoSTMalloc<4, SkFixed>* axisValues)
1809 {
1810 // CTFontCopyVariationAxes and CTFontCopyVariation do not work when applied to fonts which
1811 // started life with CGFontCreateWithDataProvider (they simply always return NULL).
1812 // As a result, we are limited to CGFontCopyVariationAxes and CGFontCopyVari ations.
1813 AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, NULL));
1814
1815 AutoCFRelease<CFDictionaryRef> cgVariations(CGFontCopyVariations(cgFont));
1816 // If a font has no variations CGFontCopyVariations returns NULL (instead of an empty dict).
1817 if (!cgVariations.get()) {
1818 return false;
1819 }
1820
1821 AutoCFRelease<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cgFont));
1822 *cgAxisCount = CFArrayGetCount(cgAxes);
1823 axisValues->reset(*cgAxisCount);
1824
1825 // Set all of the axes to their default values.
1826 // Fail if any default value cannot be determined.
1827 for (CFIndex i = 0; i < *cgAxisCount; ++i) {
1828 CFTypeRef cgAxis = CFArrayGetValueAtIndex(cgAxes, i);
1829 if (CFGetTypeID(cgAxis) != CFDictionaryGetTypeID()) {
1830 return false;
1831 }
1832
1833 CFDictionaryRef cgAxisDict = static_cast<CFDictionaryRef>(cgAxis);
1834 CFTypeRef axisDefaultValue = CFDictionaryGetValue(cgAxisDict,
1835 kCGFontVariationAxisDe faultValue);
1836 if (!axisDefaultValue || CFGetTypeID(axisDefaultValue) != CFNumberGetTyp eID()) {
1837 return false;
1838 }
1839 CFNumberRef axisDefaultValueNumber = static_cast<CFNumberRef>(axisDefaul tValue);
1840 double axisDefaultValueDouble;
1841 if (!CFNumberGetValue(axisDefaultValueNumber, kCFNumberDoubleType, &axis DefaultValueDouble))
1842 {
1843 return false;
1844 }
1845 if (axisDefaultValueDouble < SkFixedToDouble(SK_FixedMin) ||
1846 SkFixedToDouble(SK_FixedMax) < axisDefaultV alueDouble)
1847 {
1848 return false;
1849 }
1850 (*axisValues)[(int)i] = SkDoubleToFixed(axisDefaultValueDouble);
1851 }
1852
1853 // Override the default values with the given font's stated axis values.
1854 NonDefaultAxesContext c = { axisValues->get(), cgAxes.get() };
1855 CFDictionaryApplyFunction(cgVariations, set_non_default_axes, &c);
1856
1857 return true;
1858 }
1859 SkFontData* SkTypeface_Mac::onCreateFontData() const {
1860 int index;
1861 SkAutoTDelete<SkStreamAsset> stream(this->onOpenStream(&index));
1862
1863 CFIndex cgAxisCount;
1864 SkAutoSTMalloc<4, SkFixed> axisValues;
1865 if (get_variations(fFontRef, &cgAxisCount, &axisValues)) {
1866 return new SkFontData(stream.detach(), index, axisValues.get(), cgAxisCo unt);
1867 }
1868 return new SkFontData(stream.detach(), index, NULL, 0);
1869 }
1870
1871 /////////////////////////////////////////////////////////////////////////////// 1755 ///////////////////////////////////////////////////////////////////////////////
1872 /////////////////////////////////////////////////////////////////////////////// 1756 ///////////////////////////////////////////////////////////////////////////////
1873 1757
1874 int SkTypeface_Mac::onGetUPEM() const { 1758 int SkTypeface_Mac::onGetUPEM() const {
1875 AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, NULL)); 1759 AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, NULL));
1876 return CGFontGetUnitsPerEm(cgFont); 1760 return CGFontGetUnitsPerEm(cgFont);
1877 } 1761 }
1878 1762
1879 SkTypeface::LocalizedStrings* SkTypeface_Mac::onCreateFamilyNameIterator() const { 1763 SkTypeface::LocalizedStrings* SkTypeface_Mac::onCreateFamilyNameIterator() const {
1880 SkTypeface::LocalizedStrings* nameIter = 1764 SkTypeface::LocalizedStrings* nameIter =
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after
2356 } 2240 }
2357 2241
2358 SkTypeface* onCreateFromStream(SkStreamAsset* stream, int ttcIndex) const ov erride { 2242 SkTypeface* onCreateFromStream(SkStreamAsset* stream, int ttcIndex) const ov erride {
2359 AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromStream(strea m)); 2243 AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromStream(strea m));
2360 if (NULL == pr) { 2244 if (NULL == pr) {
2361 return NULL; 2245 return NULL;
2362 } 2246 }
2363 return create_from_dataProvider(pr); 2247 return create_from_dataProvider(pr);
2364 } 2248 }
2365 2249
2366 static CFDictionaryRef get_axes(CGFontRef cg, SkFontData* fontData) {
2367 AutoCFRelease<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cg));
2368 if (!cgAxes) {
2369 return NULL;
2370 }
2371
2372 CFIndex axisCount = CFArrayGetCount(cgAxes);
2373 if (0 == axisCount || axisCount != fontData->getAxisCount()) {
2374 return NULL;
2375 }
2376
2377 CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefa ult, axisCount,
2378 &kCFTypeDictiona ryKeyCallBacks,
2379 &kCFTypeDictiona ryValueCallBacks);
2380 for (int i = 0; i < fontData->getAxisCount(); ++i) {
2381 CFTypeRef axisInfo = CFArrayGetValueAtIndex(cgAxes, i);
2382 if (CFDictionaryGetTypeID() != CFGetTypeID(axisInfo)) {
2383 return NULL;
2384 }
2385 CFDictionaryRef axisInfoDict = static_cast<CFDictionaryRef>(axisInfo );
2386
2387 CFTypeRef axisName = CFDictionaryGetValue(axisInfoDict, kCGFontVaria tionAxisName);
2388 if (!axisName || CFGetTypeID(axisName) != CFStringGetTypeID()) {
2389 return NULL;
2390 }
2391
2392 // The variation axes can be set to any value, but cg will effective ly pin them.
2393 // Pin them here to normalize.
2394 CFTypeRef min = CFDictionaryGetValue(axisInfoDict, kCGFontVariationA xisMinValue);
2395 CFTypeRef max = CFDictionaryGetValue(axisInfoDict, kCGFontVariationA xisMaxValue);
2396 if (!min || CFGetTypeID(min) != CFNumberGetTypeID() ||
2397 !max || CFGetTypeID(max) != CFNumberGetTypeID())
2398 {
2399 return NULL;
2400 }
2401 CFNumberRef minNumber = static_cast<CFNumberRef>(min);
2402 CFNumberRef maxNumber = static_cast<CFNumberRef>(max);
2403 double minDouble;
2404 double maxDouble;
2405 if (!CFNumberGetValue(minNumber, kCFNumberDoubleType, &minDouble) ||
2406 !CFNumberGetValue(maxNumber, kCFNumberDoubleType, &maxDouble))
2407 {
2408 return NULL;
2409 }
2410 double value = SkTPin(SkFixedToDouble(fontData->getAxis()[i]), minDo uble, maxDouble);
2411 CFNumberRef valueNumber = CFNumberCreate(kCFAllocatorDefault, kCFNum berDoubleType,
2412 &value);
2413
2414 CFDictionaryAddValue(dict, axisName, valueNumber);
2415 CFRelease(valueNumber);
2416 }
2417 return dict;
2418 }
2419 SkTypeface* onCreateFromFontData(SkFontData* data) const override {
2420 SkAutoTDelete<SkFontData> fontData(data);
2421 SkStreamAsset* stream = fontData->detachStream();
2422 AutoCFRelease<CGDataProviderRef> provider(SkCreateDataProviderFromStream (stream));
2423 if (NULL == provider) {
2424 return NULL;
2425 }
2426 AutoCFRelease<CGFontRef> cg(CGFontCreateWithDataProvider(provider));
2427 if (NULL == cg) {
2428 return NULL;
2429 }
2430
2431 AutoCFRelease<CFDictionaryRef> cgVariations(get_axes(cg, fontData));
2432 // The CGFontRef returned by CGFontCreateCopyWithVariations when the pas sed CGFontRef was
2433 // created from a data provider does not appear to have any ownership of the underlying
2434 // data. The original CGFontRef must be kept alive until the copy will n o longer be used.
2435 AutoCFRelease<CGFontRef> cgVariant;
2436 if (cgVariations) {
2437 cgVariant.reset(CGFontCreateCopyWithVariations(cg, cgVariations));
2438 } else {
2439 cgVariant.reset(cg.detach());
2440 }
2441
2442 CTFontRef ct = CTFontCreateWithGraphicsFont(cgVariant, 0, NULL, NULL);
2443 if (!ct) {
2444 return NULL;
2445 }
2446 return NewFromFontRef(ct, NULL, true, cg.detach());
2447 }
2448
2449 SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override { 2250 SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override {
2450 AutoCFRelease<CGDataProviderRef> pr(CGDataProviderCreateWithFilename(pat h)); 2251 AutoCFRelease<CGDataProviderRef> pr(CGDataProviderCreateWithFilename(pat h));
2451 if (NULL == pr) { 2252 if (NULL == pr) {
2452 return NULL; 2253 return NULL;
2453 } 2254 }
2454 return create_from_dataProvider(pr); 2255 return create_from_dataProvider(pr);
2455 } 2256 }
2456 2257
2457 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], 2258 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
2458 unsigned styleBits) const overrid e { 2259 unsigned styleBits) const overrid e {
(...skipping 21 matching lines...) Expand all
2480 } 2281 }
2481 return face; 2282 return face;
2482 } 2283 }
2483 }; 2284 };
2484 2285
2485 /////////////////////////////////////////////////////////////////////////////// 2286 ///////////////////////////////////////////////////////////////////////////////
2486 2287
2487 SkFontMgr* SkFontMgr::Factory() { 2288 SkFontMgr* SkFontMgr::Factory() {
2488 return SkNEW(SkFontMgr_Mac); 2289 return SkNEW(SkFontMgr_Mac);
2489 } 2290 }
OLDNEW
« no previous file with comments | « src/ports/SkFontHost_linux.cpp ('k') | src/ports/SkFontMgr_android.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698