[svg] Skip "inherited" presentation attributes
Instead of propagating and attempting to handle at resolution time,
cull "inherited" values in the setters - for inherited-by-default
presentation attributes, "inherited" is the same as not specifying
a property.
Also add some missing setters for more consistent dispatching, and
assert that kInherited never shows up in computed values.
Change-Id: Iceeab4440c5c2eee18a144e2a32704fd29ec5e95
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/282396
Reviewed-by: Tyler Denniston <tdenniston@google.com>
Commit-Queue: Florin Malita <fmalita@chromium.org>
diff --git a/experimental/svg/model/SkSVGNode.cpp b/experimental/svg/model/SkSVGNode.cpp
index e872493..21c237c 100644
--- a/experimental/svg/model/SkSVGNode.cpp
+++ b/experimental/svg/model/SkSVGNode.cpp
@@ -64,12 +64,23 @@
fPresentationAttributes.fClipPath.set(clip);
}
+template <typename T>
+void SetInheritedByDefault(SkTLazy<T>& presentation_attribute, const T& value) {
+ if (value.type() != T::Type::kInherit) {
+ presentation_attribute.set(value);
+ } else {
+ // kInherited values are semantically equivalent to
+ // the absence of a local presentation attribute.
+ presentation_attribute.reset();
+ }
+}
+
void SkSVGNode::setClipRule(const SkSVGFillRule& clipRule) {
- fPresentationAttributes.fClipRule.set(clipRule);
+ SetInheritedByDefault(fPresentationAttributes.fClipRule, clipRule);
}
void SkSVGNode::setFill(const SkSVGPaint& svgPaint) {
- fPresentationAttributes.fFill.set(svgPaint);
+ SetInheritedByDefault(fPresentationAttributes.fFill, svgPaint);
}
void SkSVGNode::setFillOpacity(const SkSVGNumberType& opacity) {
@@ -78,7 +89,7 @@
}
void SkSVGNode::setFillRule(const SkSVGFillRule& fillRule) {
- fPresentationAttributes.fFillRule.set(fillRule);
+ SetInheritedByDefault(fPresentationAttributes.fFillRule, fillRule);
}
void SkSVGNode::setOpacity(const SkSVGNumberType& opacity) {
@@ -87,11 +98,11 @@
}
void SkSVGNode::setStroke(const SkSVGPaint& svgPaint) {
- fPresentationAttributes.fStroke.set(svgPaint);
+ SetInheritedByDefault(fPresentationAttributes.fStroke, svgPaint);
}
void SkSVGNode::setStrokeDashArray(const SkSVGDashArray& dashArray) {
- fPresentationAttributes.fStrokeDashArray.set(dashArray);
+ SetInheritedByDefault(fPresentationAttributes.fStrokeDashArray, dashArray);
}
void SkSVGNode::setStrokeDashOffset(const SkSVGLength& dashOffset) {
@@ -103,12 +114,24 @@
SkSVGNumberType(SkTPin<SkScalar>(opacity.value(), 0, 1)));
}
+void SkSVGNode::setStrokeLineCap(const SkSVGLineCap& lc) {
+ SetInheritedByDefault(fPresentationAttributes.fStrokeLineCap, lc);
+}
+
+void SkSVGNode::setStrokeLineJoin(const SkSVGLineJoin& lj) {
+ SetInheritedByDefault(fPresentationAttributes.fStrokeLineJoin, lj);
+}
+
+void SkSVGNode::setStrokeMiterLimit(const SkSVGNumberType& ml) {
+ fPresentationAttributes.fStrokeMiterLimit.set(ml);
+}
+
void SkSVGNode::setStrokeWidth(const SkSVGLength& strokeWidth) {
fPresentationAttributes.fStrokeWidth.set(strokeWidth);
}
void SkSVGNode::setVisibility(const SkSVGVisibility& visibility) {
- fPresentationAttributes.fVisibility.set(visibility);
+ SetInheritedByDefault(fPresentationAttributes.fVisibility, visibility);
}
void SkSVGNode::onSetAttribute(SkSVGAttribute attr, const SkSVGValue& v) {
@@ -165,17 +188,17 @@
break;
case SkSVGAttribute::kStrokeLineCap:
if (const SkSVGLineCapValue* lineCap = v.as<SkSVGLineCapValue>()) {
- fPresentationAttributes.fStrokeLineCap.set(*lineCap);
+ this->setStrokeLineCap(*lineCap);
}
break;
case SkSVGAttribute::kStrokeLineJoin:
if (const SkSVGLineJoinValue* lineJoin = v.as<SkSVGLineJoinValue>()) {
- fPresentationAttributes.fStrokeLineJoin.set(*lineJoin);
+ this->setStrokeLineJoin(*lineJoin);
}
break;
case SkSVGAttribute::kStrokeMiterLimit:
if (const SkSVGNumberValue* miterLimit = v.as<SkSVGNumberValue>()) {
- fPresentationAttributes.fStrokeMiterLimit.set(*miterLimit);
+ this->setStrokeMiterLimit(*miterLimit);
}
break;
case SkSVGAttribute::kStrokeWidth: