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

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

Issue 1027373002: Font variations. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Initial Mac implementation (buggy). Created 5 years, 8 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 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 SkASSERT(fontRef); 459 SkASSERT(fontRef);
460 } 460 }
461 461
462 SkString fRequestedName; 462 SkString fRequestedName;
463 AutoCFRelease<CTFontRef> fFontRef; 463 AutoCFRelease<CTFontRef> fFontRef;
464 const bool fHasColorGlyphs; 464 const bool fHasColorGlyphs;
465 465
466 protected: 466 protected:
467 int onGetUPEM() const override; 467 int onGetUPEM() const override;
468 SkStreamAsset* onOpenStream(int* ttcIndex) const override; 468 SkStreamAsset* onOpenStream(int* ttcIndex) const override;
469 SkFontData* onCreateFontData() const override;
469 void onGetFamilyName(SkString* familyName) const override; 470 void onGetFamilyName(SkString* familyName) const override;
470 SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override; 471 SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override;
471 int onGetTableTags(SkFontTableTag tags[]) const override; 472 int onGetTableTags(SkFontTableTag tags[]) const override;
472 virtual size_t onGetTableData(SkFontTableTag, size_t offset, 473 virtual size_t onGetTableData(SkFontTableTag, size_t offset,
473 size_t length, void* data) const override; 474 size_t length, void* data) const override;
474 SkScalerContext* onCreateScalerContext(const SkDescriptor*) const override; 475 SkScalerContext* onCreateScalerContext(const SkDescriptor*) const override;
475 void onFilterRec(SkScalerContextRec*) const override; 476 void onFilterRec(SkScalerContextRec*) const override;
476 void onGetFontDescriptor(SkFontDescriptor*, bool*) const override; 477 void onGetFontDescriptor(SkFontDescriptor*, bool*) const override;
477 virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics( 478 virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
478 SkAdvancedTypefaceMetrics::PerGlyphInfo, 479 SkAdvancedTypefaceMetrics::PerGlyphInfo,
(...skipping 1278 matching lines...) Expand 10 before | Expand all | Expand 10 after
1757 entry->logicalLength = SkEndian_SwapBE32(SkToU32(tableSize)); 1758 entry->logicalLength = SkEndian_SwapBE32(SkToU32(tableSize));
1758 1759
1759 dataPtr += (tableSize + 3) & ~3; 1760 dataPtr += (tableSize + 3) & ~3;
1760 ++entry; 1761 ++entry;
1761 } 1762 }
1762 1763
1763 *ttcIndex = 0; 1764 *ttcIndex = 0;
1764 return stream; 1765 return stream;
1765 } 1766 }
1766 1767
1768 #include <limits>
1769
1770 struct Context {
1771 SkFontData::Axis* axes;
1772 int index;
1773 CFArrayRef ctAxes;
1774 };
1775 static void accumulateAxes(CFTypeRef key, CFTypeRef value, void* context) {
1776 Context* c = static_cast<Context*>(context);
1777
1778 // The key is supposed to be a CFNumber 'FourCharCode'.
1779 // However, if the font was originally selected by style, the key is a CFStr ing with a name.
1780 // See http://lists.apple.com/archives/coretext-dev/2012/Aug/msg00006.html .
1781 // This issue observed in 10.10.3.
1782 // So if the key is a CFString convert it into CFNumber by going throught th e axis information.
1783 // Amusingly, if a CFString is specified as the key on the descriptor on a r equest,
1784 // an uncaught exception is thrown (normally causing a crash).
1785 SkFourByteTag tag = 0;
1786 if (CFGetTypeID(key) == CFStringGetTypeID()) {
1787 CFStringRef keyString = static_cast<CFStringRef>(key);
1788 for (CFIndex i = 0; i < CFArrayGetCount(c->ctAxes); ++i) {
1789 CFTypeRef variations = CFArrayGetValueAtIndex(c->ctAxes, i);
1790 if (CFGetTypeID(variations) != CFDictionaryGetTypeID()) {
1791 continue;
1792 }
1793
1794 CFDictionaryRef variationsDict = static_cast<CFDictionaryRef>(variat ions);
1795 CFTypeRef axisName;
1796 if (!CFDictionaryGetValueIfPresent(variationsDict, kCTFontVariationA xisNameKey, &axisName)) {
1797 continue;
1798 }
1799 if (CFGetTypeID(axisName) != CFStringGetTypeID()) {
1800 continue;
1801 }
1802 CFStringRef axisNameString = static_cast<CFStringRef>(axisName);
1803 if (CFStringCompare(keyString, axisNameString, 0) == kCFCompareEqual To) {
1804 CFTypeRef axisIdentifier;
1805 if (!CFDictionaryGetValueIfPresent(variationsDict, kCTFontVariat ionAxisIdentifierKey, &axisIdentifier)) {
1806 continue;
1807 }
1808 if (CFGetTypeID(axisIdentifier) != CFNumberGetTypeID()) {
1809 continue;
1810 }
1811 CFNumberRef axisIdentifierNumber = static_cast<CFNumberRef>(axis Identifier);
1812 int64_t axisIdentifier64;
1813 if (CFNumberGetValue(axisIdentifierNumber, CFNumberType::kCFNumb erSInt64Type, &axisIdentifier64)
1814 && 0 <= axisIdentifier64 && axisIdentifier64 <= std::numeric _limits<uint32_t>::max())
1815 {
1816 tag = axisIdentifier64;
1817 break;
1818 }
1819 }
1820 }
1821 } else if (CFGetTypeID(key) == CFNumberGetTypeID()) {
1822 CFNumberRef axisIdentifierNumber = static_cast<CFNumberRef>(key);
1823 int64_t axisIdentifier64;
1824 if (CFNumberGetValue(axisIdentifierNumber, CFNumberType::kCFNumberSInt64 Type, &axisIdentifier64)
1825 && 0 <= axisIdentifier64 && axisIdentifier64 <= std::numeric_limits< uint32_t>::max())
1826 {
1827 tag = axisIdentifier64;
1828 }
1829 }
1830
1831 SkFixed valueFixed = SK_Fixed1; // should this be SK_FixedNaN?
1832 if (CFGetTypeID(value) == CFNumberGetTypeID()) {
1833 CFNumberRef valueNumber = static_cast<CFNumberRef>(value);
1834 double valueDouble;
1835 if (CFNumberGetValue(valueNumber, CFNumberType::kCFNumberDoubleType, &va lueDouble)
1836 && SkFixedToDouble(SK_FixedMin) <= valueDouble && valueDouble <= SkF ixedToDouble(SK_FixedMax)) // better check?
1837 {
1838 valueFixed = SkDoubleToFixed(valueDouble);
1839 }
1840 }
1841 c->axes[c->index].fTag = tag;
1842 c->axes[c->index].fValue = valueFixed;
1843 ++c->index;
1844 }
1845 SkFontData* SkTypeface_Mac::onCreateFontData() const {
1846 int index;
1847 SkAutoTDelete<SkStreamAsset> stream(this->onOpenStream(&index));
1848
1849 AutoCFRelease<CFDictionaryRef> variations(CTFontCopyVariation(fFontRef));
1850 // If a font has no variations CTFontCopyVariation returns NULL instead of a n empty dict.
1851 if (variations.get()) {
1852 CFIndex variationCount = CFDictionaryGetCount(variations);
1853 SkAutoSTMalloc<4, SkFontData::Axis> axes(variationCount);
1854 AutoCFRelease<CFArrayRef> ctAxes(CTFontCopyVariationAxes(fFontRef));
1855 Context c = { axes.get(), 0, ctAxes.get() };
1856 CFDictionaryApplyFunction(variations, accumulateAxes, &c);
1857 axes[0].fValue = 4 * SK_Fixed1;
bungeman-skia 2015/04/23 21:16:34 This is a test to see what happens when a variatio
1858 return new SkFontData(stream.detach(), index, variationCount, axes.get() );
1859 } else {
1860 return new SkFontData(stream.detach(), index, 0, NULL);
1861 }
1862 }
1863
1767 /////////////////////////////////////////////////////////////////////////////// 1864 ///////////////////////////////////////////////////////////////////////////////
1768 /////////////////////////////////////////////////////////////////////////////// 1865 ///////////////////////////////////////////////////////////////////////////////
1769 1866
1770 int SkTypeface_Mac::onGetUPEM() const { 1867 int SkTypeface_Mac::onGetUPEM() const {
1771 AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, NULL)); 1868 AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, NULL));
1772 return CGFontGetUnitsPerEm(cgFont); 1869 return CGFontGetUnitsPerEm(cgFont);
1773 } 1870 }
1774 1871
1775 SkTypeface::LocalizedStrings* SkTypeface_Mac::onCreateFamilyNameIterator() const { 1872 SkTypeface::LocalizedStrings* SkTypeface_Mac::onCreateFamilyNameIterator() const {
1776 SkTypeface::LocalizedStrings* nameIter = 1873 SkTypeface::LocalizedStrings* nameIter =
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after
2260 } 2357 }
2261 2358
2262 SkTypeface* onCreateFromStream(SkStreamAsset* stream, int ttcIndex) const ov erride { 2359 SkTypeface* onCreateFromStream(SkStreamAsset* stream, int ttcIndex) const ov erride {
2263 AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromStream(strea m)); 2360 AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromStream(strea m));
2264 if (NULL == pr) { 2361 if (NULL == pr) {
2265 return NULL; 2362 return NULL;
2266 } 2363 }
2267 return create_from_dataProvider(pr); 2364 return create_from_dataProvider(pr);
2268 } 2365 }
2269 2366
2367 SkTypeface* onCreateFromFontData(SkFontData* fontData) const override {
2368 AutoCFRelease<CGDataProviderRef> provider(SkCreateDataProviderFromStream (fontData->transferStream()));
2369 if (NULL == provider) {
2370 return NULL;
2371 }
2372 AutoCFRelease<CGFontRef> cg(CGFontCreateWithDataProvider(provider));
2373 if (NULL == cg) {
2374 return NULL;
2375 }
2376 SkAutoSTMalloc<4, CFTypeRef> keys(fontData->getAxisCount());
2377 SkAutoSTMalloc<4, CFTypeRef> values(fontData->getAxisCount());
2378
2379 for (int i = 0; i < fontData->getAxisCount(); ++i) {
2380 int64_t key = fontData->getAxis()[i].fTag;
2381 keys[i] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, & key);
2382
2383 double value = SkFixedToDouble(fontData->getAxis()[i].fValue);
2384 values[i] = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value);
2385 }
2386 AutoCFRelease<CFDictionaryRef> variations(CFDictionaryCreate(kCFAllocato rDefault, keys.get(), values.get(), fontData->getAxisCount(),
2387 &kCFTypeDic tionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
2388 CFDictionaryRef variationLValue = variations.get();
2389 AutoCFRelease<CFDictionaryRef> attributes(CFDictionaryCreate(kCFAllocato rDefault, (const void**)&kCTFontVariationAttribute, (const void**)&variationLVal ue, 1,
2390 &kCFTypeDic tionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
2391 AutoCFRelease<CTFontDescriptorRef> descriptor(CTFontDescriptorCreateWith Attributes(attributes));
2392 //AutoCFRelease<CGFontRef> cgWithAxes(CGFontCreateCopyWithVariations(cg, variations));
2393 CTFontRef ct = CTFontCreateWithGraphicsFont(cg, 0, NULL, descriptor);
bungeman-skia 2015/04/23 21:16:34 So this starts the buggy. This will create a CTFon
2394 if (!ct) {
2395 return NULL;
2396 }
2397 AutoCFRelease<CFDictionaryRef> ctvariations(CTFontCopyVariation(ct));
2398 ///AutoCFRelease<CTFontDescriptorRef> desc(CTFontCopyFontDescriptor(ct)) ;
2399 //CFShow(desc);
2400 //AutoCFRelease<CTFontDescriptorRef> desc1(CTFontDescriptorCreateCopyWit hVariation(desc, (CFNumberRef)keys[0], 1.0));
2401 //CFShow(desc1);
2402 AutoCFRelease<CFArrayRef> ctAxes(CTFontCopyVariationAxes(ct));
2403 CFShow(ctAxes);
2404 SkTypeface* typeface = NewFromFontRef(ct, NULL, true);
2405 SkFontData* fontData1 = typeface->createFontData();
2406 delete fontData1;
2407 return typeface;
2408 }
2409
2270 SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override { 2410 SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override {
2271 AutoCFRelease<CGDataProviderRef> pr(CGDataProviderCreateWithFilename(pat h)); 2411 AutoCFRelease<CGDataProviderRef> pr(CGDataProviderCreateWithFilename(pat h));
2272 if (NULL == pr) { 2412 if (NULL == pr) {
2273 return NULL; 2413 return NULL;
2274 } 2414 }
2275 return create_from_dataProvider(pr); 2415 return create_from_dataProvider(pr);
2276 } 2416 }
2277 2417
2278 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], 2418 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
2279 unsigned styleBits) const overrid e { 2419 unsigned styleBits) const overrid e {
(...skipping 21 matching lines...) Expand all
2301 } 2441 }
2302 return face; 2442 return face;
2303 } 2443 }
2304 }; 2444 };
2305 2445
2306 /////////////////////////////////////////////////////////////////////////////// 2446 ///////////////////////////////////////////////////////////////////////////////
2307 2447
2308 SkFontMgr* SkFontMgr::Factory() { 2448 SkFontMgr* SkFontMgr::Factory() {
2309 return SkNEW(SkFontMgr_Mac); 2449 return SkNEW(SkFontMgr_Mac);
2310 } 2450 }
2451
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