diff options
author | Florin Malita <fmalita@chromium.org> | 2017-10-12 11:33:28 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-10-12 17:06:34 +0000 |
commit | ffe6ae49e48a8c5cb53cec93643a2ad054faf74a (patch) | |
tree | a05f09ad8de93641de8abdcb4a878443d40d8ae4 /experimental/svg | |
parent | 177e695589edb1f776cc5c28b9d3eee244d48284 (diff) |
[SVGDom] Add 'visibility' support
https://www.w3.org/TR/SVG/painting.html#VisibilityProperty
Change-Id: I8b872af26150d93cf39cf8eeba23c91e1decace3
Reviewed-on: https://skia-review.googlesource.com/58863
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Florin Malita <fmalita@chromium.org>
Diffstat (limited to 'experimental/svg')
-rw-r--r-- | experimental/svg/model/SkSVGAttribute.cpp | 2 | ||||
-rw-r--r-- | experimental/svg/model/SkSVGAttribute.h | 3 | ||||
-rw-r--r-- | experimental/svg/model/SkSVGAttributeParser.cpp | 24 | ||||
-rw-r--r-- | experimental/svg/model/SkSVGAttributeParser.h | 1 | ||||
-rw-r--r-- | experimental/svg/model/SkSVGDOM.cpp | 13 | ||||
-rw-r--r-- | experimental/svg/model/SkSVGNode.cpp | 14 | ||||
-rw-r--r-- | experimental/svg/model/SkSVGNode.h | 1 | ||||
-rw-r--r-- | experimental/svg/model/SkSVGRenderContext.cpp | 8 | ||||
-rw-r--r-- | experimental/svg/model/SkSVGTypes.h | 24 | ||||
-rw-r--r-- | experimental/svg/model/SkSVGValue.h | 28 |
10 files changed, 104 insertions, 14 deletions
diff --git a/experimental/svg/model/SkSVGAttribute.cpp b/experimental/svg/model/SkSVGAttribute.cpp index d16b479e1a..89b57cd1da 100644 --- a/experimental/svg/model/SkSVGAttribute.cpp +++ b/experimental/svg/model/SkSVGAttribute.cpp @@ -22,5 +22,7 @@ SkSVGPresentationAttributes SkSVGPresentationAttributes::MakeInitial() { result.fStrokeOpacity.set(SkSVGNumberType(1)); result.fStrokeWidth.set(SkSVGLength(1)); + result.fVisibility.set(SkSVGVisibility(SkSVGVisibility::Type::kVisible)); + return result; } diff --git a/experimental/svg/model/SkSVGAttribute.h b/experimental/svg/model/SkSVGAttribute.h index 71eeb916b0..bd2cf7d196 100644 --- a/experimental/svg/model/SkSVGAttribute.h +++ b/experimental/svg/model/SkSVGAttribute.h @@ -45,6 +45,7 @@ enum class SkSVGAttribute { kStrokeWidth, kTransform, kViewBox, + kVisibility, kWidth, kX, kX1, // <line>: first endpoint x @@ -73,6 +74,8 @@ struct SkSVGPresentationAttributes { SkTLazy<SkSVGNumberType> fStrokeOpacity; SkTLazy<SkSVGLength> fStrokeWidth; + SkTLazy<SkSVGVisibility> fVisibility; + // uninherited SkTLazy<SkSVGNumberType> fOpacity; SkTLazy<SkSVGClip> fClipPath; diff --git a/experimental/svg/model/SkSVGAttributeParser.cpp b/experimental/svg/model/SkSVGAttributeParser.cpp index f8eef8cfa7..aee15b394e 100644 --- a/experimental/svg/model/SkSVGAttributeParser.cpp +++ b/experimental/svg/model/SkSVGAttributeParser.cpp @@ -593,3 +593,27 @@ bool SkSVGAttributeParser::parseFillRule(SkSVGFillRule* fillRule) { return parsedValue && this->parseEOSToken(); } + +// https://www.w3.org/TR/SVG/painting.html#VisibilityProperty +bool SkSVGAttributeParser::parseVisibility(SkSVGVisibility* visibility) { + static const struct { + SkSVGVisibility::Type fType; + const char* fName; + } gVisibilityInfo[] = { + { SkSVGVisibility::Type::kVisible , "visible" }, + { SkSVGVisibility::Type::kHidden , "hidden" }, + { SkSVGVisibility::Type::kCollapse, "collapse" }, + { SkSVGVisibility::Type::kInherit , "inherit" }, + }; + + bool parsedValue = false; + for (const auto& parseInfo : gVisibilityInfo) { + if (this->parseExpectedStringToken(parseInfo.fName)) { + *visibility = SkSVGVisibility(parseInfo.fType); + parsedValue = true; + break; + } + } + + return parsedValue && this->parseEOSToken(); +} diff --git a/experimental/svg/model/SkSVGAttributeParser.h b/experimental/svg/model/SkSVGAttributeParser.h index 67c13f6b7e..b2ac98f128 100644 --- a/experimental/svg/model/SkSVGAttributeParser.h +++ b/experimental/svg/model/SkSVGAttributeParser.h @@ -27,6 +27,7 @@ public: bool parsePoints(SkSVGPointsType*); bool parseIRI(SkSVGStringType*); bool parseSpreadMethod(SkSVGSpreadMethod*); + bool parseVisibility(SkSVGVisibility*); private: // Stack-only diff --git a/experimental/svg/model/SkSVGDOM.cpp b/experimental/svg/model/SkSVGDOM.cpp index 7bb524b48c..28784c2875 100644 --- a/experimental/svg/model/SkSVGDOM.cpp +++ b/experimental/svg/model/SkSVGDOM.cpp @@ -202,6 +202,18 @@ bool SetFillRuleAttribute(const sk_sp<SkSVGNode>& node, SkSVGAttribute attr, return true; } +bool SetVisibilityAttribute(const sk_sp<SkSVGNode>& node, SkSVGAttribute attr, + const char* stringValue) { + SkSVGVisibility visibility; + SkSVGAttributeParser parser(stringValue); + if (!parser.parseVisibility(&visibility)) { + return false; + } + + node->setAttribute(attr, SkSVGVisibilityValue(visibility)); + return true; +} + SkString TrimmedString(const char* first, const char* last) { SkASSERT(first); SkASSERT(last); @@ -312,6 +324,7 @@ SortedDictionaryEntry<AttrParseInfo> gAttributeParseInfo[] = { { "style" , { SkSVGAttribute::kUnknown , SetStyleAttributes }}, { "transform" , { SkSVGAttribute::kTransform , SetTransformAttribute }}, { "viewBox" , { SkSVGAttribute::kViewBox , SetViewBoxAttribute }}, + { "visibility" , { SkSVGAttribute::kVisibility , SetVisibilityAttribute }}, { "width" , { SkSVGAttribute::kWidth , SetLengthAttribute }}, { "x" , { SkSVGAttribute::kX , SetLengthAttribute }}, { "x1" , { SkSVGAttribute::kX1 , SetLengthAttribute }}, diff --git a/experimental/svg/model/SkSVGNode.cpp b/experimental/svg/model/SkSVGNode.cpp index dfd25bafbb..ddde838f8e 100644 --- a/experimental/svg/model/SkSVGNode.cpp +++ b/experimental/svg/model/SkSVGNode.cpp @@ -50,7 +50,10 @@ SkPath SkSVGNode::asPath(const SkSVGRenderContext& ctx) const { bool SkSVGNode::onPrepareToRender(SkSVGRenderContext* ctx) const { ctx->applyPresentationAttributes(fPresentationAttributes, this->hasChildren() ? 0 : SkSVGRenderContext::kLeaf); - return true; + + // visibility:hidden disables rendering + const auto visibility = ctx->presentationContext().fInherited.fVisibility.get()->type(); + return visibility != SkSVGVisibility::Type::kHidden; } void SkSVGNode::setAttribute(SkSVGAttribute attr, const SkSVGValue& v) { @@ -96,6 +99,10 @@ void SkSVGNode::setStrokeWidth(const SkSVGLength& strokeWidth) { fPresentationAttributes.fStrokeWidth.set(strokeWidth); } +void SkSVGNode::setVisibility(const SkSVGVisibility& visibility) { + fPresentationAttributes.fVisibility.set(visibility); +} + void SkSVGNode::onSetAttribute(SkSVGAttribute attr, const SkSVGValue& v) { switch (attr) { case SkSVGAttribute::kClipPath: @@ -158,6 +165,11 @@ void SkSVGNode::onSetAttribute(SkSVGAttribute attr, const SkSVGValue& v) { this->setStrokeWidth(*strokeWidth); } break; + case SkSVGAttribute::kVisibility: + if (const SkSVGVisibilityValue* visibility = v.as<SkSVGVisibilityValue>()) { + this->setVisibility(*visibility); + } + break; default: SkDebugf("attribute ID <%d> ignored for node <%d>\n", attr, fTag); break; diff --git a/experimental/svg/model/SkSVGNode.h b/experimental/svg/model/SkSVGNode.h index c9955d1638..02c2caa86e 100644 --- a/experimental/svg/model/SkSVGNode.h +++ b/experimental/svg/model/SkSVGNode.h @@ -60,6 +60,7 @@ public: void setStroke(const SkSVGPaint&); void setStrokeOpacity(const SkSVGNumberType&); void setStrokeWidth(const SkSVGLength&); + void setVisibility(const SkSVGVisibility&); protected: SkSVGNode(SkSVGTag); diff --git a/experimental/svg/model/SkSVGRenderContext.cpp b/experimental/svg/model/SkSVGRenderContext.cpp index a3e37cb965..8ee5ffcbe6 100644 --- a/experimental/svg/model/SkSVGRenderContext.cpp +++ b/experimental/svg/model/SkSVGRenderContext.cpp @@ -210,6 +210,13 @@ void commitToPaint<SkSVGAttribute::kClipRule>(const SkSVGPresentationAttributes& // Not part of the SkPaint state; applied to the path at clip time. } +template <> +void commitToPaint<SkSVGAttribute::kVisibility>(const SkSVGPresentationAttributes&, + const SkSVGRenderContext&, + SkSVGPresentationContext*) { + // Not part of the SkPaint state; queried to veto rendering. +} + } // anonymous ns SkSVGPresentationContext::SkSVGPresentationContext() @@ -295,6 +302,7 @@ void SkSVGRenderContext::applyPresentationAttributes(const SkSVGPresentationAttr ApplyLazyInheritedAttribute(StrokeMiterLimit); ApplyLazyInheritedAttribute(StrokeOpacity); ApplyLazyInheritedAttribute(StrokeWidth); + ApplyLazyInheritedAttribute(Visibility); #undef ApplyLazyInheritedAttribute diff --git a/experimental/svg/model/SkSVGTypes.h b/experimental/svg/model/SkSVGTypes.h index c83fd7d10b..4a300b6e3c 100644 --- a/experimental/svg/model/SkSVGTypes.h +++ b/experimental/svg/model/SkSVGTypes.h @@ -248,4 +248,28 @@ private: Type fType; }; +class SkSVGVisibility { +public: + enum class Type { + kVisible, + kHidden, + kCollapse, + kInherit, + }; + + constexpr SkSVGVisibility() : fType(Type::kVisible) {} + constexpr explicit SkSVGVisibility(Type t) : fType(t) {} + + SkSVGVisibility(const SkSVGVisibility&) = default; + SkSVGVisibility& operator=(const SkSVGVisibility&) = default; + + bool operator==(const SkSVGVisibility& other) const { return fType == other.fType; } + bool operator!=(const SkSVGVisibility& other) const { return !(*this == other); } + + Type type() const { return fType; } + +private: + Type fType; +}; + #endif // SkSVGTypes_DEFINED diff --git a/experimental/svg/model/SkSVGValue.h b/experimental/svg/model/SkSVGValue.h index 8e58b0672a..c6390c0468 100644 --- a/experimental/svg/model/SkSVGValue.h +++ b/experimental/svg/model/SkSVGValue.h @@ -31,6 +31,7 @@ public: kString, kTransform, kViewBox, + kVisibility, }; Type type() const { return fType; } @@ -71,20 +72,21 @@ private: typedef SkSVGValue INHERITED; }; -using SkSVGClipValue = SkSVGWrapperValue<SkSVGClip , SkSVGValue::Type::kClip >; -using SkSVGColorValue = SkSVGWrapperValue<SkSVGColorType , SkSVGValue::Type::kColor >; -using SkSVGFillRuleValue = SkSVGWrapperValue<SkSVGFillRule , SkSVGValue::Type::kFillRule >; -using SkSVGLengthValue = SkSVGWrapperValue<SkSVGLength , SkSVGValue::Type::kLength >; -using SkSVGPathValue = SkSVGWrapperValue<SkPath , SkSVGValue::Type::kPath >; -using SkSVGTransformValue = SkSVGWrapperValue<SkSVGTransformType, SkSVGValue::Type::kTransform>; -using SkSVGViewBoxValue = SkSVGWrapperValue<SkSVGViewBoxType , SkSVGValue::Type::kViewBox >; -using SkSVGPaintValue = SkSVGWrapperValue<SkSVGPaint , SkSVGValue::Type::kPaint >; -using SkSVGLineCapValue = SkSVGWrapperValue<SkSVGLineCap , SkSVGValue::Type::kLineCap >; -using SkSVGLineJoinValue = SkSVGWrapperValue<SkSVGLineJoin , SkSVGValue::Type::kLineJoin >; -using SkSVGNumberValue = SkSVGWrapperValue<SkSVGNumberType , SkSVGValue::Type::kNumber >; -using SkSVGPointsValue = SkSVGWrapperValue<SkSVGPointsType , SkSVGValue::Type::kPoints >; -using SkSVGStringValue = SkSVGWrapperValue<SkSVGStringType , SkSVGValue::Type::kString >; +using SkSVGClipValue = SkSVGWrapperValue<SkSVGClip , SkSVGValue::Type::kClip >; +using SkSVGColorValue = SkSVGWrapperValue<SkSVGColorType , SkSVGValue::Type::kColor >; +using SkSVGFillRuleValue = SkSVGWrapperValue<SkSVGFillRule , SkSVGValue::Type::kFillRule >; +using SkSVGLengthValue = SkSVGWrapperValue<SkSVGLength , SkSVGValue::Type::kLength >; +using SkSVGPathValue = SkSVGWrapperValue<SkPath , SkSVGValue::Type::kPath >; +using SkSVGTransformValue = SkSVGWrapperValue<SkSVGTransformType, SkSVGValue::Type::kTransform >; +using SkSVGViewBoxValue = SkSVGWrapperValue<SkSVGViewBoxType , SkSVGValue::Type::kViewBox >; +using SkSVGPaintValue = SkSVGWrapperValue<SkSVGPaint , SkSVGValue::Type::kPaint >; +using SkSVGLineCapValue = SkSVGWrapperValue<SkSVGLineCap , SkSVGValue::Type::kLineCap >; +using SkSVGLineJoinValue = SkSVGWrapperValue<SkSVGLineJoin , SkSVGValue::Type::kLineJoin >; +using SkSVGNumberValue = SkSVGWrapperValue<SkSVGNumberType , SkSVGValue::Type::kNumber >; +using SkSVGPointsValue = SkSVGWrapperValue<SkSVGPointsType , SkSVGValue::Type::kPoints >; +using SkSVGStringValue = SkSVGWrapperValue<SkSVGStringType , SkSVGValue::Type::kString >; using SkSVGSpreadMethodValue = SkSVGWrapperValue<SkSVGSpreadMethod , SkSVGValue::Type::kSpreadMethod>; +using SkSVGVisibilityValue = SkSVGWrapperValue<SkSVGVisibility , SkSVGValue::Type::kVisibility>; #endif // SkSVGValue_DEFINED |