Merge changes from the android repo upstream to Skia
authordjsollen@google.com <djsollen@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 15 Feb 2012 18:49:15 +0000 (18:49 +0000)
committerdjsollen@google.com <djsollen@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 15 Feb 2012 18:49:15 +0000 (18:49 +0000)
Review URL: https://codereview.appspot.com/5545070

git-svn-id: http://skia.googlecode.com/svn/trunk@3199 2bbb7eff-a529-9590-31e7-b0007b416f81

15 files changed:
gyp/effects.gyp
gyp/ports.gyp
include/core/SkImageFilter.h
include/core/SkPaint.h
include/core/SkPreConfig.h
include/core/SkScalerContext.h
src/core/SkCanvas.cpp
src/core/SkGlyphCache.h
src/core/SkPaint.cpp
src/core/SkScalerContext.cpp
src/gpu/GrTesselatedPathRenderer.cpp
src/opts/SkBlitRow_opts_arm.cpp
src/ports/SkFontHost_android.cpp
src/ports/SkImageRef_ashmem.cpp
src/utils/SkNinePatch.cpp

index 2d716e3..28f0017 100644 (file)
@@ -37,6 +37,7 @@
         '../include/effects/SkPorterDuff.h',
         '../include/effects/SkRectShape.h',
         '../include/effects/SkTableColorFilter.h',
+        '../include/effects/SkTableMaskFilter.h',
         '../include/effects/SkTransparentShader.h',
 
         '../src/effects/Sk1DPathEffect.cpp',
@@ -71,6 +72,7 @@
         '../src/effects/SkRadialGradient_Table.h',
         '../src/effects/SkRectShape.cpp',
         '../src/effects/SkTableColorFilter.cpp',
+        '../src/effects/SkTableMaskFilter.cpp',
         '../src/effects/SkTestImageFilters.cpp',
         '../src/effects/SkTransparentShader.cpp',
       ],
index 5d697e5..c89a06d 100644 (file)
@@ -90,6 +90,7 @@
             '../src/ports/SkFontHost_gamma.cpp',
             '../src/ports/SkFontHost_FreeType.cpp',
             '../src/ports/FontHostConfiguration_android.cpp',
+            #TODO: include the ports/SkImageRef_ashmem.cpp for non-NDK builds
           ],
           'dependencies': [
              'android_system.gyp:ft2',
index 1bb723f..22b9569 100644 (file)
@@ -47,6 +47,7 @@ public:
         virtual bool filterImage(SkImageFilter*, const SkBitmap& src,
                                  const SkMatrix& ctm,
                                  SkBitmap* result, SkIPoint* offset) = 0;
+        virtual ~Proxy() {};
     };
 
     /**
index e4717af..31bc30b 100644 (file)
@@ -849,9 +849,14 @@ public:
 
 #ifdef SK_BUILD_FOR_ANDROID
     const SkGlyph& getUnicharMetrics(SkUnichar);
+    const SkGlyph& getGlyphMetrics(uint16_t);
     const void* findImage(const SkGlyph&);
 
     uint32_t getGenerationID() const;
+
+    /** Returns the base glyph count for the strike associated with this paint
+    */
+    unsigned getBaseGlyphCount(SkUnichar text) const;
 #endif
 
     // returns true if the paint's settings (e.g. xfermode + alpha) resolve to
index 0ddbbb8..4485f1d 100644 (file)
         #define SK_BUILD_FOR_WIN32
     #elif defined(__SYMBIAN32__)
         #define SK_BUILD_FOR_WIN32
+    #elif defined(ANDROID_NDK)
+        #define SK_BUILD_FOR_ANDROID_NDK
+    #elif defined(ANDROID)
+        #define SK_BUILD_FOR_ANDROID
     #elif defined(linux) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
           defined(__sun) || defined(__NetBSD__) || defined(__DragonFly__)
         #define SK_BUILD_FOR_UNIX
     #elif TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
         #define SK_BUILD_FOR_IOS
-    #elif defined(ANDROID_NDK)
-        #define SK_BUILD_FOR_ANDROID_NDK
-    #elif defined(ANDROID)
-        #define SK_BUILD_FOR_ANDROID
     #else
         #define SK_BUILD_FOR_MAC
     #endif
index 43baedf..e4a28b9 100644 (file)
@@ -298,6 +298,10 @@ public:
     void        getFontMetrics(SkPaint::FontMetrics* mX,
                                SkPaint::FontMetrics* mY);
 
