SkPaintFilterCanvas should inherit the target canvas state
Currently, SkPaintFilterCanvas does not provide any help in cloning target canvas state. While that could be handled in subclasses, it is easy to miss (see linked bug). This CL adds a new constructor variant which ensures that the initial matrix and clip bounds are inherited from the target canvas. BUG=516790 R=reed@google.com,robertphillips@google.com Review URL: https://codereview.chromium.org/1294013002
This commit is contained in:
parent
340f3074b4
commit
f433bb2beb
@ -16,8 +16,17 @@
|
||||
*/
|
||||
class SK_API SkPaintFilterCanvas : public SkNWayCanvas {
|
||||
public:
|
||||
/**
|
||||
* DEPRECATED: use the variant below.
|
||||
*/
|
||||
SkPaintFilterCanvas(int width, int height);
|
||||
|
||||
/**
|
||||
* The new SkPaintFilterCanvas is configured for forwarding to the
|
||||
* specified canvas. Also copies the target canvas matrix and clip bounds.
|
||||
*/
|
||||
SkPaintFilterCanvas(SkCanvas* canvas);
|
||||
|
||||
enum Type {
|
||||
kPaint_Type,
|
||||
kPoint_Type,
|
||||
|
@ -30,6 +30,18 @@ private:
|
||||
|
||||
SkPaintFilterCanvas::SkPaintFilterCanvas(int width, int height) : INHERITED(width, height) { }
|
||||
|
||||
SkPaintFilterCanvas::SkPaintFilterCanvas(SkCanvas *canvas)
|
||||
: INHERITED(canvas->imageInfo().width(), canvas->imageInfo().height()) {
|
||||
|
||||
// Transfer matrix & clip state before adding the target canvas.
|
||||
SkIRect devClip;
|
||||
canvas->getClipDeviceBounds(&devClip);
|
||||
this->clipRect(SkRect::Make(devClip));
|
||||
this->setMatrix(canvas->getTotalMatrix());
|
||||
|
||||
this->addCanvas(canvas);
|
||||
}
|
||||
|
||||
void SkPaintFilterCanvas::onDrawPaint(const SkPaint& paint) {
|
||||
AutoPaintFilter apf(this, kPaint_Type, paint);
|
||||
this->INHERITED::onDrawPaint(*apf.paint());
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include "SkMatrix.h"
|
||||
#include "SkNWayCanvas.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkPaintFilterCanvas.h"
|
||||
#include "SkPath.h"
|
||||
#include "SkPicture.h"
|
||||
#include "SkPictureRecord.h"
|
||||
@ -782,3 +783,38 @@ DEF_TEST(Canvas_ClipEmptyPath, reporter) {
|
||||
canvas.clipPath(path); // should not assert here
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class MockFilterCanvas : public SkPaintFilterCanvas {
|
||||
public:
|
||||
MockFilterCanvas(SkCanvas* canvas) : INHERITED(canvas) { }
|
||||
|
||||
protected:
|
||||
void onFilterPaint(SkPaint *paint, Type type) const override { }
|
||||
|
||||
private:
|
||||
typedef SkPaintFilterCanvas INHERITED;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// SkPaintFilterCanvas should inherit the initial target canvas state.
|
||||
DEF_TEST(PaintFilterCanvas_ConsistentState, reporter) {
|
||||
SkCanvas canvas(100, 100);
|
||||
canvas.clipRect(SkRect::MakeXYWH(12.7f, 12.7f, 75, 75));
|
||||
canvas.scale(0.5f, 0.75f);
|
||||
|
||||
SkRect clip1, clip2;
|
||||
|
||||
MockFilterCanvas filterCanvas(&canvas);
|
||||
REPORTER_ASSERT(reporter, canvas.getTotalMatrix() == filterCanvas.getTotalMatrix());
|
||||
REPORTER_ASSERT(reporter, canvas.getClipBounds(&clip1) == filterCanvas.getClipBounds(&clip2));
|
||||
REPORTER_ASSERT(reporter, clip1 == clip2);
|
||||
|
||||
filterCanvas.clipRect(SkRect::MakeXYWH(30.5f, 30.7f, 100, 100));
|
||||
filterCanvas.scale(0.75f, 0.5f);
|
||||
REPORTER_ASSERT(reporter, canvas.getTotalMatrix() == filterCanvas.getTotalMatrix());
|
||||
REPORTER_ASSERT(reporter, canvas.getClipBounds(&clip1) == filterCanvas.getClipBounds(&clip2));
|
||||
REPORTER_ASSERT(reporter, clip1 == clip2);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user