[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>
This commit is contained in:
parent
177e695589
commit
ffe6ae49e4
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ public:
|
||||
bool parsePoints(SkSVGPointsType*);
|
||||
bool parseIRI(SkSVGStringType*);
|
||||
bool parseSpreadMethod(SkSVGSpreadMethod*);
|
||||
bool parseVisibility(SkSVGVisibility*);
|
||||
|
||||
private:
|
||||
// Stack-only
|
||||
|
@ -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 }},
|
||||
|
@ -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;
|
||||
|
@ -60,6 +60,7 @@ public:
|
||||
void setStroke(const SkSVGPaint&);
|
||||
void setStrokeOpacity(const SkSVGNumberType&);
|
||||
void setStrokeWidth(const SkSVGLength&);
|
||||
void setVisibility(const SkSVGVisibility&);
|
||||
|
||||
protected:
|
||||
SkSVGNode(SkSVGTag);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user