diff options
author | 2016-09-30 12:41:42 -0700 | |
---|---|---|
committer | 2016-09-30 12:41:42 -0700 | |
commit | 71df2d7bc1bbc83ad4cf005f9027df4cb3b88a9b (patch) | |
tree | 9113c13e0d2285f1204e0a4bee8d89eb644d16ed /src/core | |
parent | 9c8a32ff4507481aadf1a190637ee8d55c8dc217 (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.cpp | 24 | ||||
-rw-r--r-- | src/core/SkDevice.cpp | 4 | ||||
-rw-r--r-- | src/core/SkLatticeIter.cpp | 69 | ||||
-rw-r--r-- | src/core/SkLatticeIter.h | 3 | ||||
-rw-r--r-- | src/core/SkLiteDL.cpp | 16 | ||||
-rw-r--r-- | src/core/SkPicturePlayback.cpp | 3 | ||||
-rw-r--r-- | src/core/SkPictureRecord.cpp | 4 | ||||
-rw-r--r-- | src/core/SkRecordDraw.cpp | 1 | ||||
-rw-r--r-- | src/core/SkRecorder.cpp | 3 |
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, |