blob: 245f36e7d34ec1f00c22c4ff3d7fc578ff71a6cf [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "experimental/svg/model/SkSVGNode.h"
9#include "experimental/svg/model/SkSVGRenderContext.h"
10#include "experimental/svg/model/SkSVGValue.h"
11#include "include/core/SkCanvas.h"
12#include "include/core/SkMatrix.h"
13#include "include/pathops/SkPathOps.h"
14#include "src/core/SkTLazy.h"
fmalita6ceef3d2016-07-26 18:46:34 -070015
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);
Florin Malitaffe6ae42017-10-12 11:33:28 -040053
54 // visibility:hidden disables rendering
55 const auto visibility = ctx->presentationContext().fInherited.fVisibility.get()->type();
56 return visibility != SkSVGVisibility::Type::kHidden;
fmalita6ceef3d2016-07-26 18:46:34 -070057}
58
59void SkSVGNode::setAttribute(SkSVGAttribute attr, const SkSVGValue& v) {
60 this->onSetAttribute(attr, v);
61}
62
Florin Malitace8840e2016-12-08 09:26:47 -050063void SkSVGNode::setClipPath(const SkSVGClip& clip) {
64 fPresentationAttributes.fClipPath.set(clip);
65}
66
Florin Malita09294252020-04-09 08:54:29 -040067template <typename T>
68void SetInheritedByDefault(SkTLazy<T>& presentation_attribute, const T& value) {
69 if (value.type() != T::Type::kInherit) {
70 presentation_attribute.set(value);
71 } else {
72 // kInherited values are semantically equivalent to
73 // the absence of a local presentation attribute.
74 presentation_attribute.reset();
75 }
76}
77
Florin Malita57a0edf2017-10-10 11:22:08 -040078void SkSVGNode::setClipRule(const SkSVGFillRule& clipRule) {
Florin Malita09294252020-04-09 08:54:29 -040079 SetInheritedByDefault(fPresentationAttributes.fClipRule, clipRule);
Florin Malita57a0edf2017-10-10 11:22:08 -040080}
81
Tyler Denniston6c8314e2020-04-09 14:14:10 -040082void SkSVGNode::setColor(const SkSVGColorType& color) {
83 // TODO: Color should be inherited by default
84 fPresentationAttributes.fColor.set(color);
85}
86
fmalitaca39d712016-08-12 13:17:11 -070087void SkSVGNode::setFill(const SkSVGPaint& svgPaint) {
Florin Malita09294252020-04-09 08:54:29 -040088 SetInheritedByDefault(fPresentationAttributes.fFill, svgPaint);
fmalitaca39d712016-08-12 13:17:11 -070089}
90
91void SkSVGNode::setFillOpacity(const SkSVGNumberType& opacity) {
92 fPresentationAttributes.fFillOpacity.set(
93 SkSVGNumberType(SkTPin<SkScalar>(opacity.value(), 0, 1)));
94}
95
Florin Malitae932d4b2016-12-01 13:35:11 -050096void SkSVGNode::setFillRule(const SkSVGFillRule& fillRule) {
Florin Malita09294252020-04-09 08:54:29 -040097 SetInheritedByDefault(fPresentationAttributes.fFillRule, fillRule);
Florin Malitae932d4b2016-12-01 13:35:11 -050098}
99
fmalita6fb06482016-08-15 12:45:11 -0700100void SkSVGNode::setOpacity(const SkSVGNumberType& opacity) {
101 fPresentationAttributes.fOpacity.set(
102 SkSVGNumberType(SkTPin<SkScalar>(opacity.value(), 0, 1)));
103}
104
fmalitaca39d712016-08-12 13:17:11 -0700105void SkSVGNode::setStroke(const SkSVGPaint& svgPaint) {
Florin Malita09294252020-04-09 08:54:29 -0400106 SetInheritedByDefault(fPresentationAttributes.fStroke, svgPaint);
fmalitaca39d712016-08-12 13:17:11 -0700107}
108
Florin Malitaf543a602017-10-13 14:07:44 -0400109void SkSVGNode::setStrokeDashArray(const SkSVGDashArray& dashArray) {
Florin Malita09294252020-04-09 08:54:29 -0400110 SetInheritedByDefault(fPresentationAttributes.fStrokeDashArray, dashArray);
Florin Malitaf543a602017-10-13 14:07:44 -0400111}
112
Florin Malitae1dadd72017-10-13 18:18:32 -0400113void SkSVGNode::setStrokeDashOffset(const SkSVGLength& dashOffset) {
114 fPresentationAttributes.fStrokeDashOffset.set(dashOffset);
115}
116
fmalitaca39d712016-08-12 13:17:11 -0700117void SkSVGNode::setStrokeOpacity(const SkSVGNumberType& opacity) {
118 fPresentationAttributes.fStrokeOpacity.set(
119 SkSVGNumberType(SkTPin<SkScalar>(opacity.value(), 0, 1)));
120}
121
Florin Malita09294252020-04-09 08:54:29 -0400122void SkSVGNode::setStrokeLineCap(const SkSVGLineCap& lc) {
123 SetInheritedByDefault(fPresentationAttributes.fStrokeLineCap, lc);
124}
125
126void SkSVGNode::setStrokeLineJoin(const SkSVGLineJoin& lj) {
127 SetInheritedByDefault(fPresentationAttributes.fStrokeLineJoin, lj);
128}
129
130void SkSVGNode::setStrokeMiterLimit(const SkSVGNumberType& ml) {
131 fPresentationAttributes.fStrokeMiterLimit.set(ml);
132}
133
fmalitaca39d712016-08-12 13:17:11 -0700134void SkSVGNode::setStrokeWidth(const SkSVGLength& strokeWidth) {
135 fPresentationAttributes.fStrokeWidth.set(strokeWidth);
136}
137
Florin Malitaffe6ae42017-10-12 11:33:28 -0400138void SkSVGNode::setVisibility(const SkSVGVisibility& visibility) {
Florin Malita09294252020-04-09 08:54:29 -0400139 SetInheritedByDefault(fPresentationAttributes.fVisibility, visibility);
Florin Malitaffe6ae42017-10-12 11:33:28 -0400140}
141
fmalita6ceef3d2016-07-26 18:46:34 -0700142void SkSVGNode::onSetAttribute(SkSVGAttribute attr, const SkSVGValue& v) {
143 switch (attr) {
Florin Malitace8840e2016-12-08 09:26:47 -0500144 case SkSVGAttribute::kClipPath:
145 if (const SkSVGClipValue* clip = v.as<SkSVGClipValue>()) {
146 this->setClipPath(*clip);
147 }
148 break;
Florin Malita57a0edf2017-10-10 11:22:08 -0400149 case SkSVGAttribute::kClipRule:
150 if (const SkSVGFillRuleValue* clipRule = v.as<SkSVGFillRuleValue>()) {
151 this->setClipRule(*clipRule);
152 }
153 break;
Tyler Denniston6c8314e2020-04-09 14:14:10 -0400154 case SkSVGAttribute::kColor:
155 if (const SkSVGColorValue* color = v.as<SkSVGColorValue>()) {
156 this->setColor(*color);
157 }
158 break;
fmalita58649cc2016-07-29 08:52:03 -0700159 case SkSVGAttribute::kFill:
fmalita2d961e02016-08-11 09:16:29 -0700160 if (const SkSVGPaintValue* paint = v.as<SkSVGPaintValue>()) {
fmalitaca39d712016-08-12 13:17:11 -0700161 this->setFill(*paint);
fmalita2d961e02016-08-11 09:16:29 -0700162 }
163 break;
164 case SkSVGAttribute::kFillOpacity:
165 if (const SkSVGNumberValue* opacity = v.as<SkSVGNumberValue>()) {
fmalitaca39d712016-08-12 13:17:11 -0700166 this->setFillOpacity(*opacity);
fmalita6ceef3d2016-07-26 18:46:34 -0700167 }
168 break;
Florin Malitae932d4b2016-12-01 13:35:11 -0500169 case SkSVGAttribute::kFillRule:
170 if (const SkSVGFillRuleValue* fillRule = v.as<SkSVGFillRuleValue>()) {
171 this->setFillRule(*fillRule);
172 }
173 break;
fmalita6fb06482016-08-15 12:45:11 -0700174 case SkSVGAttribute::kOpacity:
175 if (const SkSVGNumberValue* opacity = v.as<SkSVGNumberValue>()) {
176 this->setOpacity(*opacity);
177 }
178 break;
fmalita58649cc2016-07-29 08:52:03 -0700179 case SkSVGAttribute::kStroke:
fmalita2d961e02016-08-11 09:16:29 -0700180 if (const SkSVGPaintValue* paint = v.as<SkSVGPaintValue>()) {
fmalitaca39d712016-08-12 13:17:11 -0700181 this->setStroke(*paint);
fmalita2d961e02016-08-11 09:16:29 -0700182 }
183 break;
Florin Malitaf543a602017-10-13 14:07:44 -0400184 case SkSVGAttribute::kStrokeDashArray:
185 if (const SkSVGDashArrayValue* dashArray = v.as<SkSVGDashArrayValue>()) {
186 this->setStrokeDashArray(*dashArray);
187 }
188 break;
Florin Malitae1dadd72017-10-13 18:18:32 -0400189 case SkSVGAttribute::kStrokeDashOffset:
190 if (const SkSVGLengthValue* dashOffset= v.as<SkSVGLengthValue>()) {
191 this->setStrokeDashOffset(*dashOffset);
192 }
193 break;
fmalita2d961e02016-08-11 09:16:29 -0700194 case SkSVGAttribute::kStrokeOpacity:
195 if (const SkSVGNumberValue* opacity = v.as<SkSVGNumberValue>()) {
fmalitaca39d712016-08-12 13:17:11 -0700196 this->setStrokeOpacity(*opacity);
fmalita2d961e02016-08-11 09:16:29 -0700197 }
198 break;
199 case SkSVGAttribute::kStrokeLineCap:
200 if (const SkSVGLineCapValue* lineCap = v.as<SkSVGLineCapValue>()) {
Florin Malita09294252020-04-09 08:54:29 -0400201 this->setStrokeLineCap(*lineCap);
fmalita2d961e02016-08-11 09:16:29 -0700202 }
203 break;
204 case SkSVGAttribute::kStrokeLineJoin:
205 if (const SkSVGLineJoinValue* lineJoin = v.as<SkSVGLineJoinValue>()) {
Florin Malita09294252020-04-09 08:54:29 -0400206 this->setStrokeLineJoin(*lineJoin);
fmalita2d961e02016-08-11 09:16:29 -0700207 }
208 break;
Florin Malita4de426b2017-10-09 12:57:41 -0400209 case SkSVGAttribute::kStrokeMiterLimit:
210 if (const SkSVGNumberValue* miterLimit = v.as<SkSVGNumberValue>()) {
Florin Malita09294252020-04-09 08:54:29 -0400211 this->setStrokeMiterLimit(*miterLimit);
Florin Malita4de426b2017-10-09 12:57:41 -0400212 }
213 break;
fmalita2d961e02016-08-11 09:16:29 -0700214 case SkSVGAttribute::kStrokeWidth:
215 if (const SkSVGLengthValue* strokeWidth = v.as<SkSVGLengthValue>()) {
fmalitaca39d712016-08-12 13:17:11 -0700216 this->setStrokeWidth(*strokeWidth);
fmalita6ceef3d2016-07-26 18:46:34 -0700217 }
218 break;
Florin Malitaffe6ae42017-10-12 11:33:28 -0400219 case SkSVGAttribute::kVisibility:
220 if (const SkSVGVisibilityValue* visibility = v.as<SkSVGVisibilityValue>()) {
221 this->setVisibility(*visibility);
222 }
223 break;
fmalita6ceef3d2016-07-26 18:46:34 -0700224 default:
Florin Malitac9649ce2018-02-16 13:49:48 -0500225#if defined(SK_VERBOSE_SVG_PARSING)
226 SkDebugf("attribute ID <%d> ignored for node <%d>\n", attr, fTag);
227#endif
fmalita6ceef3d2016-07-26 18:46:34 -0700228 break;
229 }
230}