diff --git a/modules/svg/include/SkSVGNode.h b/modules/svg/include/SkSVGNode.h index a2991f14182db..001b5ca67901f 100644 --- a/modules/svg/include/SkSVGNode.h +++ b/modules/svg/include/SkSVGNode.h @@ -15,6 +15,7 @@ class SkCanvas; class SkMatrix; class SkPaint; class SkPath; +class SkSVGLengthContext; class SkSVGRenderContext; class SkSVGValue; @@ -72,6 +73,7 @@ class SkSVGNode : public SkRefCnt { void render(const SkSVGRenderContext&) const; bool asPaint(const SkSVGRenderContext&, SkPaint*) const; SkPath asPath(const SkSVGRenderContext&) const; + SkRect objectBoundingBox(const SkSVGLengthContext&) const; void setAttribute(SkSVGAttribute, const SkSVGValue&); bool setAttribute(const char* attributeName, const char* attributeValue); @@ -119,6 +121,10 @@ class SkSVGNode : public SkRefCnt { virtual bool hasChildren() const { return false; } + virtual SkRect onObjectBoundingBox(const SkSVGLengthContext&) const { + return SkRect::MakeEmpty(); + } + private: SkSVGTag fTag; diff --git a/modules/svg/include/SkSVGRenderContext.h b/modules/svg/include/SkSVGRenderContext.h index 0659a89e3df71..8b535f3e5c14a 100644 --- a/modules/svg/include/SkSVGRenderContext.h +++ b/modules/svg/include/SkSVGRenderContext.h @@ -59,9 +59,10 @@ struct SkSVGPresentationContext { class SkSVGRenderContext { public: SkSVGRenderContext(SkCanvas*, const SkSVGIDMapper&, const SkSVGLengthContext&, - const SkSVGPresentationContext&); + const SkSVGPresentationContext&, const SkSVGNode*); SkSVGRenderContext(const SkSVGRenderContext&); SkSVGRenderContext(const SkSVGRenderContext&, SkCanvas*); + SkSVGRenderContext(const SkSVGRenderContext&, const SkSVGNode*); ~SkSVGRenderContext(); const SkSVGLengthContext& lengthContext() const { return *fLengthContext; } @@ -119,6 +120,9 @@ class SkSVGRenderContext { // The local computed clip path (not inherited). const SkPath* clipPath() const { return fClipPath.getMaybeNull(); } + // The node being rendered (may be null). + const SkSVGNode* node() const { return fNode; } + private: // Stack-only void* operator new(size_t) = delete; @@ -139,6 +143,8 @@ class SkSVGRenderContext { // clipPath, if present for the current context (not inherited). SkTLazy fClipPath; + + const SkSVGNode* fNode; }; #endif // SkSVGRenderContext_DEFINED diff --git a/modules/svg/src/SkSVGDOM.cpp b/modules/svg/src/SkSVGDOM.cpp index 27e2540773c7b..b989b7000806d 100644 --- a/modules/svg/src/SkSVGDOM.cpp +++ b/modules/svg/src/SkSVGDOM.cpp @@ -593,7 +593,7 @@ void SkSVGDOM::render(SkCanvas* canvas) const { if (fRoot) { SkSVGLengthContext lctx(fContainerSize); SkSVGPresentationContext pctx; - fRoot->render(SkSVGRenderContext(canvas, fIDMapper, lctx, pctx)); + fRoot->render(SkSVGRenderContext(canvas, fIDMapper, lctx, pctx, nullptr)); } } diff --git a/modules/svg/src/SkSVGNode.cpp b/modules/svg/src/SkSVGNode.cpp index ce05aa54d7ac3..cf12945d2db61 100644 --- a/modules/svg/src/SkSVGNode.cpp +++ b/modules/svg/src/SkSVGNode.cpp @@ -19,7 +19,7 @@ SkSVGNode::SkSVGNode(SkSVGTag t) : fTag(t) { } SkSVGNode::~SkSVGNode() { } void SkSVGNode::render(const SkSVGRenderContext& ctx) const { - SkSVGRenderContext localContext(ctx); + SkSVGRenderContext localContext(ctx, this); if (this->onPrepareToRender(&localContext)) { this->onRender(localContext); @@ -48,6 +48,10 @@ SkPath SkSVGNode::asPath(const SkSVGRenderContext& ctx) const { return path; } +SkRect SkSVGNode::objectBoundingBox(const SkSVGLengthContext& lctx) const { + return this->onObjectBoundingBox(lctx); +} + bool SkSVGNode::onPrepareToRender(SkSVGRenderContext* ctx) const { ctx->applyPresentationAttributes(fPresentationAttributes, this->hasChildren() ? 0 : SkSVGRenderContext::kLeaf); diff --git a/modules/svg/src/SkSVGRenderContext.cpp b/modules/svg/src/SkSVGRenderContext.cpp index 759c5cf902695..4b1b93b87adcb 100644 --- a/modules/svg/src/SkSVGRenderContext.cpp +++ b/modules/svg/src/SkSVGRenderContext.cpp @@ -317,7 +317,7 @@ SkSVGPresentationContext::SkSVGPresentationContext() // Commit initial values to the paint cache. SkCanvas fakeCanvas(0, 0); SkSVGRenderContext fake(&fakeCanvas, SkSVGIDMapper(), SkSVGLengthContext(SkSize::Make(0, 0)), - *this); + *this, nullptr); commitToPaint(fInherited, fake, this); commitToPaint(fInherited, fake, this); @@ -332,24 +332,35 @@ SkSVGPresentationContext::SkSVGPresentationContext() SkSVGRenderContext::SkSVGRenderContext(SkCanvas* canvas, const SkSVGIDMapper& mapper, const SkSVGLengthContext& lctx, - const SkSVGPresentationContext& pctx) + const SkSVGPresentationContext& pctx, + const SkSVGNode* node) : fIDMapper(mapper) , fLengthContext(lctx) , fPresentationContext(pctx) , fCanvas(canvas) - , fCanvasSaveCount(canvas->getSaveCount()) {} + , fCanvasSaveCount(canvas->getSaveCount()) + , fNode(node) {} SkSVGRenderContext::SkSVGRenderContext(const SkSVGRenderContext& other) : SkSVGRenderContext(other.fCanvas, other.fIDMapper, *other.fLengthContext, - *other.fPresentationContext) {} + *other.fPresentationContext, + other.fNode) {} SkSVGRenderContext::SkSVGRenderContext(const SkSVGRenderContext& other, SkCanvas* canvas) : SkSVGRenderContext(canvas, other.fIDMapper, *other.fLengthContext, - *other.fPresentationContext) {} + *other.fPresentationContext, + other.fNode) {} + +SkSVGRenderContext::SkSVGRenderContext(const SkSVGRenderContext& other, const SkSVGNode* node) + : SkSVGRenderContext(other.fCanvas, + other.fIDMapper, + *other.fLengthContext, + *other.fPresentationContext, + node) {} SkSVGRenderContext::~SkSVGRenderContext() { fCanvas->restoreToCount(fCanvasSaveCount);