Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / ports / SkFontHost_mac.cpp
index e00b87b..72a3274 100755 (executable)
@@ -82,14 +82,10 @@ public:
     ~AutoCFRelease() { CFSafeRelease(fCFRef); }
 
     void reset(CFRef that = NULL) {
-        CFSafeRetain(that);
-        CFSafeRelease(fCFRef);
-        fCFRef = that;
-    }
-
-    AutoCFRelease& operator =(CFRef that) {
-        reset(that);
-        return *this;
+        if (that != fCFRef) {
+            CFSafeRelease(fCFRef);
+            fCFRef = that;
+        }
     }
 
     operator CFRef() const { return fCFRef; }
@@ -426,21 +422,23 @@ static SkTypeface::Style fontstyle2stylebits(const SkFontStyle& fs) {
 class SkTypeface_Mac : public SkTypeface {
 public:
     SkTypeface_Mac(SkTypeface::Style style, SkFontID fontID, bool isFixedPitch,
-                   CTFontRef fontRef, const char name[])
+                   CTFontRef fontRef, const char name[], bool isLocalStream)
         : SkTypeface(style, fontID, isFixedPitch)
         , fName(name)
         , fFontRef(fontRef) // caller has already called CFRetain for us
         , fFontStyle(stylebits2fontstyle(style))
+        , fIsLocalStream(isLocalStream)
     {
         SkASSERT(fontRef);
     }
 
     SkTypeface_Mac(const SkFontStyle& fs, SkFontID fontID, bool isFixedPitch,
-                   CTFontRef fontRef, const char name[])
+                   CTFontRef fontRef, const char name[], bool isLocalStream)
         : SkTypeface(fontstyle2stylebits(fs), fontID, isFixedPitch)
         , fName(name)
         , fFontRef(fontRef) // caller has already called CFRetain for us
         , fFontStyle(fs)
+        , fIsLocalStream(isLocalStream)
     {
         SkASSERT(fontRef);
     }
@@ -469,17 +467,18 @@ protected:
     virtual int onCountGlyphs() const SK_OVERRIDE;
 
 private:
+    bool fIsLocalStream;
 
     typedef SkTypeface INHERITED;
 };
 
-static SkTypeface* NewFromFontRef(CTFontRef fontRef, const char name[]) {
+static SkTypeface* NewFromFontRef(CTFontRef fontRef, const char name[], bool isLocalStream) {
     SkASSERT(fontRef);
     bool isFixedPitch;
     SkTypeface::Style style = computeStyleBits(fontRef, &isFixedPitch);
     SkFontID fontID = CTFontRef_to_SkFontID(fontRef);
 
-    return new SkTypeface_Mac(style, fontID, isFixedPitch, fontRef, name);
+    return new SkTypeface_Mac(style, fontID, isFixedPitch, fontRef, name, isLocalStream);
 }
 
 static SkTypeface* NewFromName(const char familyName[], SkTypeface::Style theStyle) {
@@ -524,12 +523,12 @@ static SkTypeface* NewFromName(const char familyName[], SkTypeface::Style theSty
         }
     }
 
-    return ctFont ? NewFromFontRef(ctFont, familyName) : NULL;
+    return ctFont ? NewFromFontRef(ctFont, familyName, false) : NULL;
 }
 
