Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / core / SkGlyphCache.cpp
old mode 100644 (file)
new mode 100755 (executable)
index faa3f89..cb7c1b0
@@ -9,7 +9,9 @@
 
 #include "SkGlyphCache.h"
 #include "SkGlyphCache_Globals.h"
+#include "SkDistanceFieldGen.h"
 #include "SkGraphics.h"
+#include "SkOnce.h"
 #include "SkPaint.h"
 #include "SkPath.h"
 #include "SkTemplates.h"
 
 bool gSkSuppressFontCachePurgeSpew;
 
+static void create_globals(SkGlyphCache_Globals** globals) {
+    *globals = SkNEW_ARGS(SkGlyphCache_Globals, (SkGlyphCache_Globals::kYes_UseMutex));
+}
+
 // Returns the shared globals
 static SkGlyphCache_Globals& getSharedGlobals() {
     // we leak this, so we don't incur any shutdown cost of the destructor
-    static SkGlyphCache_Globals* gGlobals = SkNEW_ARGS(SkGlyphCache_Globals,
-                                                       (SkGlyphCache_Globals::kYes_UseMutex));
+    static SkGlyphCache_Globals* gGlobals = NULL;
+    SK_DECLARE_STATIC_ONCE(once);
+    SkOnce(&once, create_globals, &gGlobals);
+    SkASSERT(NULL != gGlobals);
     return *gGlobals;
 }
 
@@ -87,8 +95,6 @@ SkGlyphCache::SkGlyphCache(SkTypeface* typeface, const SkDescriptor* desc, SkSca
 
     fGlyphArray.setReserve(kMinGlyphCount);
 
-    fMetricsCount = 0;
-    fAdvanceCount = 0;
     fAuxProcList = NULL;
 }
 
@@ -320,11 +326,9 @@ SkGlyph* SkGlyphCache::lookupMetrics(uint32_t id, MetricsType mtype) {
 
     if (kJustAdvance_MetricsType == mtype) {
         fScalerContext->getAdvance(glyph);
-        fAdvanceCount += 1;
     } else {
         SkASSERT(kFull_MetricsType == mtype);
         fScalerContext->getMetrics(glyph);
-        fMetricsCount += 1;
     }
 
     return glyph;
@@ -332,12 +336,12 @@ SkGlyph* SkGlyphCache::lookupMetrics(uint32_t id, MetricsType mtype) {
 
 const void* SkGlyphCache::findImage(const SkGlyph& glyph) {
     if (glyph.fWidth > 0 && glyph.fWidth < kMaxGlyphWidth) {
-        if (glyph.fImage == NULL) {
+        if (NULL == glyph.fImage) {
             size_t  size = glyph.computeImageSize();
             const_cast<SkGlyph&>(glyph).fImage = fGlyphAlloc.alloc(size,
                                         SkChunkAlloc::kReturnNil_AllocFailType);
             // check that alloc() actually succeeded
-            if (glyph.fImage) {
+            if (NULL != glyph.fImage) {
                 fScalerContext->getImage(glyph);
                 // TODO: the scaler may have changed the maskformat during
                 // getImage (e.g. from AA or LCD to BW) which means we may have
@@ -362,6 +366,45 @@ const SkPath* SkGlyphCache::findPath(const SkGlyph& glyph) {
     return glyph.fPath;
 }
 
+const void* SkGlyphCache::findDistanceField(const SkGlyph& glyph) {
+    if (glyph.fWidth > 0 && glyph.fWidth < kMaxGlyphWidth) {
+        if (NULL == glyph.fDistanceField) {
+            size_t  size = SkComputeDistanceFieldSize(glyph.fWidth, glyph.fHeight);
+            if (size == 0) {
+                return NULL;
+            }
+            const void* image = this->findImage(glyph);
+            // now generate the distance field
+            if (NULL != image) {
+                const_cast<SkGlyph&>(glyph).fDistanceField = fGlyphAlloc.alloc(size,
+                                            SkChunkAlloc::kReturnNil_AllocFailType);
+                if (NULL != glyph.fDistanceField) {
+                    SkMask::Format maskFormat = static_cast<SkMask::Format>(glyph.fMaskFormat);
+                    if (SkMask::kA8_Format == maskFormat) {
+                        // make the distance field from the image
+                        SkGenerateDistanceFieldFromA8Image((unsigned char*)glyph.fDistanceField,
+                                                           (unsigned char*)glyph.fImage,
+                                                           glyph.fWidth, glyph.fHeight,
+                                                           glyph.rowBytes());
+                        fMemoryUsed += size;
+                    } else if (SkMask::kBW_Format == maskFormat) {
+                        // make the distance field from the image
+                        SkGenerateDistanceFieldFromBWImage((unsigned char*)glyph.fDistanceField,
+                                                           (unsigned char*)glyph.fImage,
+                                                           glyph.fWidth, glyph.fHeight,
+                                                           glyph.rowBytes());
+                        fMemoryUsed += size;
+                    } else {
+                        fGlyphAlloc.unalloc(glyph.fDistanceField);
+                        const_cast<SkGlyph&>(glyph).fDistanceField = NULL;
+                    }
+                }
+            }
+        }
+    }
+    return glyph.fDistanceField;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 bool SkGlyphCache::getAuxProcData(void (*proc)(void*), void** dataPtr) const {
@@ -564,10 +607,10 @@ size_t SkGlyphCache_Globals::internalPurge(size_t minBytesNeeded) {
     if (fTotalMemoryUsed > fCacheSizeLimit) {
         bytesNeeded = fTotalMemoryUsed - fCacheSizeLimit;
     }
-    bytesNeeded = SkMax32(bytesNeeded, minBytesNeeded);
+    bytesNeeded = SkTMax(bytesNeeded, minBytesNeeded);
     if (bytesNeeded) {
         // no small purges!
-        bytesNeeded = SkMax32(bytesNeeded, fTotalMemoryUsed >> 2);
+        bytesNeeded = SkTMax(bytesNeeded, fTotalMemoryUsed >> 2);
     }
 
     int countNeeded = 0;
@@ -653,6 +696,9 @@ void SkGlyphCache::validate() const {
         if (glyph->fImage) {
             SkASSERT(fGlyphAlloc.contains(glyph->fImage));
         }
+        if (glyph->fDistanceField) {
+            SkASSERT(fGlyphAlloc.contains(glyph->fDistanceField));
+        }
     }
 #endif
 }