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) | |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |