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 {
|
||||
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
|
||||
// (result, offset).
|
||||
class Cache : public SkRefCnt {
|
||||
@ -77,6 +59,41 @@ public:
|
||||
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 {
|
||||
public:
|
||||
Proxy(SkBaseDevice* device) : fDevice(device) { }
|
||||
@ -182,7 +199,8 @@ public:
|
||||
/**
|
||||
* 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
|
||||
* 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
|
||||
* should be used to offset access to the input images, and should also
|
||||
* be added to the "offset" parameter in onFilterImage and
|
||||
|
@ -33,6 +33,64 @@
|
||||
enum { kDefaultCacheSize = 128 * 1024 * 1024 };
|
||||
#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 gImageFilterUniqueID;
|
||||
|
||||
@ -298,27 +356,7 @@ bool SkImageFilter::applyCropRect(const Context& ctx, const SkBitmap& src,
|
||||
SkIRect srcBounds;
|
||||
src.getBounds(&srcBounds);
|
||||
srcBounds.offset(srcOffset);
|
||||
SkRect cropRect;
|
||||
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;
|
||||
return fCropRect.applyTo(srcBounds, ctx, bounds);
|
||||
}
|
||||
|
||||
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;
|
||||
src.getBounds(&srcBounds);
|
||||
srcBounds.offset(*srcOffset);
|
||||
SkRect cropRect;
|
||||
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())) {
|
||||
if (!fCropRect.applyTo(srcBounds, ctx, bounds)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (srcBounds.contains(*bounds)) {
|
||||
*dst = src;
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user