[svg] Implement 'display:none'

The full 'display' presentation attribute [1] has a number of settings
that we likely don't want to support. However, 'display:none' has some
practical uses and is easy enough to support. This progresses some
local tests as well as a few W3C tests.

[1] https://www.w3.org/TR/SVG11/painting.html#DisplayProperty

Bug: skia:10842
Change-Id: I60fef959fb45c3cfb229b85b720dfa69fc458bc3
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/403438
Commit-Queue: Tyler Denniston <tdenniston@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
This commit is contained in:
Tyler Denniston 2021-05-03 13:12:21 -04:00 committed by Skia Commit-Bot
parent 561aa83a3f
commit 80ba617cab
6 changed files with 40 additions and 2 deletions

View File

@ -100,6 +100,7 @@ struct SkSVGPresentationAttributes {
// uninherited
SkSVGProperty<SkSVGNumberType, false> fOpacity;
SkSVGProperty<SkSVGFuncIRI , false> fClipPath;
SkSVGProperty<SkSVGDisplay , false> fDisplay;
SkSVGProperty<SkSVGFuncIRI , false> fMask;
SkSVGProperty<SkSVGFuncIRI , false> fFilter;
SkSVGProperty<SkSVGColor , false> fStopColor;

View File

@ -135,6 +135,7 @@ public:
// not inherited
SVG_PRES_ATTR(ClipPath , SkSVGFuncIRI , false)
SVG_PRES_ATTR(Display , SkSVGDisplay , false)
SVG_PRES_ATTR(Mask , SkSVGFuncIRI , false)
SVG_PRES_ATTR(Filter , SkSVGFuncIRI , false)
SVG_PRES_ATTR(Opacity , SkSVGNumberType, false)

View File

@ -682,4 +682,10 @@ enum class SkSVGColorspace {
kLinearRGB,
};
// https://www.w3.org/TR/SVG11/painting.html#DisplayProperty
enum class SkSVGDisplay {
kInline,
kNone,
};
#endif // SkSVGTypes_DEFINED

View File

@ -36,6 +36,8 @@ SkSVGPresentationAttributes SkSVGPresentationAttributes::MakeInitial() {
result.fFontWeight.init(SkSVGFontWeight::Type::kNormal);
result.fTextAnchor.init(SkSVGTextAnchor::Type::kStart);
result.fDisplay.init(SkSVGDisplay::kInline);
result.fStopColor.set(SkSVGColor(SK_ColorBLACK));
result.fStopOpacity.set(SkSVGNumberType(1));
result.fFloodColor.set(SkSVGColor(SK_ColorBLACK));

View File

@ -963,3 +963,26 @@ bool SkSVGAttributeParser::parse(SkSVGColorspace* colorspace) {
return this->parseEnumMap(gColorspaceMap, colorspace) && this->parseEOSToken();
}
// https://www.w3.org/TR/SVG11/painting.html#DisplayProperty
template <>
bool SkSVGAttributeParser::parse(SkSVGDisplay* display) {
static const struct {
SkSVGDisplay fType;
const char* fName;
} gDisplayInfo[] = {
{ SkSVGDisplay::kInline, "inline" },
{ SkSVGDisplay::kNone , "none" },
};
bool parsedValue = false;
for (const auto& parseInfo : gDisplayInfo) {
if (this->parseExpectedStringToken(parseInfo.fName)) {
*display = SkSVGDisplay(parseInfo.fType);
parsedValue = true;
break;
}
}
return parsedValue && this->parseEOSToken();
}

View File

@ -63,9 +63,13 @@ bool SkSVGNode::onPrepareToRender(SkSVGRenderContext* ctx) const {
ctx->applyPresentationAttributes(fPresentationAttributes,
this->hasChildren() ? 0 : SkSVGRenderContext::kLeaf);
// visibility:hidden disables rendering
// visibility:hidden and display:none disable rendering.
// TODO: if display is not a value (true when display="inherit"), we currently
// ignore it. Eventually we should be able to add SkASSERT(display.isValue()).
const auto visibility = ctx->presentationContext().fInherited.fVisibility->type();
return visibility != SkSVGVisibility::Type::kHidden;
const auto display = fPresentationAttributes.fDisplay; // display is uninherited
return visibility != SkSVGVisibility::Type::kHidden &&
(!display.isValue() || *display != SkSVGDisplay::kNone);
}
void SkSVGNode::setAttribute(SkSVGAttribute attr, const SkSVGValue& v) {
@ -94,6 +98,7 @@ bool SkSVGNode::parseAndSetAttribute(const char* n, const char* v) {
|| PARSE_AND_SET("color" , Color)
|| PARSE_AND_SET("color-interpolation" , ColorInterpolation)
|| PARSE_AND_SET("color-interpolation-filters", ColorInterpolationFilters)
|| PARSE_AND_SET("display" , Display)
|| PARSE_AND_SET("fill" , Fill)
|| PARSE_AND_SET("fill-opacity" , FillOpacity)
|| PARSE_AND_SET("fill-rule" , FillRule)