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
This commit is contained in:
parent
9c8a32ff45
commit
71df2d7bc1
@ -8,31 +8,39 @@
|
|||||||
#include "gm.h"
|
#include "gm.h"
|
||||||
#include "SkSurface.h"
|
#include "SkSurface.h"
|
||||||
|
|
||||||
static sk_sp<SkSurface> make_surface(SkCanvas* root, int N) {
|
static sk_sp<SkSurface> make_surface(SkCanvas* root, int N, int padLeft, int padTop,
|
||||||
SkImageInfo info = SkImageInfo::MakeN32Premul(N, N);
|
int padRight, int padBottom) {
|
||||||
|
SkImageInfo info = SkImageInfo::MakeN32Premul(N + padLeft + padRight, N + padTop + padBottom);
|
||||||
auto surface = root->makeSurface(info);
|
auto surface = root->makeSurface(info);
|
||||||
if (!surface) {
|
if (!surface) {
|
||||||
surface = SkSurface::MakeRaster(info);
|
surface = SkSurface::MakeRaster(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
static sk_sp<SkImage> make_image(SkCanvas* root, int* xDivs, int* yDivs) {
|
static sk_sp<SkImage> make_image(SkCanvas* root, int* xDivs, int* yDivs, int padLeft, int padTop,
|
||||||
|
int padRight, int padBottom) {
|
||||||
const int kCap = 28;
|
const int kCap = 28;
|
||||||
const int kMid = 8;
|
const int kMid = 8;
|
||||||
const int kSize = 2*kCap + 3*kMid;
|
const int kSize = 2*kCap + 3*kMid;
|
||||||
|
|
||||||
auto surface(make_surface(root, kSize));
|
auto surface(make_surface(root, kSize, padLeft, padTop, padRight, padBottom));
|
||||||
SkCanvas* canvas = surface->getCanvas();
|
SkCanvas* canvas = surface->getCanvas();
|
||||||
|
canvas->translate((float) padLeft, (float) padTop);
|
||||||
|
|
||||||
SkRect r = SkRect::MakeWH(SkIntToScalar(kSize), SkIntToScalar(kSize));
|
SkRect r = SkRect::MakeWH(SkIntToScalar(kSize), SkIntToScalar(kSize));
|
||||||
const SkScalar strokeWidth = SkIntToScalar(6);
|
const SkScalar strokeWidth = SkIntToScalar(6);
|
||||||
const SkScalar radius = SkIntToScalar(kCap) - strokeWidth/2;
|
const SkScalar radius = SkIntToScalar(kCap) - strokeWidth/2;
|
||||||
|
|
||||||
xDivs[0] = yDivs[0] = kCap;
|
xDivs[0] = kCap + padLeft;
|
||||||
xDivs[1] = yDivs[1] = kCap + kMid;
|
yDivs[0] = kCap + padTop;
|
||||||
xDivs[2] = yDivs[2] = kCap + 2 * kMid;
|
xDivs[1] = kCap + kMid + padLeft;
|
||||||
xDivs[3] = yDivs[3] = kCap + 3 * kMid;
|
yDivs[1] = kCap + kMid + padTop;
|
||||||
|
xDivs[2] = kCap + 2 * kMid + padLeft;
|
||||||
|
yDivs[2] = kCap + 2 * kMid + padTop;
|
||||||
|
xDivs[3] = kCap + 3 * kMid + padLeft;
|
||||||
|
yDivs[3] = kCap + 3 * kMid + padTop;
|
||||||
|
|
||||||
SkPaint paint;
|
SkPaint paint;
|
||||||
paint.setAntiAlias(true);
|
paint.setAntiAlias(true);
|
||||||
@ -83,17 +91,20 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
SkISize onISize() override {
|
SkISize onISize() override {
|
||||||
return SkISize::Make(800, 400);
|
return SkISize::Make(800, 800);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onDraw(SkCanvas* canvas) override {
|
void onDrawHelper(SkCanvas* canvas, int padLeft, int padTop, int padRight, int padBottom) {
|
||||||
|
canvas->save();
|
||||||
|
|
||||||
int xDivs[5];
|
int xDivs[5];
|
||||||
int yDivs[5];
|
int yDivs[5];
|
||||||
xDivs[0] = 0;
|
xDivs[0] = padLeft;
|
||||||
yDivs[0] = 0;
|
yDivs[0] = padTop;
|
||||||
|
|
||||||
SkBitmap bitmap;
|
SkBitmap bitmap;
|
||||||
sk_sp<SkImage> image = make_image(canvas, xDivs + 1, yDivs + 1);
|
sk_sp<SkImage> image = make_image(canvas, xDivs + 1, yDivs + 1, padLeft, padTop,
|
||||||
|
padRight, padBottom);
|
||||||
image_to_bitmap(image.get(), &bitmap);
|
image_to_bitmap(image.get(), &bitmap);
|
||||||
|
|
||||||
const SkTSize<SkScalar> size[] = {
|
const SkTSize<SkScalar> size[] = {
|
||||||
@ -115,6 +126,11 @@ protected:
|
|||||||
lattice.fYDivs = yDivs + 1;
|
lattice.fYDivs = yDivs + 1;
|
||||||
lattice.fFlags = nullptr;
|
lattice.fFlags = nullptr;
|
||||||
|
|
||||||
|
SkIRect bounds = SkIRect::MakeLTRB(padLeft, padTop,
|
||||||
|
image->width() - padRight, image->height() - padBottom);
|
||||||
|
lattice.fBounds = (bounds == SkIRect::MakeWH(image->width(), image->height())) ?
|
||||||
|
nullptr : &bounds;
|
||||||
|
|
||||||
for (int iy = 0; iy < 2; ++iy) {
|
for (int iy = 0; iy < 2; ++iy) {
|
||||||
for (int ix = 0; ix < 2; ++ix) {
|
for (int ix = 0; ix < 2; ++ix) {
|
||||||
int i = ix * 2 + iy;
|
int i = ix * 2 + iy;
|
||||||
@ -149,6 +165,14 @@ protected:
|
|||||||
canvas->drawImageLattice(image.get(), lattice, r);
|
canvas->drawImageLattice(image.get(), lattice, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
canvas->restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
void onDraw(SkCanvas* canvas) override {
|
||||||
|
this->onDrawHelper(canvas, 0, 0, 0, 0);
|
||||||
|
canvas->translate(0.0f, 400.0f);
|
||||||
|
this->onDrawHelper(canvas, 3, 7, 4, 11);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -948,6 +948,9 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies coordinates to divide a bitmap into (xCount*yCount) rects.
|
* Specifies coordinates to divide a bitmap into (xCount*yCount) rects.
|
||||||
|
*
|
||||||
|
* If the lattice divs or bounds are invalid, the entire lattice
|
||||||
|
* struct will be ignored on the draw call.
|
||||||
*/
|
*/
|
||||||
struct Lattice {
|
struct Lattice {
|
||||||
enum Flags : uint8_t {
|
enum Flags : uint8_t {
|
||||||
@ -956,29 +959,34 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// An array of x-coordinates that divide the bitmap vertically.
|
// An array of x-coordinates that divide the bitmap vertically.
|
||||||
// These must be unique, increasing, and in the set [0, width).
|
// These must be unique, increasing, and in the set [fBounds.fLeft, fBounds.fRight).
|
||||||
// Does not have ownership.
|
// Does not have ownership.
|
||||||
const int* fXDivs;
|
const int* fXDivs;
|
||||||
|
|
||||||
// An array of y-coordinates that divide the bitmap horizontally.
|
// An array of y-coordinates that divide the bitmap horizontally.
|
||||||
// These must be unique, increasing, and in the set [0, height).
|
// These must be unique, increasing, and in the set [fBounds.fTop, fBounds.fBottom).
|
||||||
// Does not have ownership.
|
// Does not have ownership.
|
||||||
const int* fYDivs;
|
const int* fYDivs;
|
||||||
|
|
||||||
// If non-null, the length of this array must be equal to
|
// If non-null, the length of this array must be equal to
|
||||||
// (fXCount + 1) * (fYCount + 1). Note that we allow the first rect
|
// (fXCount + 1) * (fYCount + 1). Note that we allow the first rect
|
||||||
// in each direction to empty (divs[0] = 0). In this case, the
|
// in each direction to be empty (ex: fXDivs[0] = fBounds.fLeft).
|
||||||
// caller still must specify a flag (as a placeholder) for these
|
// In this case, the caller still must specify a flag (as a placeholder)
|
||||||
// empty rects.
|
// for these empty rects.
|
||||||
// The flags correspond to the rects in the lattice, first moving
|
// The flags correspond to the rects in the lattice, first moving
|
||||||
// left to right and then top to bottom.
|
// left to right and then top to bottom.
|
||||||
const Flags* fFlags;
|
const Flags* fFlags;
|
||||||
|
|
||||||
// The number of fXDivs.
|
// The number of fXDivs.
|
||||||
int fXCount;
|
int fXCount;
|
||||||
|
|
||||||
// The number of fYDivs.
|
// The number of fYDivs.
|
||||||
int fYCount;
|
int fYCount;
|
||||||
|
|
||||||
|
// The bound to draw from. Must be contained by the src that is being drawn,
|
||||||
|
// non-empty, and non-inverted.
|
||||||
|
// If nullptr, the bounds are the entire src.
|
||||||
|
const SkIRect* fBounds;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -244,6 +244,7 @@ RECORD(DrawImageLattice, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
|
|||||||
PODArray<int> yDivs;
|
PODArray<int> yDivs;
|
||||||
int flagCount;
|
int flagCount;
|
||||||
PODArray<SkCanvas::Lattice::Flags> flags;
|
PODArray<SkCanvas::Lattice::Flags> flags;
|
||||||
|
SkIRect src;
|
||||||
SkRect dst);
|
SkRect dst);
|
||||||
RECORD(DrawImageRect, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
|
RECORD(DrawImageRect, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
|
||||||
Optional<SkPaint> paint;
|
Optional<SkPaint> paint;
|
||||||
|
@ -1999,8 +1999,16 @@ void SkCanvas::drawImageLattice(const SkImage* image, const Lattice& lattice, co
|
|||||||
if (dst.isEmpty()) {
|
if (dst.isEmpty()) {
|
||||||
return;
|
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 {
|
} else {
|
||||||
this->drawImageRect(image, dst, paint);
|
this->drawImageRect(image, dst, paint);
|
||||||
}
|
}
|
||||||
@ -2049,8 +2057,16 @@ void SkCanvas::drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice,
|
|||||||
if (bitmap.drawsNothing() || dst.isEmpty()) {
|
if (bitmap.drawsNothing() || dst.isEmpty()) {
|
||||||
return;
|
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 {
|
} else {
|
||||||
this->drawBitmapRect(bitmap, dst, paint);
|
this->drawBitmapRect(bitmap, dst, paint);
|
||||||
}
|
}
|
||||||
|
@ -219,7 +219,7 @@ void SkBaseDevice::drawBitmapNine(const SkDraw& draw, const SkBitmap& bitmap, co
|
|||||||
void SkBaseDevice::drawImageLattice(const SkDraw& draw, const SkImage* image,
|
void SkBaseDevice::drawImageLattice(const SkDraw& draw, const SkImage* image,
|
||||||
const SkCanvas::Lattice& lattice, const SkRect& dst,
|
const SkCanvas::Lattice& lattice, const SkRect& dst,
|
||||||
const SkPaint& paint) {
|
const SkPaint& paint) {
|
||||||
SkLatticeIter iter(image->width(), image->height(), lattice, dst);
|
SkLatticeIter iter(lattice, dst);
|
||||||
|
|
||||||
SkRect srcR, dstR;
|
SkRect srcR, dstR;
|
||||||
while (iter.next(&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,
|
void SkBaseDevice::drawBitmapLattice(const SkDraw& draw, const SkBitmap& bitmap,
|
||||||
const SkCanvas::Lattice& lattice, const SkRect& dst,
|
const SkCanvas::Lattice& lattice, const SkRect& dst,
|
||||||
const SkPaint& paint) {
|
const SkPaint& paint) {
|
||||||
SkLatticeIter iter(bitmap.width(), bitmap.height(), lattice, dst);
|
SkLatticeIter iter(lattice, dst);
|
||||||
|
|
||||||
SkRect srcR, dstR;
|
SkRect srcR, dstR;
|
||||||
while (iter.next(&srcR, &dstR)) {
|
while (iter.next(&srcR, &dstR)) {
|
||||||
|
@ -11,10 +11,10 @@
|
|||||||
/**
|
/**
|
||||||
* Divs must be in increasing order with no duplicates.
|
* Divs must be in increasing order with no duplicates.
|
||||||
*/
|
*/
|
||||||
static bool valid_divs(const int* divs, int count, int len) {
|
static bool valid_divs(const int* divs, int count, int start, int end) {
|
||||||
int prev = -1;
|
int prev = start - 1;
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
if (prev >= divs[i] || divs[i] >= len) {
|
if (prev >= divs[i] || divs[i] >= end) {
|
||||||
return false;
|
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 SkLatticeIter::Valid(int width, int height, const SkCanvas::Lattice& lattice) {
|
||||||
bool zeroXDivs = lattice.fXCount <= 0 || (1 == lattice.fXCount && 0 == lattice.fXDivs[0]);
|
SkIRect totalBounds = SkIRect::MakeWH(width, height);
|
||||||
bool zeroYDivs = lattice.fYCount <= 0 || (1 == lattice.fYCount && 0 == lattice.fYDivs[0]);
|
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) {
|
if (zeroXDivs && zeroYDivs) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return valid_divs(lattice.fXDivs, lattice.fXCount, width) &&
|
return valid_divs(lattice.fXDivs, lattice.fXCount, latticeBounds.fLeft, latticeBounds.fRight)
|
||||||
valid_divs(lattice.fYDivs, lattice.fYCount, height);
|
&& valid_divs(lattice.fYDivs, lattice.fYCount, latticeBounds.fTop, latticeBounds.fBottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Count the number of pixels that are in "scalable" patches.
|
* Count the number of pixels that are in "scalable" patches.
|
||||||
*/
|
*/
|
||||||
static int count_scalable_pixels(const int32_t* divs, int numDivs, bool firstIsScalable,
|
static int count_scalable_pixels(const int32_t* divs, int numDivs, bool firstIsScalable,
|
||||||
int length) {
|
int start, int end) {
|
||||||
if (0 == numDivs) {
|
if (0 == numDivs) {
|
||||||
return firstIsScalable ? length : 0;
|
return firstIsScalable ? end - start : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
int count;
|
int count;
|
||||||
if (firstIsScalable) {
|
if (firstIsScalable) {
|
||||||
count = divs[0];
|
count = divs[0] - start;
|
||||||
i = 1;
|
i = 1;
|
||||||
} else {
|
} else {
|
||||||
count = 0;
|
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
|
// Alternatively, we could use |top| and |bottom| as variable names, instead of
|
||||||
// |left| and |right|.
|
// |left| and |right|.
|
||||||
int left = divs[i];
|
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;
|
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.
|
* 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,
|
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;
|
float dstLen = dstEnd - dstStart;
|
||||||
int srcLen = srcFixed + srcScalable;
|
|
||||||
float scale;
|
float scale;
|
||||||
if (srcFixed <= dstLen) {
|
if (srcFixed <= dstLen) {
|
||||||
// This is the "normal" case, where we scale the "scalable" patches and leave
|
// 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);
|
scale = dstLen / ((float) srcFixed);
|
||||||
}
|
}
|
||||||
|
|
||||||
src[0] = 0.0f;
|
src[0] = srcStart;
|
||||||
dst[0] = dstStart;
|
dst[0] = dstStart;
|
||||||
for (int i = 0; i < divCount; i++) {
|
for (int i = 0; i < divCount; i++) {
|
||||||
src[i + 1] = (float) (divs[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;
|
isScalable = !isScalable;
|
||||||
}
|
}
|
||||||
|
|
||||||
src[divCount + 1] = (float) srcLen;
|
src[divCount + 1] = srcEnd;
|
||||||
dst[divCount + 1] = dstStop;
|
dst[divCount + 1] = dstEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkLatticeIter::SkLatticeIter(int srcWidth, int srcHeight, const SkCanvas::Lattice& lattice,
|
SkLatticeIter::SkLatticeIter(const SkCanvas::Lattice& lattice, const SkRect& dst) {
|
||||||
const SkRect& dst)
|
|
||||||
{
|
|
||||||
const int* xDivs = lattice.fXDivs;
|
const int* xDivs = lattice.fXDivs;
|
||||||
const int origXCount = lattice.fXCount;
|
const int origXCount = lattice.fXCount;
|
||||||
const int* yDivs = lattice.fYDivs;
|
const int* yDivs = lattice.fYDivs;
|
||||||
const int origYCount = lattice.fYCount;
|
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".
|
// 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
|
// 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.
|
// patches will be "fixed" or "scalable" in the y-direction.
|
||||||
int xCount = origXCount;
|
int xCount = origXCount;
|
||||||
int yCount = origYCount;
|
int yCount = origYCount;
|
||||||
bool xIsScalable = (xCount > 0 && 0 == xDivs[0]);
|
bool xIsScalable = (xCount > 0 && src.fLeft == xDivs[0]);
|
||||||
if (xIsScalable) {
|
if (xIsScalable) {
|
||||||
// Once we've decided that the first patch is "scalable", we don't need the
|
// 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++;
|
xDivs++;
|
||||||
xCount--;
|
xCount--;
|
||||||
}
|
}
|
||||||
bool yIsScalable = (yCount > 0 && 0 == yDivs[0]);
|
bool yIsScalable = (yCount > 0 && src.fTop == yDivs[0]);
|
||||||
if (yIsScalable) {
|
if (yIsScalable) {
|
||||||
// Once we've decided that the first patch is "scalable", we don't need the
|
// 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++;
|
yDivs++;
|
||||||
yCount--;
|
yCount--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count "scalable" and "fixed" pixels in each dimension.
|
// Count "scalable" and "fixed" pixels in each dimension.
|
||||||
int xCountScalable = count_scalable_pixels(xDivs, xCount, xIsScalable, srcWidth);
|
int xCountScalable = count_scalable_pixels(xDivs, xCount, xIsScalable, src.fLeft, src.fRight);
|
||||||
int xCountFixed = srcWidth - xCountScalable;
|
int xCountFixed = src.width() - xCountScalable;
|
||||||
int yCountScalable = count_scalable_pixels(yDivs, yCount, yIsScalable, srcHeight);
|
int yCountScalable = count_scalable_pixels(yDivs, yCount, yIsScalable, src.fTop, src.fBottom);
|
||||||
int yCountFixed = srcHeight - yCountScalable;
|
int yCountFixed = src.height() - yCountScalable;
|
||||||
|
|
||||||
fSrcX.reset(xCount + 2);
|
fSrcX.reset(xCount + 2);
|
||||||
fDstX.reset(xCount + 2);
|
fDstX.reset(xCount + 2);
|
||||||
set_points(fDstX.begin(), fSrcX.begin(), xDivs, xCount, xCountFixed, xCountScalable,
|
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);
|
fSrcY.reset(yCount + 2);
|
||||||
fDstY.reset(yCount + 2);
|
fDstY.reset(yCount + 2);
|
||||||
set_points(fDstY.begin(), fSrcY.begin(), yDivs, yCount, yCountFixed, yCountScalable,
|
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;
|
fCurrX = fCurrY = 0;
|
||||||
fNumRectsInLattice = (xCount + 1) * (yCount + 1);
|
fNumRectsInLattice = (xCount + 1) * (yCount + 1);
|
||||||
|
@ -23,8 +23,7 @@ public:
|
|||||||
|
|
||||||
static bool Valid(int imageWidth, int imageHeight, const SkCanvas::Lattice& lattice);
|
static bool Valid(int imageWidth, int imageHeight, const SkCanvas::Lattice& lattice);
|
||||||
|
|
||||||
SkLatticeIter(int imageWidth, int imageHeight, const SkCanvas::Lattice& lattice,
|
SkLatticeIter(const SkCanvas::Lattice& lattice, const SkRect& dst);
|
||||||
const SkRect& dst);
|
|
||||||
|
|
||||||
static bool Valid(int imageWidth, int imageHeight, const SkIRect& center);
|
static bool Valid(int imageWidth, int imageHeight, const SkIRect& center);
|
||||||
|
|
||||||
|
@ -353,12 +353,13 @@ namespace {
|
|||||||
struct DrawImageLattice final : Op {
|
struct DrawImageLattice final : Op {
|
||||||
static const auto kType = Type::DrawImageLattice;
|
static const auto kType = Type::DrawImageLattice;
|
||||||
DrawImageLattice(sk_sp<const SkImage>&& image, int xs, int ys, int fs,
|
DrawImageLattice(sk_sp<const SkImage>&& image, int xs, int ys, int fs,
|
||||||
const SkRect& dst, const SkPaint* paint)
|
const SkIRect& src, const SkRect& dst, const SkPaint* paint)
|
||||||
: image(std::move(image)), xs(xs), ys(ys), fs(fs), dst(dst) {
|
: image(std::move(image)), xs(xs), ys(ys), fs(fs), src(src), dst(dst) {
|
||||||
if (paint) { this->paint = *paint; }
|
if (paint) { this->paint = *paint; }
|
||||||
}
|
}
|
||||||
sk_sp<const SkImage> image;
|
sk_sp<const SkImage> image;
|
||||||
int xs, ys, fs;
|
int xs, ys, fs;
|
||||||
|
SkIRect src;
|
||||||
SkRect dst;
|
SkRect dst;
|
||||||
SkPaint paint;
|
SkPaint paint;
|
||||||
void draw(SkCanvas* c, const SkMatrix&) {
|
void draw(SkCanvas* c, const SkMatrix&) {
|
||||||
@ -366,7 +367,7 @@ namespace {
|
|||||||
ydivs = pod<int>(this, xs*sizeof(int));
|
ydivs = pod<int>(this, xs*sizeof(int));
|
||||||
auto flags = (0 == fs) ? nullptr :
|
auto flags = (0 == fs) ? nullptr :
|
||||||
pod<SkCanvas::Lattice::Flags>(this, (xs+ys)*sizeof(int));
|
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 xs = lattice.fXCount, ys = lattice.fYCount;
|
||||||
int fs = lattice.fFlags ? (xs + 1) * (ys + 1) : 0;
|
int fs = lattice.fFlags ? (xs + 1) * (ys + 1) : 0;
|
||||||
size_t bytes = (xs + ys) * sizeof(int) + fs * sizeof(SkCanvas::Lattice::Flags);
|
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,
|
SkASSERT(lattice.fBounds);
|
||||||
paint);
|
void* pod = this->push<DrawImageLattice>(bytes, SkImage::MakeFromBitmap(bm), xs, ys, fs,
|
||||||
|
*lattice.fBounds, dst, paint);
|
||||||
copy_v(pod, lattice.fXDivs, xs,
|
copy_v(pod, lattice.fXDivs, xs,
|
||||||
lattice.fYDivs, ys,
|
lattice.fYDivs, ys,
|
||||||
lattice.fFlags, fs);
|
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 xs = lattice.fXCount, ys = lattice.fYCount;
|
||||||
int fs = lattice.fFlags ? (xs + 1) * (ys + 1) : 0;
|
int fs = lattice.fFlags ? (xs + 1) * (ys + 1) : 0;
|
||||||
size_t bytes = (xs + ys) * sizeof(int) + fs * sizeof(SkCanvas::Lattice::Flags);
|
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,
|
copy_v(pod, lattice.fXDivs, xs,
|
||||||
lattice.fYDivs, ys,
|
lattice.fYDivs, ys,
|
||||||
lattice.fFlags, fs);
|
lattice.fFlags, fs);
|
||||||
|
@ -327,6 +327,9 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
|||||||
int flagCount = reader->readInt();
|
int flagCount = reader->readInt();
|
||||||
lattice.fFlags = (0 == flagCount) ? nullptr : (const SkCanvas::Lattice::Flags*)
|
lattice.fFlags = (0 == flagCount) ? nullptr : (const SkCanvas::Lattice::Flags*)
|
||||||
reader->skip(SkAlign4(flagCount * sizeof(SkCanvas::Lattice::Flags)));
|
reader->skip(SkAlign4(flagCount * sizeof(SkCanvas::Lattice::Flags)));
|
||||||
|
SkIRect src;
|
||||||
|
reader->readIRect(&src);
|
||||||
|
lattice.fBounds = &src;
|
||||||
SkRect dst;
|
SkRect dst;
|
||||||
reader->readRect(&dst);
|
reader->readRect(&dst);
|
||||||
canvas->drawImageLattice(image, lattice, dst, paint);
|
canvas->drawImageLattice(image, lattice, dst, paint);
|
||||||
|
@ -540,7 +540,7 @@ void SkPictureRecord::onDrawImageLattice(const SkImage* image, const Lattice& la
|
|||||||
// xCount + xDivs + yCount+ yDivs
|
// xCount + xDivs + yCount+ yDivs
|
||||||
int flagCount = (nullptr == lattice.fFlags) ? 0 : (lattice.fXCount + 1) * (lattice.fYCount + 1);
|
int flagCount = (nullptr == lattice.fFlags) ? 0 : (lattice.fXCount + 1) * (lattice.fYCount + 1);
|
||||||
size_t latticeSize = (1 + lattice.fXCount + 1 + lattice.fYCount + 1) * kUInt32Size +
|
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
|
// op + paint index + image index + lattice + dst rect
|
||||||
size_t size = 3 * kUInt32Size + latticeSize + sizeof(dst);
|
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);
|
fWriter.writePad(lattice.fYDivs, lattice.fYCount * kUInt32Size);
|
||||||
this->addInt(flagCount);
|
this->addInt(flagCount);
|
||||||
fWriter.writePad(lattice.fFlags, flagCount * sizeof(SkCanvas::Lattice::Flags));
|
fWriter.writePad(lattice.fFlags, flagCount * sizeof(SkCanvas::Lattice::Flags));
|
||||||
|
SkASSERT(lattice.fBounds);
|
||||||
|
this->addIRect(*lattice.fBounds);
|
||||||
this->addRect(dst);
|
this->addRect(dst);
|
||||||
this->validate(initialOffset, size);
|
this->validate(initialOffset, size);
|
||||||
}
|
}
|
||||||
|
@ -107,6 +107,7 @@ template <> void Draw::draw(const DrawImageLattice& r) {
|
|||||||
lattice.fYCount = r.yCount;
|
lattice.fYCount = r.yCount;
|
||||||
lattice.fYDivs = r.yDivs;
|
lattice.fYDivs = r.yDivs;
|
||||||
lattice.fFlags = (0 == r.flagCount) ? nullptr : r.flags;
|
lattice.fFlags = (0 == r.flagCount) ? nullptr : r.flags;
|
||||||
|
lattice.fBounds = &r.src;
|
||||||
fCanvas->drawImageLattice(r.image.get(), lattice, r.dst, r.paint);
|
fCanvas->drawImageLattice(r.image.get(), lattice, r.dst, r.paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
void SkRecorder::onDrawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
|
||||||
const SkPaint* paint) {
|
const SkPaint* paint) {
|
||||||
int flagCount = lattice.fFlags ? (lattice.fXCount + 1) * (lattice.fYCount + 1) : 0;
|
int flagCount = lattice.fFlags ? (lattice.fXCount + 1) * (lattice.fYCount + 1) : 0;
|
||||||
|
SkASSERT(lattice.fBounds);
|
||||||
APPEND(DrawImageLattice, this->copy(paint), sk_ref_sp(image),
|
APPEND(DrawImageLattice, this->copy(paint), sk_ref_sp(image),
|
||||||
lattice.fXCount, this->copy(lattice.fXDivs, lattice.fXCount),
|
lattice.fXCount, this->copy(lattice.fXDivs, lattice.fXCount),
|
||||||
lattice.fYCount, this->copy(lattice.fYDivs, lattice.fYCount),
|
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,
|
void SkRecorder::onDrawText(const void* text, size_t byteLength,
|
||||||
|
@ -1501,7 +1501,7 @@ void SkGpuDevice::drawProducerLattice(const SkDraw& draw, GrTextureProducer* pro
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<SkLatticeIter> iter(
|
std::unique_ptr<SkLatticeIter> iter(
|
||||||
new SkLatticeIter(producer->width(), producer->height(), lattice, dst));
|
new SkLatticeIter(lattice, dst));
|
||||||
fDrawContext->drawImageLattice(fClip, grPaint, *draw.fMatrix, producer->width(),
|
fDrawContext->drawImageLattice(fClip, grPaint, *draw.fMatrix, producer->width(),
|
||||||
producer->height(), std::move(iter), dst);
|
producer->height(), std::move(iter), dst);
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ void SkPDFCanvas::onDrawImageLattice(const SkImage* image,
|
|||||||
const Lattice& lattice,
|
const Lattice& lattice,
|
||||||
const SkRect& dst,
|
const SkRect& dst,
|
||||||
const SkPaint* paint) {
|
const SkPaint* paint) {
|
||||||
SkLatticeIter iter(image->width(), image->height(), lattice, dst);
|
SkLatticeIter iter(lattice, dst);
|
||||||
SkRect srcR, dstR;
|
SkRect srcR, dstR;
|
||||||
while (iter.next(&srcR, &dstR)) {
|
while (iter.next(&srcR, &dstR)) {
|
||||||
this->drawImageRect(image, srcR, dstR, paint);
|
this->drawImageRect(image, srcR, dstR, paint);
|
||||||
@ -88,7 +88,7 @@ void SkPDFCanvas::onDrawBitmapLattice(const SkBitmap& bitmap,
|
|||||||
const Lattice& lattice,
|
const Lattice& lattice,
|
||||||
const SkRect& dst,
|
const SkRect& dst,
|
||||||
const SkPaint* paint) {
|
const SkPaint* paint) {
|
||||||
SkLatticeIter iter(bitmap.width(), bitmap.height(), lattice, dst);
|
SkLatticeIter iter(lattice, dst);
|
||||||
SkRect srcR, dstR;
|
SkRect srcR, dstR;
|
||||||
while (iter.next(&srcR, &dstR)) {
|
while (iter.next(&srcR, &dstR)) {
|
||||||
this->drawBitmapRect(bitmap, srcR, dstR, paint);
|
this->drawBitmapRect(bitmap, srcR, dstR, paint);
|
||||||
|
@ -582,6 +582,8 @@ void SkPipeCanvas::onDrawImageLattice(const SkImage* image, const Lattice& latti
|
|||||||
SkASSERT(count > 0);
|
SkASSERT(count > 0);
|
||||||
write_pad(&writer, lattice.fFlags, count);
|
write_pad(&writer, lattice.fFlags, count);
|
||||||
}
|
}
|
||||||
|
SkASSERT(lattice.fBounds);
|
||||||
|
writer.write(&lattice.fBounds, sizeof(*lattice.fBounds));
|
||||||
writer.write(&dst, sizeof(dst));
|
writer.write(&dst, sizeof(dst));
|
||||||
if (paint) {
|
if (paint) {
|
||||||
write_paint(writer, *paint, kImage_PaintUsage);
|
write_paint(writer, *paint, kImage_PaintUsage);
|
||||||
|
@ -559,6 +559,7 @@ static void drawImageLattice_handler(SkPipeReader& reader, uint32_t packedVerb,
|
|||||||
} else {
|
} else {
|
||||||
lattice.fFlags = nullptr;
|
lattice.fFlags = nullptr;
|
||||||
}
|
}
|
||||||
|
lattice.fBounds = skip<SkIRect>(reader);
|
||||||
const SkRect* dst = skip<SkRect>(reader);
|
const SkRect* dst = skip<SkRect>(reader);
|
||||||
|
|
||||||
SkPaint paintStorage, *paint = nullptr;
|
SkPaint paintStorage, *paint = nullptr;
|
||||||
|
Loading…
Reference in New Issue
Block a user