+#ifdef SK_BUILD_FOR_ANDROID
+    unsigned getBaseGlyphCount(SkUnichar charCode);
+#endif
+
     static inline void MakeRec(const SkPaint&, const SkMatrix*, Rec* rec);
     static SkScalerContext* Create(const SkDescriptor*);
 
index 14ab405..034486d 100644 (file)
@@ -1517,7 +1517,12 @@ void SkCanvas::internalDrawBitmapNine(const SkBitmap& bitmap,
                                       const SkIRect& center, const SkRect& dst,
                                       const SkPaint* paint) {
     if (NULL == paint || paint->canComputeFastBounds()) {
-        if (this->quickReject(dst, paint2EdgeType(paint))) {
+        SkRect storage;
+        const SkRect* bounds = &dst;
+        if (paint) {
+            bounds = &paint->computeFastBounds(dst, &storage);
+        }
+        if (this->quickReject(*bounds, paint2EdgeType(paint))) {
             return;
         }
     }
index 090a73f..2895c54 100644 (file)
@@ -73,6 +73,14 @@ public:
     */
     unsigned getGlyphCount();
 
+#ifdef SK_BUILD_FOR_ANDROID
+    /** Returns the base glyph count for this strike.
+    */
+    unsigned getBaseGlyphCount(SkUnichar charCode) const {
+        return fScalerContext->getBaseGlyphCount(charCode);
+    }
+#endif
+
     /** Return the image associated with the glyph. If it has not been generated
         this will trigger that.
     */
index 3b9714e..0578f3c 100644 (file)
@@ -22,6 +22,7 @@
 #include "SkTypeface.h"
 #include "SkXfermode.h"
 #include "SkAutoKern.h"
+#include "SkGlyphCache.h"
 
 // define this to get a printf for out-of-range parameter in setters
 // e.g. setTextSize(-1)
@@ -162,6 +163,14 @@ uint32_t SkPaint::getGenerationID() const {
 }
 #endif
 
+#ifdef SK_BUILD_FOR_ANDROID
+unsigned SkPaint::getBaseGlyphCount(SkUnichar text) const {
+    SkAutoGlyphCache autoCache(*this, NULL);
+    SkGlyphCache* cache = autoCache.getCache();
+    return cache->getBaseGlyphCount(text);
+}
+#endif
+
 void SkPaint::setHinting(Hinting hintingLevel) {
     GEN_ID_INC_EVAL((unsigned) hintingLevel != fHinting);
     fHinting = hintingLevel;
@@ -397,6 +406,16 @@ const SkGlyph& SkPaint::getUnicharMetrics(SkUnichar text) {
     return glyph;
 }
 
+const SkGlyph& SkPaint::getGlyphMetrics(uint16_t glyphId) {
+    SkGlyphCache* cache;
+    descriptorProc(NULL, DetachDescProc, &cache, true);
+
+    const SkGlyph& glyph = cache->getGlyphIDMetrics(glyphId);
+
+    SkGlyphCache::AttachCache(cache);
+    return glyph;
+}
+
 const void* SkPaint::findImage(const SkGlyph& glyph) {
     // See ::detachCache()
     SkGlyphCache* cache;
index 4403da6..2921b1e 100644 (file)
@@ -175,6 +175,32 @@ SkScalerContext* SkScalerContext::getGlyphContext(const SkGlyph& glyph) {
     return ctx;
 }
 
+#ifdef SK_BUILD_FOR_ANDROID
+/*  This loops through all available fallback contexts (if needed) until it
+    finds some context that can handle the unichar and return it.
+
+    As this is somewhat expensive operation, it should only be done on the first
+    char of a run.
+ */
+unsigned SkScalerContext::getBaseGlyphCount(SkUnichar uni) {
+    SkScalerContext* ctx = this;
+    unsigned glyphID;
+    for (;;) {
+        glyphID = ctx->generateCharToGlyph(uni);
+        if (glyphID) {
+            break;  // found it
+        }
+        ctx = ctx->getNextContext();
+        if (NULL == ctx) {
+            SkDebugf("--- no context for char %x\n", uni);
+            // just return the original context (this)
+            return this->fBaseGlyphCount;
+        }
+    }
+    return ctx->fBaseGlyphCount;
+}
+#endif
+
 /*  This loops through all available fallback contexts (if needed) until it
     finds some context that can handle the unichar. If all fail, returns 0
  */
index f7fd8e4..f6fcdef 100644 (file)
@@ -61,7 +61,7 @@ public:
         Sk_gluTessCallback(fTess, GLU_TESS_COMBINE_DATA, (TESSCB) &combineCB);
         fInVertices = new double[count * 3];
     }
-    ~GrTess() {
+    virtual ~GrTess() {
         Sk_gluDeleteTess(fTess);
         delete[] fInVertices;
     }
index 761bf74..20a82c8 100644 (file)
@@ -988,7 +988,7 @@ static void S32A_D565_Opaque_Dither_neon (uint16_t * SK_RESTRICT dst,
 
            /* calculate 'd', which will be 0..7 */
            /* dbase[] is 0..7; alpha is 0..256; 16 bits suffice */
-#if SK_BUILD_FOR_ANDROID
+#if defined(SK_BUILD_FOR_ANDROID)
            /* SkAlpha255To256() semantic a+1 vs a+a>>7 */
            alpha8 = vaddw_u8(vmovl_u8(sa), vdup_n_u8(1));
 #else
index a3bd79c..9a6d633 100644 (file)
@@ -1,4 +1,4 @@
-/*
+/* libs/graphics/ports/SkFontHost_android.cpp
 **
 ** Copyright 2006, The Android Open Source Project
 **
@@ -26,6 +26,8 @@
 #include "FontHostConfiguration_android.h"
 #include <stdio.h>
 
+#define FONT_CACHE_MEMORY_BUDGET    (768 * 1024)
+
 #ifndef SK_FONT_FILE_PREFIX
     #define SK_FONT_FILE_PREFIX          "/fonts/"
 #endif
@@ -179,7 +181,7 @@ static void detach_and_delete_family(FamilyRec* family) {
         prev = curr;
         curr = next;
     }
-    SkDEBUGFAIL("Yikes, couldn't find family in our list to remove/delete");
+    SkASSERT(!"Yikes, couldn't find family in our list to remove/delete");
 }
 
 static SkTypeface* find_typeface(const char name[], SkTypeface::Style style) {
@@ -462,9 +464,11 @@ static void load_font_info() {
         // shouldn't get here
         gNumSystemFonts = 0;
     }
+//    SkDebugf("---- We have %d system fonts", gNumSystemFonts);
     for (size_t i = 0; i < gNumSystemFonts; ++i) {
         gSystemFonts[i].fFileName = fontInfo[i].fFileName;
         gSystemFonts[i].fNames = fontInfo[i].fNames;
+//        SkDebugf("---- gSystemFonts[%d] fileName=%s", i, fontInfo[i].fFileName);
     }
     fontFamilies.deleteAll();
 }
@@ -509,11 +513,13 @@ static void load_system_fonts() {
                                      isFixedWidth) // filename
                                     );
 
+//        SkDebugf("---- SkTypeface[%d] %s fontID %d\n", i, rec[i].fFileName, tf->uniqueID());
+
         if (rec[i].fNames != NULL) {
             // see if this is one of our fallback fonts
             if (rec[i].fNames == gFBNames) {
-            //    SkDebugf("---- adding %s as fallback[%d] fontID %d\n",
-            //             rec[i].fFileName, fallbackCount, tf->uniqueID());
+//                SkDebugf("---- adding %s as fallback[%d] fontID %d\n",
+//                         rec[i].fFileName, fallbackCount, tf->uniqueID());
                 gFallbackFonts[fallbackCount++] = tf->uniqueID();
             }
 
@@ -760,4 +766,3 @@ SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
     stream->unref();
     return face;
 }
-
index 8c69b38..f9c6aff 100644 (file)
@@ -91,15 +91,17 @@ public:
             
             int err = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
             if (err) {
-                SkDebugf("------ ashmem_set_prot_region(%d) failed %d %d\n",
-                         fd, err, errno);
+                SkDebugf("------ ashmem_set_prot_region(%d) failed %d\n",
+                         fd, err);
+                close(fd);
                 return false;
             }
             
             addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
             if (-1 == (long)addr) {
-                SkDebugf("---------- mmap failed for imageref_ashmem size=%d err=%d\n",
-                         size, errno);
+                SkDebugf("---------- mmap failed for imageref_ashmem size=%d\n",
+                         size);
+                close(fd);
                 return false;
             }
             
@@ -178,8 +180,7 @@ void* SkImageRef_ashmem::onLockPixels(SkColorTable** ct) {
             SkDebugf("===== ashmem purged %d\n", fBitmap.getSize());
 #endif
         } else {
-            SkDebugf("===== ashmem pin_region(%d) returned %d, treating as error %d\n",
-                     fRec.fFD, pin, errno);
+            SkDebugf("===== ashmem pin_region(%d) returned %d\n", fRec.fFD, pin);
             // return null result for failure
             if (ct) {
                 *ct = NULL;
index 9729a13..26ae8eb 100644 (file)
@@ -46,6 +46,31 @@ static int fillIndices(uint16_t indices[], int xCount, int yCount) {
     return indices - startIndices;
 }
 
+// Computes the delta between vertices along a single axis
+static SkScalar computeVertexDelta(bool isStretchyVertex,
+                                   SkScalar currentVertex,
+                                   SkScalar prevVertex,
+                                   SkScalar stretchFactor) {
+    // the standard delta between vertices if no stretching is required
+    SkScalar delta = currentVertex - prevVertex;
+
+    // if the stretch factor is negative or zero we need to shrink the 9-patch
+    // to fit within the target bounds.  This means that we will eliminate all
+    // stretchy areas and scale the fixed areas to fit within the target bounds.
+    if (stretchFactor <= 0) {
+        if (isStretchyVertex)
+            delta = 0; // collapse stretchable areas
+        else
+            delta = SkScalarMul(delta, -stretchFactor); // scale fixed areas
+    // if the stretch factor is positive then we use the standard delta for
+    // fixed and scale the stretchable areas to fill the target bounds.
+    } else if (isStretchyVertex) {
+        delta = SkScalarMul(delta, stretchFactor);
+    }
+
+    return delta;
+}
+
 static void fillRow(SkPoint verts[], SkPoint texs[],
                     const SkScalar vy, const SkScalar ty,
                     const SkRect& bounds, const int32_t xDivs[], int numXDivs,
@@ -53,21 +78,14 @@ static void fillRow(SkPoint verts[], SkPoint texs[],
     SkScalar vx = bounds.fLeft;
     verts->set(vx, vy); verts++;
     texs->set(0, ty); texs++;
+
+    SkScalar prev = 0;
     for (int x = 0; x < numXDivs; x++) {
-        SkScalar tx = SkIntToScalar(xDivs[x]);
-        if (stretchX >= 0) {
-            if (x & 1) {
-                vx += stretchX;
-            } else {
-                vx += tx;
-            }
-        } else {
-            if (x & 1) {
-                ; // do nothing
-            } else {
-                vx += SkScalarMul(tx, -stretchX);
-            }
-        }
+
+        const SkScalar tx = SkIntToScalar(xDivs[x]);
+        vx += computeVertexDelta(x & 1, tx, prev, stretchX);
+        prev = tx;
+
         verts->set(vx, vy); verts++;
         texs->set(tx, ty); texs++;
     }
@@ -139,12 +157,11 @@ void SkNinePatch::DrawMesh(SkCanvas* canvas, const SkRect& bounds,
         for (int i = 1; i < numXDivs; i += 2) {
             stretchSize += xDivs[i] - xDivs[i-1];
         }
-        int fixed = bitmap.width() - stretchSize;
-        stretchX = (bounds.width() - SkIntToScalar(fixed)) / numXStretch;
-        if (stretchX < 0) {
-            // reuse stretchX, but keep it negative as a signal
-            stretchX = -SkIntToScalar(bitmap.width()) / fixed;
-        }
+        const SkScalar fixed = SkIntToScalar(bitmap.width() - stretchSize);
+        if (bounds.width() >= fixed)
+            stretchX = (bounds.width() - fixed) / stretchSize;
+        else // reuse stretchX, but keep it negative as a signal
+            stretchX = SkScalarDiv(-bounds.width(), fixed);
     }
     
     if (numYStretch > 0) {
@@ -152,12 +169,11 @@ void SkNinePatch::DrawMesh(SkCanvas* canvas, const SkRect& bounds,
         for (int i = 1; i < numYDivs; i += 2) {
             stretchSize += yDivs[i] - yDivs[i-1];
         }
-        int fixed = bitmap.height() - stretchSize;
-        stretchY = (bounds.height() - SkIntToScalar(fixed)) / numYStretch;
-        if (stretchY < 0) {
-            // reuse stretchY, but keep it negative as a signal
-            stretchY = -SkIntToScalar(bitmap.height()) / fixed;
-        }
+        const SkScalar fixed = SkIntToScalar(bitmap.height() - stretchSize);
+        if (bounds.height() >= fixed)
+            stretchY = (bounds.height() - fixed) / stretchSize;
+        else // reuse stretchX, but keep it negative as a signal
+            stretchY = SkScalarDiv(-bounds.height(), fixed);
     }
     
 #if 0