[svg] Initial mask plumbing
Introduce SkSVGMask and plumb related attributes. Also consolidate the clip/mask/filter property types - they all support the same values: <funciri>|none|inherit. Bug: skia:10842 Change-Id: If45a75cccc19b84d6547237336fe5d562a85d594 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/353436 Commit-Queue: Florin Malita <fmalita@chromium.org> Commit-Queue: Florin Malita <fmalita@google.com> Reviewed-by: Tyler Denniston <tdenniston@google.com>
This commit is contained in:
parent
92969f2656
commit
836c2ca6a1
@ -98,8 +98,9 @@ struct SkSVGPresentationAttributes {
|
||||
|
||||
// uninherited
|
||||
SkSVGProperty<SkSVGNumberType, false> fOpacity;
|
||||
SkSVGProperty<SkSVGClip , false> fClipPath;
|
||||
SkSVGProperty<SkSVGFilterType, false> fFilter;
|
||||
SkSVGProperty<SkSVGFuncIRI , false> fClipPath;
|
||||
SkSVGProperty<SkSVGFuncIRI , false> fMask;
|
||||
SkSVGProperty<SkSVGFuncIRI , false> fFilter;
|
||||
SkSVGProperty<SkSVGColor , false> fStopColor;
|
||||
SkSVGProperty<SkSVGNumberType, false> fStopOpacity;
|
||||
SkSVGProperty<SkSVGColor , false> fFloodColor;
|
||||
|
38
modules/svg/include/SkSVGMask.h
Normal file
38
modules/svg/include/SkSVGMask.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2021 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkSVGMask_DEFINED
|
||||
#define SkSVGMask_DEFINED
|
||||
|
||||
#include "modules/svg/include/SkSVGHiddenContainer.h"
|
||||
#include "modules/svg/include/SkSVGTypes.h"
|
||||
|
||||
class SkSVGMask final : public SkSVGHiddenContainer {
|
||||
public:
|
||||
static sk_sp<SkSVGMask> Make() {
|
||||
return sk_sp<SkSVGMask>(new SkSVGMask());
|
||||
}
|
||||
|
||||
SVG_ATTR(X , SkSVGLength, SkSVGLength(-10, SkSVGLength::Unit::kPercentage))
|
||||
SVG_ATTR(Y , SkSVGLength, SkSVGLength(-10, SkSVGLength::Unit::kPercentage))
|
||||
SVG_ATTR(Width , SkSVGLength, SkSVGLength(120, SkSVGLength::Unit::kPercentage))
|
||||
SVG_ATTR(Height, SkSVGLength, SkSVGLength(120, SkSVGLength::Unit::kPercentage))
|
||||
|
||||
SVG_ATTR(MaskUnits, SkSVGObjectBoundingBoxUnits,
|
||||
SkSVGObjectBoundingBoxUnits(SkSVGObjectBoundingBoxUnits::Type::kObjectBoundingBox))
|
||||
SVG_ATTR(MaskContentUnits, SkSVGObjectBoundingBoxUnits,
|
||||
SkSVGObjectBoundingBoxUnits(SkSVGObjectBoundingBoxUnits::Type::kUserSpaceOnUse))
|
||||
|
||||
private:
|
||||
SkSVGMask() : INHERITED(SkSVGTag::kMask) {}
|
||||
|
||||
bool parseAndSetAttribute(const char*, const char*) override;
|
||||
|
||||
using INHERITED = SkSVGHiddenContainer;
|
||||
};
|
||||
|
||||
#endif // SkSVGMask_DEFINED
|
@ -34,6 +34,7 @@ enum class SkSVGTag {
|
||||
kG,
|
||||
kLine,
|
||||
kLinearGradient,
|
||||
kMask,
|
||||
kPath,
|
||||
kPattern,
|
||||
kPolygon,
|
||||
@ -121,8 +122,9 @@ public:
|
||||
SVG_PRES_ATTR(Visibility , SkSVGVisibility, true)
|
||||
|
||||
// not inherited
|
||||
SVG_PRES_ATTR(ClipPath , SkSVGClip , false)
|
||||
SVG_PRES_ATTR(Filter , SkSVGFilterType, false)
|
||||
SVG_PRES_ATTR(ClipPath , SkSVGFuncIRI , false)
|
||||
SVG_PRES_ATTR(Mask , SkSVGFuncIRI , false)
|
||||
SVG_PRES_ATTR(Filter , SkSVGFuncIRI , false)
|
||||
SVG_PRES_ATTR(Opacity , SkSVGNumberType, false)
|
||||
SVG_PRES_ATTR(StopColor , SkSVGColor , false)
|
||||
SVG_PRES_ATTR(StopOpacity , SkSVGNumberType, false)
|
||||
|
@ -138,8 +138,8 @@ private:
|
||||
SkSVGRenderContext& operator=(const SkSVGRenderContext&) = delete;
|
||||
|
||||
void applyOpacity(SkScalar opacity, uint32_t flags);
|
||||
void applyFilter(const SkSVGFilterType&);
|
||||
void applyClip(const SkSVGClip&);
|
||||
void applyFilter(const SkSVGFuncIRI&);
|
||||
void applyClip(const SkSVGFuncIRI&);
|
||||
void updatePaintsWithCurrentColor(const SkSVGPresentationAttributes&);
|
||||
|
||||
const sk_sp<SkFontMgr>& fFontMgr;
|
||||
|
@ -196,24 +196,22 @@ private:
|
||||
SkString fIRI;
|
||||
};
|
||||
|
||||
class SkSVGClip {
|
||||
// <funciri> | none (used for clip/mask/filter properties)
|
||||
class SkSVGFuncIRI {
|
||||
public:
|
||||
enum class Type {
|
||||
kNone,
|
||||
kIRI,
|
||||
};
|
||||
|
||||
SkSVGClip() : fType(Type::kNone) {}
|
||||
explicit SkSVGClip(Type t) : fType(t) {}
|
||||
explicit SkSVGClip(const SkString& iri) : fType(Type::kIRI), fIRI(iri) {}
|
||||
SkSVGFuncIRI() : fType(Type::kNone) {}
|
||||
explicit SkSVGFuncIRI(Type t) : fType(t) {}
|
||||
explicit SkSVGFuncIRI(SkString&& iri) : fType(Type::kIRI), fIRI(std::move(iri)) {}
|
||||
|
||||
SkSVGClip(const SkSVGClip&) = default;
|
||||
SkSVGClip& operator=(const SkSVGClip&) = default;
|
||||
|
||||
bool operator==(const SkSVGClip& other) const {
|
||||
bool operator==(const SkSVGFuncIRI& other) const {
|
||||
return fType == other.fType && fIRI == other.fIRI;
|
||||
}
|
||||
bool operator!=(const SkSVGClip& other) const { return !(*this == other); }
|
||||
bool operator!=(const SkSVGFuncIRI& other) const { return !(*this == other); }
|
||||
|
||||
Type type() const { return fType; }
|
||||
const SkString& iri() const { SkASSERT(fType == Type::kIRI); return fIRI; }
|
||||
@ -569,35 +567,6 @@ private:
|
||||
Type fType;
|
||||
};
|
||||
|
||||
class SkSVGFilterType {
|
||||
public:
|
||||
enum class Type {
|
||||
kNone,
|
||||
kIRI,
|
||||
kInherit,
|
||||
};
|
||||
|
||||
SkSVGFilterType() : fType(Type::kNone) {}
|
||||
explicit SkSVGFilterType(Type t) : fType(t) {}
|
||||
explicit SkSVGFilterType(const SkString& iri) : fType(Type::kIRI), fIRI(iri) {}
|
||||
|
||||
bool operator==(const SkSVGFilterType& other) const {
|
||||
return fType == other.fType && fIRI == other.fIRI;
|
||||
}
|
||||
bool operator!=(const SkSVGFilterType& other) const { return !(*this == other); }
|
||||
|
||||
const SkString& iri() const {
|
||||
SkASSERT(fType == Type::kIRI);
|
||||
return fIRI;
|
||||
}
|
||||
|
||||
Type type() const { return fType; }
|
||||
|
||||
private:
|
||||
Type fType;
|
||||
SkString fIRI;
|
||||
};
|
||||
|
||||
class SkSVGFeInputType {
|
||||
public:
|
||||
enum class Type {
|
||||
|
@ -71,7 +71,6 @@ private:
|
||||
};
|
||||
|
||||
using SkSVGColorValue = SkSVGWrapperValue<SkSVGColorType , SkSVGValue::Type::kColor >;
|
||||
using SkSVGFilterValue = SkSVGWrapperValue<SkSVGFilterType , SkSVGValue::Type::kFilter >;
|
||||
using SkSVGLengthValue = SkSVGWrapperValue<SkSVGLength , SkSVGValue::Type::kLength >;
|
||||
using SkSVGPathValue = SkSVGWrapperValue<SkPath , SkSVGValue::Type::kPath >;
|
||||
using SkSVGTransformValue = SkSVGWrapperValue<SkSVGTransformType, SkSVGValue::Type::kTransform >;
|
||||
|
@ -539,16 +539,18 @@ bool SkSVGAttributeParser::parse(SkSVGPaint* paint) {
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/SVG11/masking.html#ClipPathProperty
|
||||
// https://www.w3.org/TR/SVG11/masking.html#MaskProperty
|
||||
// https://www.w3.org/TR/SVG11/filters.html#FilterProperty
|
||||
template <>
|
||||
bool SkSVGAttributeParser::parse(SkSVGClip* clip) {
|
||||
bool SkSVGAttributeParser::parse(SkSVGFuncIRI* firi) {
|
||||
SkSVGStringType iri;
|
||||
bool parsedValue = false;
|
||||
|
||||
if (this->parseExpectedStringToken("none")) {
|
||||
*clip = SkSVGClip(SkSVGClip::Type::kNone);
|
||||
*firi = SkSVGFuncIRI();
|
||||
parsedValue = true;
|
||||
} else if (this->parseFuncIRI(&iri)) {
|
||||
*clip = SkSVGClip(iri);
|
||||
*firi = SkSVGFuncIRI(std::move(iri));
|
||||
parsedValue = true;
|
||||
}
|
||||
|
||||
@ -692,26 +694,6 @@ bool SkSVGAttributeParser::parse(SkSVGFillRule* fillRule) {
|
||||
return parsedValue && this->parseEOSToken();
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/SVG11/filters.html#FilterProperty
|
||||
template <>
|
||||
bool SkSVGAttributeParser::parse(SkSVGFilterType* filter) {
|
||||
SkSVGStringType iri;
|
||||
bool parsedValue = false;
|
||||
|
||||
if (this->parseExpectedStringToken("none")) {
|
||||
*filter = SkSVGFilterType(SkSVGFilterType::Type::kNone);
|
||||
parsedValue = true;
|
||||
} else if (this->parseExpectedStringToken("inherit")) {
|
||||
*filter = SkSVGFilterType(SkSVGFilterType::Type::kInherit);
|
||||
parsedValue = true;
|
||||
} else if (this->parseFuncIRI(&iri)) {
|
||||
*filter = SkSVGFilterType(iri);
|
||||
parsedValue = true;
|
||||
}
|
||||
|
||||
return parsedValue && this->parseEOSToken();
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/SVG11/painting.html#VisibilityProperty
|
||||
template <>
|
||||
bool SkSVGAttributeParser::parse(SkSVGVisibility* visibility) {
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "modules/svg/include/SkSVGG.h"
|
||||
#include "modules/svg/include/SkSVGLine.h"
|
||||
#include "modules/svg/include/SkSVGLinearGradient.h"
|
||||
#include "modules/svg/include/SkSVGMask.h"
|
||||
#include "modules/svg/include/SkSVGNode.h"
|
||||
#include "modules/svg/include/SkSVGPath.h"
|
||||
#include "modules/svg/include/SkSVGPattern.h"
|
||||
@ -267,6 +268,7 @@ SortedDictionaryEntry<sk_sp<SkSVGNode>(*)()> gTagFactories[] = {
|
||||
{ "g" , []() -> sk_sp<SkSVGNode> { return SkSVGG::Make(); }},
|
||||
{ "line" , []() -> sk_sp<SkSVGNode> { return SkSVGLine::Make(); }},
|
||||
{ "linearGradient", []() -> sk_sp<SkSVGNode> { return SkSVGLinearGradient::Make(); }},
|
||||
{ "mask" , []() -> sk_sp<SkSVGNode> { return SkSVGMask::Make(); }},
|
||||
{ "path" , []() -> sk_sp<SkSVGNode> { return SkSVGPath::Make(); }},
|
||||
{ "pattern" , []() -> sk_sp<SkSVGNode> { return SkSVGPattern::Make(); }},
|
||||
{ "polygon" , []() -> sk_sp<SkSVGNode> { return SkSVGPoly::MakePolygon(); }},
|
||||
|
20
modules/svg/src/SkSVGMask.cpp
Normal file
20
modules/svg/src/SkSVGMask.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2021 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "modules/svg/include/SkSVGMask.h"
|
||||
|
||||
bool SkSVGMask::parseAndSetAttribute(const char* n, const char* v) {
|
||||
return INHERITED::parseAndSetAttribute(n, v) ||
|
||||
this->setX(SkSVGAttributeParser::parse<SkSVGLength>("x", n, v)) ||
|
||||
this->setY(SkSVGAttributeParser::parse<SkSVGLength>("y", n, v)) ||
|
||||
this->setWidth(SkSVGAttributeParser::parse<SkSVGLength>("width", n, v)) ||
|
||||
this->setHeight(SkSVGAttributeParser::parse<SkSVGLength>("height", n, v)) ||
|
||||
this->setMaskUnits(
|
||||
SkSVGAttributeParser::parse<SkSVGObjectBoundingBoxUnits>("maskUnits", n, v)) ||
|
||||
this->setMaskContentUnits(
|
||||
SkSVGAttributeParser::parse<SkSVGObjectBoundingBoxUnits>("maskContentUnits", n, v));
|
||||
}
|
@ -88,32 +88,33 @@ bool SkSVGNode::parseAndSetAttribute(const char* n, const char* v) {
|
||||
SkSVGAttributeParser::parseProperty<decltype(fPresentationAttributes.f##attrName)>( \
|
||||
svgName, n, v))
|
||||
|
||||
return PARSE_AND_SET( "clip-path" , ClipPath)
|
||||
|| PARSE_AND_SET("clip-rule" , ClipRule)
|
||||
|| PARSE_AND_SET("color" , Color)
|
||||
|| PARSE_AND_SET("fill" , Fill)
|
||||
|| PARSE_AND_SET("fill-opacity" , FillOpacity)
|
||||
|| PARSE_AND_SET("fill-rule" , FillRule)
|
||||
|| PARSE_AND_SET("filter" , Filter)
|
||||
|| PARSE_AND_SET("flood-color" , FloodColor)
|
||||
|| PARSE_AND_SET("flood-opacity" , FloodOpacity)
|
||||
|| PARSE_AND_SET("font-family" , FontFamily)
|
||||
|| PARSE_AND_SET("font-size" , FontSize)
|
||||
|| PARSE_AND_SET("font-style" , FontStyle)
|
||||
|| PARSE_AND_SET("font-weight" , FontWeight)
|
||||
|| PARSE_AND_SET("opacity" , Opacity)
|
||||
|| PARSE_AND_SET("stop-color" , StopColor)
|
||||
|| PARSE_AND_SET("stop-opacity" , StopOpacity)
|
||||
|| PARSE_AND_SET("stroke" , Stroke)
|
||||
|| PARSE_AND_SET("stroke-dasharray" , StrokeDashArray)
|
||||
|| PARSE_AND_SET("stroke-dashoffset", StrokeDashOffset)
|
||||
|| PARSE_AND_SET("stroke-linecap" , StrokeLineCap)
|
||||
|| PARSE_AND_SET("stroke-linejoin" , StrokeLineJoin)
|
||||
|| PARSE_AND_SET("stroke-miterlimit", StrokeMiterLimit)
|
||||
|| PARSE_AND_SET("stroke-opacity" , StrokeOpacity)
|
||||
|| PARSE_AND_SET("stroke-width" , StrokeWidth)
|
||||
|| PARSE_AND_SET("text-anchor" , TextAnchor)
|
||||
|| PARSE_AND_SET("visibility" , Visibility);
|
||||
return PARSE_AND_SET("clip-path" , ClipPath)
|
||||
|| PARSE_AND_SET("clip-rule" , ClipRule)
|
||||
|| PARSE_AND_SET("color" , Color)
|
||||
|| PARSE_AND_SET("fill" , Fill)
|
||||
|| PARSE_AND_SET("fill-opacity" , FillOpacity)
|
||||
|| PARSE_AND_SET("fill-rule" , FillRule)
|
||||
|| PARSE_AND_SET("filter" , Filter)
|
||||
|| PARSE_AND_SET("flood-color" , FloodColor)
|
||||
|| PARSE_AND_SET("flood-opacity" , FloodOpacity)
|
||||
|| PARSE_AND_SET("font-family" , FontFamily)
|
||||
|| PARSE_AND_SET("font-size" , FontSize)
|
||||
|| PARSE_AND_SET("font-style" , FontStyle)
|
||||
|| PARSE_AND_SET("font-weight" , FontWeight)
|
||||
|| PARSE_AND_SET("mask" , Mask)
|
||||
|| PARSE_AND_SET("opacity" , Opacity)
|
||||
|| PARSE_AND_SET("stop-color" , StopColor)
|
||||
|| PARSE_AND_SET("stop-opacity" , StopOpacity)
|
||||
|| PARSE_AND_SET("stroke" , Stroke)
|
||||
|| PARSE_AND_SET("stroke-dasharray" , StrokeDashArray)
|
||||
|| PARSE_AND_SET("stroke-dashoffset", StrokeDashOffset)
|
||||
|| PARSE_AND_SET("stroke-linecap" , StrokeLineCap)
|
||||
|| PARSE_AND_SET("stroke-linejoin" , StrokeLineJoin)
|
||||
|| PARSE_AND_SET("stroke-miterlimit", StrokeMiterLimit)
|
||||
|| PARSE_AND_SET("stroke-opacity" , StrokeOpacity)
|
||||
|| PARSE_AND_SET("stroke-width" , StrokeWidth)
|
||||
|| PARSE_AND_SET("text-anchor" , TextAnchor)
|
||||
|| PARSE_AND_SET("visibility" , Visibility);
|
||||
|
||||
#undef PARSE_AND_SET
|
||||
}
|
||||
|
@ -468,8 +468,8 @@ void SkSVGRenderContext::applyOpacity(SkScalar opacity, uint32_t flags) {
|
||||
}
|
||||
}
|
||||
|
||||
void SkSVGRenderContext::applyFilter(const SkSVGFilterType& filter) {
|
||||
if (filter.type() != SkSVGFilterType::Type::kIRI) {
|
||||
void SkSVGRenderContext::applyFilter(const SkSVGFuncIRI& filter) {
|
||||
if (filter.type() != SkSVGFuncIRI::Type::kIRI) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -497,8 +497,8 @@ void SkSVGRenderContext::saveOnce() {
|
||||
SkASSERT(fCanvas->getSaveCount() > fCanvasSaveCount);
|
||||
}
|
||||
|
||||
void SkSVGRenderContext::applyClip(const SkSVGClip& clip) {
|
||||
if (clip.type() != SkSVGClip::Type::kIRI) {
|
||||
void SkSVGRenderContext::applyClip(const SkSVGFuncIRI& clip) {
|
||||
if (clip.type() != SkSVGFuncIRI::Type::kIRI) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@ skia_svg_public = [
|
||||
"$_include/SkSVGIDMapper.h",
|
||||
"$_include/SkSVGLinearGradient.h",
|
||||
"$_include/SkSVGLine.h",
|
||||
"$_include/SkSVGMask.h",
|
||||
"$_include/SkSVGNode.h",
|
||||
"$_include/SkSVGPath.h",
|
||||
"$_include/SkSVGPattern.h",
|
||||
@ -66,6 +67,7 @@ skia_svg_sources = [
|
||||
"$_src/SkSVGGradient.cpp",
|
||||
"$_src/SkSVGLine.cpp",
|
||||
"$_src/SkSVGLinearGradient.cpp",
|
||||
"$_src/SkSVGMask.cpp",
|
||||
"$_src/SkSVGNode.cpp",
|
||||
"$_src/SkSVGPath.cpp",
|
||||
"$_src/SkSVGPattern.cpp",
|
||||
|
Loading…
Reference in New Issue
Block a user