diff options
-rw-r--r-- | include/utils/SkPaintFilterCanvas.h | 30 | ||||
-rw-r--r-- | samplecode/SampleApp.cpp | 23 | ||||
-rw-r--r-- | src/utils/SkPaintFilterCanvas.cpp | 114 | ||||
-rw-r--r-- | src/utils/debugger/SkDebugCanvas.cpp | 18 | ||||
-rw-r--r-- | tests/CanvasTest.cpp | 2 |
5 files changed, 133 insertions, 54 deletions
diff --git a/include/utils/SkPaintFilterCanvas.h b/include/utils/SkPaintFilterCanvas.h index 0ad7e251b6..505f965565 100644 --- a/include/utils/SkPaintFilterCanvas.h +++ b/include/utils/SkPaintFilterCanvas.h @@ -9,10 +9,11 @@ #define SkPaintFilterCanvas_DEFINED #include "SkNWayCanvas.h" +#include "SkTLazy.h" /** \class SkPaintFilterCanvas - A utility proxy base class for implementing paint filters. + A utility proxy base class for implementing draw/paint filters. */ class SK_API SkPaintFilterCanvas : public SkNWayCanvas { public: @@ -48,13 +49,28 @@ public: protected: /** * Called with the paint that will be used to draw the specified type. - * The implementation may modify the paint as they wish. * - * Note: The base implementation calls onFilterPaint() for top-level/explicit paints only. + * Upon return, if filteredPaint is initialized it will replace the original paint + * for the current draw. Note that that implementation is responsible for + * initializing *filteredPaint (e.g. via set(*paint)). + * + * The result bool is used to determine whether the draw op is to be + * executed (true) or skipped (false). When the draw is skipped, filteredPaint is + * ignored. + * + * Note: The base implementation calls onFilter() for top-level/explicit paints only. * To also filter encapsulated paints (e.g. SkPicture, SkTextBlob), clients may need to * override the relevant methods (i.e. drawPicture, drawTextBlob). */ - virtual void onFilterPaint(SkPaint* paint, Type type) const = 0; + virtual bool onFilter(const SkPaint* paint, Type type, SkTLazy<SkPaint>* filteredPaint) const { + if (paint) { + this->onFilterPaint(filteredPaint->set(*paint), type); + } + return true; + } + + // DEPRECATED - do not use + virtual void onFilterPaint(SkPaint*, Type) const { } void onDrawPaint(const SkPaint&) override; void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override; @@ -66,11 +82,13 @@ protected: void onDrawBitmap(const SkBitmap&, SkScalar left, SkScalar top, const SkPaint*) override; void onDrawBitmapRect(const SkBitmap&, const SkRect* src, const SkRect& dst, const SkPaint*, SrcRectConstraint) override; + void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst, + const SkPaint*) override; void onDrawImage(const SkImage*, SkScalar left, SkScalar top, const SkPaint*) override; void onDrawImageRect(const SkImage*, const SkRect* src, const SkRect& dst, const SkPaint*, SrcRectConstraint) override; - void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst, - const SkPaint*) override; + void onDrawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst, + const SkPaint*) override; void onDrawVertices(VertexMode vmode, int vertexCount, const SkPoint vertices[], const SkPoint texs[], const SkColor colors[], SkXfermode* xmode, diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp index 9f0bd4524c..ce2cfb2590 100644 --- a/samplecode/SampleApp.cpp +++ b/samplecode/SampleApp.cpp @@ -465,34 +465,39 @@ class FlagsFilterCanvas : public SkPaintFilterCanvas { public: FlagsFilterCanvas(SkCanvas* canvas, SkOSMenu::TriState lcd, SkOSMenu::TriState aa, SkOSMenu::TriState subpixel, int hinting, int filterQuality) - : INHERITED(canvas->imageInfo().width(), canvas->imageInfo().height()) + : INHERITED(canvas) , fLCDState(lcd) , fAAState(aa) , fSubpixelState(subpixel) , fHintingState(hinting) , fFilterQualityIndex(filterQuality) { SkASSERT((unsigned)filterQuality < SK_ARRAY_COUNT(gFilterQualityStates)); - - this->addCanvas(canvas); } protected: - void onFilterPaint(SkPaint* paint, Type t) const override { + bool onFilter(const SkPaint* paint, Type t, SkTLazy<SkPaint>* filteredPaint) const override { + if (!paint) { + return true; + } + + filteredPaint->set(*paint); if (kText_Type == t && SkOSMenu::kMixedState != fLCDState) { - paint->setLCDRenderText(SkOSMenu::kOnState == fLCDState); + filteredPaint->get()->setLCDRenderText(SkOSMenu::kOnState == fLCDState); } if (SkOSMenu::kMixedState != fAAState) { - paint->setAntiAlias(SkOSMenu::kOnState == fAAState); + filteredPaint->get()->setAntiAlias(SkOSMenu::kOnState == fAAState); } if (0 != fFilterQualityIndex) { - paint->setFilterQuality(gFilterQualityStates[fFilterQualityIndex].fQuality); + filteredPaint->get()->setFilterQuality( + gFilterQualityStates[fFilterQualityIndex].fQuality); } if (SkOSMenu::kMixedState != fSubpixelState) { - paint->setSubpixelText(SkOSMenu::kOnState == fSubpixelState); + filteredPaint->get()->setSubpixelText(SkOSMenu::kOnState == fSubpixelState); } if (0 != fHintingState && fHintingState < (int)SK_ARRAY_COUNT(gHintingStates)) { - paint->setHinting(gHintingStates[fHintingState].hinting); + filteredPaint->get()->setHinting(gHintingStates[fHintingState].hinting); } + return true; } private: diff --git a/src/utils/SkPaintFilterCanvas.cpp b/src/utils/SkPaintFilterCanvas.cpp index ce1e4b7dbf..0a5b7e6629 100644 --- a/src/utils/SkPaintFilterCanvas.cpp +++ b/src/utils/SkPaintFilterCanvas.cpp @@ -12,20 +12,24 @@ class SkPaintFilterCanvas::AutoPaintFilter { public: - AutoPaintFilter(const SkPaintFilterCanvas* canvas, Type type, const SkPaint* paint) { - if (paint) { - canvas->onFilterPaint(fLazyPaint.set(*paint), type); - } + AutoPaintFilter(const SkPaintFilterCanvas* canvas, Type type, const SkPaint* paint) + : fOrigPaint(paint) { + fShouldDraw = canvas->onFilter(fOrigPaint, type, &fFilteredPaint); } - AutoPaintFilter(const SkPaintFilterCanvas* canvas, Type type, const SkPaint& paint) { - canvas->onFilterPaint(fLazyPaint.set(paint), type); + AutoPaintFilter(const SkPaintFilterCanvas* canvas, Type type, const SkPaint& paint) + : AutoPaintFilter(canvas, type, &paint) { } + + const SkPaint* paint() const { + return fFilteredPaint.isValid() ? fFilteredPaint.get() : fOrigPaint; } - const SkPaint* paint() const { return fLazyPaint.getMaybeNull(); } + bool shouldDraw() const { return fShouldDraw; } private: - SkTLazy<SkPaint> fLazyPaint; + const SkPaint* fOrigPaint; + SkTLazy<SkPaint> fFilteredPaint; + bool fShouldDraw; }; SkPaintFilterCanvas::SkPaintFilterCanvas(int width, int height) : INHERITED(width, height) { } @@ -44,70 +48,102 @@ SkPaintFilterCanvas::SkPaintFilterCanvas(SkCanvas *canvas) void SkPaintFilterCanvas::onDrawPaint(const SkPaint& paint) { AutoPaintFilter apf(this, kPaint_Type, paint); - this->INHERITED::onDrawPaint(*apf.paint()); + if (apf.shouldDraw()) { + this->INHERITED::onDrawPaint(*apf.paint()); + } } void SkPaintFilterCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint) { AutoPaintFilter apf(this, kPoint_Type, paint); - this->INHERITED::onDrawPoints(mode, count, pts, *apf.paint()); + if (apf.shouldDraw()) { + this->INHERITED::onDrawPoints(mode, count, pts, *apf.paint()); + } } void SkPaintFilterCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) { AutoPaintFilter apf(this, kRect_Type, paint); - this->INHERITED::onDrawRect(rect, *apf.paint()); + if (apf.shouldDraw()) { + this->INHERITED::onDrawRect(rect, *apf.paint()); + } } void SkPaintFilterCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { AutoPaintFilter apf(this, kRRect_Type, paint); - this->INHERITED::onDrawRRect(rrect, *apf.paint()); + if (apf.shouldDraw()) { + this->INHERITED::onDrawRRect(rrect, *apf.paint()); + } } void SkPaintFilterCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) { AutoPaintFilter apf(this, kDRRect_Type, paint); - this->INHERITED::onDrawDRRect(outer, inner, *apf.paint()); + if (apf.shouldDraw()) { + this->INHERITED::onDrawDRRect(outer, inner, *apf.paint()); + } } void SkPaintFilterCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) { AutoPaintFilter apf(this, kOval_Type, paint); - this->INHERITED::onDrawOval(rect, *apf.paint()); + if (apf.shouldDraw()) { + this->INHERITED::onDrawOval(rect, *apf.paint()); + } } void SkPaintFilterCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { AutoPaintFilter apf(this, kPath_Type, paint); - this->INHERITED::onDrawPath(path, *apf.paint()); + if (apf.shouldDraw()) { + this->INHERITED::onDrawPath(path, *apf.paint()); + } } void SkPaintFilterCanvas::onDrawBitmap(const SkBitmap& bm, SkScalar left, SkScalar top, const SkPaint* paint) { AutoPaintFilter apf(this, kBitmap_Type, paint); - this->INHERITED::onDrawBitmap(bm, left, top, apf.paint()); + if (apf.shouldDraw()) { + this->INHERITED::onDrawBitmap(bm, left, top, apf.paint()); + } } void SkPaintFilterCanvas::onDrawBitmapRect(const SkBitmap& bm, const SkRect* src, const SkRect& dst, const SkPaint* paint, SrcRectConstraint constraint) { AutoPaintFilter apf(this, kBitmap_Type, paint); - this->INHERITED::onDrawBitmapRect(bm, src, dst, apf.paint(), constraint); + if (apf.shouldDraw()) { + this->INHERITED::onDrawBitmapRect(bm, src, dst, apf.paint(), constraint); + } +} + +void SkPaintFilterCanvas::onDrawBitmapNine(const SkBitmap& bm, const SkIRect& center, + const SkRect& dst, const SkPaint* paint) { + AutoPaintFilter apf(this, kBitmap_Type, paint); + if (apf.shouldDraw()) { + this->INHERITED::onDrawBitmapNine(bm, center, dst, apf.paint()); + } } void SkPaintFilterCanvas::onDrawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint) { AutoPaintFilter apf(this, kBitmap_Type, paint); - this->INHERITED::onDrawImage(image, left, top, apf.paint()); + if (apf.shouldDraw()) { + this->INHERITED::onDrawImage(image, left, top, apf.paint()); + } } void SkPaintFilterCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, const SkPaint* paint, SrcRectConstraint constraint) { AutoPaintFilter apf(this, kBitmap_Type, paint); - this->INHERITED::onDrawImageRect(image, src, dst, apf.paint(), constraint); + if (apf.shouldDraw()) { + this->INHERITED::onDrawImageRect(image, src, dst, apf.paint(), constraint); + } } -void SkPaintFilterCanvas::onDrawBitmapNine(const SkBitmap& bm, const SkIRect& center, - const SkRect& dst, const SkPaint* paint) { +void SkPaintFilterCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, + const SkRect& dst, const SkPaint* paint) { AutoPaintFilter apf(this, kBitmap_Type, paint); - this->INHERITED::onDrawBitmapNine(bm, center, dst, apf.paint()); + if (apf.shouldDraw()) { + this->INHERITED::onDrawImageNine(image, center, dst, apf.paint()); + } } void SkPaintFilterCanvas::onDrawVertices(VertexMode vmode, int vertexCount, @@ -116,49 +152,65 @@ void SkPaintFilterCanvas::onDrawVertices(VertexMode vmode, int vertexCount, const uint16_t indices[], int indexCount, const SkPaint& paint) { AutoPaintFilter apf(this, kVertices_Type, paint); - this->INHERITED::onDrawVertices(vmode, vertexCount, vertices, texs, colors, xmode, indices, - indexCount, *apf.paint()); + if (apf.shouldDraw()) { + this->INHERITED::onDrawVertices(vmode, vertexCount, vertices, texs, colors, xmode, indices, + indexCount, *apf.paint()); + } } void SkPaintFilterCanvas::onDrawPatch(const SkPoint cubics[], const SkColor colors[], const SkPoint texCoords[], SkXfermode* xmode, const SkPaint& paint) { AutoPaintFilter apf(this, kPatch_Type, paint); - this->INHERITED::onDrawPatch(cubics, colors, texCoords, xmode, *apf.paint()); + if (apf.shouldDraw()) { + this->INHERITED::onDrawPatch(cubics, colors, texCoords, xmode, *apf.paint()); + } } void SkPaintFilterCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* m, const SkPaint* paint) { AutoPaintFilter apf(this, kPicture_Type, paint); - this->INHERITED::onDrawPicture(picture, m, apf.paint()); + if (apf.shouldDraw()) { + this->INHERITED::onDrawPicture(picture, m, apf.paint()); + } } void SkPaintFilterCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, const SkPaint& paint) { AutoPaintFilter apf(this, kText_Type, paint); - this->INHERITED::onDrawText(text, byteLength, x, y, *apf.paint()); + if (apf.shouldDraw()) { + this->INHERITED::onDrawText(text, byteLength, x, y, *apf.paint()); + } } void SkPaintFilterCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], const SkPaint& paint) { AutoPaintFilter apf(this, kText_Type, paint); - this->INHERITED::onDrawPosText(text, byteLength, pos, *apf.paint()); + if (apf.shouldDraw()) { + this->INHERITED::onDrawPosText(text, byteLength, pos, *apf.paint()); + } } void SkPaintFilterCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkPaint& paint) { AutoPaintFilter apf(this, kText_Type, paint); - this->INHERITED::onDrawPosTextH(text, byteLength, xpos, constY, *apf.paint()); + if (apf.shouldDraw()) { + this->INHERITED::onDrawPosTextH(text, byteLength, xpos, constY, *apf.paint()); + } } void SkPaintFilterCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, const SkMatrix* matrix, const SkPaint& paint) { AutoPaintFilter apf(this, kText_Type, paint); - this->INHERITED::onDrawTextOnPath(text, byteLength, path, matrix, *apf.paint()); + if (apf.shouldDraw()) { + this->INHERITED::onDrawTextOnPath(text, byteLength, path, matrix, *apf.paint()); + } } void SkPaintFilterCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint) { AutoPaintFilter apf(this, kTextBlob_Type, paint); - this->INHERITED::onDrawTextBlob(blob, x, y, *apf.paint()); + if (apf.shouldDraw()) { + this->INHERITED::onDrawTextBlob(blob, x, y, *apf.paint()); + } } diff --git a/src/utils/debugger/SkDebugCanvas.cpp b/src/utils/debugger/SkDebugCanvas.cpp index 560976cbb7..9f11a9e3f3 100644 --- a/src/utils/debugger/SkDebugCanvas.cpp +++ b/src/utils/debugger/SkDebugCanvas.cpp @@ -69,15 +69,19 @@ public: , fFilterQuality(quality) {} protected: - void onFilterPaint(SkPaint* paint, Type) const override { - if (nullptr != fOverdrawXfermode.get()) { - paint->setAntiAlias(false); - paint->setXfermode(fOverdrawXfermode.get()); - } + bool onFilter(const SkPaint* paint, Type, SkTLazy<SkPaint>* filteredPaint) const override { + if (paint) { + filteredPaint->set(*paint); + if (nullptr != fOverdrawXfermode.get()) { + filteredPaint->get()->setAntiAlias(false); + filteredPaint->get()->setXfermode(fOverdrawXfermode.get()); + } - if (fOverrideFilterQuality) { - paint->setFilterQuality(fFilterQuality); + if (fOverrideFilterQuality) { + filteredPaint->get()->setFilterQuality(fFilterQuality); + } } + return true; } void onDrawPicture(const SkPicture* picture, diff --git a/tests/CanvasTest.cpp b/tests/CanvasTest.cpp index 87705dc7f5..516dd05c25 100644 --- a/tests/CanvasTest.cpp +++ b/tests/CanvasTest.cpp @@ -730,7 +730,7 @@ public: MockFilterCanvas(SkCanvas* canvas) : INHERITED(canvas) { } protected: - void onFilterPaint(SkPaint *paint, Type type) const override { } + bool onFilter(const SkPaint*, Type, SkTLazy<SkPaint>*) const override { return true; } private: typedef SkPaintFilterCanvas INHERITED; |