Fix bug in raster implementation of SkRRectsGaussianEdgeMaskFilter
The bug was the raster version didn't correctly handle the CTM. This CL also adds a way to test the behavior (by translating the reveal GM around in SampleApp) GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=3729 Change-Id: Iaacc905167d20b453203307e5ef840f552fdbb38 Reviewed-on: https://skia-review.googlesource.com/3729 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
parent
ddb37d67ba
commit
d2fe3bce07
@ -28,7 +28,9 @@ constexpr int kClipOffset = 32;
|
||||
class Object {
|
||||
public:
|
||||
virtual ~Object() {}
|
||||
virtual bool asRRect(SkRRect* rr) const = 0;
|
||||
// When it returns true, this call will have placed a device-space _circle, rect or
|
||||
// simple circular_ RRect in "rr"
|
||||
virtual bool asDevSpaceRRect(const SkMatrix& ctm, SkRRect* rr) const = 0;
|
||||
virtual SkPath asPath(SkScalar inset) const = 0;
|
||||
virtual void draw(SkCanvas* canvas, const SkPaint& paint) const = 0;
|
||||
virtual void clip(SkCanvas* canvas) const = 0;
|
||||
@ -44,8 +46,24 @@ public:
|
||||
fRRect = SkRRect::MakeRectXY(r, 4*kPad, 4*kPad);
|
||||
}
|
||||
|
||||
bool asRRect(SkRRect* rr) const override {
|
||||
*rr = fRRect;
|
||||
bool asDevSpaceRRect(const SkMatrix& ctm, SkRRect* rr) const override {
|
||||
if (!ctm.isSimilarity()) { // the corners have to remain circular
|
||||
return false;
|
||||
}
|
||||
|
||||
SkScalar scales[2];
|
||||
if (!ctm.getMinMaxScales(scales)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SkASSERT(SkScalarNearlyEqual(scales[0], scales[1]));
|
||||
|
||||
SkRect devRect;
|
||||
ctm.mapRect(&devRect, fRRect.rect());
|
||||
|
||||
SkScalar scaledRad = scales[0] * fRRect.getSimpleRadii().fX;
|
||||
|
||||
*rr = SkRRect::MakeRectXY(devRect, scaledRad, scaledRad);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -88,7 +106,7 @@ public:
|
||||
fStrokedBounds = r.makeOutset(kPad, kPad);
|
||||
}
|
||||
|
||||
bool asRRect(SkRRect* rr) const override {
|
||||
bool asDevSpaceRRect(const SkMatrix& ctm, SkRRect* rr) const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -144,8 +162,14 @@ public:
|
||||
fRRect = SkRRect::MakeOval(r);
|
||||
}
|
||||
|
||||
bool asRRect(SkRRect* rr) const override {
|
||||
*rr = fRRect;
|
||||
bool asDevSpaceRRect(const SkMatrix& ctm, SkRRect* rr) const override {
|
||||
if (!ctm.isSimilarity()) { // circles have to remain circles
|
||||
return false;
|
||||
}
|
||||
|
||||
SkRect devRect;
|
||||
ctm.mapRect(&devRect, fRRect.rect());
|
||||
*rr = SkRRect::MakeOval(devRect);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -186,8 +210,14 @@ class Rect : public Object {
|
||||
public:
|
||||
Rect(const SkRect& r) : fRect(r) { }
|
||||
|
||||
bool asRRect(SkRRect* rr) const override {
|
||||
*rr = SkRRect::MakeRect(fRect);
|
||||
bool asDevSpaceRRect(const SkMatrix& ctm, SkRRect* rr) const override {
|
||||
if (!ctm.rectStaysRect()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SkRect devRect;
|
||||
ctm.mapRect(&devRect, fRect);
|
||||
*rr = SkRRect::MakeRect(devRect);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -246,7 +276,7 @@ public:
|
||||
fPath.close();
|
||||
}
|
||||
|
||||
bool asRRect(SkRRect* rr) const override {
|
||||
bool asDevSpaceRRect(const SkMatrix& ctm, SkRRect* rr) const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -311,6 +341,7 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
bool runAsBench() const override { return true; }
|
||||
|
||||
SkString onShortName() override {
|
||||
return SkString("reveal");
|
||||
@ -393,10 +424,12 @@ protected:
|
||||
|
||||
SkPaint paint;
|
||||
|
||||
SkRRect clipRR, drawnRR;
|
||||
SkRRect devSpaceClipRR, devSpaceDrawnRR;
|
||||
|
||||
if (clipObj->asRRect(&clipRR) && drawObj->asRRect(&drawnRR)) {
|
||||
paint.setMaskFilter(SkRRectsGaussianEdgeMaskFilter::Make(clipRR, drawnRR,
|
||||
if (clipObj->asDevSpaceRRect(canvas->getTotalMatrix(), &devSpaceClipRR) &&
|
||||
drawObj->asDevSpaceRRect(canvas->getTotalMatrix(), &devSpaceDrawnRR)) {
|
||||
paint.setMaskFilter(SkRRectsGaussianEdgeMaskFilter::Make(devSpaceClipRR,
|
||||
devSpaceDrawnRR,
|
||||
fBlurRadius));
|
||||
}
|
||||
|
||||
|
@ -160,7 +160,6 @@ bool SkRRectsGaussianEdgeMaskFilterImpl::filterMask(SkMask* dst, const SkMask& s
|
||||
uint8_t* dstPixels = dst->fImage = SkMask::AllocImage(dstSize);
|
||||
|
||||
SkPoint basePt = { SkIntToScalar(src.fBounds.fLeft), SkIntToScalar(src.fBounds.fTop) };
|
||||
matrix.mapPoints(&basePt, 1);
|
||||
|
||||
for (int y = 0; y < dst->fBounds.height(); ++y) {
|
||||
const uint8_t* srcRow = srcPixels + y * dst->fRowBytes;
|
||||
|
Loading…
Reference in New Issue
Block a user