aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar msarett <msarett@google.com>2016-09-30 12:41:42 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-09-30 12:41:42 -0700
commit71df2d7bc1bbc83ad4cf005f9027df4cb3b88a9b (patch)
tree9113c13e0d2285f1204e0a4bee8d89eb644d16ed /src/core
parent9c8a32ff4507481aadf1a190637ee8d55c8dc217 (diff)
Add a src rect to drawImageLattice() API
This will allow us to draw ninepatches directly from an asset texture without having to upload them individually. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2382893002 Review-Url: https://codereview.chromium.org/2382893002
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkCanvas.cpp24
-rw-r--r--src/core/SkDevice.cpp4
-rw-r--r--src/core/SkLatticeIter.cpp69
-rw-r--r--src/core/SkLatticeIter.h3
-rw-r--r--src/core/SkLiteDL.cpp16
-rw-r--r--src/core/SkPicturePlayback.cpp3
-rw-r--r--src/core/SkPictureRecord.cpp4
-rw-r--r--src/core/SkRecordDraw.cpp1
-rw-r--r--src/core/SkRecorder.cpp3
9 files changed, 81 insertions, 46 deletions
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 6a0d5e6da6..7597c7a07a 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -1999,8 +1999,16 @@ void SkCanvas::drawImageLattice(const SkImage* image, const Lattice& lattice, co
if (dst.isEmpty()) {
return;
}
- if (SkLatticeIter::Valid(image->width(), image->height(), lattice)) {
- this->onDrawImageLattice(image, lattice, dst, paint);
+
+ SkIRect bounds;
+ Lattice latticePlusBounds = lattice;
+ if (!latticePlusBounds.fBounds) {
+ bounds = SkIRect::MakeWH(image->width(), image->height());
+ latticePlusBounds.fBounds = &bounds;
+ }
+
+ if (SkLatticeIter::Valid(image->width(), image->height(), latticePlusBounds)) {
+ this->onDrawImageLattice(image, latticePlusBounds, dst, paint);
} else {
this->drawImageRect(image, dst, paint);
}
@@ -2049,8 +2057,16 @@ void SkCanvas::drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice,
if (bitmap.drawsNothing() || dst.isEmpty()) {
return;
}
- if (SkLatticeIter::Valid(bitmap.width(), bitmap.height(), lattice)) {
- this->onDrawBitmapLattice(bitmap, lattice, dst, paint);
+
+ SkIRect bounds;
+ Lattice latticePlusBounds = lattice;
+ if (!latticePlusBounds.fBounds) {
+ bounds = SkIRect::MakeWH(bitmap.width(), bitmap.height());
+ latticePlusBounds.fBounds = &bounds;
+ }
+
+ if (SkLatticeIter::Valid(bitmap.width(), bitmap.height(), latticePlusBounds)) {
+ this->onDrawBitmapLattice(bitmap, latticePlusBounds, dst, paint);
} else {
this->drawBitmapRect(bitmap, dst, paint);
}
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index 8a9fa96926..70eabab736 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -219,7 +219,7 @@ void SkBaseDevice::drawBitmapNine(const SkDraw& draw, const SkBitmap& bitmap, co
void SkBaseDevice::drawImageLattice(const SkDraw& draw, const SkImage* image,
const SkCanvas::Lattice& lattice, const SkRect& dst,
const SkPaint& paint) {
- SkLatticeIter iter(image->width(), image->height(), lattice, dst);
+ SkLatticeIter iter(lattice, dst);
SkRect srcR, dstR;
while (iter.next(&srcR, &dstR)) {
@@ -230,7 +230,7 @@ void SkBaseDevice::drawImageLattice(const SkDraw& draw, const SkImage* image,
void SkBaseDevice::drawBitmapLattice(const SkDraw& draw, const SkBitmap& bitmap,
const SkCanvas::Lattice& lattice, const SkRect& dst,
const SkPaint& paint) {
- SkLatticeIter iter(bitmap.width(), bitmap.height(), lattice, dst);
+ SkLatticeIter iter(lattice, dst);
SkRect srcR, dstR;
while (iter.next(&srcR, &dstR)) {
diff --git a/src/core/SkLatticeIter.cpp b/src/core/SkLatticeIter.cpp
index 38ef2828bd..4fe9352d0a 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);
diff --git a/src/core/SkLatticeIter.h b/src/core/SkLatticeIter.h
index deb2fe95eb..f3d37e6688 100644
--- a/src/core/SkLatticeIter.h
+++ b/src/core/SkLatticeIter.h
@@ -23,8 +23,7 @@ public:
static bool Valid(int imageWidth, int imageHeight, const SkCanvas::Lattice& lattice);
- SkLatticeIter(int imageWidth, int imageHeight, const SkCanvas::Lattice& lattice,
- const SkRect& dst);
+ SkLatticeIter(const SkCanvas::Lattice& lattice, const SkRect& dst);
static bool Valid(int imageWidth, int imageHeight, const SkIRect& center);
diff --git a/src/core/SkLiteDL.cpp b/src/core/SkLiteDL.cpp
index 8e64ae0a7d..701e9bd38f 100644
--- a/src/core/SkLiteDL.cpp
+++ b/src/core/SkLiteDL.cpp
@@ -353,12 +353,13 @@ namespace {
struct DrawImageLattice final : Op {
static const auto kType = Type::DrawImageLattice;
DrawImageLattice(sk_sp<const SkImage>&& image, int xs, int ys, int fs,
- const SkRect& dst, const SkPaint* paint)
- : image(std::move(image)), xs(xs), ys(ys), fs(fs), dst(dst) {
+ const SkIRect& src, const SkRect& dst, const SkPaint* paint)
+ : image(std::move(image)), xs(xs), ys(ys), fs(fs), src(src), dst(dst) {
if (paint) { this->paint = *paint; }
}
sk_sp<const SkImage> image;
int xs, ys, fs;
+ SkIRect src;
SkRect dst;
SkPaint paint;
void draw(SkCanvas* c, const SkMatrix&) {
@@ -366,7 +367,7 @@ namespace {
ydivs = pod<int>(this, xs*sizeof(int));
auto flags = (0 == fs) ? nullptr :
pod<SkCanvas::Lattice::Flags>(this, (xs+ys)*sizeof(int));
- c->drawImageLattice(image.get(), {xdivs, ydivs, flags, xs, ys}, dst, &paint);
+ c->drawImageLattice(image.get(), {xdivs, ydivs, flags, xs, ys, &src}, dst, &paint);
}
};
@@ -669,8 +670,9 @@ void SkLiteDL::drawBitmapLattice(const SkBitmap& bm, const SkCanvas::Lattice& la
int xs = lattice.fXCount, ys = lattice.fYCount;
int fs = lattice.fFlags ? (xs + 1) * (ys + 1) : 0;
size_t bytes = (xs + ys) * sizeof(int) + fs * sizeof(SkCanvas::Lattice::Flags);
- void* pod = this->push<DrawImageLattice>(bytes, SkImage::MakeFromBitmap(bm), xs, ys, fs, dst,
- paint);
+ SkASSERT(lattice.fBounds);
+ void* pod = this->push<DrawImageLattice>(bytes, SkImage::MakeFromBitmap(bm), xs, ys, fs,
+ *lattice.fBounds, dst, paint);
copy_v(pod, lattice.fXDivs, xs,
lattice.fYDivs, ys,
lattice.fFlags, fs);
@@ -692,7 +694,9 @@ void SkLiteDL::drawImageLattice(const SkImage* image, const SkCanvas::Lattice& l
int xs = lattice.fXCount, ys = lattice.fYCount;
int fs = lattice.fFlags ? (xs + 1) * (ys + 1) : 0;
size_t bytes = (xs + ys) * sizeof(int) + fs * sizeof(SkCanvas::Lattice::Flags);
- void* pod = this->push<DrawImageLattice>(bytes, sk_ref_sp(image), xs, ys, fs, dst, paint);
+ SkASSERT(lattice.fBounds);
+ void* pod = this->push<DrawImageLattice>(bytes, sk_ref_sp(image), xs, ys, fs, *lattice.fBounds,
+ dst, paint);
copy_v(pod, lattice.fXDivs, xs,
lattice.fYDivs, ys,
lattice.fFlags, fs);
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index 1aa4712d4f..a246a306e6 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -327,6 +327,9 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
int flagCount = reader->readInt();
lattice.fFlags = (0 == flagCount) ? nullptr : (const SkCanvas::Lattice::Flags*)
reader->skip(SkAlign4(flagCount * sizeof(SkCanvas::Lattice::Flags)));
+ SkIRect src;
+ reader->readIRect(&src);
+ lattice.fBounds = &src;
SkRect dst;
reader->readRect(&dst);
canvas->drawImageLattice(image, lattice, dst, paint);
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index 4cba3b067f..6325edae00 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -540,7 +540,7 @@ void SkPictureRecord::onDrawImageLattice(const SkImage* image, const Lattice& la
// xCount + xDivs + yCount+ yDivs
int flagCount = (nullptr == lattice.fFlags) ? 0 : (lattice.fXCount + 1) * (lattice.fYCount + 1);
size_t latticeSize = (1 + lattice.fXCount + 1 + lattice.fYCount + 1) * kUInt32Size +
- SkAlign4(flagCount * sizeof(SkCanvas::Lattice::Flags));
+ SkAlign4(flagCount * sizeof(SkCanvas::Lattice::Flags)) + sizeof(SkIRect);
// op + paint index + image index + lattice + dst rect
size_t size = 3 * kUInt32Size + latticeSize + sizeof(dst);
@@ -553,6 +553,8 @@ void SkPictureRecord::onDrawImageLattice(const SkImage* image, const Lattice& la
fWriter.writePad(lattice.fYDivs, lattice.fYCount * kUInt32Size);
this->addInt(flagCount);
fWriter.writePad(lattice.fFlags, flagCount * sizeof(SkCanvas::Lattice::Flags));
+ SkASSERT(lattice.fBounds);
+ this->addIRect(*lattice.fBounds);
this->addRect(dst);
this->validate(initialOffset, size);
}
diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp
index 2952591319..ca9c1b6f78 100644
--- a/src/core/SkRecordDraw.cpp
+++ b/src/core/SkRecordDraw.cpp
@@ -107,6 +107,7 @@ template <> void Draw::draw(const DrawImageLattice& r) {
lattice.fYCount = r.yCount;
lattice.fYDivs = r.yDivs;
lattice.fFlags = (0 == r.flagCount) ? nullptr : r.flags;
+ lattice.fBounds = &r.src;
fCanvas->drawImageLattice(r.image.get(), lattice, r.dst, r.paint);
}
diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp
index 0c236716bc..08c73700d8 100644
--- a/src/core/SkRecorder.cpp
+++ b/src/core/SkRecorder.cpp
@@ -239,10 +239,11 @@ void SkRecorder::onDrawImageNine(const SkImage* image, const SkIRect& center,
void SkRecorder::onDrawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
const SkPaint* paint) {
int flagCount = lattice.fFlags ? (lattice.fXCount + 1) * (lattice.fYCount + 1) : 0;
+ SkASSERT(lattice.fBounds);
APPEND(DrawImageLattice, this->copy(paint), sk_ref_sp(image),
lattice.fXCount, this->copy(lattice.fXDivs, lattice.fXCount),
lattice.fYCount, this->copy(lattice.fYDivs, lattice.fYCount),
- flagCount, this->copy(lattice.fFlags, flagCount), dst);
+ flagCount, this->copy(lattice.fFlags, flagCount), *lattice.fBounds, dst);
}
void SkRecorder::onDrawText(const void* text, size_t byteLength,