Index: src/core/SkLatticeIter.cpp |
diff --git a/src/core/SkLatticeIter.cpp b/src/core/SkLatticeIter.cpp |
index 38ef2828bdfc34a4c96ebd04e50c73fd4690d968..4fe9352d0a5e055a978605d50e0701938d2bb78e 100644 |
--- a/src/core/SkLatticeIter.cpp |
+++ b/src/core/SkLatticeIter.cpp |
@@ -11,10 +11,10 @@ |
/** |
* Divs must be in increasing order with no duplicates. |
*/ |
-static bool valid_divs(const int* divs, int count, int len) { |
- int prev = -1; |
+static bool valid_divs(const int* divs, int count, int start, int end) { |
+ int prev = start - 1; |
for (int i = 0; i < count; i++) { |
- if (prev >= divs[i] || divs[i] >= len) { |
+ if (prev >= divs[i] || divs[i] >= end) { |
return false; |
} |
} |
@@ -23,29 +23,38 @@ static bool valid_divs(const int* divs, int count, int len) { |
} |
bool SkLatticeIter::Valid(int width, int height, const SkCanvas::Lattice& lattice) { |
- bool zeroXDivs = lattice.fXCount <= 0 || (1 == lattice.fXCount && 0 == lattice.fXDivs[0]); |
- bool zeroYDivs = lattice.fYCount <= 0 || (1 == lattice.fYCount && 0 == lattice.fYDivs[0]); |
+ SkIRect totalBounds = SkIRect::MakeWH(width, height); |
+ SkASSERT(lattice.fBounds); |
+ const SkIRect latticeBounds = *lattice.fBounds; |
+ if (!totalBounds.contains(latticeBounds)) { |
+ return false; |
+ } |
+ |
+ bool zeroXDivs = lattice.fXCount <= 0 || (1 == lattice.fXCount && |
+ latticeBounds.fLeft == lattice.fXDivs[0]); |
+ bool zeroYDivs = lattice.fYCount <= 0 || (1 == lattice.fYCount && |
+ latticeBounds.fTop == lattice.fYDivs[0]); |
if (zeroXDivs && zeroYDivs) { |
return false; |
} |
- return valid_divs(lattice.fXDivs, lattice.fXCount, width) && |
- valid_divs(lattice.fYDivs, lattice.fYCount, height); |
+ return valid_divs(lattice.fXDivs, lattice.fXCount, latticeBounds.fLeft, latticeBounds.fRight) |
+ && valid_divs(lattice.fYDivs, lattice.fYCount, latticeBounds.fTop, latticeBounds.fBottom); |
} |
/** |
* Count the number of pixels that are in "scalable" patches. |
*/ |
static int count_scalable_pixels(const int32_t* divs, int numDivs, bool firstIsScalable, |
- int length) { |
+ int start, int end) { |
if (0 == numDivs) { |
- return firstIsScalable ? length : 0; |
+ return firstIsScalable ? end - start : 0; |
} |
int i; |
int count; |
if (firstIsScalable) { |
- count = divs[0]; |
+ count = divs[0] - start; |
i = 1; |
} else { |
count = 0; |
@@ -56,7 +65,7 @@ static int count_scalable_pixels(const int32_t* divs, int numDivs, bool firstIsS |
// Alternatively, we could use |top| and |bottom| as variable names, instead of |
// |left| and |right|. |
int left = divs[i]; |
- int right = (i + 1 < numDivs) ? divs[i + 1] : length; |
+ int right = (i + 1 < numDivs) ? divs[i + 1] : end; |
count += right - left; |
} |
@@ -67,10 +76,10 @@ static int count_scalable_pixels(const int32_t* divs, int numDivs, bool firstIsS |
* Set points for the src and dst rects on subsequent draw calls. |
*/ |
static void set_points(float* dst, float* src, const int* divs, int divCount, int srcFixed, |
- int srcScalable, float dstStart, float dstStop, bool isScalable) { |
+ int srcScalable, float srcStart, float srcEnd, float dstStart, float dstEnd, |
+ bool isScalable) { |
- float dstLen = dstStop - dstStart; |
- int srcLen = srcFixed + srcScalable; |
+ float dstLen = dstEnd - dstStart; |
float scale; |
if (srcFixed <= dstLen) { |
// This is the "normal" case, where we scale the "scalable" patches and leave |
@@ -81,7 +90,7 @@ static void set_points(float* dst, float* src, const int* divs, int divCount, in |
scale = dstLen / ((float) srcFixed); |
} |
- src[0] = 0.0f; |
+ src[0] = srcStart; |
dst[0] = dstStart; |
for (int i = 0; i < divCount; i++) { |
src[i + 1] = (float) (divs[i]); |
@@ -98,17 +107,17 @@ static void set_points(float* dst, float* src, const int* divs, int divCount, in |
isScalable = !isScalable; |
} |
- src[divCount + 1] = (float) srcLen; |
- dst[divCount + 1] = dstStop; |
+ src[divCount + 1] = srcEnd; |
+ dst[divCount + 1] = dstEnd; |
} |
-SkLatticeIter::SkLatticeIter(int srcWidth, int srcHeight, const SkCanvas::Lattice& lattice, |
- const SkRect& dst) |
-{ |
+SkLatticeIter::SkLatticeIter(const SkCanvas::Lattice& lattice, const SkRect& dst) { |
const int* xDivs = lattice.fXDivs; |
const int origXCount = lattice.fXCount; |
const int* yDivs = lattice.fYDivs; |
const int origYCount = lattice.fYCount; |
+ SkASSERT(lattice.fBounds); |
+ const SkIRect src = *lattice.fBounds; |
// In the x-dimension, the first rectangle always starts at x = 0 and is "scalable". |
// If xDiv[0] is 0, it indicates that the first rectangle is degenerate, so the |
@@ -121,36 +130,36 @@ SkLatticeIter::SkLatticeIter(int srcWidth, int srcHeight, const SkCanvas::Lattic |
// patches will be "fixed" or "scalable" in the y-direction. |
int xCount = origXCount; |
int yCount = origYCount; |
- bool xIsScalable = (xCount > 0 && 0 == xDivs[0]); |
+ bool xIsScalable = (xCount > 0 && src.fLeft == xDivs[0]); |
if (xIsScalable) { |
// Once we've decided that the first patch is "scalable", we don't need the |
- // xDiv. It is always implied that we start at zero. |
+ // xDiv. It is always implied that we start at the edge of the bounds. |
xDivs++; |
xCount--; |
} |
- bool yIsScalable = (yCount > 0 && 0 == yDivs[0]); |
+ bool yIsScalable = (yCount > 0 && src.fTop == yDivs[0]); |
if (yIsScalable) { |
// Once we've decided that the first patch is "scalable", we don't need the |
- // yDiv. It is always implied that we start at zero. |
+ // yDiv. It is always implied that we start at the edge of the bounds. |
yDivs++; |
yCount--; |
} |
// Count "scalable" and "fixed" pixels in each dimension. |
- int xCountScalable = count_scalable_pixels(xDivs, xCount, xIsScalable, srcWidth); |
- int xCountFixed = srcWidth - xCountScalable; |
- int yCountScalable = count_scalable_pixels(yDivs, yCount, yIsScalable, srcHeight); |
- int yCountFixed = srcHeight - yCountScalable; |
+ int xCountScalable = count_scalable_pixels(xDivs, xCount, xIsScalable, src.fLeft, src.fRight); |
+ int xCountFixed = src.width() - xCountScalable; |
+ int yCountScalable = count_scalable_pixels(yDivs, yCount, yIsScalable, src.fTop, src.fBottom); |
+ int yCountFixed = src.height() - yCountScalable; |
fSrcX.reset(xCount + 2); |
fDstX.reset(xCount + 2); |
set_points(fDstX.begin(), fSrcX.begin(), xDivs, xCount, xCountFixed, xCountScalable, |
- dst.fLeft, dst.fRight, xIsScalable); |
+ src.fLeft, src.fRight, dst.fLeft, dst.fRight, xIsScalable); |
fSrcY.reset(yCount + 2); |
fDstY.reset(yCount + 2); |
set_points(fDstY.begin(), fSrcY.begin(), yDivs, yCount, yCountFixed, yCountScalable, |
- dst.fTop, dst.fBottom, yIsScalable); |
+ src.fTop, src.fBottom, dst.fTop, dst.fBottom, yIsScalable); |
fCurrX = fCurrY = 0; |
fNumRectsInLattice = (xCount + 1) * (yCount + 1); |