OLD | NEW |
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 Loading... |
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) |
432 : SkTypeface(fs, SkTypefaceCache::NewFontID(), isFixedPitch) | 433 : SkTypeface(fs, SkTypefaceCache::NewFontID(), isFixedPitch) |
433 , fRequestedName(requestedName) | 434 , fRequestedName(requestedName) |
434 , fFontRef(fontRef) // caller has already called CFRetain for us | 435 , fFontRef(fontRef) // caller has already called CFRetain for us |
| 436 , fOriginatingCGFontRef(originatingCGFontRef) |
435 , fHasColorGlyphs(SkToBool(CTFontGetSymbolicTraits(fFontRef) & SkCTFontC
olorGlyphsTrait)) | 437 , fHasColorGlyphs(SkToBool(CTFontGetSymbolicTraits(fFontRef) & SkCTFontC
olorGlyphsTrait)) |
436 , fIsLocalStream(isLocalStream) | 438 , fIsLocalStream(isLocalStream) |
437 { | 439 { |
438 SkASSERT(fontRef); | 440 SkASSERT(fontRef); |
439 } | 441 } |
440 | 442 |
441 SkString fRequestedName; | 443 SkString fRequestedName; |
442 AutoCFRelease<CTFontRef> fFontRef; | 444 AutoCFRelease<CTFontRef> fFontRef; |
| 445 AutoCFRelease<CGFontRef> fOriginatingCGFontRef; |
443 const bool fHasColorGlyphs; | 446 const bool fHasColorGlyphs; |
444 | 447 |
445 protected: | 448 protected: |
446 int onGetUPEM() const override; | 449 int onGetUPEM() const override; |
447 SkStreamAsset* onOpenStream(int* ttcIndex) const override; | 450 SkStreamAsset* onOpenStream(int* ttcIndex) const override; |
| 451 SkFontData* onCreateFontData() const override; |
448 void onGetFamilyName(SkString* familyName) const override; | 452 void onGetFamilyName(SkString* familyName) const override; |
449 SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override; | 453 SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override; |
450 int onGetTableTags(SkFontTableTag tags[]) const override; | 454 int onGetTableTags(SkFontTableTag tags[]) const override; |
451 virtual size_t onGetTableData(SkFontTableTag, size_t offset, | 455 virtual size_t onGetTableData(SkFontTableTag, size_t offset, |
452 size_t length, void* data) const override; | 456 size_t length, void* data) const override; |
453 SkScalerContext* onCreateScalerContext(const SkDescriptor*) const override; | 457 SkScalerContext* onCreateScalerContext(const SkDescriptor*) const override; |
454 void onFilterRec(SkScalerContextRec*) const override; | 458 void onFilterRec(SkScalerContextRec*) const override; |
455 void onGetFontDescriptor(SkFontDescriptor*, bool*) const override; | 459 void onGetFontDescriptor(SkFontDescriptor*, bool*) const override; |
456 virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics( | 460 virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics( |
457 PerGlyphInfo, | 461 PerGlyphInfo, |
458 const uint32_t*, uint32_t) const override; | 462 const uint32_t*, uint32_t) const override; |
459 virtual int onCharsToGlyphs(const void* chars, Encoding, uint16_t glyphs[], | 463 virtual int onCharsToGlyphs(const void* chars, Encoding, uint16_t glyphs[], |
460 int glyphCount) const override; | 464 int glyphCount) const override; |
461 int onCountGlyphs() const override; | 465 int onCountGlyphs() const override; |
462 | 466 |
463 private: | 467 private: |
464 bool fIsLocalStream; | 468 bool fIsLocalStream; |
465 | 469 |
466 typedef SkTypeface INHERITED; | 470 typedef SkTypeface INHERITED; |
467 }; | 471 }; |
468 | 472 |
469 /** Creates a typeface without searching the cache. Takes ownership of the CTFon
tRef. */ | 473 /** Creates a typeface without searching the cache. Takes ownership of the CTFon
tRef. */ |
470 static SkTypeface* NewFromFontRef(CTFontRef fontRef, const char name[], bool isL
ocalStream) { | 474 static SkTypeface* NewFromFontRef(CTFontRef fontRef, const char name[], bool isL
ocalStream, |
| 475 CGFontRef originatingCGFontRef = NULL) |
| 476 { |
471 SkASSERT(fontRef); | 477 SkASSERT(fontRef); |
472 bool isFixedPitch; | 478 bool isFixedPitch; |
473 SkFontStyle style = SkFontStyle(computeStyleBits(fontRef, &isFixedPitch)); | 479 SkFontStyle style = SkFontStyle(computeStyleBits(fontRef, &isFixedPitch)); |
474 | 480 |
475 return new SkTypeface_Mac(style, isFixedPitch, fontRef, name, isLocalStream)
; | 481 return new SkTypeface_Mac(style, isFixedPitch, fontRef, name, isLocalStream, |
| 482 originatingCGFontRef); |
476 } | 483 } |
477 | 484 |
478 static bool find_by_CTFontRef(SkTypeface* cached, const SkFontStyle&, void* cont
ext) { | 485 static bool find_by_CTFontRef(SkTypeface* cached, const SkFontStyle&, void* cont
ext) { |
479 CTFontRef self = (CTFontRef)context; | 486 CTFontRef self = (CTFontRef)context; |
480 CTFontRef other = ((SkTypeface_Mac*)cached)->fFontRef; | 487 CTFontRef other = ((SkTypeface_Mac*)cached)->fFontRef; |
481 | 488 |
482 return CFEqual(self, other); | 489 return CFEqual(self, other); |
483 } | 490 } |
484 | 491 |
485 /** Creates a typeface from a name, searching the cache. */ | 492 /** Creates a typeface from a name, searching the cache. */ |
(...skipping 1259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1745 entry->logicalLength = SkEndian_SwapBE32(SkToU32(tableSize)); | 1752 entry->logicalLength = SkEndian_SwapBE32(SkToU32(tableSize)); |
1746 | 1753 |
1747 dataPtr += (tableSize + 3) & ~3; | 1754 dataPtr += (tableSize + 3) & ~3; |
1748 ++entry; | 1755 ++entry; |
1749 } | 1756 } |
1750 | 1757 |
1751 *ttcIndex = 0; | 1758 *ttcIndex = 0; |
1752 return stream; | 1759 return stream; |
1753 } | 1760 } |
1754 | 1761 |
| 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 |
1755 /////////////////////////////////////////////////////////////////////////////// | 1871 /////////////////////////////////////////////////////////////////////////////// |
1756 /////////////////////////////////////////////////////////////////////////////// | 1872 /////////////////////////////////////////////////////////////////////////////// |
1757 | 1873 |
1758 int SkTypeface_Mac::onGetUPEM() const { | 1874 int SkTypeface_Mac::onGetUPEM() const { |
1759 AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, NULL)); | 1875 AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, NULL)); |
1760 return CGFontGetUnitsPerEm(cgFont); | 1876 return CGFontGetUnitsPerEm(cgFont); |
1761 } | 1877 } |
1762 | 1878 |
1763 SkTypeface::LocalizedStrings* SkTypeface_Mac::onCreateFamilyNameIterator() const
{ | 1879 SkTypeface::LocalizedStrings* SkTypeface_Mac::onCreateFamilyNameIterator() const
{ |
1764 SkTypeface::LocalizedStrings* nameIter = | 1880 SkTypeface::LocalizedStrings* nameIter = |
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2240 } | 2356 } |
2241 | 2357 |
2242 SkTypeface* onCreateFromStream(SkStreamAsset* stream, int ttcIndex) const ov
erride { | 2358 SkTypeface* onCreateFromStream(SkStreamAsset* stream, int ttcIndex) const ov
erride { |
2243 AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromStream(strea
m)); | 2359 AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromStream(strea
m)); |
2244 if (NULL == pr) { | 2360 if (NULL == pr) { |
2245 return NULL; | 2361 return NULL; |
2246 } | 2362 } |
2247 return create_from_dataProvider(pr); | 2363 return create_from_dataProvider(pr); |
2248 } | 2364 } |
2249 | 2365 |
| 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 |
2250 SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override
{ | 2449 SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override
{ |
2251 AutoCFRelease<CGDataProviderRef> pr(CGDataProviderCreateWithFilename(pat
h)); | 2450 AutoCFRelease<CGDataProviderRef> pr(CGDataProviderCreateWithFilename(pat
h)); |
2252 if (NULL == pr) { | 2451 if (NULL == pr) { |
2253 return NULL; | 2452 return NULL; |
2254 } | 2453 } |
2255 return create_from_dataProvider(pr); | 2454 return create_from_dataProvider(pr); |
2256 } | 2455 } |
2257 | 2456 |
2258 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], | 2457 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], |
2259 unsigned styleBits) const overrid
e { | 2458 unsigned styleBits) const overrid
e { |
(...skipping 21 matching lines...) Expand all Loading... |
2281 } | 2480 } |
2282 return face; | 2481 return face; |
2283 } | 2482 } |
2284 }; | 2483 }; |
2285 | 2484 |
2286 /////////////////////////////////////////////////////////////////////////////// | 2485 /////////////////////////////////////////////////////////////////////////////// |
2287 | 2486 |
2288 SkFontMgr* SkFontMgr::Factory() { | 2487 SkFontMgr* SkFontMgr::Factory() { |
2289 return SkNEW(SkFontMgr_Mac); | 2488 return SkNEW(SkFontMgr_Mac); |
2290 } | 2489 } |
OLD | NEW |