refactor code to apply the croprect
BUG=skia: Review URL: https://codereview.chromium.org/1218993002
This commit is contained in:
parent
dfa0ecf169
commit
189186337e
@ -32,24 +32,6 @@ struct SkIPoint;
|
|||||||
*/
|
*/
|
||||||
class SK_API SkImageFilter : public SkFlattenable {
|
class SK_API SkImageFilter : public SkFlattenable {
|
||||||
public:
|
public:
|
||||||
class CropRect {
|
|
||||||
public:
|
|
||||||
enum CropEdge {
|
|
||||||
kHasLeft_CropEdge = 0x01,
|
|
||||||
kHasTop_CropEdge = 0x02,
|
|
||||||
kHasRight_CropEdge = 0x04,
|
|
||||||
kHasBottom_CropEdge = 0x08,
|
|
||||||
kHasAll_CropEdge = 0x0F,
|
|
||||||
};
|
|
||||||
CropRect() {}
|
|
||||||
explicit CropRect(const SkRect& rect, uint32_t flags = kHasAll_CropEdge) : fRect(rect), fFlags(flags) {}
|
|
||||||
uint32_t flags() const { return fFlags; }
|
|
||||||
const SkRect& rect() const { return fRect; }
|
|
||||||
private:
|
|
||||||
SkRect fRect;
|
|
||||||
uint32_t fFlags;
|
|
||||||
};
|
|
||||||
|
|
||||||
// This cache maps from (filter's unique ID + CTM + clipBounds + src bitmap generation ID) to
|
// This cache maps from (filter's unique ID + CTM + clipBounds + src bitmap generation ID) to
|
||||||
// (result, offset).
|
// (result, offset).
|
||||||
class Cache : public SkRefCnt {
|
class Cache : public SkRefCnt {
|
||||||
@ -77,6 +59,41 @@ public:
|
|||||||
Cache* fCache;
|
Cache* fCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CropRect {
|
||||||
|
public:
|
||||||
|
enum CropEdge {
|
||||||
|
kHasLeft_CropEdge = 0x01,
|
||||||
|
kHasTop_CropEdge = 0x02,
|
||||||
|
kHasRight_CropEdge = 0x04,
|
||||||
|
kHasBottom_CropEdge = 0x08,
|
||||||
|
kHasAll_CropEdge = 0x0F,
|
||||||
|
};
|
||||||
|
CropRect() {}
|
||||||
|
explicit CropRect(const SkRect& rect, uint32_t flags = kHasAll_CropEdge)
|
||||||
|
: fRect(rect), fFlags(flags) {}
|
||||||
|
uint32_t flags() const { return fFlags; }
|
||||||
|
const SkRect& rect() const { return fRect; }
|
||||||
|
#ifndef SK_IGNORE_TO_STRING
|
||||||
|
void toString(SkString* str) const;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply this cropRect to the imageBounds. If a given edge of the cropRect is not
|
||||||
|
* set, then the corresponding edge from imageBounds will be used.
|
||||||
|
*
|
||||||
|
* Note: imageBounds is in "device" space, as the output cropped rectangle will be,
|
||||||
|
* so the context's CTM is ignore for those. It is only applied the croprect's bounds.
|
||||||
|
*
|
||||||
|
* The resulting rect will be intersected with the context's clip. If that intersection is
|
||||||
|
* empty, then this returns false and cropped is unmodified.
|
||||||
|
*/
|
||||||
|
bool applyTo(const SkIRect& imageBounds, const Context&, SkIRect* cropped) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
SkRect fRect;
|
||||||
|
uint32_t fFlags;
|
||||||
|
};
|
||||||
|
|
||||||
class Proxy {
|
class Proxy {
|
||||||
public:
|
public:
|
||||||
Proxy(SkBaseDevice* device) : fDevice(device) { }
|
Proxy(SkBaseDevice* device) : fDevice(device) { }
|
||||||
@ -182,7 +199,8 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Returns whether any edges of the crop rect have been set. The crop
|
* Returns whether any edges of the crop rect have been set. The crop
|
||||||
* rect is set at construction time, and determines which pixels from the
|
* rect is set at construction time, and determines which pixels from the
|
||||||
* input image will be processed. The size of the crop rect should be
|
* input image will be processed, and which pixels in the output image will be allowed.
|
||||||
|
* The size of the crop rect should be
|
||||||
* used as the size of the destination image. The origin of this rect
|
* used as the size of the destination image. The origin of this rect
|
||||||
* should be used to offset access to the input images, and should also
|
* should be used to offset access to the input images, and should also
|
||||||
* be added to the "offset" parameter in onFilterImage and
|
* be added to the "offset" parameter in onFilterImage and
|
||||||
|
@ -33,6 +33,64 @@
|
|||||||
enum { kDefaultCacheSize = 128 * 1024 * 1024 };
|
enum { kDefaultCacheSize = 128 * 1024 * 1024 };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef SK_IGNORE_TO_STRING
|
||||||
|
void SkImageFilter::CropRect::toString(SkString* str) const {
|
||||||
|
if (!fFlags) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
str->appendf("cropRect (");
|
||||||
|
if (fFlags & CropRect::kHasLeft_CropEdge) {
|
||||||
|
str->appendf("%.2f, ", fRect.fLeft);
|
||||||
|
} else {
|
||||||
|
str->appendf("X, ");
|
||||||
|
}
|
||||||
|
if (fFlags & CropRect::kHasTop_CropEdge) {
|
||||||
|
str->appendf("%.2f, ", fRect.fTop);
|
||||||
|
} else {
|
||||||
|
str->appendf("X, ");
|
||||||
|
}
|
||||||
|
if (fFlags & CropRect::kHasRight_CropEdge) {
|
||||||
|
str->appendf("%.2f, ", fRect.fRight);
|
||||||
|
} else {
|
||||||
|
str->appendf("X, ");
|
||||||
|
}
|
||||||
|
if (fFlags & CropRect::kHasBottom_CropEdge) {
|
||||||
|
str->appendf("%.2f", fRect.fBottom);
|
||||||
|
} else {
|
||||||
|
str->appendf("X");
|
||||||
|
}
|
||||||
|
str->appendf(") ");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool SkImageFilter::CropRect::applyTo(const SkIRect& imageBounds, const Context& ctx,
|
||||||
|
SkIRect* cropped) const {
|
||||||
|
*cropped = imageBounds;
|
||||||
|
if (fFlags) {
|
||||||
|
SkRect devCropR;
|
||||||
|
ctx.ctm().mapRect(&devCropR, fRect);
|
||||||
|
const SkIRect devICropR = devCropR.roundOut();
|
||||||
|
|
||||||
|
// Compute the left/top first, in case we have to read them to compute right/bottom
|
||||||
|
if (fFlags & kHasLeft_CropEdge) {
|
||||||
|
cropped->fLeft = devICropR.fLeft;
|
||||||
|
}
|
||||||
|
if (fFlags & kHasTop_CropEdge) {
|
||||||
|
cropped->fTop = devICropR.fTop;
|
||||||
|
}
|
||||||
|
if (fFlags & kHasRight_CropEdge) {
|
||||||
|
cropped->fRight = cropped->fLeft + devICropR.width();
|
||||||
|
}
|
||||||
|
if (fFlags & kHasBottom_CropEdge) {
|
||||||
|
cropped->fBottom = cropped->fTop + devICropR.height();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cropped->intersect(ctx.clipBounds());
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static int32_t next_image_filter_unique_id() {
|
static int32_t next_image_filter_unique_id() {
|
||||||
static int32_t gImageFilterUniqueID;
|
static int32_t gImageFilterUniqueID;
|
||||||
|
|
||||||
@ -298,27 +356,7 @@ bool SkImageFilter::applyCropRect(const Context& ctx, const SkBitmap& src,
|
|||||||
SkIRect srcBounds;
|
SkIRect srcBounds;
|
||||||
src.getBounds(&srcBounds);
|
src.getBounds(&srcBounds);
|
||||||
srcBounds.offset(srcOffset);
|
srcBounds.offset(srcOffset);
|
||||||
SkRect cropRect;
|
return fCropRect.applyTo(srcBounds, ctx, bounds);
|
||||||
ctx.ctm().mapRect(&cropRect, fCropRect.rect());
|
|
||||||
const SkIRect cropRectI = cropRect.roundOut();
|
|
||||||
uint32_t flags = fCropRect.flags();
|
|
||||||
if (flags & CropRect::kHasLeft_CropEdge) {
|
|
||||||
srcBounds.fLeft = cropRectI.fLeft;
|
|
||||||
}
|
|
||||||
if (flags & CropRect::kHasTop_CropEdge) {
|
|
||||||
srcBounds.fTop = cropRectI.fTop;
|
|
||||||
}
|
|
||||||
if (flags & CropRect::kHasRight_CropEdge) {
|
|
||||||
srcBounds.fRight = srcBounds.fLeft + cropRectI.width();
|
|
||||||
}
|
|
||||||
if (flags & CropRect::kHasBottom_CropEdge) {
|
|
||||||
srcBounds.fBottom = srcBounds.fTop + cropRectI.height();
|
|
||||||
}
|
|
||||||
if (!srcBounds.intersect(ctx.clipBounds())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
*bounds = srcBounds;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkImageFilter::applyCropRect(const Context& ctx, Proxy* proxy, const SkBitmap& src,
|
bool SkImageFilter::applyCropRect(const Context& ctx, Proxy* proxy, const SkBitmap& src,
|
||||||
@ -326,26 +364,10 @@ bool SkImageFilter::applyCropRect(const Context& ctx, Proxy* proxy, const SkBitm
|
|||||||
SkIRect srcBounds;
|
SkIRect srcBounds;
|
||||||
src.getBounds(&srcBounds);
|
src.getBounds(&srcBounds);
|
||||||
srcBounds.offset(*srcOffset);
|
srcBounds.offset(*srcOffset);
|
||||||
SkRect cropRect;
|
if (!fCropRect.applyTo(srcBounds, ctx, bounds)) {
|
||||||
ctx.ctm().mapRect(&cropRect, fCropRect.rect());
|
|
||||||
const SkIRect cropRectI = cropRect.roundOut();
|
|
||||||
uint32_t flags = fCropRect.flags();
|
|
||||||
*bounds = srcBounds;
|
|
||||||
if (flags & CropRect::kHasLeft_CropEdge) {
|
|
||||||
bounds->fLeft = cropRectI.fLeft;
|
|
||||||
}
|
|
||||||
if (flags & CropRect::kHasTop_CropEdge) {
|
|
||||||
bounds->fTop = cropRectI.fTop;
|
|
||||||
}
|
|
||||||
if (flags & CropRect::kHasRight_CropEdge) {
|
|
||||||
bounds->fRight = bounds->fLeft + cropRectI.width();
|
|
||||||
}
|
|
||||||
if (flags & CropRect::kHasBottom_CropEdge) {
|
|
||||||
bounds->fBottom = bounds->fTop + cropRectI.height();
|
|
||||||
}
|
|
||||||
if (!bounds->intersect(ctx.clipBounds())) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srcBounds.contains(*bounds)) {
|
if (srcBounds.contains(*bounds)) {
|
||||||
*dst = src;
|
*dst = src;
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
Reference in New Issue
Block a user