From 60abb078e5597c9c6ceaba1ef495c4916ff4df0d Mon Sep 17 00:00:00 2001 From: "djsollen@google.com" Date: Wed, 15 Feb 2012 18:49:15 +0000 Subject: [PATCH] Merge changes from the android repo upstream to Skia Review URL: https://codereview.appspot.com/5545070 git-svn-id: http://skia.googlecode.com/svn/trunk@3199 2bbb7eff-a529-9590-31e7-b0007b416f81 --- gyp/effects.gyp | 2 ++ gyp/ports.gyp | 1 + include/core/SkImageFilter.h | 1 + include/core/SkPaint.h | 5 +++ include/core/SkPreConfig.h | 8 ++--- include/core/SkScalerContext.h | 4 +++ src/core/SkCanvas.cpp | 7 +++- src/core/SkGlyphCache.h | 8 +++++ src/core/SkPaint.cpp | 19 ++++++++++ src/core/SkScalerContext.cpp | 26 ++++++++++++++ src/gpu/GrTesselatedPathRenderer.cpp | 2 +- src/opts/SkBlitRow_opts_arm.cpp | 2 +- src/ports/SkFontHost_android.cpp | 15 +++++--- src/ports/SkImageRef_ashmem.cpp | 13 +++---- src/utils/SkNinePatch.cpp | 68 ++++++++++++++++++++++-------------- 15 files changed, 137 insertions(+), 44 deletions(-) diff --git a/gyp/effects.gyp b/gyp/effects.gyp index 2d716e3..28f0017 100644 --- a/gyp/effects.gyp +++ b/gyp/effects.gyp @@ -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', ], diff --git a/gyp/ports.gyp b/gyp/ports.gyp index 5d697e5..c89a06d 100644 --- a/gyp/ports.gyp +++ b/gyp/ports.gyp @@ -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', diff --git a/include/core/SkImageFilter.h b/include/core/SkImageFilter.h index 1bb723f..22b9569 100644 --- a/include/core/SkImageFilter.h +++ b/include/core/SkImageFilter.h @@ -47,6 +47,7 @@ public: virtual bool filterImage(SkImageFilter*, const SkBitmap& src, const SkMatrix& ctm, SkBitmap* result, SkIPoint* offset) = 0; + virtual ~Proxy() {}; }; /** diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h index e4717af..31bc30b 100644 --- a/include/core/SkPaint.h +++ b/include/core/SkPaint.h @@ -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 diff --git a/include/core/SkPreConfig.h b/include/core/SkPreConfig.h index 0ddbbb8..4485f1d 100644 --- a/include/core/SkPreConfig.h +++ b/include/core/SkPreConfig.h @@ -30,15 +30,15 @@ #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 diff --git a/include/core/SkScalerContext.h b/include/core/SkScalerContext.h index 43baedf..e4a28b9 100644 --- a/include/core/SkScalerContext.h +++ b/include/core/SkScalerContext.h @@ -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*); diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index 14ab405..034486d 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -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; } } diff --git a/src/core/SkGlyphCache.h b/src/core/SkGlyphCache.h index 090a73f..2895c54 100644 --- a/src/core/SkGlyphCache.h +++ b/src/core/SkGlyphCache.h @@ -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. */ diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp index 3b9714e..0578f3c 100644 --- a/src/core/SkPaint.cpp +++ b/src/core/SkPaint.cpp @@ -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; diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp index 4403da6..2921b1e 100644 --- a/src/core/SkScalerContext.cpp +++ b/src/core/SkScalerContext.cpp @@ -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 */ diff --git a/src/gpu/GrTesselatedPathRenderer.cpp b/src/gpu/GrTesselatedPathRenderer.cpp index f7fd8e4..f6fcdef 100644 --- a/src/gpu/GrTesselatedPathRenderer.cpp +++ b/src/gpu/GrTesselatedPathRenderer.cpp @@ -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; } diff --git a/src/opts/SkBlitRow_opts_arm.cpp b/src/opts/SkBlitRow_opts_arm.cpp index 761bf74..20a82c8 100644 --- a/src/opts/SkBlitRow_opts_arm.cpp +++ b/src/opts/SkBlitRow_opts_arm.cpp @@ -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 diff --git a/src/ports/SkFontHost_android.cpp b/src/ports/SkFontHost_android.cpp index a3bd79c..9a6d633 100644 --- a/src/ports/SkFontHost_android.cpp +++ b/src/ports/SkFontHost_android.cpp @@ -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 +#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; } - diff --git a/src/ports/SkImageRef_ashmem.cpp b/src/ports/SkImageRef_ashmem.cpp index 8c69b38..f9c6aff 100644 --- a/src/ports/SkImageRef_ashmem.cpp +++ b/src/ports/SkImageRef_ashmem.cpp @@ -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; diff --git a/src/utils/SkNinePatch.cpp b/src/utils/SkNinePatch.cpp index 9729a13..26ae8eb 100644 --- a/src/utils/SkNinePatch.cpp +++ b/src/utils/SkNinePatch.cpp @@ -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 -- 2.7.4