+SK_DECLARE_STATIC_MUTEX(gGetDefaultFaceMutex);
 static SkTypeface* GetDefaultFace() {
-    SK_DECLARE_STATIC_MUTEX(gMutex);
-    SkAutoMutexAcquire ma(gMutex);
+    SkAutoMutexAcquire ma(gGetDefaultFaceMutex);
 
     static SkTypeface* gDefaultFace;
 
@@ -557,7 +556,7 @@ SkTypeface* SkCreateTypefaceFromCTFont(CTFontRef fontRef) {
     if (face) {
         face->ref();
     } else {
-        face = NewFromFontRef(fontRef, NULL);
+        face = NewFromFontRef(fontRef, NULL, false);
         SkTypefaceCache::Add(face, face->style());
         // NewFromFontRef doesn't retain the parameter, but the typeface it
         // creates does release it in its destructor, so we balance that with
@@ -653,7 +652,7 @@ protected:
     void generateMetrics(SkGlyph* glyph) SK_OVERRIDE;
     void generateImage(const SkGlyph& glyph) SK_OVERRIDE;
     void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE;
-    void generateFontMetrics(SkPaint::FontMetrics* mX, SkPaint::FontMetrics* mY) SK_OVERRIDE;
+    void generateFontMetrics(SkPaint::FontMetrics*) SK_OVERRIDE;
 
 private:
     static void CTPathElement(void *info, const CGPathElement *element);
@@ -746,16 +745,16 @@ SkScalerContext_Mac::SkScalerContext_Mac(SkTypeface_Mac* typeface,
             AutoCFRelease<CFNumberRef> cfVertical(CFNumberCreate(
                     kCFAllocatorDefault, kCFNumberSInt32Type, &ctOrientation));
             CFDictionaryAddValue(cfAttributes, kCTFontOrientationAttribute, cfVertical);
-            ctFontDesc = CTFontDescriptorCreateWithAttributes(cfAttributes);
+            ctFontDesc.reset(CTFontDescriptorCreateWithAttributes(cfAttributes));
         }
     }
     // Since our matrix includes everything, we pass 1 for size.
-    fCTFont = CTFontCreateCopyWithAttributes(ctFont, 1, &transform, ctFontDesc);
-    fCGFont = CTFontCopyGraphicsFont(fCTFont, NULL);
+    fCTFont.reset(CTFontCreateCopyWithAttributes(ctFont, 1, &transform, ctFontDesc));
+    fCGFont.reset(CTFontCopyGraphicsFont(fCTFont, NULL));
     if (fVertical) {
         CGAffineTransform rotateLeft = CGAffineTransformMake(0, -1, 1, 0, 0, 0);
         transform = CGAffineTransformConcat(rotateLeft, transform);
-        fCTVerticalFont = CTFontCreateCopyWithAttributes(ctFont, 1, &transform, NULL);
+        fCTVerticalFont.reset(CTFontCreateCopyWithAttributes(ctFont, 1, &transform, NULL));
     }
 
     SkScalar emPerFUnit = SkScalarInvert(SkIntToScalar(CGFontGetUnitsPerEm(fCGFont)));
@@ -769,7 +768,7 @@ CGRGBPixel* Offscreen::getCG(const SkScalerContext_Mac& context, const SkGlyph&
         //It doesn't appear to matter what color space is specified.
         //Regular blends and antialiased text are always (s*a + d*(1-a))
         //and smoothed text is always g=2.0.
-        fRGBSpace = CGColorSpaceCreateDeviceRGB();
+        fRGBSpace.reset(CGColorSpaceCreateDeviceRGB());
     }
 
     // default to kBW_Format
@@ -798,8 +797,8 @@ CGRGBPixel* Offscreen::getCG(const SkScalerContext_Mac& context, const SkGlyph&
 
         rowBytes = fSize.fWidth * sizeof(CGRGBPixel);
         void* image = fImageStorage.reset(rowBytes * fSize.fHeight);
-        fCG = CGBitmapContextCreate(image, fSize.fWidth, fSize.fHeight, 8,
-                                    rowBytes, fRGBSpace, BITMAP_INFO_RGB);
+        fCG.reset(CGBitmapContextCreate(image, fSize.fWidth, fSize.fHeight, 8,
+                                        rowBytes, fRGBSpace, BITMAP_INFO_RGB));
 
         // skia handles quantization itself, so we disable this for cg to get
         // full fractional data from them.
@@ -959,7 +958,7 @@ void SkScalerContext_Mac::generateAdvance(SkGlyph* glyph) {
 }
 
 void SkScalerContext_Mac::generateMetrics(SkGlyph* glyph) {
-    const CGGlyph cgGlyph = (CGGlyph) glyph->getGlyphID(fBaseGlyphCount);
+    const CGGlyph cgGlyph = (CGGlyph) glyph->getGlyphID();
     glyph->zeroMetrics();
 
     // The following block produces cgAdvance in CG units (pixels, y up).
@@ -1204,7 +1203,7 @@ template <typename T> T* SkTAddByteOffset(T* ptr, size_t byteOffset) {
 }
 
 void SkScalerContext_Mac::generateImage(const SkGlyph& glyph) {
-    CGGlyph cgGlyph = (CGGlyph) glyph.getGlyphID(fBaseGlyphCount);
+    CGGlyph cgGlyph = (CGGlyph) glyph.getGlyphID();
 
     // FIXME: lcd smoothed un-hinted rasterization unsupported.
     bool generateA8FromLCD = fRec.getHinting() != SkPaint::kNo_Hinting;
@@ -1343,7 +1342,7 @@ void SkScalerContext_Mac::generatePath(const SkGlyph& glyph, SkPath* path) {
         font = CTFontCreateCopyWithAttributes(fCTFont, 1, &xform, NULL);
     }
 
-    CGGlyph cgGlyph = (CGGlyph)glyph.getGlyphID(fBaseGlyphCount);
+    CGGlyph cgGlyph = (CGGlyph)glyph.getGlyphID();
     AutoCFRelease<CGPathRef> cgPath(CTFontCreatePathForGlyph(font, cgGlyph, NULL));
 
     path->reset();
@@ -1365,32 +1364,27 @@ void SkScalerContext_Mac::generatePath(const SkGlyph& glyph, SkPath* path) {
     }
 }
 
-void SkScalerContext_Mac::generateFontMetrics(SkPaint::FontMetrics* mx,
-                                              SkPaint::FontMetrics* my) {
-    CGRect theBounds = CTFontGetBoundingBox(fCTFont);
+void SkScalerContext_Mac::generateFontMetrics(SkPaint::FontMetrics* metrics) {
+    if (NULL == metrics) {
+        return;
+    }
 
-    SkPaint::FontMetrics theMetrics;
-    theMetrics.fTop          = CGToScalar(-CGRectGetMaxY_inline(theBounds));
-    theMetrics.fAscent       = CGToScalar(-CTFontGetAscent(fCTFont));
-    theMetrics.fDescent      = CGToScalar( CTFontGetDescent(fCTFont));
-    theMetrics.fBottom       = CGToScalar(-CGRectGetMinY_inline(theBounds));
-    theMetrics.fLeading      = CGToScalar( CTFontGetLeading(fCTFont));
-    theMetrics.fAvgCharWidth = CGToScalar( CGRectGetWidth_inline(theBounds));
-    theMetrics.fXMin         = CGToScalar( CGRectGetMinX_inline(theBounds));
-    theMetrics.fXMax         = CGToScalar( CGRectGetMaxX_inline(theBounds));
-    theMetrics.fXHeight      = CGToScalar( CTFontGetXHeight(fCTFont));
-    theMetrics.fUnderlineThickness = CGToScalar( CTFontGetUnderlineThickness(fCTFont));
-    theMetrics.fUnderlinePosition = -CGToScalar( CTFontGetUnderlinePosition(fCTFont));
+    CGRect theBounds = CTFontGetBoundingBox(fCTFont);
 
-    theMetrics.fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
-    theMetrics.fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
+    metrics->fTop          = CGToScalar(-CGRectGetMaxY_inline(theBounds));
+    metrics->fAscent       = CGToScalar(-CTFontGetAscent(fCTFont));
+    metrics->fDescent      = CGToScalar( CTFontGetDescent(fCTFont));
+    metrics->fBottom       = CGToScalar(-CGRectGetMinY_inline(theBounds));
+    metrics->fLeading      = CGToScalar( CTFontGetLeading(fCTFont));
+    metrics->fAvgCharWidth = CGToScalar( CGRectGetWidth_inline(theBounds));
+    metrics->fXMin         = CGToScalar( CGRectGetMinX_inline(theBounds));
+    metrics->fXMax         = CGToScalar( CGRectGetMaxX_inline(theBounds));
+    metrics->fXHeight      = CGToScalar( CTFontGetXHeight(fCTFont));
+    metrics->fUnderlineThickness = CGToScalar( CTFontGetUnderlineThickness(fCTFont));
+    metrics->fUnderlinePosition = -CGToScalar( CTFontGetUnderlinePosition(fCTFont));
 
-    if (mx != NULL) {
-        *mx = theMetrics;
-    }
-    if (my != NULL) {
-        *my = theMetrics;
-    }
+    metrics->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
+    metrics->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
 }
 
 void SkScalerContext_Mac::CTPathElement(void *info, const CGPathElement *element) {
@@ -1438,7 +1432,7 @@ static SkTypeface* create_from_dataProvider(CGDataProviderRef provider) {
         return NULL;
     }
     CTFontRef ct = CTFontCreateWithGraphicsFont(cg, 0, NULL, NULL);
-    return cg ? SkCreateTypefaceFromCTFont(ct) : NULL;
+    return ct ? NewFromFontRef(ct, NULL, true) : NULL;
 }
 
 // Web fonts added to the the CTFont registry do not return their character set.
@@ -1517,7 +1511,7 @@ static bool getWidthAdvance(CTFontRef ctFont, int gId, int16_t* data) {
     return true;
 }
 
-// we might move this into our CGUtils...
+/** Assumes src and dst are not NULL. */
 static void CFStringToSkString(CFStringRef src, SkString* dst) {
     // Reserve enough room for the worst-case string,
     // plus 1 byte for the trailing null.
@@ -1541,7 +1535,9 @@ SkAdvancedTypefaceMetrics* SkTypeface_Mac::onGetAdvancedTypefaceMetrics(
 
     {
         AutoCFRelease<CFStringRef> fontName(CTFontCopyPostScriptName(ctFont));
-        CFStringToSkString(fontName, &info->fFontName);
+        if (fontName.get()) {
+            CFStringToSkString(fontName, &info->fFontName);
+        }
     }
 
     CFIndex glyphCount = CTFontGetGlyphCount(ctFont);
@@ -1896,6 +1892,9 @@ void SkTypeface_Mac::onFilterRec(SkScalerContextRec* rec) const {
 
 // we take ownership of the ref
 static const char* get_str(CFStringRef ref, SkString* str) {
+    if (NULL == ref) {
+        return NULL;
+    }
     CFStringToSkString(ref, str);
     CFSafeRelease(ref);
     return str->c_str();
@@ -1908,8 +1907,7 @@ void SkTypeface_Mac::onGetFontDescriptor(SkFontDescriptor* desc,
     desc->setFamilyName(get_str(CTFontCopyFamilyName(fFontRef), &tmpStr));
     desc->setFullName(get_str(CTFontCopyFullName(fFontRef), &tmpStr));
     desc->setPostscriptName(get_str(CTFontCopyPostScriptName(fFontRef), &tmpStr));
-    // TODO: need to add support for local-streams (here and openStream)
-    *isLocalStream = false;
+    *isLocalStream = fIsLocalStream;
 }
 
 int SkTypeface_Mac::onCharsToGlyphs(const void* chars, Encoding encoding,
@@ -2128,7 +2126,7 @@ static SkTypeface* createFromDesc(CFStringRef cfFamilyName,
     SkFontID fontID = CTFontRef_to_SkFontID(ctFont);
 
     face = SkNEW_ARGS(SkTypeface_Mac, (rec.fFontStyle, fontID, isFixedPitch,
-                                       ctFont, str.c_str()));
+                                       ctFont, str.c_str(), false));
     SkTypefaceCache::Add(face, face->style());
     return face;
 }