• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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"
10 #include "SkPathOps.h"
11 #include "SkSVGNode.h"
12 #include "SkSVGRenderContext.h"
13 #include "SkSVGValue.h"
14 #include "SkTLazy.h"
15 
SkSVGNode(SkSVGTag t)16 SkSVGNode::SkSVGNode(SkSVGTag t) : fTag(t) { }
17 
~SkSVGNode()18 SkSVGNode::~SkSVGNode() { }
19 
render(const SkSVGRenderContext & ctx) const20 void SkSVGNode::render(const SkSVGRenderContext& ctx) const {
21     SkSVGRenderContext localContext(ctx);
22 
23     if (this->onPrepareToRender(&localContext)) {
24         this->onRender(localContext);
25     }
26 }
27 
asPaint(const SkSVGRenderContext & ctx,SkPaint * paint) const28 bool SkSVGNode::asPaint(const SkSVGRenderContext& ctx, SkPaint* paint) const {
29     SkSVGRenderContext localContext(ctx);
30 
31     return this->onPrepareToRender(&localContext) && this->onAsPaint(localContext, paint);
32 }
33 
asPath(const SkSVGRenderContext & ctx) const34 SkPath SkSVGNode::asPath(const SkSVGRenderContext& ctx) const {
35     SkSVGRenderContext localContext(ctx);
36     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;
48 }
49 
onPrepareToRender(SkSVGRenderContext * ctx) const50 bool SkSVGNode::onPrepareToRender(SkSVGRenderContext* ctx) const {
51     ctx->applyPresentationAttributes(fPresentationAttributes,
52                                      this->hasChildren() ? 0 : SkSVGRenderContext::kLeaf);
53 
54     // visibility:hidden disables rendering
55     const auto visibility = ctx->presentationContext().fInherited.fVisibility.get()->type();
56     return visibility != SkSVGVisibility::Type::kHidden;
57 }
58 
setAttribute(SkSVGAttribute attr,const SkSVGValue & v)59 void SkSVGNode::setAttribute(SkSVGAttribute attr, const SkSVGValue& v) {
60     this->onSetAttribute(attr, v);
61 }
62 
setClipPath(const SkSVGClip & clip)63 void SkSVGNode::setClipPath(const SkSVGClip& clip) {
64     fPresentationAttributes.fClipPath.set(clip);
65 }
66 
setClipRule(const SkSVGFillRule & clipRule)67 void SkSVGNode::setClipRule(const SkSVGFillRule& clipRule) {
68     fPresentationAttributes.fClipRule.set(clipRule);
69 }
70 
setFill(const SkSVGPaint & svgPaint)71 void SkSVGNode::setFill(const SkSVGPaint& svgPaint) {
72     fPresentationAttributes.fFill.set(svgPaint);
73 }
74 
setFillOpacity(const SkSVGNumberType & opacity)75 void SkSVGNode::setFillOpacity(const SkSVGNumberType& opacity) {
76     fPresentationAttributes.fFillOpacity.set(
77         SkSVGNumberType(SkTPin<SkScalar>(opacity.value(), 0, 1)));
78 }
79 
setFillRule(const SkSVGFillRule & fillRule)80 void SkSVGNode::setFillRule(const SkSVGFillRule& fillRule) {
81     fPresentationAttributes.fFillRule.set(fillRule);
82 }
83 
setOpacity(const SkSVGNumberType & opacity)84 void SkSVGNode::setOpacity(const SkSVGNumberType& opacity) {
85     fPresentationAttributes.fOpacity.set(
86         SkSVGNumberType(SkTPin<SkScalar>(opacity.value(), 0, 1)));
87 }
88 
setStroke(const SkSVGPaint & svgPaint)89 void SkSVGNode::setStroke(const SkSVGPaint& svgPaint) {
90     fPresentationAttributes.fStroke.set(svgPaint);
91 }
92 
setStrokeDashArray(const SkSVGDashArray & dashArray)93 void SkSVGNode::setStrokeDashArray(const SkSVGDashArray& dashArray) {
94     fPresentationAttributes.fStrokeDashArray.set(dashArray);
95 }
96 
setStrokeDashOffset(const SkSVGLength & dashOffset)97 void SkSVGNode::setStrokeDashOffset(const SkSVGLength& dashOffset) {
98     fPresentationAttributes.fStrokeDashOffset.set(dashOffset);
99 }
100 
setStrokeOpacity(const SkSVGNumberType & opacity)101 void SkSVGNode::setStrokeOpacity(const SkSVGNumberType& opacity) {
102     fPresentationAttributes.fStrokeOpacity.set(
103         SkSVGNumberType(SkTPin<SkScalar>(opacity.value(), 0, 1)));
104 }
105 
setStrokeWidth(const SkSVGLength & strokeWidth)106 void SkSVGNode::setStrokeWidth(const SkSVGLength& strokeWidth) {
107     fPresentationAttributes.fStrokeWidth.set(strokeWidth);
108 }
109 
setVisibility(const SkSVGVisibility & visibility)110 void SkSVGNode::setVisibility(const SkSVGVisibility& visibility) {
111     fPresentationAttributes.fVisibility.set(visibility);
112 }
113 
onSetAttribute(SkSVGAttribute attr,const SkSVGValue & v)114 void SkSVGNode::onSetAttribute(SkSVGAttribute attr, const SkSVGValue& v) {
115     switch (attr) {
116     case SkSVGAttribute::kClipPath:
117         if (const SkSVGClipValue* clip = v.as<SkSVGClipValue>()) {
118             this->setClipPath(*clip);
119         }
120         break;
121     case SkSVGAttribute::kClipRule:
122         if (const SkSVGFillRuleValue* clipRule = v.as<SkSVGFillRuleValue>()) {
123             this->setClipRule(*clipRule);
124         }
125         break;
126     case SkSVGAttribute::kFill:
127         if (const SkSVGPaintValue* paint = v.as<SkSVGPaintValue>()) {
128             this->setFill(*paint);
129         }
130         break;
131     case SkSVGAttribute::kFillOpacity:
132         if (const SkSVGNumberValue* opacity = v.as<SkSVGNumberValue>()) {
133             this->setFillOpacity(*opacity);
134         }
135         break;
136     case SkSVGAttribute::kFillRule:
137         if (const SkSVGFillRuleValue* fillRule = v.as<SkSVGFillRuleValue>()) {
138             this->setFillRule(*fillRule);
139         }
140         break;
141     case SkSVGAttribute::kOpacity:
142         if (const SkSVGNumberValue* opacity = v.as<SkSVGNumberValue>()) {
143             this->setOpacity(*opacity);
144         }
145         break;
146     case SkSVGAttribute::kStroke:
147         if (const SkSVGPaintValue* paint = v.as<SkSVGPaintValue>()) {
148             this->setStroke(*paint);
149         }
150         break;
151     case SkSVGAttribute::kStrokeDashArray:
152         if (const SkSVGDashArrayValue* dashArray = v.as<SkSVGDashArrayValue>()) {
153             this->setStrokeDashArray(*dashArray);
154         }
155         break;
156     case SkSVGAttribute::kStrokeDashOffset:
157         if (const SkSVGLengthValue* dashOffset= v.as<SkSVGLengthValue>()) {
158             this->setStrokeDashOffset(*dashOffset);
159         }
160         break;
161     case SkSVGAttribute::kStrokeOpacity:
162         if (const SkSVGNumberValue* opacity = v.as<SkSVGNumberValue>()) {
163             this->setStrokeOpacity(*opacity);
164         }
165         break;
166     case SkSVGAttribute::kStrokeLineCap:
167         if (const SkSVGLineCapValue* lineCap = v.as<SkSVGLineCapValue>()) {
168             fPresentationAttributes.fStrokeLineCap.set(*lineCap);
169         }
170         break;
171     case SkSVGAttribute::kStrokeLineJoin:
172         if (const SkSVGLineJoinValue* lineJoin = v.as<SkSVGLineJoinValue>()) {
173             fPresentationAttributes.fStrokeLineJoin.set(*lineJoin);
174         }
175         break;
176     case SkSVGAttribute::kStrokeMiterLimit:
177         if (const SkSVGNumberValue* miterLimit = v.as<SkSVGNumberValue>()) {
178             fPresentationAttributes.fStrokeMiterLimit.set(*miterLimit);
179         }
180         break;
181     case SkSVGAttribute::kStrokeWidth:
182         if (const SkSVGLengthValue* strokeWidth = v.as<SkSVGLengthValue>()) {
183             this->setStrokeWidth(*strokeWidth);
184         }
185         break;
186     case SkSVGAttribute::kVisibility:
187         if (const SkSVGVisibilityValue* visibility = v.as<SkSVGVisibilityValue>()) {
188             this->setVisibility(*visibility);
189         }
190         break;
191     default:
192 #if defined(SK_VERBOSE_SVG_PARSING)
193         SkDebugf("attribute ID <%d> ignored for node <%d>\n", attr, fTag);
194 #endif
195         break;
196     }
197 }
198