• 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     return true;
54 }
55 
setAttribute(SkSVGAttribute attr,const SkSVGValue & v)56 void SkSVGNode::setAttribute(SkSVGAttribute attr, const SkSVGValue& v) {
57     this->onSetAttribute(attr, v);
58 }
59 
setClipPath(const SkSVGClip & clip)60 void SkSVGNode::setClipPath(const SkSVGClip& clip) {
61     fPresentationAttributes.fClipPath.set(clip);
62 }
63 
setFill(const SkSVGPaint & svgPaint)64 void SkSVGNode::setFill(const SkSVGPaint& svgPaint) {
65     fPresentationAttributes.fFill.set(svgPaint);
66 }
67 
setFillOpacity(const SkSVGNumberType & opacity)68 void SkSVGNode::setFillOpacity(const SkSVGNumberType& opacity) {
69     fPresentationAttributes.fFillOpacity.set(
70         SkSVGNumberType(SkTPin<SkScalar>(opacity.value(), 0, 1)));
71 }
72 
setFillRule(const SkSVGFillRule & fillRule)73 void SkSVGNode::setFillRule(const SkSVGFillRule& fillRule) {
74     fPresentationAttributes.fFillRule.set(fillRule);
75 }
76 
setOpacity(const SkSVGNumberType & opacity)77 void SkSVGNode::setOpacity(const SkSVGNumberType& opacity) {
78     fPresentationAttributes.fOpacity.set(
79         SkSVGNumberType(SkTPin<SkScalar>(opacity.value(), 0, 1)));
80 }
81 
setStroke(const SkSVGPaint & svgPaint)82 void SkSVGNode::setStroke(const SkSVGPaint& svgPaint) {
83     fPresentationAttributes.fStroke.set(svgPaint);
84 }
85 
setStrokeOpacity(const SkSVGNumberType & opacity)86 void SkSVGNode::setStrokeOpacity(const SkSVGNumberType& opacity) {
87     fPresentationAttributes.fStrokeOpacity.set(
88         SkSVGNumberType(SkTPin<SkScalar>(opacity.value(), 0, 1)));
89 }
90 
setStrokeWidth(const SkSVGLength & strokeWidth)91 void SkSVGNode::setStrokeWidth(const SkSVGLength& strokeWidth) {
92     fPresentationAttributes.fStrokeWidth.set(strokeWidth);
93 }
94 
onSetAttribute(SkSVGAttribute attr,const SkSVGValue & v)95 void SkSVGNode::onSetAttribute(SkSVGAttribute attr, const SkSVGValue& v) {
96     switch (attr) {
97     case SkSVGAttribute::kClipPath:
98         if (const SkSVGClipValue* clip = v.as<SkSVGClipValue>()) {
99             this->setClipPath(*clip);
100         }
101         break;
102     case SkSVGAttribute::kFill:
103         if (const SkSVGPaintValue* paint = v.as<SkSVGPaintValue>()) {
104             this->setFill(*paint);
105         }
106         break;
107     case SkSVGAttribute::kFillOpacity:
108         if (const SkSVGNumberValue* opacity = v.as<SkSVGNumberValue>()) {
109             this->setFillOpacity(*opacity);
110         }
111         break;
112     case SkSVGAttribute::kFillRule:
113         if (const SkSVGFillRuleValue* fillRule = v.as<SkSVGFillRuleValue>()) {
114             this->setFillRule(*fillRule);
115         }
116         break;
117     case SkSVGAttribute::kOpacity:
118         if (const SkSVGNumberValue* opacity = v.as<SkSVGNumberValue>()) {
119             this->setOpacity(*opacity);
120         }
121         break;
122     case SkSVGAttribute::kStroke:
123         if (const SkSVGPaintValue* paint = v.as<SkSVGPaintValue>()) {
124             this->setStroke(*paint);
125         }
126         break;
127     case SkSVGAttribute::kStrokeOpacity:
128         if (const SkSVGNumberValue* opacity = v.as<SkSVGNumberValue>()) {
129             this->setStrokeOpacity(*opacity);
130         }
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>()) {
144             this->setStrokeWidth(*strokeWidth);
145         }
146         break;
147     default:
148         SkDebugf("attribute ID <%d> ignored for node <%d>\n", attr, fTag);
149         break;
150     }
151 }
152