aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Fredrik Söderquist <fs@opera.com>2017-10-26 13:54:16 +0200
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-10-26 13:10:07 +0000
commitb87f798e5a629284cc008b4986bb2ddba7ed9cb1 (patch)
treecb3b9545f6f99a089a6e4ce8a02471a987955e49
parent154beea85961f73ed7f0da047b7ebd16d2a2d829 (diff)
Consistently round fOffset in SkOffsetImageFilter
Since SkScalarRoundToInt rounds differently depending on the sign of the value, care must be taken to perform rounding before any potential change to the sign - like in SkOffsetImageFilter::onFilterNodeBounds. Bug: chromium:778204 Change-Id: I3debff7565f45022c7b8566662927149850b1bea Reviewed-on: https://skia-review.googlesource.com/64020 Reviewed-by: Stephen White <senorblanco@chromium.org> Commit-Queue: Robert Phillips <robertphillips@google.com>
-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,