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
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 @@
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 @@
*/
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 @@
}
#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 @@
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 @@
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 @@
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 @@
/* 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 <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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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