Skip to content

Commit 53281c7

Browse files
tdennistonSkia Commit-Bot
authored andcommitted
[svg] Add current node to render context
A couple of render-time decisions require knowledge of object bounding boxes, such as gradients (whose default coordinate space is "objectBoundingBox". This CL adds the current node being rendered to the render context so that it can be accessed down-stack (for example, when gradients are being resolved and added to the paint as Skia shaders). Each node will overload the bounds computation, for now it just returns empty bounds for all nodes. TBD if we want to cache bounds somewhere, either inside the node object or in a separate cache. Bug: skia:10842 Change-Id: I40061ffedcb840e4dd28dba6351421f5b4fc904b Reviewed-on: https://skia-review.googlesource.com/c/skia/+/329221 Commit-Queue: Tyler Denniston <tdenniston@google.com> Reviewed-by: Florin Malita <fmalita@chromium.org>
1 parent 01b05e5 commit 53281c7

File tree

5 files changed

+35
-8
lines changed

5 files changed

+35
-8
lines changed

modules/svg/include/SkSVGNode.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class SkCanvas;
1515
class SkMatrix;
1616
class SkPaint;
1717
class SkPath;
18+
class SkSVGLengthContext;
1819
class SkSVGRenderContext;
1920
class SkSVGValue;
2021

@@ -72,6 +73,7 @@ class SkSVGNode : public SkRefCnt {
7273
void render(const SkSVGRenderContext&) const;
7374
bool asPaint(const SkSVGRenderContext&, SkPaint*) const;
7475
SkPath asPath(const SkSVGRenderContext&) const;
76+
SkRect objectBoundingBox(const SkSVGLengthContext&) const;
7577

7678
void setAttribute(SkSVGAttribute, const SkSVGValue&);
7779
bool setAttribute(const char* attributeName, const char* attributeValue);
@@ -119,6 +121,10 @@ class SkSVGNode : public SkRefCnt {
119121

120122
virtual bool hasChildren() const { return false; }
121123

124+
virtual SkRect onObjectBoundingBox(const SkSVGLengthContext&) const {
125+
return SkRect::MakeEmpty();
126+
}
127+
122128
private:
123129
SkSVGTag fTag;
124130

modules/svg/include/SkSVGRenderContext.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,10 @@ struct SkSVGPresentationContext {
5959
class SkSVGRenderContext {
6060
public:
6161
SkSVGRenderContext(SkCanvas*, const SkSVGIDMapper&, const SkSVGLengthContext&,
62-
const SkSVGPresentationContext&);
62+
const SkSVGPresentationContext&, const SkSVGNode*);
6363
SkSVGRenderContext(const SkSVGRenderContext&);
6464
SkSVGRenderContext(const SkSVGRenderContext&, SkCanvas*);
65+
SkSVGRenderContext(const SkSVGRenderContext&, const SkSVGNode*);
6566
~SkSVGRenderContext();
6667

6768
const SkSVGLengthContext& lengthContext() const { return *fLengthContext; }
@@ -119,6 +120,9 @@ class SkSVGRenderContext {
119120
// The local computed clip path (not inherited).
120121
const SkPath* clipPath() const { return fClipPath.getMaybeNull(); }
121122

123+
// The node being rendered (may be null).
124+
const SkSVGNode* node() const { return fNode; }
125+
122126
private:
123127
// Stack-only
124128
void* operator new(size_t) = delete;
@@ -139,6 +143,8 @@ class SkSVGRenderContext {
139143

140144
// clipPath, if present for the current context (not inherited).
141145
SkTLazy<SkPath> fClipPath;
146+
147+
const SkSVGNode* fNode;
142148
};
143149

144150
#endif // SkSVGRenderContext_DEFINED

modules/svg/src/SkSVGDOM.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ void SkSVGDOM::render(SkCanvas* canvas) const {
593593
if (fRoot) {
594594
SkSVGLengthContext lctx(fContainerSize);
595595
SkSVGPresentationContext pctx;
596-
fRoot->render(SkSVGRenderContext(canvas, fIDMapper, lctx, pctx));
596+
fRoot->render(SkSVGRenderContext(canvas, fIDMapper, lctx, pctx, nullptr));
597597
}
598598
}
599599

modules/svg/src/SkSVGNode.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ SkSVGNode::SkSVGNode(SkSVGTag t) : fTag(t) { }
1919
SkSVGNode::~SkSVGNode() { }
2020

2121
void SkSVGNode::render(const SkSVGRenderContext& ctx) const {
22-
SkSVGRenderContext localContext(ctx);
22+
SkSVGRenderContext localContext(ctx, this);
2323

2424
if (this->onPrepareToRender(&localContext)) {
2525
this->onRender(localContext);
@@ -48,6 +48,10 @@ SkPath SkSVGNode::asPath(const SkSVGRenderContext& ctx) const {
4848
return path;
4949
}
5050

51+
SkRect SkSVGNode::objectBoundingBox(const SkSVGLengthContext& lctx) const {
52+
return this->onObjectBoundingBox(lctx);
53+
}
54+
5155
bool SkSVGNode::onPrepareToRender(SkSVGRenderContext* ctx) const {
5256
ctx->applyPresentationAttributes(fPresentationAttributes,
5357
this->hasChildren() ? 0 : SkSVGRenderContext::kLeaf);

modules/svg/src/SkSVGRenderContext.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ SkSVGPresentationContext::SkSVGPresentationContext()
317317
// Commit initial values to the paint cache.
318318
SkCanvas fakeCanvas(0, 0);
319319
SkSVGRenderContext fake(&fakeCanvas, SkSVGIDMapper(), SkSVGLengthContext(SkSize::Make(0, 0)),
320-
*this);
320+
*this, nullptr);
321321

322322
commitToPaint<SkSVGAttribute::kFill>(fInherited, fake, this);
323323
commitToPaint<SkSVGAttribute::kFillOpacity>(fInherited, fake, this);
@@ -332,24 +332,35 @@ SkSVGPresentationContext::SkSVGPresentationContext()
332332
SkSVGRenderContext::SkSVGRenderContext(SkCanvas* canvas,
333333
const SkSVGIDMapper& mapper,
334334
const SkSVGLengthContext& lctx,
335-
const SkSVGPresentationContext& pctx)
335+
const SkSVGPresentationContext& pctx,
336+
const SkSVGNode* node)
336337
: fIDMapper(mapper)
337338
, fLengthContext(lctx)
338339
, fPresentationContext(pctx)
339340
, fCanvas(canvas)
340-
, fCanvasSaveCount(canvas->getSaveCount()) {}
341+
, fCanvasSaveCount(canvas->getSaveCount())
342+
, fNode(node) {}
341343

342344
SkSVGRenderContext::SkSVGRenderContext(const SkSVGRenderContext& other)
343345
: SkSVGRenderContext(other.fCanvas,
344346
other.fIDMapper,
345347
*other.fLengthContext,
346-
*other.fPresentationContext) {}
348+
*other.fPresentationContext,
349+
other.fNode) {}
347350

348351
SkSVGRenderContext::SkSVGRenderContext(const SkSVGRenderContext& other, SkCanvas* canvas)
349352
: SkSVGRenderContext(canvas,
350353
other.fIDMapper,
351354
*other.fLengthContext,
352-
*other.fPresentationContext) {}
355+
*other.fPresentationContext,
356+
other.fNode) {}
357+
358+
SkSVGRenderContext::SkSVGRenderContext(const SkSVGRenderContext& other, const SkSVGNode* node)
359+
: SkSVGRenderContext(other.fCanvas,
360+
other.fIDMapper,
361+
*other.fLengthContext,
362+
*other.fPresentationContext,
363+
node) {}
353364

354365
SkSVGRenderContext::~SkSVGRenderContext() {
355366
fCanvas->restoreToCount(fCanvasSaveCount);

0 commit comments

Comments
 (0)