[svg] Split out SkSVGColor from paint
This color type will be shared in paint, stop-color, and flood-color
attributes (mainly so they can use 'currentColor').
Change-Id: Ib4200ea729a91a0db5da069c68d64e5e8e3f5010
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/340617
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Tyler Denniston <tdenniston@google.com>
diff --git a/modules/svg/include/SkSVGTypes.h b/modules/svg/include/SkSVGTypes.h
index 2afee73..4adc759 100644
--- a/modules/svg/include/SkSVGTypes.h
+++ b/modules/svg/include/SkSVGTypes.h
@@ -137,18 +137,42 @@
SkSVGStringType fIRI;
};
+// https://www.w3.org/TR/SVG11/types.html#InterfaceSVGColor
+class SkSVGColor {
+public:
+ enum class Type {
+ kCurrentColor,
+ kColor,
+ kICCColor,
+ };
+
+ SkSVGColor() : fType(Type::kColor), fColor(SK_ColorBLACK) {}
+ explicit SkSVGColor(Type t) : fType(t), fColor(SK_ColorBLACK) {}
+ explicit SkSVGColor(const SkSVGColorType& c) : fType(Type::kColor), fColor(c) {}
+ bool operator==(const SkSVGColor& other) const {
+ return fType == other.fType && fColor == other.fColor;
+ }
+ bool operator!=(const SkSVGColor& other) const { return !(*this == other); }
+
+ Type type() const { return fType; }
+ const SkSVGColorType& color() const { SkASSERT(fType == Type::kColor); return fColor; }
+
+private:
+ Type fType;
+ SkSVGColorType fColor;
+};
+
class SkSVGPaint {
public:
enum class Type {
kNone,
- kCurrentColor,
kColor,
kIRI,
};
SkSVGPaint() : fType(Type::kNone), fColor(SK_ColorBLACK) {}
explicit SkSVGPaint(Type t) : fType(t), fColor(SK_ColorBLACK) {}
- explicit SkSVGPaint(const SkSVGColorType& c) : fType(Type::kColor), fColor(c) {}
+ explicit SkSVGPaint(const SkSVGColor& c) : fType(Type::kColor), fColor(c) {}
explicit SkSVGPaint(const SkString& iri)
: fType(Type::kIRI), fColor(SK_ColorBLACK), fIRI(iri) {}
@@ -161,15 +185,15 @@
bool operator!=(const SkSVGPaint& other) const { return !(*this == other); }
Type type() const { return fType; }
- const SkSVGColorType& color() const { SkASSERT(fType == Type::kColor); return fColor; }
+ const SkSVGColor& color() const { SkASSERT(fType == Type::kColor); return fColor; }
const SkString& iri() const { SkASSERT(fType == Type::kIRI); return fIRI; }
private:
Type fType;
// Logical union.
- SkSVGColorType fColor;
- SkString fIRI;
+ SkSVGColor fColor;
+ SkString fIRI;
};
class SkSVGClip {
diff --git a/modules/svg/src/SkSVGAttribute.cpp b/modules/svg/src/SkSVGAttribute.cpp
index fdc45f6..6a9129d 100644
--- a/modules/svg/src/SkSVGAttribute.cpp
+++ b/modules/svg/src/SkSVGAttribute.cpp
@@ -10,7 +10,7 @@
SkSVGPresentationAttributes SkSVGPresentationAttributes::MakeInitial() {
SkSVGPresentationAttributes result;
- result.fFill.set(SkSVGPaint(SkSVGColorType(SK_ColorBLACK)));
+ result.fFill.set(SkSVGPaint(SkSVGColor(SK_ColorBLACK)));
result.fFillOpacity.set(SkSVGNumberType(1));
result.fFillRule.set(SkSVGFillRule(SkSVGFillRule::Type::kNonZero));
result.fClipRule.set(SkSVGFillRule(SkSVGFillRule::Type::kNonZero));
diff --git a/modules/svg/src/SkSVGAttributeParser.cpp b/modules/svg/src/SkSVGAttributeParser.cpp
index 4da7f50..d34f153 100644
--- a/modules/svg/src/SkSVGAttributeParser.cpp
+++ b/modules/svg/src/SkSVGAttributeParser.cpp
@@ -245,6 +245,23 @@
return parsedValue && this->parseEOSToken();
}
+// https://www.w3.org/TR/SVG11/types.html#InterfaceSVGColor
+template <>
+bool SkSVGAttributeParser::parse(SkSVGColor* color) {
+ SkSVGColorType c;
+ bool parsedValue = false;
+
+ if (this->parse(&c)) {
+ *color = SkSVGColor(c);
+ parsedValue = true;
+ } else if (this->parseExpectedStringToken("currentColor")) {
+ *color = SkSVGColor(SkSVGColor::Type::kCurrentColor);
+ parsedValue = true;
+ }
+
+ return parsedValue && this->parseEOSToken();
+}
+
// https://www.w3.org/TR/SVG11/linking.html#IRIReference
template <>
bool SkSVGAttributeParser::parse(SkSVGIRI* iri) {
@@ -505,7 +522,7 @@
// https://www.w3.org/TR/SVG11/painting.html#SpecifyingPaint
template <>
bool SkSVGAttributeParser::parse(SkSVGPaint* paint) {
- SkSVGColorType c;
+ SkSVGColor c;
SkSVGStringType iri;
bool parsedValue = false;
if (this->parse(&c)) {
@@ -514,9 +531,6 @@
} else if (this->parseExpectedStringToken("none")) {
*paint = SkSVGPaint(SkSVGPaint::Type::kNone);
parsedValue = true;
- } else if (this->parseExpectedStringToken("currentColor")) {
- *paint = SkSVGPaint(SkSVGPaint::Type::kCurrentColor);
- parsedValue = true;
} else if (this->parseFuncIRI(&iri)) {
*paint = SkSVGPaint(iri);
parsedValue = true;
diff --git a/modules/svg/src/SkSVGRenderContext.cpp b/modules/svg/src/SkSVGRenderContext.cpp
index cd87e87..7f7be49 100644
--- a/modules/svg/src/SkSVGRenderContext.cpp
+++ b/modules/svg/src/SkSVGRenderContext.cpp
@@ -103,10 +103,23 @@
}
}
+SkSVGColorType resolveSvgColor(const SkSVGRenderContext& ctx, const SkSVGColor& color) {
+ switch (color.type()) {
+ case SkSVGColor::Type::kColor:
+ return color.color();
+ case SkSVGColor::Type::kCurrentColor:
+ return *ctx.presentationContext().fInherited.fColor;
+ case SkSVGColor::Type::kICCColor:
+ SkDebugf("ICC color unimplemented");
+ return SK_ColorBLACK;
+ }
+ SkUNREACHABLE;
+}
+
void applySvgPaint(const SkSVGRenderContext& ctx, const SkSVGPaint& svgPaint, SkPaint* p) {
switch (svgPaint.type()) {
case SkSVGPaint::Type::kColor:
- p->setColor(SkColorSetA(svgPaint.color(), p->getAlpha()));
+ p->setColor(SkColorSetA(resolveSvgColor(ctx, svgPaint.color()), p->getAlpha()));
break;
case SkSVGPaint::Type::kIRI: {
const auto node = ctx.findNodeById(svgPaint.iri());
@@ -115,9 +128,6 @@
}
break;
}
- case SkSVGPaint::Type::kCurrentColor:
- p->setColor(*ctx.presentationContext().fInherited.fColor);
- break;
case SkSVGPaint::Type::kNone:
// Do nothing
break;
@@ -536,14 +546,16 @@
// https://www.w3.org/TR/SVG11/color.html#ColorProperty
// Only fill and stroke require paint updates. The others are resolved at render time.
- if (fPresentationContext->fInherited.fFill->type() == SkSVGPaint::Type::kCurrentColor) {
- applySvgPaint(*this, *fPresentationContext->fInherited.fFill,
- &fPresentationContext.writable()->fFillPaint);
+ const auto& fill = fPresentationContext->fInherited.fFill;
+ if (fill->type() == SkSVGPaint::Type::kColor &&
+ fill->color().type() == SkSVGColor::Type::kCurrentColor) {
+ applySvgPaint(*this, *fill, &fPresentationContext.writable()->fFillPaint);
}
- if (fPresentationContext->fInherited.fStroke->type() == SkSVGPaint::Type::kCurrentColor) {
- applySvgPaint(*this, *fPresentationContext->fInherited.fStroke,
- &fPresentationContext.writable()->fStrokePaint);
+ const auto& stroke = fPresentationContext->fInherited.fStroke;
+ if (stroke->type() == SkSVGPaint::Type::kColor &&
+ stroke->color().type() == SkSVGColor::Type::kCurrentColor) {
+ applySvgPaint(*this, *stroke, &fPresentationContext.writable()->fStrokePaint);
}
}