aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar bungeman <bungeman@google.com>2016-12-20 12:04:29 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-12-21 18:56:57 +0000
commitc292b5fa323ecb46bc1977f0fd14224953d8caff (patch)
treea65c746f3b8a81f1edad752e06e74b9ac07e8eb3 /src
parent463c848f3b63b52e3834e405ff11fd1e653ed271 (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.cpp732
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(&paramAxisCount);
- 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);
}
};