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

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: Some clean up. 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
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 struct NonDefaultAxesContext {
1769 SkFixed* axisValue;
1770 CFArrayRef cgAxes;
1771 };
1772 static void set_non_default_axes(CFTypeRef key, CFTypeRef value, void* context) {
1773 NonDefaultAxesContext* c = static_cast<NonDefaultAxesContext*>(context);
1774
1775 // The key is a CFString which is a string from the 'name' table.
1776 // Search the cgAxes for an axis with this name, and use its index to store the value.
1777 CFIndex keyIndex = -1;
1778 if (CFGetTypeID(key) == CFStringGetTypeID()) {
1779 CFStringRef keyString = static_cast<CFStringRef>(key);
1780 for (CFIndex i = 0; i < CFArrayGetCount(c->cgAxes); ++i) {
1781 CFTypeRef cgAxis = CFArrayGetValueAtIndex(c->cgAxes, i);
1782 if (CFGetTypeID(cgAxis) != CFDictionaryGetTypeID()) {
1783 continue;
1784 }
1785
1786 CFDictionaryRef cgAxisDict = static_cast<CFDictionaryRef>(cgAxis);
1787 CFTypeRef cgAxisName = CFDictionaryGetValue(cgAxisDict, kCGFontVaria tionAxisName);
1788 if (!cgAxisName || CFGetTypeID(cgAxisName) != CFStringGetTypeID()) {
1789 continue;
1790 }
1791 CFStringRef cgAxisNameString = static_cast<CFStringRef>(cgAxisName);
1792 if (CFStringCompare(keyString, cgAxisNameString, 0) == kCFCompareEqu alTo) {
1793 keyIndex = i;
1794 break;
1795 }
1796 }
1797 }
1798 if (keyIndex == -1) {
1799 return;
1800 }
1801
1802 if (CFGetTypeID(value) == CFNumberGetTypeID()) {
1803 CFNumberRef valueNumber = static_cast<CFNumberRef>(value);
1804 double valueDouble;
1805 if (CFNumberGetValue(valueNumber, CFNumberType::kCFNumberDoubleType, &va lueDouble)
1806 && SkFixedToDouble(SK_FixedMin) <= valueDouble && valueDouble <= SkF ixedToDouble(SK_FixedMax)) // better check?
1807 {
1808 c->axisValue[keyIndex] = SkDoubleToFixed(valueDouble);
1809 }
1810 }
1811 }
1812 static bool get_variations(CTFontRef fFontRef, CFIndex* cgAxisCount, SkAutoSTMal loc<4, SkFixed>* axisValues) {
1813 // CTFontCopyVariationAxes and CTFontCopyVariation do not work when applied to fonts which
1814 // started life with CGFontCreateWithDataProvider (they simply always return NULL).
1815 // As a result, we are limited to CGFontCopyVariationAxes and CGFontCopyVari ations.
1816 AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, NULL));
1817
1818 AutoCFRelease<CFDictionaryRef> cgVariations(CGFontCopyVariations(cgFont));
1819 // If a font has no variations CGFontCopyVariations returns NULL (instead of an empty dict).
1820 if (!cgVariations.get()) {
1821 return false;
1822 }
1823
1824 AutoCFRelease<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cgFont));
1825 *cgAxisCount = CFArrayGetCount(cgAxes);
1826 axisValues->reset(*cgAxisCount);
1827
1828 // Set all of the axes to their default values.
1829 // Fail if any default value cannot be determined.
1830 for (CFIndex i = 0; i < *cgAxisCount; ++i) {
1831 CFTypeRef cgAxis = CFArrayGetValueAtIndex(cgAxes, i);
1832 if (CFGetTypeID(cgAxis) != CFDictionaryGetTypeID()) {
1833 return false;
1834 }
1835
1836 CFDictionaryRef cgAxisDict = static_cast<CFDictionaryRef>(cgAxis);
1837 CFTypeRef axisDefaultValue = CFDictionaryGetValue(cgAxisDict, kCGFontVar iationAxisDefaultValue);
1838 if (!axisDefaultValue || CFGetTypeID(axisDefaultValue) != CFNumberGetTyp eID()) {
1839 return false;
1840 }
1841 CFNumberRef axisDefaultValueNumber = static_cast<CFNumberRef>(axisDefaul tValue);
1842 double axisDefaultValueDouble;
1843 if (!CFNumberGetValue(axisDefaultValueNumber, CFNumberType::kCFNumberDou bleType, &axisDefaultValueDouble)) {
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 //axisValues[0] = 4 * SK_Fixed1; // TODO:remove, for testing out of boun d values
1868 return new SkFontData(stream.detach(), index, cgAxisCount, axisValues.ge t());
1869 }
1870 return new SkFontData(stream.detach(), index, 0, NULL);
1871 }
1872
1767 /////////////////////////////////////////////////////////////////////////////// 1873 ///////////////////////////////////////////////////////////////////////////////
1768 /////////////////////////////////////////////////////////////////////////////// 1874 ///////////////////////////////////////////////////////////////////////////////
1769 1875
1770 int SkTypeface_Mac::onGetUPEM() const { 1876 int SkTypeface_Mac::onGetUPEM() const {
1771 AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, NULL)); 1877 AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, NULL));
1772 return CGFontGetUnitsPerEm(cgFont); 1878 return CGFontGetUnitsPerEm(cgFont);
1773 } 1879 }
1774 1880
1775 SkTypeface::LocalizedStrings* SkTypeface_Mac::onCreateFamilyNameIterator() const { 1881 SkTypeface::LocalizedStrings* SkTypeface_Mac::onCreateFamilyNameIterator() const {
1776 SkTypeface::LocalizedStrings* nameIter = 1882 SkTypeface::LocalizedStrings* nameIter =
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after
2260 } 2366 }
2261 2367
2262 SkTypeface* onCreateFromStream(SkStreamAsset* stream, int ttcIndex) const ov erride { 2368 SkTypeface* onCreateFromStream(SkStreamAsset* stream, int ttcIndex) const ov erride {
2263 AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromStream(strea m)); 2369 AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromStream(strea m));
2264 if (NULL == pr) { 2370 if (NULL == pr) {
2265 return NULL; 2371 return NULL;
2266 } 2372 }
2267 return create_from_dataProvider(pr); 2373 return create_from_dataProvider(pr);
2268 } 2374 }
2269 2375
2376 static CFDictionaryRef get_axes(CGFontRef cg, SkFontData* fontData) {
2377 AutoCFRelease<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cg));
2378 if (!cgAxes) {
2379 return NULL;
2380 }
2381
2382 CFIndex axisCount = CFArrayGetCount(cgAxes);
2383 if (axisCount != fontData->getAxisCount()) {
2384 return NULL;
2385 }
2386
2387 SkAutoSTMalloc<4, CFTypeRef> keys(fontData->getAxisCount());
2388 SkAutoSTMalloc<4, CFTypeRef> values(fontData->getAxisCount());
2389 for (int i = 0; i < fontData->getAxisCount(); ++i) {
2390 CFTypeRef axisInfo = CFArrayGetValueAtIndex(cgAxes, i);
2391 if (CFDictionaryGetTypeID() != CFGetTypeID(axisInfo)) {
2392 return NULL;
2393 }
2394 CFDictionaryRef axisInfoDict = static_cast<CFDictionaryRef>(axisInfo );
2395
2396 CFTypeRef axisName = CFDictionaryGetValue(axisInfoDict, kCGFontVaria tionAxisName);
2397 if (!axisName || CFGetTypeID(axisName) != CFStringGetTypeID()) {
2398 return NULL;
2399 }
2400 keys[i] = axisName;
2401
2402 //CFNumberRef min = static_cast<CFNumberRef>(CFDictionaryGetValue(ax isInfo, kCGFontVariationAxisMinValue));
2403 //CFNumberRef max = static_cast<CFNumberRef>(CFDictionaryGetValue(ax isInfo, kCGFontVariationAxisMaxValue));
2404 //TODO: should the value be pinned?
2405 double value = SkFixedToDouble(fontData->getAxis()[i]);
2406 values[i] = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value);
2407 }
2408
2409 return CFDictionaryCreate(kCFAllocatorDefault, keys.get(), values.get(), fontData->getAxisCount(),
2410 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictio naryValueCallBacks);
2411
2412 }
2413 SkTypeface* onCreateFromFontData(SkFontData* fontData) const override {
2414 AutoCFRelease<CGDataProviderRef> provider(SkCreateDataProviderFromStream (fontData->transferStream()));
2415 if (NULL == provider) {
2416 return NULL;
2417 }
2418 AutoCFRelease<CGFontRef> cg(CGFontCreateWithDataProvider(provider));
2419 if (NULL == cg) {
2420 return NULL;
2421 }
2422
2423 AutoCFRelease<CFDictionaryRef> cgVariations(get_axes(cg, fontData));
2424 AutoCFRelease<CGFontRef> cgVariant(cgVariations ? CGFontCreateCopyWithVa riations(cg, cgVariations) : cg);
2425
2426 CTFontRef ct = CTFontCreateWithGraphicsFont(cgVariant, 0, NULL, NULL);
2427 if (!ct) {
2428 return NULL;
2429 }
2430 //SkTypeface* typeface = NewFromFontRef(ct, NULL, true);
2431 //SkFontData* fontData1 = typeface->createFontData();
2432 //delete fontData1;
2433 //return typeface;
2434 return NewFromFontRef(ct, NULL, true);
2435 }
2436
2270 SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override { 2437 SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override {
2271 AutoCFRelease<CGDataProviderRef> pr(CGDataProviderCreateWithFilename(pat h)); 2438 AutoCFRelease<CGDataProviderRef> pr(CGDataProviderCreateWithFilename(pat h));
2272 if (NULL == pr) { 2439 if (NULL == pr) {
2273 return NULL; 2440 return NULL;
2274 } 2441 }
2275 return create_from_dataProvider(pr); 2442 return create_from_dataProvider(pr);
2276 } 2443 }
2277 2444
2278 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], 2445 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
2279 unsigned styleBits) const overrid e { 2446 unsigned styleBits) const overrid e {
(...skipping 21 matching lines...) Expand all
2301 } 2468 }
2302 return face; 2469 return face;
2303 } 2470 }
2304 }; 2471 };
2305 2472
2306 /////////////////////////////////////////////////////////////////////////////// 2473 ///////////////////////////////////////////////////////////////////////////////
2307 2474
2308 SkFontMgr* SkFontMgr::Factory() { 2475 SkFontMgr* SkFontMgr::Factory() {
2309 return SkNEW(SkFontMgr_Mac); 2476 return SkNEW(SkFontMgr_Mac);
2310 } 2477 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698