aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/effects/SkOffsetImageFilter.cpp19
-rw-r--r--tests/ImageFilterTest.cpp15
2 files changed, 26 insertions, 8 deletions
diff --git a/src/effects/SkOffsetImageFilter.cpp b/src/effects/SkOffsetImageFilter.cpp
index f25ffdc7ca..0c2949f0e3 100644
--- a/src/effects/SkOffsetImageFilter.cpp
+++ b/src/effects/SkOffsetImageFilter.cpp
@@ -15,6 +15,11 @@
#include "SkSpecialSurface.h"
#include "SkWriteBuffer.h"
+static SkIPoint map_offset_vector(const SkMatrix& ctm, const SkVector& offset) {
+ SkVector vec = ctm.mapVector(offset.fX, offset.fY);
+ return SkIPoint::Make(SkScalarRoundToInt(vec.fX), SkScalarRoundToInt(vec.fY));
+}
+
sk_sp<SkImageFilter> SkOffsetImageFilter::Make(SkScalar dx, SkScalar dy,
sk_sp<SkImageFilter> input,
const CropRect* cropRect) {
@@ -34,12 +39,11 @@ sk_sp<SkSpecialImage> SkOffsetImageFilter::onFilterImage(SkSpecialImage* source,
return nullptr;
}
- SkVector vec;
- ctx.ctm().mapVectors(&vec, &fOffset, 1);
+ SkIPoint vec = map_offset_vector(ctx.ctm(), fOffset);
if (!this->cropRectIsSet()) {
- offset->fX = srcOffset.fX + SkScalarRoundToInt(vec.fX);
- offset->fY = srcOffset.fY + SkScalarRoundToInt(vec.fY);
+ offset->fX = srcOffset.fX + vec.fX;
+ offset->fY = srcOffset.fY + vec.fY;
return input;
} else {
SkIRect bounds;
@@ -65,7 +69,7 @@ sk_sp<SkSpecialImage> SkOffsetImageFilter::onFilterImage(SkSpecialImage* source,
canvas->translate(SkIntToScalar(srcOffset.fX - bounds.fLeft),
SkIntToScalar(srcOffset.fY - bounds.fTop));
- input->draw(canvas, vec.x(), vec.y(), &paint);
+ input->draw(canvas, vec.fX, vec.fY, &paint);
offset->fX = bounds.fLeft;
offset->fY = bounds.fTop;
@@ -92,13 +96,12 @@ SkRect SkOffsetImageFilter::computeFastBounds(const SkRect& src) const {
SkIRect SkOffsetImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
MapDirection direction) const {
- SkVector vec;
- ctm.mapVectors(&vec, &fOffset, 1);
+ SkIPoint vec = map_offset_vector(ctm, fOffset);
if (kReverse_MapDirection == direction) {
vec.negate();
}
- return src.makeOffset(SkScalarCeilToInt(vec.fX), SkScalarCeilToInt(vec.fY));
+ return src.makeOffset(vec.fX, vec.fY);
}
sk_sp<SkFlattenable> SkOffsetImageFilter::CreateProc(SkReadBuffer& buffer) {
diff --git a/tests/ImageFilterTest.cpp b/tests/ImageFilterTest.cpp
index c39cc2ee83..59f0f2853b 100644
--- a/tests/ImageFilterTest.cpp
+++ b/tests/ImageFilterTest.cpp
@@ -1998,6 +1998,21 @@ DEF_TEST(XfermodeImageFilterBounds, reporter) {
REPORTER_ASSERT(reporter, bounds.isEmpty());
}
+DEF_TEST(OffsetImageFilterBounds, reporter) {
+ SkIRect src = SkIRect::MakeXYWH(0, 0, 100, 100);
+ sk_sp<SkImageFilter> offset(SkOffsetImageFilter::Make(-50.5f, -50.5f, nullptr));
+
+ SkIRect expectedForward = SkIRect::MakeXYWH(-50, -50, 100, 100);
+ SkIRect boundsForward = offset->filterBounds(src, SkMatrix::I(),
+ SkImageFilter::kForward_MapDirection);
+ REPORTER_ASSERT(reporter, boundsForward == expectedForward);
+
+ SkIRect expectedReverse = SkIRect::MakeXYWH(50, 50, 100, 100);
+ SkIRect boundsReverse = offset->filterBounds(src, SkMatrix::I(),
+ SkImageFilter::kReverse_MapDirection);
+ REPORTER_ASSERT(reporter, boundsReverse == expectedReverse);
+}
+
static void test_arithmetic_bounds(skiatest::Reporter* reporter, float k1, float k2, float k3,
float k4, sk_sp<SkImageFilter> background,
sk_sp<SkImageFilter> foreground,