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/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