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

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

Issue 1128913008: 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, CFNumberType::kCFNumberDoubleType, &value Double) ||
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, CFNumberType::kCFNumberDou bleType,
1842 &axisDefaultValueDouble))
1843 {
1844 return false;
1845 }
1846 if (axisDefaultValueDouble < SkFixedToDouble(SK_FixedMin) ||
1847 SkFixedToDouble(SK_FixedMax) < axisDefaultV alueDouble)
1848 {
1849 return false;
1850 }
1851 (*axisValues)[(int)i] = SkDoubleToFixed(axisDefaultValueDouble);
1852 }
1853
1854 // Override the default values with the given font's stated axis values.
1855 NonDefaultAxesContext c = { axisValues->get(), cgAxes.get() };
1856 CFDictionaryApplyFunction(cgVariations, set_non_default_axes, &c);
1857
1858 return true;
1859 }
1860 SkFontData* SkTypeface_Mac::onCreateFontData() const {
1861 int index;
1862 SkAutoTDelete<SkStreamAsset> stream(this->onOpenStream(&index));
1863
1864 CFIndex cgAxisCount;
1865 SkAutoSTMalloc<4, SkFixed> axisValues;
1866 if (get_variations(fFontRef, &cgAxisCount, &axisValues)) {
1867 return new SkFontData(stream.detach(), index, axisValues.get(), cgAxisCo unt);
1868 }
1869 return new SkFontData(stream.detach(), index, NULL, 0);
1870 }
1871
1872 /////////////////////////////////////////////////////////////////////////////// 1755 ///////////////////////////////////////////////////////////////////////////////
1873 /////////////////////////////////////////////////////////////////////////////// 1756 ///////////////////////////////////////////////////////////////////////////////
1874 1757
1875 int SkTypeface_Mac::onGetUPEM() const { 1758 int SkTypeface_Mac::onGetUPEM() const {
1876 AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, NULL)); 1759 AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, NULL));
1877 return CGFontGetUnitsPerEm(cgFont); 1760 return CGFontGetUnitsPerEm(cgFont);
1878 } 1761 }
1879 1762
1880 SkTypeface::LocalizedStrings* SkTypeface_Mac::onCreateFamilyNameIterator() const { 1763 SkTypeface::LocalizedStrings* SkTypeface_Mac::onCreateFamilyNameIterator() const {
1881 SkTypeface::LocalizedStrings* nameIter = 1764 SkTypeface::LocalizedStrings* nameIter =
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after
2357 } 2240 }
2358 2241
2359 SkTypeface* onCreateFromStream(SkStreamAsset* stream, int ttcIndex) const ov erride { 2242 SkTypeface* onCreateFromStream(SkStreamAsset* stream, int ttcIndex) const ov erride {
2360 AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromStream(strea m)); 2243 AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromStream(strea m));
2361 if (NULL == pr) { 2244 if (NULL == pr) {
2362 return NULL; 2245 return NULL;
2363 } 2246 }
2364 return create_from_dataProvider(pr); 2247 return create_from_dataProvider(pr);
2365 } 2248 }
2366 2249
2367 static CFDictionaryRef get_axes(CGFontRef cg, SkFontData* fontData) {
2368 AutoCFRelease<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cg));
2369 if (!cgAxes) {
2370 return NULL;
2371 }
2372
2373 CFIndex axisCount = CFArrayGetCount(cgAxes);
2374 if (0 == axisCount || axisCount != fontData->getAxisCount()) {
2375 return NULL;
2376 }
2377
2378 CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefa ult, axisCount,
2379 &kCFTypeDictiona ryKeyCallBacks,
2380 &kCFTypeDictiona ryValueCallBacks);
2381 for (int i = 0; i < fontData->getAxisCount(); ++i) {
2382 CFTypeRef axisInfo = CFArrayGetValueAtIndex(cgAxes, i);
2383 if (CFDictionaryGetTypeID() != CFGetTypeID(axisInfo)) {
2384 return NULL;
2385 }
2386 CFDictionaryRef axisInfoDict = static_cast<CFDictionaryRef>(axisInfo );
2387
2388 CFTypeRef axisName = CFDictionaryGetValue(axisInfoDict, kCGFontVaria tionAxisName);
2389 if (!axisName || CFGetTypeID(axisName) != CFStringGetTypeID()) {
2390 return NULL;
2391 }
2392
2393 // The variation axes can be set to any value, but cg will effective ly pin them.
2394 // Pin them here to normalize.
2395 CFTypeRef min = CFDictionaryGetValue(axisInfoDict, kCGFontVariationA xisMinValue);
2396 CFTypeRef max = CFDictionaryGetValue(axisInfoDict, kCGFontVariationA xisMaxValue);
2397 if (!min || CFGetTypeID(min) != CFNumberGetTypeID() ||
2398 !max || CFGetTypeID(max) != CFNumberGetTypeID())
2399 {
2400 return NULL;
2401 }
2402 CFNumberRef minNumber = static_cast<CFNumberRef>(min);
2403 CFNumberRef maxNumber = static_cast<CFNumberRef>(max);
2404 double minDouble;
2405 double maxDouble;
2406 if (!CFNumberGetValue(minNumber, kCFNumberDoubleType, &minDouble) ||
2407 !CFNumberGetValue(maxNumber, kCFNumberDoubleType, &maxDouble))
2408 {
2409 return NULL;
2410 }
2411 double value = SkTPin(SkFixedToDouble(fontData->getAxis()[i]), minDo uble, maxDouble);
2412 CFNumberRef valueNumber = CFNumberCreate(kCFAllocatorDefault, kCFNum berDoubleType,
2413 &value);
2414
2415 CFDictionaryAddValue(dict, axisName, valueNumber);
2416 CFRelease(valueNumber);
2417 }
2418 return dict;
2419 }
2420 SkTypeface* onCreateFromFontData(SkFontData* data) const override {
2421 SkAutoTDelete<SkFontData> fontData(data);
2422 SkStreamAsset* stream = fontData->detachStream();
2423 AutoCFRelease<CGDataProviderRef> provider(SkCreateDataProviderFromStream (stream));
2424 if (NULL == provider) {
2425 return NULL;
2426 }
2427 AutoCFRelease<CGFontRef> cg(CGFontCreateWithDataProvider(provider));
2428 if (NULL == cg) {
2429 return NULL;
2430 }
2431
2432 AutoCFRelease<CFDictionaryRef> cgVariations(get_axes(cg, fontData));
2433 // The CGFontRef returned by CGFontCreateCopyWithVariations when the pas sed CGFontRef was
2434 // created from a data provider does not appear to have any ownership of the underlying
2435 // data. The original CGFontRef must be kept alive until the copy will n o longer be used.
2436 AutoCFRelease<CGFontRef> cgVariant;
2437 if (cgVariations) {
2438 cgVariant.reset(CGFontCreateCopyWithVariations(cg, cgVariations));
2439 } else {
2440 cgVariant.reset(cg.detach());
2441 }
2442
2443 CTFontRef ct = CTFontCreateWithGraphicsFont(cgVariant, 0, NULL, NULL);
2444 if (!ct) {
2445 return NULL;
2446 }
2447 return NewFromFontRef(ct, NULL, true, cg.detach());
2448 }
2449
2450 SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override { 2250 SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override {
2451 AutoCFRelease<CGDataProviderRef> pr(CGDataProviderCreateWithFilename(pat h)); 2251 AutoCFRelease<CGDataProviderRef> pr(CGDataProviderCreateWithFilename(pat h));
2452 if (NULL == pr) { 2252 if (NULL == pr) {
2453 return NULL; 2253 return NULL;
2454 } 2254 }
2455 return create_from_dataProvider(pr); 2255 return create_from_dataProvider(pr);
2456 } 2256 }
2457 2257
2458 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], 2258 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
2459 unsigned styleBits) const overrid e { 2259 unsigned styleBits) const overrid e {
(...skipping 21 matching lines...) Expand all
2481 } 2281 }
2482 return face; 2282 return face;
2483 } 2283 }
2484 }; 2284 };
2485 2285
2486 /////////////////////////////////////////////////////////////////////////////// 2286 ///////////////////////////////////////////////////////////////////////////////
2487 2287
2488 SkFontMgr* SkFontMgr::Factory() { 2288 SkFontMgr* SkFontMgr::Factory() {
2489 return SkNEW(SkFontMgr_Mac); 2289 return SkNEW(SkFontMgr_Mac);
2490 } 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