blob: a8f39ad3643378cef4333758cf983ef45fc55d50 [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 {
Tyler Denniston53281c72020-10-22 15:54:24 -040022 SkSVGRenderContext localContext(ctx, this);
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
Tyler Dennistonf548a022020-10-27 15:02:02 -040051SkRect SkSVGNode::objectBoundingBox(const SkSVGRenderContext& ctx) const {
52 return this->onObjectBoundingBox(ctx);
Tyler Denniston53281c72020-10-22 15:54:24 -040053}
54
fmalita397a5172016-08-08 11:38:55 -070055bool SkSVGNode::onPrepareToRender(SkSVGRenderContext* ctx) const {
fmalitabef51c22016-09-20 15:45:57 -070056 ctx->applyPresentationAttributes(fPresentationAttributes,
57 this->hasChildren() ? 0 : SkSVGRenderContext::kLeaf);
Florin Malitaffe6ae42017-10-12 11:33:28 -040058
59 // visibility:hidden disables rendering
John Stilesa008b0f2020-08-16 08:48:02 -040060 const auto visibility = ctx->presentationContext().fInherited.fVisibility->type();
Florin Malitaffe6ae42017-10-12 11:33:28 -040061 return visibility != SkSVGVisibility::Type::kHidden;
fmalita6ceef3d2016-07-26 18:46:34 -070062}
63
Florin Malitaf4403e72020-04-10 14:14:04 +000064void SkSVGNode::setAttribute(SkSVGAttribute attr, const SkSVGValue& v) {
fmalita6ceef3d2016-07-26 18:46:34 -070065 this->onSetAttribute(attr, v);
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 Malita8c425672020-11-06 13:49:37 -050079bool SkSVGNode::parseAndSetAttribute(const char* n, const char* v) {
Tyler Denniston79832e32020-11-18 09:34:07 -050080#define PARSE_AND_SET(svgName, attrName) \
81 this->set##attrName( \
82 SkSVGAttributeParser::parseProperty<decltype(fPresentationAttributes.f##attrName)>( \
83 svgName, n, v))
84
Tyler Denniston4c6f57a2020-11-30 15:31:32 -050085 return PARSE_AND_SET( "clip-path" , ClipPath)
86 || PARSE_AND_SET("clip-rule" , ClipRule)
87 || PARSE_AND_SET("color" , Color)
88 || PARSE_AND_SET("fill" , Fill)
89 || PARSE_AND_SET("fill-opacity" , FillOpacity)
90 || PARSE_AND_SET("fill-rule" , FillRule)
91 || PARSE_AND_SET("filter" , Filter)
92 || PARSE_AND_SET("font-family" , FontFamily)
93 || PARSE_AND_SET("font-size" , FontSize)
94 || PARSE_AND_SET("font-style" , FontStyle)
95 || PARSE_AND_SET("font-weight" , FontWeight)
96 || PARSE_AND_SET("opacity" , Opacity)
97 || PARSE_AND_SET("stroke" , Stroke)
98 || PARSE_AND_SET("stroke-dasharray" , StrokeDashArray)
99 || PARSE_AND_SET("stroke-dashoffset", StrokeDashOffset)
100 || PARSE_AND_SET("stroke-linecap" , StrokeLineCap)
101 || PARSE_AND_SET("stroke-linejoin" , StrokeLineJoin)
102 || PARSE_AND_SET("stroke-miterlimit", StrokeMiterLimit)
103 || PARSE_AND_SET("stroke-opacity" , StrokeOpacity)
104 || PARSE_AND_SET("stroke-width" , StrokeWidth)
105 || PARSE_AND_SET("text-anchor" , TextAnchor)
106 || PARSE_AND_SET("visibility" , Visibility);
Tyler Denniston79832e32020-11-18 09:34:07 -0500107
108#undef PARSE_AND_SET
Tyler Denniston57154992020-11-04 16:08:30 -0500109}