blob: 0f3743ffd20e5ce95d64ca50f8d1a3859c705172 [file] [log] [blame]
fmalita6ceef3d2016-07-26 18:46:34 -07001/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SkCanvas.h"
9#include "SkMatrix.h"
Florin Malita7d529882016-12-08 16:04:24 -050010#include "SkPathOps.h"
fmalita6ceef3d2016-07-26 18:46:34 -070011#include "SkSVGNode.h"
12#include "SkSVGRenderContext.h"
13#include "SkSVGValue.h"
14#include "SkTLazy.h"
15
16SkSVGNode::SkSVGNode(SkSVGTag t) : fTag(t) { }
17
18SkSVGNode::~SkSVGNode() { }
19
fmalita397a5172016-08-08 11:38:55 -070020void SkSVGNode::render(const SkSVGRenderContext& ctx) const {
21 SkSVGRenderContext localContext(ctx);
fmalita6ceef3d2016-07-26 18:46:34 -070022
fmalita397a5172016-08-08 11:38:55 -070023 if (this->onPrepareToRender(&localContext)) {
24 this->onRender(localContext);
fmalita6ceef3d2016-07-26 18:46:34 -070025 }
fmalita397a5172016-08-08 11:38:55 -070026}
fmalita6ceef3d2016-07-26 18:46:34 -070027
fmalita28d5b722016-09-12 17:06:47 -070028bool SkSVGNode::asPaint(const SkSVGRenderContext& ctx, SkPaint* paint) const {
29 SkSVGRenderContext localContext(ctx);
30
31 return this->onPrepareToRender(&localContext) && this->onAsPaint(localContext, paint);
32}
33
Florin Malitace8840e2016-12-08 09:26:47 -050034SkPath SkSVGNode::asPath(const SkSVGRenderContext& ctx) const {
35 SkSVGRenderContext localContext(ctx);
Florin Malita7d529882016-12-08 16:04:24 -050036 if (!this->onPrepareToRender(&localContext)) {
37 return SkPath();
38 }
39
40 SkPath path = this->onAsPath(localContext);
41
42 if (const auto* clipPath = localContext.clipPath()) {
43 // There is a clip-path present on the current node.
44 Op(path, *clipPath, kIntersect_SkPathOp, &path);
45 }
46
47 return path;
Florin Malitace8840e2016-12-08 09:26:47 -050048}
49
fmalita397a5172016-08-08 11:38:55 -070050bool SkSVGNode::onPrepareToRender(SkSVGRenderContext* ctx) const {
fmalitabef51c22016-09-20 15:45:57 -070051 ctx->applyPresentationAttributes(fPresentationAttributes,
52 this->hasChildren() ? 0 : SkSVGRenderContext::kLeaf);
fmalita397a5172016-08-08 11:38:55 -070053 return true;
fmalita6ceef3d2016-07-26 18:46:34 -070054}
55
56void SkSVGNode::setAttribute(SkSVGAttribute attr, const SkSVGValue& v) {
57 this->onSetAttribute(attr, v);
58}
59
Florin Malitace8840e2016-12-08 09:26:47 -050060void SkSVGNode::setClipPath(const SkSVGClip& clip) {
61 fPresentationAttributes.fClipPath.set(clip);
62}
63
fmalitaca39d712016-08-12 13:17:11 -070064void SkSVGNode::setFill(const SkSVGPaint& svgPaint) {
65 fPresentationAttributes.fFill.set(svgPaint);
66}
67
68void SkSVGNode::setFillOpacity(const SkSVGNumberType& opacity) {
69 fPresentationAttributes.fFillOpacity.set(
70 SkSVGNumberType(SkTPin<SkScalar>(opacity.value(), 0, 1)));
71}
72
Florin Malitae932d4b2016-12-01 13:35:11 -050073void SkSVGNode::setFillRule(const SkSVGFillRule& fillRule) {
74 fPresentationAttributes.fFillRule.set(fillRule);
75}
76
fmalita6fb06482016-08-15 12:45:11 -070077void SkSVGNode::setOpacity(const SkSVGNumberType& opacity) {
78 fPresentationAttributes.fOpacity.set(
79 SkSVGNumberType(SkTPin<SkScalar>(opacity.value(), 0, 1)));
80}
81
fmalitaca39d712016-08-12 13:17:11 -070082void SkSVGNode::setStroke(const SkSVGPaint& svgPaint) {
83 fPresentationAttributes.fStroke.set(svgPaint);
84}
85
86void SkSVGNode::setStrokeOpacity(const SkSVGNumberType& opacity) {
87 fPresentationAttributes.fStrokeOpacity.set(
88 SkSVGNumberType(SkTPin<SkScalar>(opacity.value(), 0, 1)));
89}
90
91void SkSVGNode::setStrokeWidth(const SkSVGLength& strokeWidth) {
92 fPresentationAttributes.fStrokeWidth.set(strokeWidth);
93}
94
fmalita6ceef3d2016-07-26 18:46:34 -070095void SkSVGNode::onSetAttribute(SkSVGAttribute attr, const SkSVGValue& v) {
96 switch (attr) {
Florin Malitace8840e2016-12-08 09:26:47 -050097 case SkSVGAttribute::kClipPath:
98 if (const SkSVGClipValue* clip = v.as<SkSVGClipValue>()) {
99 this->setClipPath(*clip);
100 }
101 break;
fmalita58649cc2016-07-29 08:52:03 -0700102 case SkSVGAttribute::kFill:
fmalita2d961e02016-08-11 09:16:29 -0700103 if (const SkSVGPaintValue* paint = v.as<SkSVGPaintValue>()) {
fmalitaca39d712016-08-12 13:17:11 -0700104 this->setFill(*paint);
fmalita2d961e02016-08-11 09:16:29 -0700105 }
106 break;
107 case SkSVGAttribute::kFillOpacity:
108 if (const SkSVGNumberValue* opacity = v.as<SkSVGNumberValue>()) {
fmalitaca39d712016-08-12 13:17:11 -0700109 this->setFillOpacity(*opacity);
fmalita6ceef3d2016-07-26 18:46:34 -0700110 }
111 break;
Florin Malitae932d4b2016-12-01 13:35:11 -0500112 case SkSVGAttribute::kFillRule:
113 if (const SkSVGFillRuleValue* fillRule = v.as<SkSVGFillRuleValue>()) {
114 this->setFillRule(*fillRule);
115 }
116 break;
fmalita6fb06482016-08-15 12:45:11 -0700117 case SkSVGAttribute::kOpacity:
118 if (const SkSVGNumberValue* opacity = v.as<SkSVGNumberValue>()) {
119 this->setOpacity(*opacity);
120 }
121 break;
fmalita58649cc2016-07-29 08:52:03 -0700122 case SkSVGAttribute::kStroke:
fmalita2d961e02016-08-11 09:16:29 -0700123 if (const SkSVGPaintValue* paint = v.as<SkSVGPaintValue>()) {
fmalitaca39d712016-08-12 13:17:11 -0700124 this->setStroke(*paint);
fmalita2d961e02016-08-11 09:16:29 -0700125 }
126 break;
127 case SkSVGAttribute::kStrokeOpacity:
128 if (const SkSVGNumberValue* opacity = v.as<SkSVGNumberValue>()) {
fmalitaca39d712016-08-12 13:17:11 -0700129 this->setStrokeOpacity(*opacity);
fmalita2d961e02016-08-11 09:16:29 -0700130 }
131 break;
132 case SkSVGAttribute::kStrokeLineCap:
133 if (const SkSVGLineCapValue* lineCap = v.as<SkSVGLineCapValue>()) {
134 fPresentationAttributes.fStrokeLineCap.set(*lineCap);
135 }
136 break;
137 case SkSVGAttribute::kStrokeLineJoin:
138 if (const SkSVGLineJoinValue* lineJoin = v.as<SkSVGLineJoinValue>()) {
139 fPresentationAttributes.fStrokeLineJoin.set(*lineJoin);
140 }
141 break;
142 case SkSVGAttribute::kStrokeWidth:
143 if (const SkSVGLengthValue* strokeWidth = v.as<SkSVGLengthValue>()) {
fmalitaca39d712016-08-12 13:17:11 -0700144 this->setStrokeWidth(*strokeWidth);
fmalita6ceef3d2016-07-26 18:46:34 -0700145 }
146 break;
147 default:
fmalitabffc2562016-08-03 10:21:11 -0700148 SkDebugf("attribute ID <%d> ignored for node <%d>\n", attr, fTag);
fmalita6ceef3d2016-07-26 18:46:34 -0700149 break;
150 }
151}