Fix for partially-specified crop rects.

When only the left or top edge of a crop rect is given, the
right and bottom should be computed based on the incoming width
and height, not based on the crop rect's width & height. This
complies more accurately with SVG semantics.

BUG=240827

Review URL: https://codereview.chromium.org/1232873002
This commit is contained in:
senorblanco 2015-07-13 10:27:05 -07:00 committed by Commit bot
parent 4421a4c90d
commit 24d2a7b463
2 changed files with 45 additions and 8 deletions

View File

@ -302,10 +302,18 @@ bool SkImageFilter::applyCropRect(const Context& ctx, const SkBitmap& src,
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 = cropRectI.fRight;
if (flags & CropRect::kHasBottom_CropEdge) srcBounds.fBottom = cropRectI.fBottom;
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;
}
@ -323,10 +331,18 @@ bool SkImageFilter::applyCropRect(const Context& ctx, Proxy* proxy, const SkBitm
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 = cropRectI.fRight;
if (flags & CropRect::kHasBottom_CropEdge) bounds->fBottom = cropRectI.fBottom;
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;
}

View File

@ -1139,6 +1139,27 @@ DEF_TEST(ComposedImageFilterOffset, reporter) {
REPORTER_ASSERT(reporter, offset.fX == 1 && offset.fY == 0);
}
DEF_TEST(PartialCropRect, reporter) {
SkBitmap bitmap;
bitmap.allocN32Pixels(100, 100);
bitmap.eraseARGB(0, 0, 0, 0);
const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
SkBitmapDevice device(bitmap, props);
SkImageFilter::Proxy proxy(&device);
SkImageFilter::CropRect cropRect(SkRect::MakeXYWH(100, 0, 20, 30),
SkImageFilter::CropRect::kHasRight_CropEdge | SkImageFilter::CropRect::kHasBottom_CropEdge);
SkAutoTUnref<SkImageFilter> filter(make_grayscale(NULL, &cropRect));
SkBitmap result;
SkIPoint offset;
SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeLargest(), NULL);
REPORTER_ASSERT(reporter, filter->filterImage(&proxy, bitmap, ctx, &result, &offset));
REPORTER_ASSERT(reporter, offset.fX == 0);
REPORTER_ASSERT(reporter, offset.fY == 0);
REPORTER_ASSERT(reporter, result.width() == 20);
REPORTER_ASSERT(reporter, result.height() == 30);
}
#if SK_SUPPORT_GPU
DEF_GPUTEST(ImageFilterCropRectGPU, reporter, factory) {