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 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 // Being an enum value it is not guarded by version macros, but old SDKs must st
ill be supported. | 420 // Being an enum value it is not guarded by version macros, but old SDKs must st
ill be supported. |
421 #if defined(__MAC_10_7) || defined(__IPHONE_4_3) | 421 #if defined(__MAC_10_7) || defined(__IPHONE_4_3) |
422 static const uint32_t SkCTFontColorGlyphsTrait = kCTFontColorGlyphsTrait; | 422 static const uint32_t SkCTFontColorGlyphsTrait = kCTFontColorGlyphsTrait; |
423 #else | 423 #else |
424 static const uint32_t SkCTFontColorGlyphsTrait = (1 << 13); | 424 static const uint32_t SkCTFontColorGlyphsTrait = (1 << 13); |
425 #endif | 425 #endif |
426 | 426 |
427 class SkTypeface_Mac : public SkTypeface { | 427 class SkTypeface_Mac : public SkTypeface { |
428 public: | 428 public: |
429 SkTypeface_Mac(const SkFontStyle& fs, bool isFixedPitch, | 429 SkTypeface_Mac(const SkFontStyle& fs, bool isFixedPitch, |
430 CTFontRef fontRef, const char requestedName[], bool isLocalSt
ream) | 430 CTFontRef fontRef, const char requestedName[], bool isLocalSt
ream, |
| 431 CGFontRef originatingCGFontRef = NULL) |
431 : SkTypeface(fs, SkTypefaceCache::NewFontID(), isFixedPitch) | 432 : SkTypeface(fs, SkTypefaceCache::NewFontID(), isFixedPitch) |
432 , fRequestedName(requestedName) | 433 , fRequestedName(requestedName) |
433 , fFontRef(fontRef) // caller has already called CFRetain for us | 434 , fFontRef(fontRef) // caller has already called CFRetain for us |
| 435 , fOriginatingCGFontRef(originatingCGFontRef) |
434 , fHasColorGlyphs(SkToBool(CTFontGetSymbolicTraits(fFontRef) & SkCTFontC
olorGlyphsTrait)) | 436 , fHasColorGlyphs(SkToBool(CTFontGetSymbolicTraits(fFontRef) & SkCTFontC
olorGlyphsTrait)) |
435 , fIsLocalStream(isLocalStream) | 437 , fIsLocalStream(isLocalStream) |
436 { | 438 { |
437 SkASSERT(fontRef); | 439 SkASSERT(fontRef); |
438 } | 440 } |
439 | 441 |
440 SkString fRequestedName; | 442 SkString fRequestedName; |
441 AutoCFRelease<CTFontRef> fFontRef; | 443 AutoCFRelease<CTFontRef> fFontRef; |
| 444 AutoCFRelease<CGFontRef> fOriginatingCGFontRef; |
442 const bool fHasColorGlyphs; | 445 const bool fHasColorGlyphs; |
443 | 446 |
444 protected: | 447 protected: |
445 int onGetUPEM() const override; | 448 int onGetUPEM() const override; |
446 SkStreamAsset* onOpenStream(int* ttcIndex) const override; | 449 SkStreamAsset* onOpenStream(int* ttcIndex) const override; |
| 450 SkFontData* onCreateFontData() const override; |
447 void onGetFamilyName(SkString* familyName) const override; | 451 void onGetFamilyName(SkString* familyName) const override; |
448 SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override; | 452 SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override; |
449 int onGetTableTags(SkFontTableTag tags[]) const override; | 453 int onGetTableTags(SkFontTableTag tags[]) const override; |
450 virtual size_t onGetTableData(SkFontTableTag, size_t offset, | 454 virtual size_t onGetTableData(SkFontTableTag, size_t offset, |
451 size_t length, void* data) const override; | 455 size_t length, void* data) const override; |
452 SkScalerContext* onCreateScalerContext(const SkDescriptor*) const override; | 456 SkScalerContext* onCreateScalerContext(const SkDescriptor*) const override; |
453 void onFilterRec(SkScalerContextRec*) const override; | 457 void onFilterRec(SkScalerContextRec*) const override; |
454 void onGetFontDescriptor(SkFontDescriptor*, bool*) const override; | 458 void onGetFontDescriptor(SkFontDescriptor*, bool*) const override; |
455 virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics( | 459 virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics( |
456 SkAdvancedTypefaceMetrics::PerGlyphInfo, | 460 SkAdvancedTypefaceMetrics::PerGlyphInfo, |
457 const uint32_t*, uint32_t) const override; | 461 const uint32_t*, uint32_t) const override; |
458 virtual int onCharsToGlyphs(const void* chars, Encoding, uint16_t glyphs[], | 462 virtual int onCharsToGlyphs(const void* chars, Encoding, uint16_t glyphs[], |
459 int glyphCount) const override; | 463 int glyphCount) const override; |
460 int onCountGlyphs() const override; | 464 int onCountGlyphs() const override; |
461 | 465 |
462 private: | 466 private: |
463 bool fIsLocalStream; | 467 bool fIsLocalStream; |
464 | 468 |
465 typedef SkTypeface INHERITED; | 469 typedef SkTypeface INHERITED; |
466 }; | 470 }; |
467 | 471 |
468 /** Creates a typeface without searching the cache. Takes ownership of the CTFon
tRef. */ | 472 /** Creates a typeface without searching the cache. Takes ownership of the CTFon
tRef. */ |
469 static SkTypeface* NewFromFontRef(CTFontRef fontRef, const char name[], bool isL
ocalStream) { | 473 static SkTypeface* NewFromFontRef(CTFontRef fontRef, const char name[], bool isL
ocalStream, |
| 474 CGFontRef originatingCGFontRef = NULL) |
| 475 { |
470 SkASSERT(fontRef); | 476 SkASSERT(fontRef); |
471 bool isFixedPitch; | 477 bool isFixedPitch; |
472 SkFontStyle style = SkFontStyle(computeStyleBits(fontRef, &isFixedPitch)); | 478 SkFontStyle style = SkFontStyle(computeStyleBits(fontRef, &isFixedPitch)); |
473 | 479 |
474 return new SkTypeface_Mac(style, isFixedPitch, fontRef, name, isLocalStream)
; | 480 return new SkTypeface_Mac(style, isFixedPitch, fontRef, name, isLocalStream, |
| 481 originatingCGFontRef); |
475 } | 482 } |
476 | 483 |
477 static bool find_by_CTFontRef(SkTypeface* cached, const SkFontStyle&, void* cont
ext) { | 484 static bool find_by_CTFontRef(SkTypeface* cached, const SkFontStyle&, void* cont
ext) { |
478 CTFontRef self = (CTFontRef)context; | 485 CTFontRef self = (CTFontRef)context; |
479 CTFontRef other = ((SkTypeface_Mac*)cached)->fFontRef; | 486 CTFontRef other = ((SkTypeface_Mac*)cached)->fFontRef; |
480 | 487 |
481 return CFEqual(self, other); | 488 return CFEqual(self, other); |
482 } | 489 } |
483 | 490 |
484 /** Creates a typeface from a name, searching the cache. */ | 491 /** Creates a typeface from a name, searching the cache. */ |
(...skipping 1259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1744 entry->logicalLength = SkEndian_SwapBE32(SkToU32(tableSize)); | 1751 entry->logicalLength = SkEndian_SwapBE32(SkToU32(tableSize)); |
1745 | 1752 |
1746 dataPtr += (tableSize + 3) & ~3; | 1753 dataPtr += (tableSize + 3) & ~3; |
1747 ++entry; | 1754 ++entry; |
1748 } | 1755 } |
1749 | 1756 |
1750 *ttcIndex = 0; | 1757 *ttcIndex = 0; |
1751 return stream; | 1758 return stream; |
1752 } | 1759 } |
1753 | 1760 |
| 1761 struct NonDefaultAxesContext { |
| 1762 SkFixed* axisValue; |
| 1763 CFArrayRef cgAxes; |
| 1764 }; |
| 1765 static void set_non_default_axes(CFTypeRef key, CFTypeRef value, void* context)
{ |
| 1766 NonDefaultAxesContext* self = static_cast<NonDefaultAxesContext*>(context); |
| 1767 |
| 1768 if (CFGetTypeID(key) != CFStringGetTypeID() || CFGetTypeID(value) != CFNumbe
rGetTypeID()) { |
| 1769 return; |
| 1770 } |
| 1771 |
| 1772 // The key is a CFString which is a string from the 'name' table. |
| 1773 // Search the cgAxes for an axis with this name, and use its index to store
the value. |
| 1774 CFIndex keyIndex = -1; |
| 1775 CFStringRef keyString = static_cast<CFStringRef>(key); |
| 1776 for (CFIndex i = 0; i < CFArrayGetCount(self->cgAxes); ++i) { |
| 1777 CFTypeRef cgAxis = CFArrayGetValueAtIndex(self->cgAxes, i); |
| 1778 if (CFGetTypeID(cgAxis) != CFDictionaryGetTypeID()) { |
| 1779 continue; |
| 1780 } |
| 1781 |
| 1782 CFDictionaryRef cgAxisDict = static_cast<CFDictionaryRef>(cgAxis); |
| 1783 CFTypeRef cgAxisName = CFDictionaryGetValue(cgAxisDict, kCGFontVariation
AxisName); |
| 1784 if (!cgAxisName || CFGetTypeID(cgAxisName) != CFStringGetTypeID()) { |
| 1785 continue; |
| 1786 } |
| 1787 CFStringRef cgAxisNameString = static_cast<CFStringRef>(cgAxisName); |
| 1788 if (CFStringCompare(keyString, cgAxisNameString, 0) == kCFCompareEqualTo
) { |
| 1789 keyIndex = i; |
| 1790 break; |
| 1791 } |
| 1792 } |
| 1793 if (keyIndex == -1) { |
| 1794 return; |
| 1795 } |
| 1796 |
| 1797 CFNumberRef valueNumber = static_cast<CFNumberRef>(value); |
| 1798 double valueDouble; |
| 1799 if (!CFNumberGetValue(valueNumber, CFNumberType::kCFNumberDoubleType, &value
Double) || |
| 1800 valueDouble < SkFixedToDouble(SK_FixedMin) || SkFixedToDouble(SK_FixedMa
x) < valueDouble) |
| 1801 { |
| 1802 return; |
| 1803 } |
| 1804 self->axisValue[keyIndex] = SkDoubleToFixed(valueDouble); |
| 1805 } |
| 1806 static bool get_variations(CTFontRef fFontRef, CFIndex* cgAxisCount, |
| 1807 SkAutoSTMalloc<4, SkFixed>* axisValues) |
| 1808 { |
| 1809 // CTFontCopyVariationAxes and CTFontCopyVariation do not work when applied
to fonts which |
| 1810 // started life with CGFontCreateWithDataProvider (they simply always return
NULL). |
| 1811 // As a result, we are limited to CGFontCopyVariationAxes and CGFontCopyVari
ations. |
| 1812 AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, NULL)); |
| 1813 |
| 1814 AutoCFRelease<CFDictionaryRef> cgVariations(CGFontCopyVariations(cgFont)); |
| 1815 // If a font has no variations CGFontCopyVariations returns NULL (instead of
an empty dict). |
| 1816 if (!cgVariations.get()) { |
| 1817 return false; |
| 1818 } |
| 1819 |
| 1820 AutoCFRelease<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cgFont)); |
| 1821 *cgAxisCount = CFArrayGetCount(cgAxes); |
| 1822 axisValues->reset(*cgAxisCount); |
| 1823 |
| 1824 // Set all of the axes to their default values. |
| 1825 // Fail if any default value cannot be determined. |
| 1826 for (CFIndex i = 0; i < *cgAxisCount; ++i) { |
| 1827 CFTypeRef cgAxis = CFArrayGetValueAtIndex(cgAxes, i); |
| 1828 if (CFGetTypeID(cgAxis) != CFDictionaryGetTypeID()) { |
| 1829 return false; |
| 1830 } |
| 1831 |
| 1832 CFDictionaryRef cgAxisDict = static_cast<CFDictionaryRef>(cgAxis); |
| 1833 CFTypeRef axisDefaultValue = CFDictionaryGetValue(cgAxisDict, |
| 1834 kCGFontVariationAxisDe
faultValue); |
| 1835 if (!axisDefaultValue || CFGetTypeID(axisDefaultValue) != CFNumberGetTyp
eID()) { |
| 1836 return false; |
| 1837 } |
| 1838 CFNumberRef axisDefaultValueNumber = static_cast<CFNumberRef>(axisDefaul
tValue); |
| 1839 double axisDefaultValueDouble; |
| 1840 if (!CFNumberGetValue(axisDefaultValueNumber, CFNumberType::kCFNumberDou
bleType, |
| 1841 &axisDefaultValueDouble)) |
| 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, cgAxisCount, axisValues.ge
t()); |
| 1867 } |
| 1868 return new SkFontData(stream.detach(), index, 0, NULL); |
| 1869 } |
| 1870 |
1754 /////////////////////////////////////////////////////////////////////////////// | 1871 /////////////////////////////////////////////////////////////////////////////// |
1755 /////////////////////////////////////////////////////////////////////////////// | 1872 /////////////////////////////////////////////////////////////////////////////// |
1756 | 1873 |
1757 int SkTypeface_Mac::onGetUPEM() const { | 1874 int SkTypeface_Mac::onGetUPEM() const { |
1758 AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, NULL)); | 1875 AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, NULL)); |
1759 return CGFontGetUnitsPerEm(cgFont); | 1876 return CGFontGetUnitsPerEm(cgFont); |
1760 } | 1877 } |
1761 | 1878 |
1762 SkTypeface::LocalizedStrings* SkTypeface_Mac::onCreateFamilyNameIterator() const
{ | 1879 SkTypeface::LocalizedStrings* SkTypeface_Mac::onCreateFamilyNameIterator() const
{ |
1763 SkTypeface::LocalizedStrings* nameIter = | 1880 SkTypeface::LocalizedStrings* nameIter = |
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2239 } | 2356 } |
2240 | 2357 |
2241 SkTypeface* onCreateFromStream(SkStreamAsset* stream, int ttcIndex) const ov
erride { | 2358 SkTypeface* onCreateFromStream(SkStreamAsset* stream, int ttcIndex) const ov
erride { |
2242 AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromStream(strea
m)); | 2359 AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromStream(strea
m)); |
2243 if (NULL == pr) { | 2360 if (NULL == pr) { |
2244 return NULL; | 2361 return NULL; |
2245 } | 2362 } |
2246 return create_from_dataProvider(pr); | 2363 return create_from_dataProvider(pr); |
2247 } | 2364 } |
2248 | 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* fontData) const override { |
| 2420 SkStreamAsset* stream = fontData->detachStream(); |
| 2421 AutoCFRelease<CGDataProviderRef> provider(SkCreateDataProviderFromStream
(stream)); |
| 2422 if (NULL == provider) { |
| 2423 return NULL; |
| 2424 } |
| 2425 AutoCFRelease<CGFontRef> cg(CGFontCreateWithDataProvider(provider)); |
| 2426 if (NULL == cg) { |
| 2427 return NULL; |
| 2428 } |
| 2429 |
| 2430 AutoCFRelease<CFDictionaryRef> cgVariations(get_axes(cg, fontData)); |
| 2431 // The CGFontRef returned by CGFontCreateCopyWithVariations when the pas
sed CGFontRef was |
| 2432 // created from a data provider does not appear to have any ownership of
the underlying |
| 2433 // data. The original CGFontRef must be kept alive until the copy will n
o longer be used. |
| 2434 AutoCFRelease<CGFontRef> cgVariant; |
| 2435 if (cgVariations) { |
| 2436 cgVariant.reset(CGFontCreateCopyWithVariations(cg, cgVariations)); |
| 2437 } else { |
| 2438 cgVariant.reset(cg.detach()); |
| 2439 } |
| 2440 |
| 2441 CTFontRef ct = CTFontCreateWithGraphicsFont(cgVariant, 0, NULL, NULL); |
| 2442 if (!ct) { |
| 2443 return NULL; |
| 2444 } |
| 2445 return NewFromFontRef(ct, NULL, true, cg.detach()); |
| 2446 } |
| 2447 |
2249 SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override
{ | 2448 SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override
{ |
2250 AutoCFRelease<CGDataProviderRef> pr(CGDataProviderCreateWithFilename(pat
h)); | 2449 AutoCFRelease<CGDataProviderRef> pr(CGDataProviderCreateWithFilename(pat
h)); |
2251 if (NULL == pr) { | 2450 if (NULL == pr) { |
2252 return NULL; | 2451 return NULL; |
2253 } | 2452 } |
2254 return create_from_dataProvider(pr); | 2453 return create_from_dataProvider(pr); |
2255 } | 2454 } |
2256 | 2455 |
2257 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], | 2456 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], |
2258 unsigned styleBits) const overrid
e { | 2457 unsigned styleBits) const overrid
e { |
(...skipping 21 matching lines...) Expand all Loading... |
2280 } | 2479 } |
2281 return face; | 2480 return face; |
2282 } | 2481 } |
2283 }; | 2482 }; |
2284 | 2483 |
2285 /////////////////////////////////////////////////////////////////////////////// | 2484 /////////////////////////////////////////////////////////////////////////////// |
2286 | 2485 |
2287 SkFontMgr* SkFontMgr::Factory() { | 2486 SkFontMgr* SkFontMgr::Factory() { |
2288 return SkNEW(SkFontMgr_Mac); | 2487 return SkNEW(SkFontMgr_Mac); |
2289 } | 2488 } |
OLD | NEW |