diff options
author | 2016-12-20 12:04:29 -0500 | |
---|---|---|
committer | 2016-12-21 18:56:57 +0000 | |
commit | c292b5fa323ecb46bc1977f0fd14224953d8caff (patch) | |
tree | a65c746f3b8a81f1edad752e06e74b9ac07e8eb3 /src | |
parent | 463c848f3b63b52e3834e405ff11fd1e653ed271 (diff) |
Clean up SkFontHost_Mac ownership.
This clarifies ownership rules throughout SkFontHost_Mac.cpp, as well as
tidying up various bits of code. Clarifying ownership means replacing
AutoCFRelease with UniqueCFRef which is based on std::unique_ptr. Most of
the cleanup is removing now dead code and properly indenting.
Change-Id: I6d3a225d62b5d0f2f48a9e70c1a24317faa06747
Reviewed-on: https://skia-review.googlesource.com/6297
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Ben Wagner <bungeman@google.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/ports/SkFontHost_mac.cpp | 732 |
1 files changed, 339 insertions, 393 deletions
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp index 8168cd42d2..65200e46a7 100644 --- a/src/ports/SkFontHost_mac.cpp +++ b/src/ports/SkFontHost_mac.cpp @@ -60,80 +60,20 @@ class SkScalerContext_Mac; -// CTFontManagerCopyAvailableFontFamilyNames() is not always available, so we -// provide a wrapper here that will return an empty array if need be. -static CFArrayRef SkCTFontManagerCopyAvailableFontFamilyNames() { -#ifdef SK_BUILD_FOR_IOS - return CFArrayCreate(nullptr, nullptr, 0, nullptr); -#else - return CTFontManagerCopyAvailableFontFamilyNames(); -#endif -} - - -// Being templated and taking const T* prevents calling -// CFSafeRelease(autoCFRelease) through implicit conversion. -template <typename T> static void CFSafeRelease(/*CFTypeRef*/const T* cfTypeRef) { - if (cfTypeRef) { - CFRelease(cfTypeRef); +struct CFSafeRelease { + void operator()(CFTypeRef cfTypeRef) { + if (cfTypeRef) { + CFRelease(cfTypeRef); + } } -} - -// Being templated and taking const T* prevents calling -// CFSafeRetain(autoCFRelease) through implicit conversion. -template <typename T> static void CFSafeRetain(/*CFTypeRef*/const T* cfTypeRef) { - if (cfTypeRef) { - CFRetain(cfTypeRef); - } -} - -/** Acts like a CFRef, but calls CFSafeRelease when it goes out of scope. */ -template<typename CFRef> class AutoCFRelease : private SkNoncopyable { -public: - explicit AutoCFRelease(CFRef cfRef = nullptr) : fCFRef(cfRef) { } - ~AutoCFRelease() { CFSafeRelease(fCFRef); } - - void reset(CFRef that = nullptr) { - if (that != fCFRef) { - CFSafeRelease(fCFRef); - fCFRef = that; - } - } - - CFRef release() { - CFRef self = fCFRef; - fCFRef = nullptr; - return self; - } - - operator CFRef() const { return fCFRef; } - CFRef get() const { return fCFRef; } - - CFRef* operator&() { SkASSERT(fCFRef == nullptr); return &fCFRef; } -private: - CFRef fCFRef; }; +template <typename CFRef> using UniqueCFRef = + std::unique_ptr<skstd::remove_pointer_t<CFRef>, CFSafeRelease>; -static CFStringRef make_CFString(const char str[]) { - return CFStringCreateWithCString(nullptr, str, kCFStringEncodingUTF8); +static UniqueCFRef<CFStringRef> make_CFString(const char str[]) { + return UniqueCFRef<CFStringRef>(CFStringCreateWithCString(nullptr, str, kCFStringEncodingUTF8)); } -template<typename T> class AutoCGTable : SkNoncopyable { -public: - AutoCGTable(CGFontRef font) - //Undocumented: the tag parameter in this call is expected in machine order and not BE order. - : fCFData(CGFontCopyTableForTag(font, SkSetFourByteTag(T::TAG0, T::TAG1, T::TAG2, T::TAG3))) - , fData(fCFData ? reinterpret_cast<const T*>(CFDataGetBytePtr(fCFData)) : nullptr) - { } - - const T* operator->() const { return fData; } - -private: - AutoCFRelease<CFDataRef> fCFData; -public: - const T* fData; -}; - // inline versions of these rect helpers static bool CGRectIsEmpty_inline(const CGRect& rect) { @@ -212,12 +152,6 @@ static unsigned CGRGBPixel_getAlpha(CGRGBPixel pixel) { return pixel & 0xFF; } -static const char FONT_DEFAULT_NAME[] = "Lucida Sans"; - -static bool isLCDFormat(unsigned format) { - return SkMask::kLCD16_Format == format; -} - static CGFloat ScalarToCG(SkScalar scalar) { if (sizeof(CGFloat) == sizeof(float)) { return SkScalarToFloat(scalar); @@ -245,15 +179,13 @@ static float CGToFloat(CGFloat cgFloat) { } } -static CGAffineTransform MatrixToCGAffineTransform(const SkMatrix& matrix, - SkScalar sx = SK_Scalar1, - SkScalar sy = SK_Scalar1) { - return CGAffineTransformMake( ScalarToCG(matrix[SkMatrix::kMScaleX] * sx), - -ScalarToCG(matrix[SkMatrix::kMSkewY] * sy), - -ScalarToCG(matrix[SkMatrix::kMSkewX] * sx), - ScalarToCG(matrix[SkMatrix::kMScaleY] * sy), - ScalarToCG(matrix[SkMatrix::kMTransX] * sx), - ScalarToCG(matrix[SkMatrix::kMTransY] * sy)); +static CGAffineTransform MatrixToCGAffineTransform(const SkMatrix& matrix) { + return CGAffineTransformMake( ScalarToCG(matrix[SkMatrix::kMScaleX]), + -ScalarToCG(matrix[SkMatrix::kMSkewY] ), + -ScalarToCG(matrix[SkMatrix::kMSkewX] ), + ScalarToCG(matrix[SkMatrix::kMScaleY]), + ScalarToCG(matrix[SkMatrix::kMTransX]), + ScalarToCG(matrix[SkMatrix::kMTransY])); } /////////////////////////////////////////////////////////////////////////////// @@ -271,19 +203,19 @@ static bool supports_LCD() { return (bool) gSupportsLCD; } uint32_t rgb = 0; - AutoCFRelease<CGColorSpaceRef> colorspace(CGColorSpaceCreateDeviceRGB()); - AutoCFRelease<CGContextRef> cgContext(CGBitmapContextCreate(&rgb, 1, 1, 8, 4, - colorspace, BITMAP_INFO_RGB)); - AutoCFRelease<CTFontRef> ctFont(CTFontCreateWithName(CFSTR("Helvetica"), 16, nullptr)); - CGContextSetShouldSmoothFonts(cgContext, true); - CGContextSetShouldAntialias(cgContext, true); - CGContextSetTextDrawingMode(cgContext, kCGTextFill); - CGContextSetGrayFillColor(cgContext, 1, 1); + UniqueCFRef<CGColorSpaceRef> colorspace(CGColorSpaceCreateDeviceRGB()); + UniqueCFRef<CGContextRef> cgContext( + CGBitmapContextCreate(&rgb, 1, 1, 8, 4, colorspace.get(), BITMAP_INFO_RGB)); + UniqueCFRef<CTFontRef> ctFont(CTFontCreateWithName(CFSTR("Helvetica"), 16, nullptr)); + CGContextSetShouldSmoothFonts(cgContext.get(), true); + CGContextSetShouldAntialias(cgContext.get(), true); + CGContextSetTextDrawingMode(cgContext.get(), kCGTextFill); + CGContextSetGrayFillColor(cgContext.get(), 1, 1); CGPoint point = CGPointMake(-1, 0); static const UniChar pipeChar = '|'; CGGlyph pipeGlyph; - CTFontGetGlyphsForCharacters(ctFont, &pipeChar, &pipeGlyph, 1); - CTFontDrawGlyphs(ctFont, &pipeGlyph, &point, 1, cgContext); + CTFontGetGlyphsForCharacters(ctFont.get(), &pipeChar, &pipeGlyph, 1); + CTFontDrawGlyphs(ctFont.get(), &pipeGlyph, &point, 1, cgContext.get()); uint32_t r = (rgb >> 16) & 0xFF; uint32_t g = (rgb >> 8) & 0xFF; @@ -304,18 +236,17 @@ public: } CGRGBPixel* getCG(const SkScalerContext_Mac& context, const SkGlyph& glyph, - CGGlyph glyphID, size_t* rowBytesPtr, - bool generateA8FromLCD); + CGGlyph glyphID, size_t* rowBytesPtr, bool generateA8FromLCD); private: enum { kSize = 32 * 32 * sizeof(CGRGBPixel) }; SkAutoSMalloc<kSize> fImageStorage; - AutoCFRelease<CGColorSpaceRef> fRGBSpace; + UniqueCFRef<CGColorSpaceRef> fRGBSpace; // cached state - AutoCFRelease<CGContextRef> fCG; + UniqueCFRef<CGContextRef> fCG; SkISize fSize; bool fDoAA; bool fDoLCD; @@ -330,8 +261,8 @@ private: static bool find_dict_CGFloat(CFDictionaryRef dict, CFStringRef name, CGFloat* value) { CFNumberRef num; return CFDictionaryGetValueIfPresent(dict, name, (const void**)&num) - && CFNumberIsFloatType(num) - && CFNumberGetValue(num, kCFNumberCGFloatType, value); + && CFNumberIsFloatType(num) + && CFNumberGetValue(num, kCFNumberCGFloatType, value); } template <typename S, typename D, typename C> struct LinearInterpolater { @@ -414,20 +345,20 @@ static int ct_width_to_fontstyle(CGFloat cgWidth) { } static SkFontStyle fontstyle_from_descriptor(CTFontDescriptorRef desc) { - AutoCFRelease<CFDictionaryRef> dict( - (CFDictionaryRef)CTFontDescriptorCopyAttribute(desc, kCTFontTraitsAttribute)); - if (nullptr == dict.get()) { + UniqueCFRef<CFTypeRef> fontTraits(CTFontDescriptorCopyAttribute(desc, kCTFontTraitsAttribute)); + if (!fontTraits || CFDictionaryGetTypeID() != CFGetTypeID(fontTraits.get())) { return SkFontStyle(); } + UniqueCFRef<CFDictionaryRef> fontTraitsDict(static_cast<CFDictionaryRef>(fontTraits.release())); CGFloat weight, width, slant; - if (!find_dict_CGFloat(dict, kCTFontWeightTrait, &weight)) { + if (!find_dict_CGFloat(fontTraitsDict.get(), kCTFontWeightTrait, &weight)) { weight = 0; } - if (!find_dict_CGFloat(dict, kCTFontWidthTrait, &width)) { + if (!find_dict_CGFloat(fontTraitsDict.get(), kCTFontWidthTrait, &width)) { width = 0; } - if (!find_dict_CGFloat(dict, kCTFontSlantTrait, &slant)) { + if (!find_dict_CGFloat(fontTraitsDict.get(), kCTFontSlantTrait, &slant)) { slant = 0; } @@ -439,20 +370,21 @@ static SkFontStyle fontstyle_from_descriptor(CTFontDescriptorRef desc) { class SkTypeface_Mac : public SkTypeface { public: - SkTypeface_Mac(CTFontRef fontRef, CFTypeRef resourceRef, + SkTypeface_Mac(UniqueCFRef<CTFontRef> fontRef, UniqueCFRef<CFTypeRef> resourceRef, const SkFontStyle& fs, bool isFixedPitch, bool isLocalStream) : SkTypeface(fs, isFixedPitch) - , fFontRef(fontRef) // caller has already called CFRetain for us - , fOriginatingCFTypeRef(resourceRef) // caller has already called CFRetain for us - , fHasColorGlyphs(SkToBool(CTFontGetSymbolicTraits(fFontRef) & kCTFontColorGlyphsTrait)) + , fFontRef(std::move(fontRef)) + , fOriginatingCFTypeRef(std::move(resourceRef)) + , fHasColorGlyphs( + SkToBool(CTFontGetSymbolicTraits(fFontRef.get()) & kCTFontColorGlyphsTrait)) , fIsLocalStream(isLocalStream) { - SkASSERT(fontRef); + SkASSERT(fFontRef); } - AutoCFRelease<CTFontRef> fFontRef; - AutoCFRelease<CFTypeRef> fOriginatingCFTypeRef; + UniqueCFRef<CTFontRef> fFontRef; + UniqueCFRef<CFTypeRef> fOriginatingCFTypeRef; const bool fHasColorGlyphs; protected: @@ -462,17 +394,15 @@ protected: void onGetFamilyName(SkString* familyName) const override; SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override; int onGetTableTags(SkFontTableTag tags[]) const override; - virtual size_t onGetTableData(SkFontTableTag, size_t offset, - size_t length, void* data) const override; + size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void* data) const override; SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&, const SkDescriptor*) const override; void onFilterRec(SkScalerContextRec*) const override; void onGetFontDescriptor(SkFontDescriptor*, bool*) const override; - virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics( - PerGlyphInfo, - const uint32_t*, uint32_t) const override; - virtual int onCharsToGlyphs(const void* chars, Encoding, uint16_t glyphs[], - int glyphCount) const override; + SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics( + PerGlyphInfo, const uint32_t* glyphIDs, uint32_t glyphIDsCount) const override; + int onCharsToGlyphs(const void* chars, Encoding, + uint16_t glyphs[], int glyphCount) const override; int onCountGlyphs() const override; private: @@ -483,18 +413,16 @@ private: static bool find_by_CTFontRef(SkTypeface* cached, void* context) { CTFontRef self = (CTFontRef)context; - CTFontRef other = ((SkTypeface_Mac*)cached)->fFontRef; + CTFontRef other = ((SkTypeface_Mac*)cached)->fFontRef.get(); return CFEqual(self, other); } -/** Creates a typeface, searching the cache if isLocalStream is false. - * Takes ownership of the CTFontRef and CFTypeRef. - */ -static SkTypeface* create_from_CTFontRef(CTFontRef f, CFTypeRef r, bool isLocalStream) { - SkASSERT(f); - AutoCFRelease<CTFontRef> font(f); - AutoCFRelease<CFTypeRef> resource(r); +/** Creates a typeface, searching the cache if isLocalStream is false. */ +static SkTypeface* create_from_CTFontRef(UniqueCFRef<CTFontRef> font, + UniqueCFRef<CFTypeRef> resource, + bool isLocalStream) { + SkASSERT(font); if (!isLocalStream) { SkTypeface* face = SkTypefaceCache::FindByProcAndRef(find_by_CTFontRef, (void*)font.get()); @@ -503,12 +431,12 @@ static SkTypeface* create_from_CTFontRef(CTFontRef f, CFTypeRef r, bool isLocalS } } - AutoCFRelease<CTFontDescriptorRef> desc(CTFontCopyFontDescriptor(font)); - SkFontStyle style = fontstyle_from_descriptor(desc); - CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(font); + UniqueCFRef<CTFontDescriptorRef> desc(CTFontCopyFontDescriptor(font.get())); + SkFontStyle style = fontstyle_from_descriptor(desc.get()); + CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(font.get()); bool isFixedPitch = SkToBool(traits & kCTFontMonoSpaceTrait); - SkTypeface* face = new SkTypeface_Mac(font.release(), resource.release(), + SkTypeface* face = new SkTypeface_Mac(std::move(font), std::move(resource), style, isFixedPitch, isLocalStream); if (!isLocalStream) { SkTypefaceCache::Add(face); @@ -518,15 +446,16 @@ static SkTypeface* create_from_CTFontRef(CTFontRef f, CFTypeRef r, bool isLocalS /** Creates a typeface from a descriptor, searching the cache. */ static SkTypeface* create_from_desc(CTFontDescriptorRef desc) { - AutoCFRelease<CTFontRef> ctFont(CTFontCreateWithFontDescriptor(desc, 0, nullptr)); + UniqueCFRef<CTFontRef> ctFont(CTFontCreateWithFontDescriptor(desc, 0, nullptr)); if (!ctFont) { return nullptr; } - return create_from_CTFontRef(ctFont.release(), nullptr, false); + return create_from_CTFontRef(std::move(ctFont), nullptr, false); } -static CTFontDescriptorRef create_descriptor(const char familyName[], const SkFontStyle& style) { +static UniqueCFRef<CTFontDescriptorRef> create_descriptor(const char familyName[], + const SkFontStyle& style) { CTFontSymbolicTraits ctFontTraits = 0; if (style.weight() >= SkFontStyle::kBold_Weight) { ctFontTraits |= kCTFontBoldTrait; @@ -538,17 +467,17 @@ static CTFontDescriptorRef create_descriptor(const char familyName[], const SkFo //TODO: add weight width slant // Create the font info - AutoCFRelease<CFStringRef> cfFontName(make_CFString(familyName)); + UniqueCFRef<CFStringRef> cfFontName = make_CFString(familyName); - AutoCFRelease<CFNumberRef> cfFontTraits( + UniqueCFRef<CFNumberRef> cfFontTraits( CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &ctFontTraits)); - AutoCFRelease<CFMutableDictionaryRef> cfAttributes( + UniqueCFRef<CFMutableDictionaryRef> cfAttributes( CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); - AutoCFRelease<CFMutableDictionaryRef> cfTraits( + UniqueCFRef<CFMutableDictionaryRef> cfTraits( CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); @@ -557,33 +486,22 @@ static CTFontDescriptorRef create_descriptor(const char familyName[], const SkFo return nullptr; } - CFDictionaryAddValue(cfTraits, kCTFontSymbolicTrait, cfFontTraits); + CFDictionaryAddValue(cfTraits.get(), kCTFontSymbolicTrait, cfFontTraits.get()); - CFDictionaryAddValue(cfAttributes, kCTFontFamilyNameAttribute, cfFontName); - CFDictionaryAddValue(cfAttributes, kCTFontTraitsAttribute, cfTraits); + CFDictionaryAddValue(cfAttributes.get(), kCTFontFamilyNameAttribute, cfFontName.get()); + CFDictionaryAddValue(cfAttributes.get(), kCTFontTraitsAttribute, cfTraits.get()); - return CTFontDescriptorCreateWithAttributes(cfAttributes); + return UniqueCFRef<CTFontDescriptorRef>( + CTFontDescriptorCreateWithAttributes(cfAttributes.get())); } /** Creates a typeface from a name, searching the cache. */ static SkTypeface* create_from_name(const char familyName[], const SkFontStyle& style) { - AutoCFRelease<CTFontDescriptorRef> desc(create_descriptor(familyName, style)); + UniqueCFRef<CTFontDescriptorRef> desc = create_descriptor(familyName, style); if (!desc) { return nullptr; } - return create_from_desc(desc); -} - -SK_DECLARE_STATIC_MUTEX(gGetDefaultFaceMutex); -static SkTypeface* GetDefaultFace() { - SkAutoMutexAcquire ma(gGetDefaultFaceMutex); - - static SkTypeface* gDefaultFace; - - if (nullptr == gDefaultFace) { - gDefaultFace = create_from_name(FONT_DEFAULT_NAME, SkFontStyle()); - } - return gDefaultFace; + return create_from_desc(desc.get()); } /////////////////////////////////////////////////////////////////////////////// @@ -597,12 +515,14 @@ CTFontRef SkTypeface_GetCTFontRef(const SkTypeface* face) { /* This function is visible on the outside. It first searches the cache, and if * not found, returns a new entry (after adding it to the cache). */ -SkTypeface* SkCreateTypefaceFromCTFont(CTFontRef fontRef, CFTypeRef resourceRef) { - CFRetain(fontRef); - if (resourceRef) { - CFRetain(resourceRef); +SkTypeface* SkCreateTypefaceFromCTFont(CTFontRef font, CFTypeRef resource) { + CFRetain(font); + if (resource) { + CFRetain(resource); } - return create_from_CTFontRef(fontRef, resourceRef, false); + return create_from_CTFontRef(UniqueCFRef<CTFontRef>(font), + UniqueCFRef<CFTypeRef>(resource), + false); } static const char* map_css_names(const char* name) { @@ -672,13 +592,13 @@ private: * As a result of the above (and other constraints) this font contains the size, but not the * transform. The transform must always be applied separately. */ - AutoCFRelease<CTFontRef> fCTFont; + UniqueCFRef<CTFontRef> fCTFont; /** The transform without the font size. */ CGAffineTransform fTransform; CGAffineTransform fInvTransform; - AutoCFRelease<CGFontRef> fCGFont; + UniqueCFRef<CGFontRef> fCGFont; uint16_t fGlyphCount; const bool fDoSubPosition; const bool fVertical; @@ -693,10 +613,10 @@ private: // It is not possible to use descriptors with CTFontCreateWithFontDescriptor, since that does not // work with non-system fonts. As a result, create the strike specific CTFonts from the underlying // CGFont. -static CTFontRef ctfont_create_exact_copy(CTFontRef baseFont, CGFloat textSize, - const CGAffineTransform* transform) +static UniqueCFRef<CTFontRef> ctfont_create_exact_copy(CTFontRef baseFont, CGFloat textSize, + const CGAffineTransform* transform) { - AutoCFRelease<CGFontRef> baseCGFont(CTFontCopyGraphicsFont(baseFont, nullptr)); + UniqueCFRef<CGFontRef> baseCGFont(CTFontCopyGraphicsFont(baseFont, nullptr)); // The last parameter (CTFontDescriptorRef attributes) *must* be nullptr. // If non-nullptr then with fonts with variation axes, the copy will fail in @@ -706,7 +626,8 @@ static CTFontRef ctfont_create_exact_copy(CTFontRef baseFont, CGFloat textSize, // Because we cannot setup the CTFont descriptor to match, the same restriction applies here // as other uses of CTFontCreateWithGraphicsFont which is that such CTFonts should not escape // the scaler context, since they aren't 'normal'. - return CTFontCreateWithGraphicsFont(baseCGFont, textSize, transform, nullptr); + return UniqueCFRef<CTFontRef>( + CTFontCreateWithGraphicsFont(baseCGFont.get(), textSize, transform, nullptr)); } SkScalerContext_Mac::SkScalerContext_Mac(sk_sp<SkTypeface_Mac> typeface, @@ -742,11 +663,11 @@ SkScalerContext_Mac::SkScalerContext_Mac(sk_sp<SkTypeface_Mac> typeface, // The transform contains everything except the requested text size. // Some properties, like 'trak', are based on the text size (before applying the matrix). CGFloat textSize = ScalarToCG(scale.y()); - fCTFont.reset(ctfont_create_exact_copy(ctFont, textSize, nullptr)); - fCGFont.reset(CTFontCopyGraphicsFont(fCTFont, nullptr)); + fCTFont = ctfont_create_exact_copy(ctFont, textSize, nullptr); + fCGFont.reset(CTFontCopyGraphicsFont(fCTFont.get(), nullptr)); // The fUnitMatrix includes the text size (and em) as it is used to scale the raw font data. - SkScalar emPerFUnit = SkScalarInvert(SkIntToScalar(CGFontGetUnitsPerEm(fCGFont))); + SkScalar emPerFUnit = SkScalarInvert(SkIntToScalar(CGFontGetUnitsPerEm(fCGFont.get()))); fFUnitMatrix.preScale(emPerFUnit, -emPerFUnit); } @@ -798,37 +719,37 @@ CGRGBPixel* Offscreen::getCG(const SkScalerContext_Mac& context, const SkGlyph& : kCGImageAlphaNoneSkipFirst; const CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Host | alpha; fCG.reset(CGBitmapContextCreate(image, fSize.fWidth, fSize.fHeight, 8, - rowBytes, fRGBSpace, bitmapInfo)); + rowBytes, fRGBSpace.get(), bitmapInfo)); // Skia handles quantization and subpixel positioning, // so disable quantization and enabe subpixel positioning in CG. - CGContextSetAllowsFontSubpixelQuantization(fCG, false); - CGContextSetShouldSubpixelQuantizeFonts(fCG, false); + CGContextSetAllowsFontSubpixelQuantization(fCG.get(), false); + CGContextSetShouldSubpixelQuantizeFonts(fCG.get(), false); // Because CG always draws from the horizontal baseline, // if there is a non-integral translation from the horizontal origin to the vertical origin, // then CG cannot draw the glyph in the correct location without subpixel positioning. - CGContextSetAllowsFontSubpixelPositioning(fCG, true); - CGContextSetShouldSubpixelPositionFonts(fCG, true); + CGContextSetAllowsFontSubpixelPositioning(fCG.get(), true); + CGContextSetShouldSubpixelPositionFonts(fCG.get(), true); - CGContextSetTextDrawingMode(fCG, kCGTextFill); + CGContextSetTextDrawingMode(fCG.get(), kCGTextFill); // Draw black on white to create mask. (Special path exists to speed this up in CG.) - CGContextSetGrayFillColor(fCG, 0.0f, 1.0f); + CGContextSetGrayFillColor(fCG.get(), 0.0f, 1.0f); // force our checks below to happen fDoAA = !doAA; fDoLCD = !doLCD; - CGContextSetTextMatrix(fCG, context.fTransform); + CGContextSetTextMatrix(fCG.get(), context.fTransform); } if (fDoAA != doAA) { - CGContextSetShouldAntialias(fCG, doAA); + CGContextSetShouldAntialias(fCG.get(), doAA); fDoAA = doAA; } if (fDoLCD != doLCD) { - CGContextSetShouldSmoothFonts(fCG, doLCD); + CGContextSetShouldSmoothFonts(fCG.get(), doLCD); fDoLCD = doLCD; } @@ -865,7 +786,7 @@ CGRGBPixel* Offscreen::getCG(const SkScalerContext_Mac& context, const SkGlyph& // So always make the font transform identity and place the transform on the context. point = CGPointApplyAffineTransform(point, context.fInvTransform); - CTFontDrawGlyphs(context.fCTFont, &glyphID, &point, 1, fCG); + CTFontDrawGlyphs(context.fCTFont.get(), &glyphID, &point, 1, fCG.get()); SkASSERT(rowBytesPtr); *rowBytesPtr = rowBytes; @@ -875,7 +796,7 @@ CGRGBPixel* Offscreen::getCG(const SkScalerContext_Mac& context, const SkGlyph& void SkScalerContext_Mac::getVerticalOffset(CGGlyph glyphID, SkPoint* offset) const { // CTFontGetVerticalTranslationsForGlyphs produces cgVertOffset in CG units (pixels, y up). CGSize cgVertOffset; - CTFontGetVerticalTranslationsForGlyphs(fCTFont, &glyphID, &cgVertOffset, 1); + CTFontGetVerticalTranslationsForGlyphs(fCTFont.get(), &glyphID, &cgVertOffset, 1); cgVertOffset = CGSizeApplyAffineTransform(cgVertOffset, fTransform); SkPoint skVertOffset = { CGToScalar(cgVertOffset.width), CGToScalar(cgVertOffset.height) }; // From CG units (pixels, y up) to SkGlyph units (pixels, y down). @@ -900,7 +821,7 @@ uint16_t SkScalerContext_Mac::generateCharToGlyph(SkUnichar uni) { // Undocumented behavior of CTFontGetGlyphsForCharacters with non-bmp code points: // When a surrogate pair is detected, the glyph index used is the index of the high surrogate. // It is documented that if a mapping is unavailable, the glyph will be set to 0. - CTFontGetGlyphsForCharacters(fCTFont, theChar, cgGlyph, numUniChar); + CTFontGetGlyphsForCharacters(fCTFont.get(), theChar, cgGlyph, numUniChar); return cgGlyph[0]; } @@ -917,13 +838,13 @@ void SkScalerContext_Mac::generateMetrics(SkGlyph* glyph) { // The following block produces cgAdvance in CG units (pixels, y up). CGSize cgAdvance; if (fVertical) { - CTFontGetAdvancesForGlyphs(fCTFont, kCTFontVerticalOrientation, + CTFontGetAdvancesForGlyphs(fCTFont.get(), kCTFontVerticalOrientation, &cgGlyph, &cgAdvance, 1); // Vertical advances are returned as widths instead of heights. SkTSwap(cgAdvance.height, cgAdvance.width); cgAdvance.height = -cgAdvance.height; } else { - CTFontGetAdvancesForGlyphs(fCTFont, kCTFontHorizontalOrientation, + CTFontGetAdvancesForGlyphs(fCTFont.get(), kCTFontHorizontalOrientation, &cgGlyph, &cgAdvance, 1); } cgAdvance = CGSizeApplyAffineTransform(cgAdvance, fTransform); @@ -942,7 +863,7 @@ void SkScalerContext_Mac::generateMetrics(SkGlyph* glyph) { { // CTFontGetBoundingRectsForGlyphs produces cgBounds in CG units (pixels, y up). CGRect cgBounds; - CTFontGetBoundingRectsForGlyphs(fCTFont, kCTFontHorizontalOrientation, + CTFontGetBoundingRectsForGlyphs(fCTFont.get(), kCTFontHorizontalOrientation, &cgGlyph, &cgBounds, 1); cgBounds = CGRectApplyAffineTransform(cgBounds, fTransform); @@ -952,8 +873,8 @@ void SkScalerContext_Mac::generateMetrics(SkGlyph* glyph) { // empty path or not, and if so, we jam the bounds to 0. Hopefully a zero-advance // is rare, so we won't incur a big performance cost for this extra check. if (0 == cgAdvance.width && 0 == cgAdvance.height) { - AutoCFRelease<CGPathRef> path(CTFontCreatePathForGlyph(fCTFont, cgGlyph, nullptr)); - if (nullptr == path || CGPathIsEmpty(path)) { + UniqueCFRef<CGPathRef> path(CTFontCreatePathForGlyph(fCTFont.get(), cgGlyph, nullptr)); + if (!path || CGPathIsEmpty(path.get())) { return; } } @@ -1057,8 +978,8 @@ static void rgb_to_a8(const CGRGBPixel* SK_RESTRICT cgPixels, size_t cgRowBytes, for (int i = 0; i < width; ++i) { dst[i] = rgb_to_a8<APPLY_PREBLEND>(cgPixels[i], table8); } - cgPixels = (CGRGBPixel*)((char*)cgPixels + cgRowBytes); - dst += dstRB; + cgPixels = SkTAddOffset<const CGRGBPixel>(cgPixels, cgRowBytes); + dst = SkTAddOffset<uint8_t>(dst, dstRB); } } @@ -1087,8 +1008,8 @@ static void rgb_to_lcd16(const CGRGBPixel* SK_RESTRICT cgPixels, size_t cgRowByt for (int i = 0; i < width; i++) { dst[i] = rgb_to_lcd16<APPLY_PREBLEND>(cgPixels[i], tableR, tableG, tableB); } - cgPixels = (CGRGBPixel*)((char*)cgPixels + cgRowBytes); - dst = (uint16_t*)((char*)dst + dstRB); + cgPixels = SkTAddOffset<const CGRGBPixel>(cgPixels, cgRowBytes); + dst = SkTAddOffset<uint16_t>(dst, dstRB); } } @@ -1104,7 +1025,7 @@ static SkPMColor cgpixels_to_pmcolor(CGRGBPixel rgb) { } void SkScalerContext_Mac::generateImage(const SkGlyph& glyph) { - CGGlyph cgGlyph = (CGGlyph) glyph.getGlyphID(); + CGGlyph cgGlyph = SkTo<CGGlyph>(glyph.getGlyphID()); // FIXME: lcd smoothed un-hinted rasterization unsupported. bool generateA8FromLCD = fRec.getHinting() != SkPaint::kNo_Hinting; @@ -1117,8 +1038,9 @@ void SkScalerContext_Mac::generateImage(const SkGlyph& glyph) { } // Fix the glyph - const bool isLCD = isLCDFormat(glyph.fMaskFormat); - if (isLCD || (glyph.fMaskFormat == SkMask::kA8_Format && supports_LCD() && generateA8FromLCD)) { + if ((glyph.fMaskFormat == SkMask::kLCD16_Format) || + (glyph.fMaskFormat == SkMask::kA8_Format && supports_LCD() && generateA8FromLCD)) + { const uint8_t* table = getInverseGammaTableCoreGraphicSmoothing(); //Note that the following cannot really be integrated into the @@ -1162,8 +1084,8 @@ void SkScalerContext_Mac::generateImage(const SkGlyph& glyph) { uint8_t* dst = (uint8_t*)glyph.fImage; for (int y = 0; y < glyph.fHeight; y++) { cgpixels_to_bits(dst, cgPixels, width); - cgPixels = (CGRGBPixel*)((char*)cgPixels + cgRowBytes); - dst += dstRB; + cgPixels = SkTAddOffset<CGRGBPixel>(cgPixels, cgRowBytes); + dst = SkTAddOffset<uint8_t>(dst, dstRB); } } break; case SkMask::kARGB32_Format: { @@ -1174,8 +1096,8 @@ void SkScalerContext_Mac::generateImage(const SkGlyph& glyph) { for (int x = 0; x < width; ++x) { dst[x] = cgpixels_to_pmcolor(cgPixels[x]); } - cgPixels = (CGRGBPixel*)((char*)cgPixels + cgRowBytes); - dst = (SkPMColor*)((char*)dst + dstRB); + cgPixels = SkTAddOffset<CGRGBPixel>(cgPixels, cgRowBytes); + dst = SkTAddOffset<SkPMColor>(dst, dstRB); } } break; default: @@ -1227,11 +1149,11 @@ void SkScalerContext_Mac::generatePath(SkGlyphID glyph, SkPath* path) { } CGGlyph cgGlyph = SkTo<CGGlyph>(glyph); - AutoCFRelease<CGPathRef> cgPath(CTFontCreatePathForGlyph(fCTFont, cgGlyph, &xform)); + UniqueCFRef<CGPathRef> cgPath(CTFontCreatePathForGlyph(fCTFont.get(), cgGlyph, &xform)); path->reset(); if (cgPath != nullptr) { - CGPathApply(cgPath, path, SkScalerContext_Mac::CTPathElement); + CGPathApply(cgPath.get(), path, SkScalerContext_Mac::CTPathElement); } if (fDoSubPosition) { @@ -1253,21 +1175,21 @@ void SkScalerContext_Mac::generateFontMetrics(SkPaint::FontMetrics* metrics) { AUTO_CG_LOCK(); - CGRect theBounds = CTFontGetBoundingBox(fCTFont); + CGRect theBounds = CTFontGetBoundingBox(fCTFont.get()); metrics->fTop = CGToScalar(-CGRectGetMaxY_inline(theBounds)); - metrics->fAscent = CGToScalar(-CTFontGetAscent(fCTFont)); - metrics->fDescent = CGToScalar( CTFontGetDescent(fCTFont)); + metrics->fAscent = CGToScalar(-CTFontGetAscent(fCTFont.get())); + metrics->fDescent = CGToScalar( CTFontGetDescent(fCTFont.get())); metrics->fBottom = CGToScalar(-CGRectGetMinY_inline(theBounds)); - metrics->fLeading = CGToScalar( CTFontGetLeading(fCTFont)); + metrics->fLeading = CGToScalar( CTFontGetLeading(fCTFont.get())); metrics->fAvgCharWidth = CGToScalar( CGRectGetWidth_inline(theBounds)); metrics->fXMin = CGToScalar( CGRectGetMinX_inline(theBounds)); metrics->fXMax = CGToScalar( CGRectGetMaxX_inline(theBounds)); metrics->fMaxCharWidth = metrics->fXMax - metrics->fXMin; - metrics->fXHeight = CGToScalar( CTFontGetXHeight(fCTFont)); - metrics->fCapHeight = CGToScalar( CTFontGetCapHeight(fCTFont)); - metrics->fUnderlineThickness = CGToScalar( CTFontGetUnderlineThickness(fCTFont)); - metrics->fUnderlinePosition = -CGToScalar( CTFontGetUnderlinePosition(fCTFont)); + metrics->fXHeight = CGToScalar( CTFontGetXHeight(fCTFont.get())); + metrics->fCapHeight = CGToScalar( CTFontGetCapHeight(fCTFont.get())); + metrics->fUnderlineThickness = CGToScalar( CTFontGetUnderlineThickness(fCTFont.get())); + metrics->fUnderlinePosition = -CGToScalar( CTFontGetUnderlinePosition(fCTFont.get())); metrics->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag; metrics->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag; @@ -1312,16 +1234,19 @@ void SkScalerContext_Mac::CTPathElement(void *info, const CGPathElement *element // Returns nullptr on failure // Call must still manage its ownership of provider -static SkTypeface* create_from_dataProvider(CGDataProviderRef provider) { - AutoCFRelease<CGFontRef> cg(CGFontCreateWithDataProvider(provider)); - if (nullptr == cg) { +static SkTypeface* create_from_dataProvider(UniqueCFRef<CGDataProviderRef> provider) { + UniqueCFRef<CGFontRef> cg(CGFontCreateWithDataProvider(provider.get())); + if (!cg) { return nullptr; } - CTFontRef ct = CTFontCreateWithGraphicsFont(cg, 0, nullptr, nullptr); - return ct ? create_from_CTFontRef(ct, nullptr, true) : nullptr; + UniqueCFRef<CTFontRef> ct(CTFontCreateWithGraphicsFont(cg.get(), 0, nullptr, nullptr)); + if (!ct) { + return nullptr; + } + return create_from_CTFontRef(std::move(ct), nullptr, true); } -// Web fonts added to the the CTFont registry do not return their character set. +// Web fonts added to the CTFont registry do not return their character set. // Iterate through the font in this case. The existing caller caches the result, // so the performance impact isn't too bad. static void populate_glyph_to_unicode_slow(CTFontRef ctFont, CFIndex glyphCount, @@ -1347,18 +1272,17 @@ static void populate_glyph_to_unicode_slow(CTFontRef ctFont, CFIndex glyphCount, // supported. static void populate_glyph_to_unicode(CTFontRef ctFont, CFIndex glyphCount, SkTDArray<SkUnichar>* glyphToUnicode) { - AutoCFRelease<CFCharacterSetRef> charSet(CTFontCopyCharacterSet(ctFont)); + UniqueCFRef<CFCharacterSetRef> charSet(CTFontCopyCharacterSet(ctFont)); if (!charSet) { populate_glyph_to_unicode_slow(ctFont, glyphCount, glyphToUnicode); return; } - AutoCFRelease<CFDataRef> bitmap(CFCharacterSetCreateBitmapRepresentation(kCFAllocatorDefault, - charSet)); + UniqueCFRef<CFDataRef> bitmap(CFCharacterSetCreateBitmapRepresentation(nullptr, charSet.get())); if (!bitmap) { return; } - CFIndex length = CFDataGetLength(bitmap); + CFIndex length = CFDataGetLength(bitmap.get()); if (!length) { return; } @@ -1369,7 +1293,7 @@ static void populate_glyph_to_unicode(CTFontRef ctFont, CFIndex glyphCount, // See http://developer.apple.com/library/ios/#documentation/CoreFoundation/Reference/CFCharacterSetRef/Reference/reference.html length = 8192; } - const UInt8* bits = CFDataGetBytePtr(bitmap); + const UInt8* bits = CFDataGetBytePtr(bitmap.get()); glyphToUnicode->setCount(SkToInt(glyphCount)); SkUnichar* out = glyphToUnicode->begin(); sk_bzero(out, glyphCount * sizeof(SkUnichar)); @@ -1407,25 +1331,24 @@ SkAdvancedTypefaceMetrics* SkTypeface_Mac::onGetAdvancedTypefaceMetrics( AUTO_CG_LOCK(); - CTFontRef originalCTFont = fFontRef.get(); - AutoCFRelease<CTFontRef> ctFont(ctfont_create_exact_copy( - originalCTFont, CTFontGetUnitsPerEm(originalCTFont), nullptr)); + UniqueCFRef<CTFontRef> ctFont = + ctfont_create_exact_copy(fFontRef.get(), CTFontGetUnitsPerEm(fFontRef.get()), nullptr); SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics; { - AutoCFRelease<CFStringRef> fontName(CTFontCopyPostScriptName(ctFont)); + UniqueCFRef<CFStringRef> fontName(CTFontCopyPostScriptName(ctFont.get())); if (fontName.get()) { - CFStringToSkString(fontName, &info->fFontName); + CFStringToSkString(fontName.get(), &info->fFontName); } } - CFIndex glyphCount = CTFontGetGlyphCount(ctFont); + CFIndex glyphCount = CTFontGetGlyphCount(ctFont.get()); info->fLastGlyphID = SkToU16(glyphCount - 1); - info->fEmSize = CTFontGetUnitsPerEm(ctFont); + info->fEmSize = CTFontGetUnitsPerEm(ctFont.get()); if (perGlyphInfo & kToUnicode_PerGlyphInfo) { - populate_glyph_to_unicode(ctFont, glyphCount, &info->fGlyphToUnicode); + populate_glyph_to_unicode(ctFont.get(), glyphCount, &info->fGlyphToUnicode); } // If it's not a truetype font, mark it as 'other'. Assume that TrueType @@ -1437,7 +1360,7 @@ SkAdvancedTypefaceMetrics* SkTypeface_Mac::onGetAdvancedTypefaceMetrics( } info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font; - CTFontSymbolicTraits symbolicTraits = CTFontGetSymbolicTraits(ctFont); + CTFontSymbolicTraits symbolicTraits = CTFontGetSymbolicTraits(ctFont.get()); if (symbolicTraits & kCTFontMonoSpaceTrait) { info->fStyle |= SkAdvancedTypefaceMetrics::kFixedPitch_Style; } @@ -1450,11 +1373,11 @@ SkAdvancedTypefaceMetrics* SkTypeface_Mac::onGetAdvancedTypefaceMetrics( } else if (stylisticClass & kCTFontScriptsClass) { info->fStyle |= SkAdvancedTypefaceMetrics::kScript_Style; } - info->fItalicAngle = (int16_t) CTFontGetSlantAngle(ctFont); - info->fAscent = (int16_t) CTFontGetAscent(ctFont); - info->fDescent = (int16_t) CTFontGetDescent(ctFont); - info->fCapHeight = (int16_t) CTFontGetCapHeight(ctFont); - CGRect bbox = CTFontGetBoundingBox(ctFont); + info->fItalicAngle = (int16_t) CTFontGetSlantAngle(ctFont.get()); + info->fAscent = (int16_t) CTFontGetAscent(ctFont.get()); + info->fDescent = (int16_t) CTFontGetDescent(ctFont.get()); + info->fCapHeight = (int16_t) CTFontGetCapHeight(ctFont.get()); + CGRect bbox = CTFontGetBoundingBox(ctFont.get()); SkRect r; r.set( CGToScalar(CGRectGetMinX_inline(bbox)), // Left @@ -1472,8 +1395,8 @@ SkAdvancedTypefaceMetrics* SkTypeface_Mac::onGetAdvancedTypefaceMetrics( const size_t count = sizeof(stem_chars) / sizeof(stem_chars[0]); CGGlyph glyphs[count]; CGRect boundingRects[count]; - if (CTFontGetGlyphsForCharacters(ctFont, stem_chars, glyphs, count)) { - CTFontGetBoundingRectsForGlyphs(ctFont, kCTFontHorizontalOrientation, + if (CTFontGetGlyphsForCharacters(ctFont.get(), stem_chars, glyphs, count)) { + CTFontGetBoundingRectsForGlyphs(ctFont.get(), kCTFontHorizontalOrientation, glyphs, boundingRects, count); for (size_t i = 0; i < count; i++) { int16_t width = (int16_t) boundingRects[i].size.width; @@ -1490,14 +1413,14 @@ SkAdvancedTypefaceMetrics* SkTypeface_Mac::onGetAdvancedTypefaceMetrics( static SK_SFNT_ULONG get_font_type_tag(const SkTypeface_Mac* typeface) { CTFontRef ctFont = typeface->fFontRef.get(); - AutoCFRelease<CFNumberRef> fontFormatRef( + UniqueCFRef<CFNumberRef> fontFormatRef( static_cast<CFNumberRef>(CTFontCopyAttribute(ctFont, kCTFontFormatAttribute))); if (!fontFormatRef) { return 0; } SInt32 fontFormatValue; - if (!CFNumberGetValue(fontFormatRef, kCFNumberSInt32Type, &fontFormatValue)) { + if (!CFNumberGetValue(fontFormatRef.get(), kCFNumberSInt32Type, &fontFormatValue)) { return 0; } @@ -1638,22 +1561,28 @@ static bool get_variations(CTFontRef fFontRef, CFIndex* cgAxisCount, // CTFontCopyVariationAxes and CTFontCopyVariation do not work when applied to fonts which // started life with CGFontCreateWithDataProvider (they simply always return nullptr). // As a result, we are limited to CGFontCopyVariationAxes and CGFontCopyVariations. - AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, nullptr)); + UniqueCFRef<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, nullptr)); + if (!cgFont) { + return false; + } - AutoCFRelease<CFDictionaryRef> cgVariations(CGFontCopyVariations(cgFont)); + UniqueCFRef<CFDictionaryRef> cgVariations(CGFontCopyVariations(cgFont.get())); // If a font has no variations CGFontCopyVariations returns nullptr (instead of an empty dict). - if (!cgVariations.get()) { + if (!cgVariations) { return false; } - AutoCFRelease<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cgFont)); - *cgAxisCount = CFArrayGetCount(cgAxes); + UniqueCFRef<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cgFont.get())); + if (!cgAxes) { + return false; + } + *cgAxisCount = CFArrayGetCount(cgAxes.get()); axisValues->reset(*cgAxisCount); // Set all of the axes to their default values. // Fail if any default value cannot be determined. for (CFIndex i = 0; i < *cgAxisCount; ++i) { - CFTypeRef cgAxis = CFArrayGetValueAtIndex(cgAxes, i); + CFTypeRef cgAxis = CFArrayGetValueAtIndex(cgAxes.get(), i); if (CFGetTypeID(cgAxis) != CFDictionaryGetTypeID()) { return false; } @@ -1680,7 +1609,7 @@ static bool get_variations(CTFontRef fFontRef, CFIndex* cgAxisCount, // Override the default values with the given font's stated axis values. NonDefaultAxesContext c = { axisValues->get(), cgAxes.get() }; - CFDictionaryApplyFunction(cgVariations, set_non_default_axes, &c); + CFDictionaryApplyFunction(cgVariations.get(), set_non_default_axes, &c); return true; } @@ -1690,7 +1619,7 @@ std::unique_ptr<SkFontData> SkTypeface_Mac::onMakeFontData() const { CFIndex cgAxisCount; SkAutoSTMalloc<4, SkFixed> axisValues; - if (get_variations(fFontRef, &cgAxisCount, &axisValues)) { + if (get_variations(fFontRef.get(), &cgAxisCount, &axisValues)) { return skstd::make_unique<SkFontData>(std::move(stream), index, axisValues.get(), cgAxisCount); } @@ -1701,26 +1630,27 @@ std::unique_ptr<SkFontData> SkTypeface_Mac::onMakeFontData() const { /////////////////////////////////////////////////////////////////////////////// int SkTypeface_Mac::onGetUPEM() const { - AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, nullptr)); - return CGFontGetUnitsPerEm(cgFont); + UniqueCFRef<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef.get(), nullptr)); + return CGFontGetUnitsPerEm(cgFont.get()); } SkTypeface::LocalizedStrings* SkTypeface_Mac::onCreateFamilyNameIterator() const { SkTypeface::LocalizedStrings* nameIter = - SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this); + SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this); if (nullptr == nameIter) { - AutoCFRelease<CFStringRef> cfLanguage; - AutoCFRelease<CFStringRef> cfFamilyName( - CTFontCopyLocalizedName(fFontRef, kCTFontFamilyNameKey, &cfLanguage)); + CFStringRef cfLanguageRaw; + UniqueCFRef<CFStringRef> cfFamilyName( + CTFontCopyLocalizedName(fFontRef.get(), kCTFontFamilyNameKey, &cfLanguageRaw)); + UniqueCFRef<CFStringRef> cfLanguage(cfLanguageRaw); SkString skLanguage; SkString skFamilyName; - if (cfLanguage.get()) { + if (cfLanguage) { CFStringToSkString(cfLanguage.get(), &skLanguage); } else { skLanguage = "und"; //undetermined } - if (cfFamilyName.get()) { + if (cfFamilyName) { CFStringToSkString(cfFamilyName.get(), &skFamilyName); } @@ -1729,43 +1659,44 @@ SkTypeface::LocalizedStrings* SkTypeface_Mac::onCreateFamilyNameIterator() const return nameIter; } -// If, as is the case with web fonts, the CTFont data isn't available, -// the CGFont data may work. While the CGFont may always provide the -// right result, leave the CTFont code path to minimize disruption. -static CFDataRef copyTableFromFont(CTFontRef ctFont, SkFontTableTag tag) { - CFDataRef data = CTFontCopyTable(ctFont, (CTFontTableTag) tag, - kCTFontTableOptionNoOptions); - if (nullptr == data) { - AutoCFRelease<CGFontRef> cgFont(CTFontCopyGraphicsFont(ctFont, nullptr)); - data = CGFontCopyTableForTag(cgFont, tag); - } - return data; -} - int SkTypeface_Mac::onGetTableTags(SkFontTableTag tags[]) const { - AutoCFRelease<CFArrayRef> cfArray(CTFontCopyAvailableTables(fFontRef, - kCTFontTableOptionNoOptions)); - if (nullptr == cfArray) { + UniqueCFRef<CFArrayRef> cfArray( + CTFontCopyAvailableTables(fFontRef.get(), kCTFontTableOptionNoOptions)); + if (!cfArray) { return 0; } - int count = SkToInt(CFArrayGetCount(cfArray)); + int count = SkToInt(CFArrayGetCount(cfArray.get())); if (tags) { for (int i = 0; i < count; ++i) { - uintptr_t fontTag = reinterpret_cast<uintptr_t>(CFArrayGetValueAtIndex(cfArray, i)); + uintptr_t fontTag = reinterpret_cast<uintptr_t>( + CFArrayGetValueAtIndex(cfArray.get(), i)); tags[i] = static_cast<SkFontTableTag>(fontTag); } } return count; } +// If, as is the case with web fonts, the CTFont data isn't available, +// the CGFont data may work. While the CGFont may always provide the +// right result, leave the CTFont code path to minimize disruption. +static UniqueCFRef<CFDataRef> copy_table_from_font(CTFontRef ctFont, SkFontTableTag tag) { + UniqueCFRef<CFDataRef> data(CTFontCopyTable(ctFont, (CTFontTableTag) tag, + kCTFontTableOptionNoOptions)); + if (!data) { + UniqueCFRef<CGFontRef> cgFont(CTFontCopyGraphicsFont(ctFont, nullptr)); + data.reset(CGFontCopyTableForTag(cgFont.get(), tag)); + } + return data; +} + size_t SkTypeface_Mac::onGetTableData(SkFontTableTag tag, size_t offset, size_t length, void* dstData) const { - AutoCFRelease<CFDataRef> srcData(copyTableFromFont(fFontRef, tag)); - if (nullptr == srcData) { + UniqueCFRef<CFDataRef> srcData = copy_table_from_font(fFontRef.get(), tag); + if (!srcData) { return 0; } - size_t srcSize = CFDataGetLength(srcData); + size_t srcSize = CFDataGetLength(srcData.get()); if (offset >= srcSize) { return 0; } @@ -1773,7 +1704,7 @@ size_t SkTypeface_Mac::onGetTableData(SkFontTableTag tag, size_t offset, length = srcSize - offset; } if (dstData) { - memcpy(dstData, CFDataGetBytePtr(srcData) + offset, length); + memcpy(dstData, CFDataGetBytePtr(srcData.get()) + offset, length); } return length; } @@ -1835,7 +1766,7 @@ void SkTypeface_Mac::onFilterRec(SkScalerContextRec* rec) const { // Currenly side with LCD, effectively ignoring the hinting setting. // [LCD][yes-hint]: generate LCD using CoreGraphic's LCD output. - if (isLCDFormat(rec->fMaskFormat)) { + if (rec->fMaskFormat == SkMask::kLCD16_Format) { if (lcdSupport) { //CoreGraphics creates 555 masks for smoothed text anyway. rec->fMaskFormat = SkMask::kLCD16_Format; @@ -1865,27 +1796,27 @@ void SkTypeface_Mac::onFilterRec(SkScalerContextRec* rec) const { } } -// we take ownership of the ref +/** Takes ownership of the CFStringRef. */ static const char* get_str(CFStringRef ref, SkString* str) { if (nullptr == ref) { return nullptr; } CFStringToSkString(ref, str); - CFSafeRelease(ref); + CFRelease(ref); return str->c_str(); } void SkTypeface_Mac::onGetFamilyName(SkString* familyName) const { - get_str(CTFontCopyFamilyName(fFontRef), familyName); + get_str(CTFontCopyFamilyName(fFontRef.get()), familyName); } void SkTypeface_Mac::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocalStream) const { SkString tmpStr; - desc->setFamilyName(get_str(CTFontCopyFamilyName(fFontRef), &tmpStr)); - desc->setFullName(get_str(CTFontCopyFullName(fFontRef), &tmpStr)); - desc->setPostscriptName(get_str(CTFontCopyPostScriptName(fFontRef), &tmpStr)); + desc->setFamilyName(get_str(CTFontCopyFamilyName(fFontRef.get()), &tmpStr)); + desc->setFullName(get_str(CTFontCopyFullName(fFontRef.get()), &tmpStr)); + desc->setPostscriptName(get_str(CTFontCopyPostScriptName(fFontRef.get()), &tmpStr)); desc->setStyle(this->fontStyle()); *isLocalStream = fIsLocalStream; } @@ -1943,7 +1874,7 @@ int SkTypeface_Mac::onCharsToGlyphs(const void* chars, Encoding encoding, macGlyphs = glyphStorage.reset(srcCount); } - bool allEncoded = CTFontGetGlyphsForCharacters(fFontRef, src, macGlyphs, srcCount); + bool allEncoded = CTFontGetGlyphsForCharacters(fFontRef.get(), src, macGlyphs, srcCount); // If there were any non-bmp, then copy and compact. // If 'glyphs' is nullptr, then compact glyphStorage in-place. @@ -1978,18 +1909,18 @@ int SkTypeface_Mac::onCharsToGlyphs(const void* chars, Encoding encoding, } int SkTypeface_Mac::onCountGlyphs() const { - return SkToInt(CTFontGetGlyphCount(fFontRef)); + return SkToInt(CTFontGetGlyphCount(fFontRef.get())); } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// static bool find_desc_str(CTFontDescriptorRef desc, CFStringRef name, SkString* value) { - AutoCFRelease<CFStringRef> ref((CFStringRef)CTFontDescriptorCopyAttribute(desc, name)); - if (nullptr == ref.get()) { + UniqueCFRef<CFStringRef> ref((CFStringRef)CTFontDescriptorCopyAttribute(desc, name)); + if (!ref) { return false; } - CFStringToSkString(ref, value); + CFStringToSkString(ref.get(), value); return true; } @@ -2011,15 +1942,12 @@ class SkFontStyleSet_Mac : public SkFontStyleSet { public: SkFontStyleSet_Mac(CTFontDescriptorRef desc) : fArray(CTFontDescriptorCreateMatchingFontDescriptors(desc, nullptr)) - , fCount(0) { - if (nullptr == fArray) { - fArray = CFArrayCreate(nullptr, nullptr, 0, nullptr); + , fCount(0) + { + if (!fArray) { + fArray.reset(CFArrayCreate(nullptr, nullptr, 0, nullptr)); } - fCount = SkToInt(CFArrayGetCount(fArray)); - } - - virtual ~SkFontStyleSet_Mac() { - CFRelease(fArray); + fCount = SkToInt(CFArrayGetCount(fArray.get())); } int count() override { @@ -2028,7 +1956,7 @@ public: void getStyle(int index, SkFontStyle* style, SkString* name) override { SkASSERT((unsigned)index < (unsigned)fCount); - CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fArray, index); + CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fArray.get(), index); if (style) { *style = fontstyle_from_descriptor(desc); } @@ -2040,8 +1968,8 @@ public: } SkTypeface* createTypeface(int index) override { - SkASSERT((unsigned)index < (unsigned)CFArrayGetCount(fArray)); - CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fArray, index); + SkASSERT((unsigned)index < (unsigned)CFArrayGetCount(fArray.get())); + CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fArray.get(), index); return create_from_desc(desc); } @@ -2054,15 +1982,15 @@ public: } private: - CFArrayRef fArray; - int fCount; + UniqueCFRef<CFArrayRef> fArray; + int fCount; CTFontDescriptorRef findMatchingDesc(const SkFontStyle& pattern) const { int bestMetric = SK_MaxS32; CTFontDescriptorRef bestDesc = nullptr; for (int i = 0; i < fCount; ++i) { - CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fArray, i); + CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fArray.get(), i); int metric = compute_metric(pattern, fontstyle_from_descriptor(desc)); if (0 == metric) { return desc; @@ -2078,35 +2006,42 @@ private: }; class SkFontMgr_Mac : public SkFontMgr { - CFArrayRef fNames; - int fCount; + UniqueCFRef<CFArrayRef> fNames; + int fCount; - CFStringRef stringAt(int index) const { + CFStringRef getFamilyNameAt(int index) const { SkASSERT((unsigned)index < (unsigned)fCount); - return (CFStringRef)CFArrayGetValueAtIndex(fNames, index); + return (CFStringRef)CFArrayGetValueAtIndex(fNames.get(), index); } static SkFontStyleSet* CreateSet(CFStringRef cfFamilyName) { - AutoCFRelease<CFMutableDictionaryRef> cfAttr( + UniqueCFRef<CFMutableDictionaryRef> cfAttr( CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); - CFDictionaryAddValue(cfAttr, kCTFontFamilyNameAttribute, cfFamilyName); + CFDictionaryAddValue(cfAttr.get(), kCTFontFamilyNameAttribute, cfFamilyName); + + UniqueCFRef<CTFontDescriptorRef> desc( + CTFontDescriptorCreateWithAttributes(cfAttr.get())); + return new SkFontStyleSet_Mac(desc.get()); + } - AutoCFRelease<CTFontDescriptorRef> desc( - CTFontDescriptorCreateWithAttributes(cfAttr)); - return new SkFontStyleSet_Mac(desc); + /** CTFontManagerCopyAvailableFontFamilyNames() is not always available, so we + * provide a wrapper here that will return an empty array if need be. + */ + static UniqueCFRef<CFArrayRef> CopyAvailableFontFamilyNames() { +#ifdef SK_BUILD_FOR_IOS + return UniqueCFRef<CFArrayRef>(CFArrayCreate(nullptr, nullptr, 0, nullptr)); +#else + return UniqueCFRef<CFArrayRef>(CTFontManagerCopyAvailableFontFamilyNames()); +#endif } public: SkFontMgr_Mac() - : fNames(SkCTFontManagerCopyAvailableFontFamilyNames()) - , fCount(fNames ? SkToInt(CFArrayGetCount(fNames)) : 0) {} - - virtual ~SkFontMgr_Mac() { - CFSafeRelease(fNames); - } + : fNames(CopyAvailableFontFamilyNames()) + , fCount(fNames ? SkToInt(CFArrayGetCount(fNames.get())) : 0) {} protected: int onCountFamilies() const override { @@ -2115,7 +2050,7 @@ protected: void onGetFamilyName(int index, SkString* familyName) const override { if ((unsigned)index < (unsigned)fCount) { - CFStringToSkString(this->stringAt(index), familyName); + CFStringToSkString(this->getFamilyNameAt(index), familyName); } else { familyName->reset(); } @@ -2125,26 +2060,26 @@ protected: if ((unsigned)index >= (unsigned)fCount) { return nullptr; } - return CreateSet(this->stringAt(index)); + return CreateSet(this->getFamilyNameAt(index)); } SkFontStyleSet* onMatchFamily(const char familyName[]) const override { - AutoCFRelease<CFStringRef> cfName(make_CFString(familyName)); - return CreateSet(cfName); + UniqueCFRef<CFStringRef> cfName = make_CFString(familyName); + return CreateSet(cfName.get()); } - virtual SkTypeface* onMatchFamilyStyle(const char familyName[], - const SkFontStyle& fontStyle) const override { + SkTypeface* onMatchFamilyStyle(const char familyName[], + const SkFontStyle& fontStyle) const override { sk_sp<SkFontStyleSet> sset(this->matchFamily(familyName)); return sset->matchStyle(fontStyle); } - virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], - const SkFontStyle& style, - const char* bcp47[], int bcp47Count, - SkUnichar character) const override { - AutoCFRelease<CTFontDescriptorRef> desc(create_descriptor(familyName, style)); - AutoCFRelease<CTFontRef> currentFont(CTFontCreateWithFontDescriptor(desc, 0, nullptr)); + SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], + const SkFontStyle& style, + const char* bcp47[], int bcp47Count, + SkUnichar character) const override { + UniqueCFRef<CTFontDescriptorRef> desc = create_descriptor(familyName, style); + UniqueCFRef<CTFontRef> currentFont(CTFontCreateWithFontDescriptor(desc.get(), 0, nullptr)); // kCFStringEncodingUTF32 is BE unless there is a BOM. // Since there is no machine endian option, explicitly state machine endian. @@ -2153,34 +2088,35 @@ protected: #else constexpr CFStringEncoding encoding = kCFStringEncodingUTF32BE; #endif - AutoCFRelease<CFStringRef> string(CFStringCreateWithBytes( + UniqueCFRef<CFStringRef> string(CFStringCreateWithBytes( kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(&character), sizeof(character), encoding, false)); - CFRange range = CFRangeMake(0, CFStringGetLength(string)); // in UniChar units. - AutoCFRelease<CTFontRef> fallbackFont(CTFontCreateForString(currentFont, string, range)); - return create_from_CTFontRef(fallbackFont.release(), nullptr, false); + CFRange range = CFRangeMake(0, CFStringGetLength(string.get())); // in UniChar units. + UniqueCFRef<CTFontRef> fallbackFont( + CTFontCreateForString(currentFont.get(), string.get(), range)); + return create_from_CTFontRef(std::move(fallbackFont), nullptr, false); } - virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember, - const SkFontStyle&) const override { + SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember, + const SkFontStyle&) const override { return nullptr; } SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const override { - AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromData(sk_ref_sp(data))); - if (nullptr == pr) { + UniqueCFRef<CGDataProviderRef> pr(SkCreateDataProviderFromData(sk_ref_sp(data))); + if (!pr) { return nullptr; } - return create_from_dataProvider(pr); + return create_from_dataProvider(std::move(pr)); } SkTypeface* onCreateFromStream(SkStreamAsset* bareStream, int ttcIndex) const override { std::unique_ptr<SkStreamAsset> stream(bareStream); - AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromStream(std::move(stream))); - if (nullptr == pr) { + UniqueCFRef<CGDataProviderRef> pr(SkCreateDataProviderFromStream(std::move(stream))); + if (!pr) { return nullptr; } - return create_from_dataProvider(pr); + return create_from_dataProvider(std::move(pr)); } static CFNumberRef get_tag_for_name(CFStringRef name, CFArrayRef ctAxes) { @@ -2209,32 +2145,34 @@ protected: } return nullptr; } - static CFDictionaryRef get_axes(CGFontRef cg, const FontParameters& params) { - AutoCFRelease<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cg)); + static UniqueCFRef<CFDictionaryRef> copy_axes(CGFontRef cg, const FontParameters& params) { + UniqueCFRef<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cg)); if (!cgAxes) { return nullptr; } - CFIndex axisCount = CFArrayGetCount(cgAxes); + CFIndex axisCount = CFArrayGetCount(cgAxes.get()); // The CGFont variation data is keyed by name, and lacks the tag. // The CTFont variation data is keyed by tag, and also has the name. // We would like to work with CTFont variaitons, but creating a CTFont font with // CTFont variation dictionary runs into bugs. So use the CTFont variation data // to match names to tags to create the appropriate CGFont. - AutoCFRelease<CTFontRef> ct(CTFontCreateWithGraphicsFont(cg, 0, nullptr, nullptr)); - AutoCFRelease<CFArrayRef> ctAxes(CTFontCopyVariationAxes(ct)); - if (!ctAxes || CFArrayGetCount(ctAxes) != axisCount) { + UniqueCFRef<CTFontRef> ct(CTFontCreateWithGraphicsFont(cg, 0, nullptr, nullptr)); + UniqueCFRef<CFArrayRef> ctAxes(CTFontCopyVariationAxes(ct.get())); + if (!ctAxes || CFArrayGetCount(ctAxes.get()) != axisCount) { return nullptr; } int paramAxisCount; const FontParameters::Axis* paramAxes = params.getAxes(¶mAxisCount); - CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault, axisCount, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); + UniqueCFRef<CFMutableDictionaryRef> dict( + CFDictionaryCreateMutable(kCFAllocatorDefault, axisCount, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks)); + for (int i = 0; i < axisCount; ++i) { - CFTypeRef axisInfo = CFArrayGetValueAtIndex(cgAxes, i); + CFTypeRef axisInfo = CFArrayGetValueAtIndex(cgAxes.get(), i); if (CFDictionaryGetTypeID() != CFGetTypeID(axisInfo)) { return nullptr; } @@ -2245,7 +2183,8 @@ protected: return nullptr; } - CFNumberRef tagNumber = get_tag_for_name(static_cast<CFStringRef>(axisName), ctAxes); + CFNumberRef tagNumber = + get_tag_for_name(static_cast<CFStringRef>(axisName), ctAxes.get()); if (!tagNumber) { // Could not find a tag to go with the name of this index. // This would be a bug in CG/CT. @@ -2287,58 +2226,60 @@ protected: break; } } - CFNumberRef valueNumber = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, - &value); - CFDictionaryAddValue(dict, axisName, valueNumber); - CFRelease(valueNumber); + UniqueCFRef<CFNumberRef> valueNumber( + CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value)); + CFDictionaryAddValue(dict.get(), axisName, valueNumber.get()); } - return dict; + return std::move(dict); } SkTypeface* onCreateFromStream(SkStreamAsset* bs, const FontParameters& params) const override { std::unique_ptr<SkStreamAsset> s(bs); - AutoCFRelease<CGDataProviderRef> provider(SkCreateDataProviderFromStream(std::move(s))); - if (nullptr == provider) { + UniqueCFRef<CGDataProviderRef> provider(SkCreateDataProviderFromStream(std::move(s))); + if (!provider) { return nullptr; } - AutoCFRelease<CGFontRef> cg(CGFontCreateWithDataProvider(provider)); - if (nullptr == cg) { + UniqueCFRef<CGFontRef> cg(CGFontCreateWithDataProvider(provider.get())); + if (!cg) { return nullptr; } - AutoCFRelease<CFDictionaryRef> cgVariations(get_axes(cg, params)); + UniqueCFRef<CFDictionaryRef> cgVariations = copy_axes(cg.get(), params); // The CGFontRef returned by CGFontCreateCopyWithVariations when the passed CGFontRef was // created from a data provider does not appear to have any ownership of the underlying // data. The original CGFontRef must be kept alive until the copy will no longer be used. - AutoCFRelease<CGFontRef> cgVariant; + UniqueCFRef<CGFontRef> cgVariant; if (cgVariations) { - cgVariant.reset(CGFontCreateCopyWithVariations(cg, cgVariations)); + cgVariant.reset(CGFontCreateCopyWithVariations(cg.get(), cgVariations.get())); } else { cgVariant.reset(cg.release()); } - AutoCFRelease<CTFontRef> ct(CTFontCreateWithGraphicsFont(cgVariant, 0, nullptr, nullptr)); + UniqueCFRef<CTFontRef> ct( + CTFontCreateWithGraphicsFont(cgVariant.get(), 0, nullptr, nullptr)); if (!ct) { return nullptr; } - return create_from_CTFontRef(ct.release(), cg.release(), true); + return create_from_CTFontRef(std::move(ct), std::move(cg), true); } - static CFDictionaryRef get_axes(CGFontRef cg, SkFontData* fontData) { - AutoCFRelease<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cg)); + static UniqueCFRef<CFDictionaryRef> copy_axes(CGFontRef cg, SkFontData* fontData) { + UniqueCFRef<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cg)); if (!cgAxes) { return nullptr; } - CFIndex axisCount = CFArrayGetCount(cgAxes); + CFIndex axisCount = CFArrayGetCount(cgAxes.get()); if (0 == axisCount || axisCount != fontData->getAxisCount()) { return nullptr; } - CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault, axisCount, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); + UniqueCFRef<CFMutableDictionaryRef> dict( + CFDictionaryCreateMutable(kCFAllocatorDefault, axisCount, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks)); + for (int i = 0; i < fontData->getAxisCount(); ++i) { - CFTypeRef axisInfo = CFArrayGetValueAtIndex(cgAxes, i); + CFTypeRef axisInfo = CFArrayGetValueAtIndex(cgAxes.get(), i); if (CFDictionaryGetTypeID() != CFGetTypeID(axisInfo)) { return nullptr; } @@ -2368,49 +2309,48 @@ protected: return nullptr; } double value = SkTPin(SkFixedToDouble(fontData->getAxis()[i]), minDouble, maxDouble); - CFNumberRef valueNumber = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, - &value); - - CFDictionaryAddValue(dict, axisName, valueNumber); - CFRelease(valueNumber); + UniqueCFRef<CFNumberRef> valueNumber( + CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value)); + CFDictionaryAddValue(dict.get(), axisName, valueNumber.get()); } - return dict; + return std::move(dict); } SkTypeface* onCreateFromFontData(std::unique_ptr<SkFontData> fontData) const override { - AutoCFRelease<CGDataProviderRef> provider( + UniqueCFRef<CGDataProviderRef> provider( SkCreateDataProviderFromStream(fontData->detachStream())); - if (nullptr == provider) { + if (!provider) { return nullptr; } - AutoCFRelease<CGFontRef> cg(CGFontCreateWithDataProvider(provider)); - if (nullptr == cg) { + UniqueCFRef<CGFontRef> cg(CGFontCreateWithDataProvider(provider.get())); + if (!cg) { return nullptr; } - AutoCFRelease<CFDictionaryRef> cgVariations(get_axes(cg, fontData.get())); + UniqueCFRef<CFDictionaryRef> cgVariations = copy_axes(cg.get(), fontData.get()); // The CGFontRef returned by CGFontCreateCopyWithVariations when the passed CGFontRef was // created from a data provider does not appear to have any ownership of the underlying // data. The original CGFontRef must be kept alive until the copy will no longer be used. - AutoCFRelease<CGFontRef> cgVariant; + UniqueCFRef<CGFontRef> cgVariant; if (cgVariations) { - cgVariant.reset(CGFontCreateCopyWithVariations(cg, cgVariations)); + cgVariant.reset(CGFontCreateCopyWithVariations(cg.get(), cgVariations.get())); } else { cgVariant.reset(cg.release()); } - AutoCFRelease<CTFontRef> ct(CTFontCreateWithGraphicsFont(cgVariant, 0, nullptr, nullptr)); + UniqueCFRef<CTFontRef> ct( + CTFontCreateWithGraphicsFont(cgVariant.get(), 0, nullptr, nullptr)); if (!ct) { return nullptr; } - return create_from_CTFontRef(ct.release(), cg.release(), true); + return create_from_CTFontRef(std::move(ct), std::move(cg), true); } SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override { - AutoCFRelease<CGDataProviderRef> pr(CGDataProviderCreateWithFilename(path)); - if (nullptr == pr) { + UniqueCFRef<CGDataProviderRef> pr(CGDataProviderCreateWithFilename(path)); + if (!pr) { return nullptr; } - return create_from_dataProvider(pr); + return create_from_dataProvider(std::move(pr)); } SkTypeface* onLegacyCreateTypeface(const char familyName[], SkFontStyle style) const override { @@ -2418,6 +2358,7 @@ protected: familyName = map_css_names(familyName); } + static const char FONT_DEFAULT_NAME[] = "Lucida Sans"; if (!familyName || !*familyName) { familyName = FONT_DEFAULT_NAME; } @@ -2427,7 +2368,12 @@ protected: return face; } - return SkSafeRef(GetDefaultFace()); + static SkTypeface* gDefaultFace; + static SkOnce lookupDefault; + lookupDefault([]{ + gDefaultFace = create_from_name(FONT_DEFAULT_NAME, SkFontStyle()); + }); + return SkSafeRef(gDefaultFace); } }; |