diff --git a/experimental/svg/model/SkSVGNode.cpp b/experimental/svg/model/SkSVGNode.cpp index ec452ec9c6..0f3743ffd2 100644 --- a/experimental/svg/model/SkSVGNode.cpp +++ b/experimental/svg/model/SkSVGNode.cpp @@ -7,6 +7,7 @@ #include "SkCanvas.h" #include "SkMatrix.h" +#include "SkPathOps.h" #include "SkSVGNode.h" #include "SkSVGRenderContext.h" #include "SkSVGValue.h" @@ -32,7 +33,18 @@ bool SkSVGNode::asPaint(const SkSVGRenderContext& ctx, SkPaint* paint) const { SkPath SkSVGNode::asPath(const SkSVGRenderContext& ctx) const { SkSVGRenderContext localContext(ctx); - return this->onPrepareToRender(&localContext) ? this->onAsPath(localContext) : SkPath(); + if (!this->onPrepareToRender(&localContext)) { + return SkPath(); + } + + SkPath path = this->onAsPath(localContext); + + if (const auto* clipPath = localContext.clipPath()) { + // There is a clip-path present on the current node. + Op(path, *clipPath, kIntersect_SkPathOp, &path); + } + + return path; } bool SkSVGNode::onPrepareToRender(SkSVGRenderContext* ctx) const { diff --git a/experimental/svg/model/SkSVGRenderContext.cpp b/experimental/svg/model/SkSVGRenderContext.cpp index d8307a05c0..9de605a034 100644 --- a/experimental/svg/model/SkSVGRenderContext.cpp +++ b/experimental/svg/model/SkSVGRenderContext.cpp @@ -328,12 +328,20 @@ void SkSVGRenderContext::applyClip(const SkSVGClip& clip) { const SkPath clipPath = clipNode->asPath(*this); + // We use the computed clip path in two ways: + // + // - apply to the current canvas, for drawing + // - track in the presentation context, for asPath() composition + // + // TODO: the two uses are exclusive, avoid canvas churn when non needed. + // Only save if needed if (fCanvas->getSaveCount() == fCanvasSaveCount) { fCanvas->save(); } fCanvas->clipPath(clipPath, true); + fClipPath.set(clipPath); } const SkPaint* SkSVGRenderContext::fillPaint() const { diff --git a/experimental/svg/model/SkSVGRenderContext.h b/experimental/svg/model/SkSVGRenderContext.h index ab046cd290..3cd38cbd7f 100644 --- a/experimental/svg/model/SkSVGRenderContext.h +++ b/experimental/svg/model/SkSVGRenderContext.h @@ -9,6 +9,7 @@ #define SkSVGRenderContext_DEFINED #include "SkPaint.h" +#include "SkPath.h" #include "SkRect.h" #include "SkSize.h" #include "SkSVGAttribute.h" @@ -79,6 +80,9 @@ public: const SkPaint* fillPaint() const; const SkPaint* strokePaint() const; + // The local computed clip path (not inherited). + const SkPath* clipPath() const { return fClipPath.getMaybeNull(); } + private: // Stack-only void* operator new(size_t) = delete; @@ -95,6 +99,9 @@ private: // The save count on 'fCanvas' at construction time. // A restoreToCount() will be issued on destruction. int fCanvasSaveCount; + + // clipPath, if present for the current context (not inherited). + SkTLazy fClipPath; }; #endif // SkSVGRenderContext_DEFINED