[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: