Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkSVGNode.cpp
Go to the documentation of this file.
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
15#include "src/base/SkTLazy.h"
16
18 // Uninherited presentation attributes need a non-null default value.
19 fPresentationAttributes.fStopColor.set(SkSVGColor(SK_ColorBLACK));
20 fPresentationAttributes.fStopOpacity.set(SkSVGNumberType(1.0f));
21 fPresentationAttributes.fFloodColor.set(SkSVGColor(SK_ColorBLACK));
22 fPresentationAttributes.fFloodOpacity.set(SkSVGNumberType(1.0f));
23 fPresentationAttributes.fLightingColor.set(SkSVGColor(SK_ColorWHITE));
24}
25
27
28void SkSVGNode::render(const SkSVGRenderContext& ctx) const {
29 SkSVGRenderContext localContext(ctx, this);
30
31 if (this->onPrepareToRender(&localContext)) {
32 this->onRender(localContext);
33 }
34}
35
37 SkSVGRenderContext localContext(ctx);
38
39 return this->onPrepareToRender(&localContext) && this->onAsPaint(localContext, paint);
40}
41
43 SkSVGRenderContext localContext(ctx);
44 if (!this->onPrepareToRender(&localContext)) {
45 return SkPath();
46 }
47
48 SkPath path = this->onAsPath(localContext);
49
50 if (const auto* clipPath = localContext.clipPath()) {
51 // There is a clip-path present on the current node.
52 Op(path, *clipPath, kIntersect_SkPathOp, &path);
53 }
54
55 return path;
56}
57
59 return this->onObjectBoundingBox(ctx);
60}
61
63 ctx->applyPresentationAttributes(fPresentationAttributes,
65
66 // visibility:hidden and display:none disable rendering.
67 // TODO: if display is not a value (true when display="inherit"), we currently
68 // ignore it. Eventually we should be able to add SkASSERT(display.isValue()).
69 const auto visibility = ctx->presentationContext().fInherited.fVisibility->type();
70 const auto display = fPresentationAttributes.fDisplay; // display is uninherited
71 return visibility != SkSVGVisibility::Type::kHidden &&
72 (!display.isValue() || *display != SkSVGDisplay::kNone);
73}
74
76 this->onSetAttribute(attr, v);
77}
78
79template <typename T>
80void SetInheritedByDefault(SkTLazy<T>& presentation_attribute, const T& value) {
81 if (value.type() != T::Type::kInherit) {
82 presentation_attribute.set(value);
83 } else {
84 // kInherited values are semantically equivalent to
85 // the absence of a local presentation attribute.
86 presentation_attribute.reset();
87 }
88}
89
90bool SkSVGNode::parseAndSetAttribute(const char* n, const char* v) {
91#define PARSE_AND_SET(svgName, attrName) \
92 this->set##attrName( \
93 SkSVGAttributeParser::parseProperty<decltype(fPresentationAttributes.f##attrName)>( \
94 svgName, n, v))
95
96 return PARSE_AND_SET( "clip-path" , ClipPath)
97 || PARSE_AND_SET("clip-rule" , ClipRule)
98 || PARSE_AND_SET("color" , Color)
99 || PARSE_AND_SET("color-interpolation" , ColorInterpolation)
100 || PARSE_AND_SET("color-interpolation-filters", ColorInterpolationFilters)
101 || PARSE_AND_SET("display" , Display)
102 || PARSE_AND_SET("fill" , Fill)
103 || PARSE_AND_SET("fill-opacity" , FillOpacity)
104 || PARSE_AND_SET("fill-rule" , FillRule)
105 || PARSE_AND_SET("filter" , Filter)
106 || PARSE_AND_SET("flood-color" , FloodColor)
107 || PARSE_AND_SET("flood-opacity" , FloodOpacity)
108 || PARSE_AND_SET("font-family" , FontFamily)
109 || PARSE_AND_SET("font-size" , FontSize)
110 || PARSE_AND_SET("font-style" , FontStyle)
111 || PARSE_AND_SET("font-weight" , FontWeight)
112 || PARSE_AND_SET("lighting-color" , LightingColor)
113 || PARSE_AND_SET("mask" , Mask)
114 || PARSE_AND_SET("opacity" , Opacity)
115 || PARSE_AND_SET("stop-color" , StopColor)
116 || PARSE_AND_SET("stop-opacity" , StopOpacity)
117 || PARSE_AND_SET("stroke" , Stroke)
118 || PARSE_AND_SET("stroke-dasharray" , StrokeDashArray)
119 || PARSE_AND_SET("stroke-dashoffset" , StrokeDashOffset)
120 || PARSE_AND_SET("stroke-linecap" , StrokeLineCap)
121 || PARSE_AND_SET("stroke-linejoin" , StrokeLineJoin)
122 || PARSE_AND_SET("stroke-miterlimit" , StrokeMiterLimit)
123 || PARSE_AND_SET("stroke-opacity" , StrokeOpacity)
124 || PARSE_AND_SET("stroke-width" , StrokeWidth)
125 || PARSE_AND_SET("text-anchor" , TextAnchor)
126 || PARSE_AND_SET("visibility" , Visibility);
127
128#undef PARSE_AND_SET
129}
130
131// https://www.w3.org/TR/SVG11/coords.html#PreserveAspectRatioAttribute
133 const SkRect& viewPort,
135 if (viewBox.isEmpty() || viewPort.isEmpty()) {
136 return SkMatrix::Scale(0, 0);
137 }
138
139 auto compute_scale = [&]() -> SkV2 {
140 const auto sx = viewPort.width() / viewBox.width(),
141 sy = viewPort.height() / viewBox.height();
142
144 // none -> anisotropic scaling, regardless of fScale
145 return {sx, sy};
146 }
147
148 // isotropic scaling
149 const auto s = par.fScale == SkSVGPreserveAspectRatio::kMeet
150 ? std::min(sx, sy)
151 : std::max(sx, sy);
152 return {s, s};
153 };
154
155 auto compute_trans = [&](const SkV2& scale) -> SkV2 {
156 static constexpr float gAlignCoeffs[] = {
157 0.0f, // Min
158 0.5f, // Mid
159 1.0f // Max
160 };
161
162 const size_t x_coeff = par.fAlign >> 0 & 0x03,
163 y_coeff = par.fAlign >> 2 & 0x03;
164
165 SkASSERT(x_coeff < std::size(gAlignCoeffs) &&
166 y_coeff < std::size(gAlignCoeffs));
167
168 const auto tx = -viewBox.x() * scale.x,
169 ty = -viewBox.y() * scale.y,
170 dx = viewPort.width() - viewBox.width() * scale.x,
171 dy = viewPort.height() - viewBox.height() * scale.y;
172
173 return {
174 tx + dx * gAlignCoeffs[x_coeff],
175 ty + dy * gAlignCoeffs[y_coeff]
176 };
177 };
178
179 const auto s = compute_scale(),
180 t = compute_trans(s);
181
182 return SkMatrix::Translate(t.x, t.y) *
184}
#define SkASSERT(cond)
Definition SkAssert.h:116
constexpr SkColor SK_ColorBLACK
Definition SkColor.h:103
constexpr SkColor SK_ColorWHITE
Definition SkColor.h:122
@ kIntersect_SkPathOp
intersect the two paths
Definition SkPathOps.h:24
SkSVGAttribute
void SetInheritedByDefault(SkTLazy< T > &presentation_attribute, const T &value)
Definition SkSVGNode.cpp:80
#define PARSE_AND_SET(svgName, attrName)
SkSVGTag
Definition SkSVGNode.h:23
SkScalar SkSVGNumberType
Definition SkSVGTypes.h:27
SkFilterMode
static SkMatrix Scale(SkScalar sx, SkScalar sy)
Definition SkMatrix.h:75
static SkMatrix Translate(SkScalar dx, SkScalar dy)
Definition SkMatrix.h:91
SkRect objectBoundingBox(const SkSVGRenderContext &) const
Definition SkSVGNode.cpp:58
void render(const SkSVGRenderContext &) const
Definition SkSVGNode.cpp:28
virtual bool parseAndSetAttribute(const char *name, const char *value)
Definition SkSVGNode.cpp:90
virtual SkRect onObjectBoundingBox(const SkSVGRenderContext &) const
Definition SkSVGNode.h:172
~SkSVGNode() override
Definition SkSVGNode.cpp:26
void setAttribute(SkSVGAttribute, const SkSVGValue &)
Definition SkSVGNode.cpp:75
bool asPaint(const SkSVGRenderContext &, SkPaint *) const
Definition SkSVGNode.cpp:36
virtual void onRender(const SkSVGRenderContext &) const =0
virtual bool onAsPaint(const SkSVGRenderContext &, SkPaint *) const
Definition SkSVGNode.h:164
SkPath asPath(const SkSVGRenderContext &) const
Definition SkSVGNode.cpp:42
static SkMatrix ComputeViewboxMatrix(const SkRect &, const SkRect &, SkSVGPreserveAspectRatio)
virtual void onSetAttribute(SkSVGAttribute, const SkSVGValue &)
Definition SkSVGNode.h:168
virtual bool onPrepareToRender(SkSVGRenderContext *) const
Definition SkSVGNode.cpp:62
virtual bool hasChildren() const
Definition SkSVGNode.h:170
SkSVGNode(SkSVGTag)
Definition SkSVGNode.cpp:17
virtual SkPath onAsPath(const SkSVGRenderContext &) const =0
void set(SkSVGPropertyState state)
Definition SkSVGTypes.h:70
const SkSVGPresentationContext & presentationContext() const
const SkPath * clipPath() const
void applyPresentationAttributes(const SkSVGPresentationAttributes &, uint32_t flags)
Type type() const
Definition SkSVGTypes.h:388
void reset()
Definition SkTLazy.h:69
T * set(const T &src)
Definition SkTLazy.h:56
const Paint & paint
struct MyStruct s
uint8_t value
#define T
const Scalar scale
constexpr float x() const
Definition SkRect.h:720
constexpr float y() const
Definition SkRect.h:727
constexpr float height() const
Definition SkRect.h:769
constexpr float width() const
Definition SkRect.h:762
bool isEmpty() const
Definition SkRect.h:693
SkSVGProperty< SkSVGColor, false > fLightingColor
SkSVGProperty< SkSVGColor, false > fStopColor
SkSVGProperty< SkSVGDisplay, false > fDisplay
SkSVGProperty< SkSVGVisibility, true > fVisibility
SkSVGProperty< SkSVGNumberType, false > fFloodOpacity
SkSVGProperty< SkSVGColor, false > fFloodColor
SkSVGProperty< SkSVGNumberType, false > fStopOpacity
SkSVGPresentationAttributes fInherited
Definition SkM44.h:19