blob: ce05aa54d7ac3dd467604b166bac9914966d6317 [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 "include/core/SkCanvas.h"
9#include "include/core/SkMatrix.h"
10#include "include/pathops/SkPathOps.h"
Mike Klein8aa0edf2020-10-16 11:04:18 -050011#include "include/private/SkTPin.h"
Florin Malitab3418102020-10-15 18:10:29 -040012#include "modules/svg/include/SkSVGNode.h"
13#include "modules/svg/include/SkSVGRenderContext.h"
14#include "modules/svg/include/SkSVGValue.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050015#include "src/core/SkTLazy.h"
fmalita6ceef3d2016-07-26 18:46:34 -070016
17SkSVGNode::SkSVGNode(SkSVGTag t) : fTag(t) { }
18
19SkSVGNode::~SkSVGNode() { }
20
fmalita397a5172016-08-08 11:38:55 -070021void SkSVGNode::render(const SkSVGRenderContext& ctx) const {
22 SkSVGRenderContext localContext(ctx);
fmalita6ceef3d2016-07-26 18:46:34 -070023
fmalita397a5172016-08-08 11:38:55 -070024 if (this->onPrepareToRender(&localContext)) {
25 this->onRender(localContext);
fmalita6ceef3d2016-07-26 18:46:34 -070026 }
fmalita397a5172016-08-08 11:38:55 -070027}
fmalita6ceef3d2016-07-26 18:46:34 -070028
fmalita28d5b722016-09-12 17:06:47 -070029bool SkSVGNode::asPaint(const SkSVGRenderContext& ctx, SkPaint* paint) const {
30 SkSVGRenderContext localContext(ctx);
31
32 return this->onPrepareToRender(&localContext) && this->onAsPaint(localContext, paint);
33}
34
Florin Malitace8840e2016-12-08 09:26:47 -050035SkPath SkSVGNode::asPath(const SkSVGRenderContext& ctx) const {
36 SkSVGRenderContext localContext(ctx);
Florin Malita7d529882016-12-08 16:04:24 -050037 if (!this->onPrepareToRender(&localContext)) {
38 return SkPath();
39 }
40
41 SkPath path = this->onAsPath(localContext);
42
43 if (const auto* clipPath = localContext.clipPath()) {
44 // There is a clip-path present on the current node.
45 Op(path, *clipPath, kIntersect_SkPathOp, &path);
46 }
47
48 return path;
Florin Malitace8840e2016-12-08 09:26:47 -050049}
50
fmalita397a5172016-08-08 11:38:55 -070051bool SkSVGNode::onPrepareToRender(SkSVGRenderContext* ctx) const {
fmalitabef51c22016-09-20 15:45:57 -070052 ctx->applyPresentationAttributes(fPresentationAttributes,
53 this->hasChildren() ? 0 : SkSVGRenderContext::kLeaf);
Florin Malitaffe6ae42017-10-12 11:33:28 -040054
55 // visibility:hidden disables rendering
John Stilesa008b0f2020-08-16 08:48:02 -040056 const auto visibility = ctx->presentationContext().fInherited.fVisibility->type();
Florin Malitaffe6ae42017-10-12 11:33:28 -040057 return visibility != SkSVGVisibility::Type::kHidden;
fmalita6ceef3d2016-07-26 18:46:34 -070058}
59
Florin Malitaf4403e72020-04-10 14:14:04 +000060void SkSVGNode::setAttribute(SkSVGAttribute attr, const SkSVGValue& v) {
fmalita6ceef3d2016-07-26 18:46:34 -070061 this->onSetAttribute(attr, v);
62}
63
Florin Malitace8840e2016-12-08 09:26:47 -050064void SkSVGNode::setClipPath(const SkSVGClip& clip) {
65 fPresentationAttributes.fClipPath.set(clip);
66}
67
Florin Malita09294252020-04-09 08:54:29 -040068template <typename T>
69void SetInheritedByDefault(SkTLazy<T>& presentation_attribute, const T& value) {
70 if (value.type() != T::Type::kInherit) {
71 presentation_attribute.set(value);
72 } else {
73 // kInherited values are semantically equivalent to
74 // the absence of a local presentation attribute.
75 presentation_attribute.reset();
76 }
77}
78
Florin Malita57a0edf2017-10-10 11:22:08 -040079void SkSVGNode::setClipRule(const SkSVGFillRule& clipRule) {
Florin Malita09294252020-04-09 08:54:29 -040080 SetInheritedByDefault(fPresentationAttributes.fClipRule, clipRule);
Florin Malita57a0edf2017-10-10 11:22:08 -040081}
82
Tyler Denniston6c8314e2020-04-09 14:14:10 -040083void SkSVGNode::setColor(const SkSVGColorType& color) {
84 // TODO: Color should be inherited by default
85 fPresentationAttributes.fColor.set(color);
86}
87
fmalitaca39d712016-08-12 13:17:11 -070088void SkSVGNode::setFill(const SkSVGPaint& svgPaint) {
Florin Malita09294252020-04-09 08:54:29 -040089 SetInheritedByDefault(fPresentationAttributes.fFill, svgPaint);
fmalitaca39d712016-08-12 13:17:11 -070090}
91
92void SkSVGNode::setFillOpacity(const SkSVGNumberType& opacity) {
Florin Malitaa3626692020-04-09 14:36:45 -040093 fPresentationAttributes.fFillOpacity.set(SkSVGNumberType(SkTPin<SkScalar>(opacity, 0, 1)));
fmalitaca39d712016-08-12 13:17:11 -070094}
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) {
Florin Malitaa3626692020-04-09 14:36:45 -0400101 fPresentationAttributes.fOpacity.set(SkSVGNumberType(SkTPin<SkScalar>(opacity, 0, 1)));
fmalita6fb06482016-08-15 12:45:11 -0700102}
103
fmalitaca39d712016-08-12 13:17:11 -0700104void SkSVGNode::setStroke(const SkSVGPaint& svgPaint) {
Florin Malita09294252020-04-09 08:54:29 -0400105 SetInheritedByDefault(fPresentationAttributes.fStroke, svgPaint);
fmalitaca39d712016-08-12 13:17:11 -0700106}
107
Florin Malitaf543a602017-10-13 14:07:44 -0400108void SkSVGNode::setStrokeDashArray(const SkSVGDashArray& dashArray) {
Florin Malita09294252020-04-09 08:54:29 -0400109 SetInheritedByDefault(fPresentationAttributes.fStrokeDashArray, dashArray);
Florin Malitaf543a602017-10-13 14:07:44 -0400110}
111
Florin Malitae1dadd72017-10-13 18:18:32 -0400112void SkSVGNode::setStrokeDashOffset(const SkSVGLength& dashOffset) {
113 fPresentationAttributes.fStrokeDashOffset.set(dashOffset);
114}
115
fmalitaca39d712016-08-12 13:17:11 -0700116void SkSVGNode::setStrokeOpacity(const SkSVGNumberType& opacity) {
Florin Malitaa3626692020-04-09 14:36:45 -0400117 fPresentationAttributes.fStrokeOpacity.set(SkSVGNumberType(SkTPin<SkScalar>(opacity, 0, 1)));
fmalitaca39d712016-08-12 13:17:11 -0700118}
119
Florin Malita09294252020-04-09 08:54:29 -0400120void SkSVGNode::setStrokeLineCap(const SkSVGLineCap& lc) {
121 SetInheritedByDefault(fPresentationAttributes.fStrokeLineCap, lc);
122}
123
124void SkSVGNode::setStrokeLineJoin(const SkSVGLineJoin& lj) {
125 SetInheritedByDefault(fPresentationAttributes.fStrokeLineJoin, lj);
126}
127
128void SkSVGNode::setStrokeMiterLimit(const SkSVGNumberType& ml) {
129 fPresentationAttributes.fStrokeMiterLimit.set(ml);
130}
131
fmalitaca39d712016-08-12 13:17:11 -0700132void SkSVGNode::setStrokeWidth(const SkSVGLength& strokeWidth) {
133 fPresentationAttributes.fStrokeWidth.set(strokeWidth);
134}
135
Florin Malitaffe6ae42017-10-12 11:33:28 -0400136void SkSVGNode::setVisibility(const SkSVGVisibility& visibility) {
Florin Malita09294252020-04-09 08:54:29 -0400137 SetInheritedByDefault(fPresentationAttributes.fVisibility, visibility);
Florin Malitaffe6ae42017-10-12 11:33:28 -0400138}
139
Florin Malitaf4403e72020-04-10 14:14:04 +0000140void SkSVGNode::onSetAttribute(SkSVGAttribute attr, const SkSVGValue& v) {
fmalita6ceef3d2016-07-26 18:46:34 -0700141 switch (attr) {
Florin Malitace8840e2016-12-08 09:26:47 -0500142 case SkSVGAttribute::kClipPath:
Florin Malitaf4403e72020-04-10 14:14:04 +0000143 if (const SkSVGClipValue* clip = v.as<SkSVGClipValue>()) {
Florin Malitace8840e2016-12-08 09:26:47 -0500144 this->setClipPath(*clip);
145 }
146 break;
Florin Malita57a0edf2017-10-10 11:22:08 -0400147 case SkSVGAttribute::kClipRule:
Florin Malitaf4403e72020-04-10 14:14:04 +0000148 if (const SkSVGFillRuleValue* clipRule = v.as<SkSVGFillRuleValue>()) {
Florin Malita57a0edf2017-10-10 11:22:08 -0400149 this->setClipRule(*clipRule);
150 }
151 break;
Tyler Denniston6c8314e2020-04-09 14:14:10 -0400152 case SkSVGAttribute::kColor:
Florin Malitaf4403e72020-04-10 14:14:04 +0000153 if (const SkSVGColorValue* color = v.as<SkSVGColorValue>()) {
Tyler Denniston6c8314e2020-04-09 14:14:10 -0400154 this->setColor(*color);
155 }
156 break;
fmalita58649cc2016-07-29 08:52:03 -0700157 case SkSVGAttribute::kFill:
Florin Malitaf4403e72020-04-10 14:14:04 +0000158 if (const SkSVGPaintValue* paint = v.as<SkSVGPaintValue>()) {
fmalitaca39d712016-08-12 13:17:11 -0700159 this->setFill(*paint);
fmalita2d961e02016-08-11 09:16:29 -0700160 }
161 break;
162 case SkSVGAttribute::kFillOpacity:
Florin Malitaf4403e72020-04-10 14:14:04 +0000163 if (const SkSVGNumberValue* opacity = v.as<SkSVGNumberValue>()) {
fmalitaca39d712016-08-12 13:17:11 -0700164 this->setFillOpacity(*opacity);
fmalita6ceef3d2016-07-26 18:46:34 -0700165 }
166 break;
Florin Malitae932d4b2016-12-01 13:35:11 -0500167 case SkSVGAttribute::kFillRule:
Florin Malitaf4403e72020-04-10 14:14:04 +0000168 if (const SkSVGFillRuleValue* fillRule = v.as<SkSVGFillRuleValue>()) {
Florin Malitae932d4b2016-12-01 13:35:11 -0500169 this->setFillRule(*fillRule);
170 }
171 break;
Florin Malita39fe8c82020-10-20 10:43:03 -0400172 case SkSVGAttribute::kFontFamily:
173 if (const SkSVGFontFamilyValue* family = v.as<SkSVGFontFamilyValue>()) {
174 this->setFontFamily(*family);
175 }
176 break;
177 case SkSVGAttribute::kFontSize:
178 if (const SkSVGFontSizeValue* size = v.as<SkSVGFontSizeValue>()) {
179 this->setFontSize(*size);
180 }
181 break;
182 case SkSVGAttribute::kFontStyle:
183 if (const SkSVGFontStyleValue* style = v.as<SkSVGFontStyleValue>()) {
184 this->setFontStyle(*style);
185 }
186 break;
187 case SkSVGAttribute::kFontWeight:
188 if (const SkSVGFontWeightValue* style = v.as<SkSVGFontWeightValue>()) {
189 this->setFontWeight(*style);
190 }
191 break;
fmalita6fb06482016-08-15 12:45:11 -0700192 case SkSVGAttribute::kOpacity:
Florin Malitaf4403e72020-04-10 14:14:04 +0000193 if (const SkSVGNumberValue* opacity = v.as<SkSVGNumberValue>()) {
fmalita6fb06482016-08-15 12:45:11 -0700194 this->setOpacity(*opacity);
195 }
196 break;
fmalita58649cc2016-07-29 08:52:03 -0700197 case SkSVGAttribute::kStroke:
Florin Malitaf4403e72020-04-10 14:14:04 +0000198 if (const SkSVGPaintValue* paint = v.as<SkSVGPaintValue>()) {
fmalitaca39d712016-08-12 13:17:11 -0700199 this->setStroke(*paint);
fmalita2d961e02016-08-11 09:16:29 -0700200 }
201 break;
Florin Malitaf543a602017-10-13 14:07:44 -0400202 case SkSVGAttribute::kStrokeDashArray:
Florin Malitaf4403e72020-04-10 14:14:04 +0000203 if (const SkSVGDashArrayValue* dashArray = v.as<SkSVGDashArrayValue>()) {
Florin Malitaf543a602017-10-13 14:07:44 -0400204 this->setStrokeDashArray(*dashArray);
205 }
206 break;
Florin Malitae1dadd72017-10-13 18:18:32 -0400207 case SkSVGAttribute::kStrokeDashOffset:
Florin Malitaf4403e72020-04-10 14:14:04 +0000208 if (const SkSVGLengthValue* dashOffset= v.as<SkSVGLengthValue>()) {
Florin Malitae1dadd72017-10-13 18:18:32 -0400209 this->setStrokeDashOffset(*dashOffset);
210 }
211 break;
fmalita2d961e02016-08-11 09:16:29 -0700212 case SkSVGAttribute::kStrokeOpacity:
Florin Malitaf4403e72020-04-10 14:14:04 +0000213 if (const SkSVGNumberValue* opacity = v.as<SkSVGNumberValue>()) {
fmalitaca39d712016-08-12 13:17:11 -0700214 this->setStrokeOpacity(*opacity);
fmalita2d961e02016-08-11 09:16:29 -0700215 }
216 break;
217 case SkSVGAttribute::kStrokeLineCap:
Florin Malitaf4403e72020-04-10 14:14:04 +0000218 if (const SkSVGLineCapValue* lineCap = v.as<SkSVGLineCapValue>()) {
Florin Malita09294252020-04-09 08:54:29 -0400219 this->setStrokeLineCap(*lineCap);
fmalita2d961e02016-08-11 09:16:29 -0700220 }
221 break;
222 case SkSVGAttribute::kStrokeLineJoin:
Florin Malitaf4403e72020-04-10 14:14:04 +0000223 if (const SkSVGLineJoinValue* lineJoin = v.as<SkSVGLineJoinValue>()) {
Florin Malita09294252020-04-09 08:54:29 -0400224 this->setStrokeLineJoin(*lineJoin);
fmalita2d961e02016-08-11 09:16:29 -0700225 }
226 break;
Florin Malita4de426b2017-10-09 12:57:41 -0400227 case SkSVGAttribute::kStrokeMiterLimit:
Florin Malitaf4403e72020-04-10 14:14:04 +0000228 if (const SkSVGNumberValue* miterLimit = v.as<SkSVGNumberValue>()) {
Florin Malita09294252020-04-09 08:54:29 -0400229 this->setStrokeMiterLimit(*miterLimit);
Florin Malita4de426b2017-10-09 12:57:41 -0400230 }
231 break;
fmalita2d961e02016-08-11 09:16:29 -0700232 case SkSVGAttribute::kStrokeWidth:
Florin Malitaf4403e72020-04-10 14:14:04 +0000233 if (const SkSVGLengthValue* strokeWidth = v.as<SkSVGLengthValue>()) {
fmalitaca39d712016-08-12 13:17:11 -0700234 this->setStrokeWidth(*strokeWidth);
fmalita6ceef3d2016-07-26 18:46:34 -0700235 }
236 break;
Florin Malitaffe6ae42017-10-12 11:33:28 -0400237 case SkSVGAttribute::kVisibility:
Florin Malitaf4403e72020-04-10 14:14:04 +0000238 if (const SkSVGVisibilityValue* visibility = v.as<SkSVGVisibilityValue>()) {
Florin Malitaffe6ae42017-10-12 11:33:28 -0400239 this->setVisibility(*visibility);
240 }
241 break;
fmalita6ceef3d2016-07-26 18:46:34 -0700242 default:
Florin Malitac9649ce2018-02-16 13:49:48 -0500243#if defined(SK_VERBOSE_SVG_PARSING)
244 SkDebugf("attribute ID <%d> ignored for node <%d>\n", attr, fTag);
245#endif
fmalita6ceef3d2016-07-26 18:46:34 -0700246 break;
247 }
248}