diff options
author | fmalita <fmalita@chromium.org> | 2016-07-29 08:52:03 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-07-29 08:52:03 -0700 |
commit | 58649ccc75c033ea4e0c9a664b4ed178816a50c6 (patch) | |
tree | 91117fb8be83c0ee4d07d79e5a150fa11b45e333 /experimental/svg | |
parent | 5abbb44f682038abe01b8ee63fb22439af861dda (diff) |
[SVGDom] Parse style attributes
Dispatch style-encoded (style="foo: bar; ...") attributes via normal
attribute setters.
R=reed@google.com,robertphillips@google.com
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2193663002
Review-Url: https://codereview.chromium.org/2193663002
Diffstat (limited to 'experimental/svg')
-rw-r--r-- | experimental/svg/model/SkSVGAttribute.h | 10 | ||||
-rw-r--r-- | experimental/svg/model/SkSVGDOM.cpp | 94 | ||||
-rw-r--r-- | experimental/svg/model/SkSVGG.h | 2 | ||||
-rw-r--r-- | experimental/svg/model/SkSVGNode.cpp | 4 | ||||
-rw-r--r-- | experimental/svg/model/SkSVGNode.h | 6 | ||||
-rw-r--r-- | experimental/svg/model/SkSVGPath.cpp | 4 | ||||
-rw-r--r-- | experimental/svg/model/SkSVGSVG.cpp | 2 | ||||
-rw-r--r-- | experimental/svg/model/SkSVGTransformableNode.cpp | 2 |
8 files changed, 93 insertions, 31 deletions
diff --git a/experimental/svg/model/SkSVGAttribute.h b/experimental/svg/model/SkSVGAttribute.h index 50989f17ec..83a35527c5 100644 --- a/experimental/svg/model/SkSVGAttribute.h +++ b/experimental/svg/model/SkSVGAttribute.h @@ -12,10 +12,12 @@ #include "SkTLazy.h" enum class SkSVGAttribute { - d, - fill, - stroke, - transform, + kD, + kFill, + kStroke, + kTransform, + + kUnknown, }; class SkSVGRenderContext; diff --git a/experimental/svg/model/SkSVGDOM.cpp b/experimental/svg/model/SkSVGDOM.cpp index 6f782c3a96..4e2f898942 100644 --- a/experimental/svg/model/SkSVGDOM.cpp +++ b/experimental/svg/model/SkSVGDOM.cpp @@ -9,6 +9,7 @@ #include "SkDOM.h" #include "SkParse.h" #include "SkParsePath.h" +#include "SkString.h" #include "SkSVGDOM.h" #include "SkSVGG.h" #include "SkSVGNode.h" @@ -118,6 +119,60 @@ bool SetTransformAttribute(const sk_sp<SkSVGNode>& node, SkSVGAttribute attr, return true; } +// Breaks a "foo: bar; baz: ..." string into key:value pairs. +class StyleIterator { +public: + StyleIterator(const char* str) : fPos(str) { } + + std::tuple<SkString, SkString> next() { + SkString name, value; + + if (fPos) { + const char* sep = this->nextSeparator(); + SkASSERT(*sep == ';' || *sep == '\0'); + + const char* valueSep = strchr(fPos, ':'); + if (valueSep && valueSep < sep) { + name.set(fPos, valueSep - fPos); + value.set(valueSep + 1, sep - valueSep - 1); + } + + fPos = *sep ? sep + 1 : nullptr; + } + + return std::make_tuple(name, value); + } + +private: + const char* nextSeparator() const { + const char* sep = fPos; + while (*sep != ';' && *sep != '\0') { + sep++; + } + return sep; + } + + const char* fPos; +}; + +void set_string_attribute(const sk_sp<SkSVGNode>& node, const char* name, const char* value); + +bool SetStyleAttributes(const sk_sp<SkSVGNode>& node, SkSVGAttribute, + const char* stringValue) { + + SkString name, value; + StyleIterator iter(stringValue); + for (;;) { + std::tie(name, value) = iter.next(); + if (name.isEmpty()) { + break; + } + set_string_attribute(node, name.c_str(), value.c_str()); + } + + return true; +} + template<typename T> struct SortedDictionaryEntry { const char* fKey; @@ -130,10 +185,11 @@ struct AttrParseInfo { }; SortedDictionaryEntry<AttrParseInfo> gAttributeParseInfo[] = { - { "d", { SkSVGAttribute::d, SetPathDataAttribute }}, - { "fill", { SkSVGAttribute::fill, SetPaintAttribute }}, - { "stroke", { SkSVGAttribute::stroke, SetPaintAttribute }}, - { "transform", { SkSVGAttribute::transform, SetTransformAttribute }}, + { "d", { SkSVGAttribute::kD, SetPathDataAttribute }}, + { "fill", { SkSVGAttribute::kFill, SetPaintAttribute }}, + { "stroke", { SkSVGAttribute::kStroke, SetPaintAttribute }}, + { "style", { SkSVGAttribute::kUnknown, SetStyleAttributes }}, + { "transform", { SkSVGAttribute::kTransform, SetTransformAttribute }}, }; SortedDictionaryEntry<sk_sp<SkSVGNode>(*)()> gTagFactories[] = { @@ -150,24 +206,28 @@ struct ConstructionContext { const SkSVGNode* fParent; }; +void set_string_attribute(const sk_sp<SkSVGNode>& node, const char* name, const char* value) { + const int attrIndex = SkStrSearch(&gAttributeParseInfo[0].fKey, + SkTo<int>(SK_ARRAY_COUNT(gAttributeParseInfo)), + name, sizeof(gAttributeParseInfo[0])); + if (attrIndex < 0) { + SkDebugf("unhandled attribute: %s\n", name); + return; + } + + SkASSERT(SkTo<size_t>(attrIndex) < SK_ARRAY_COUNT(gAttributeParseInfo)); + const auto& attrInfo = gAttributeParseInfo[attrIndex].fValue; + if (!attrInfo.fSetter(node, attrInfo.fAttr, value)) { + SkDebugf("could not parse attribute: '%s=\"%s\"'\n", name, value); + } +} + void parse_node_attributes(const SkDOM& xmlDom, const SkDOM::Node* xmlNode, const sk_sp<SkSVGNode>& svgNode) { const char* name, *value; SkDOM::AttrIter attrIter(xmlDom, xmlNode); while ((name = attrIter.next(&value))) { - const int attrIndex = SkStrSearch(&gAttributeParseInfo[0].fKey, - SkTo<int>(SK_ARRAY_COUNT(gAttributeParseInfo)), - name, sizeof(gAttributeParseInfo[0])); - if (attrIndex < 0) { - SkDebugf("unhandled attribute: %s\n", name); - continue; - } - - SkASSERT(SkTo<size_t>(attrIndex) < SK_ARRAY_COUNT(gAttributeParseInfo)); - const auto& attrInfo = gAttributeParseInfo[attrIndex].fValue; - if (!attrInfo.fSetter(svgNode, attrInfo.fAttr, value)) { - SkDebugf("could not parse attribute: '%s=\"%s\"'\n", name, value); - } + set_string_attribute(svgNode, name, value); } } diff --git a/experimental/svg/model/SkSVGG.h b/experimental/svg/model/SkSVGG.h index eaaf822d78..b8229c0553 100644 --- a/experimental/svg/model/SkSVGG.h +++ b/experimental/svg/model/SkSVGG.h @@ -17,7 +17,7 @@ public: static sk_sp<SkSVGG> Make() { return sk_sp<SkSVGG>(new SkSVGG()); } private: - SkSVGG() : INHERITED(SkSVGTag::g) { } + SkSVGG() : INHERITED(SkSVGTag::kG) { } typedef SkSVGContainer INHERITED; }; diff --git a/experimental/svg/model/SkSVGNode.cpp b/experimental/svg/model/SkSVGNode.cpp index 2b891792fd..58e0ad4989 100644 --- a/experimental/svg/model/SkSVGNode.cpp +++ b/experimental/svg/model/SkSVGNode.cpp @@ -40,12 +40,12 @@ void SkSVGNode::setAttribute(SkSVGAttribute attr, const SkSVGValue& v) { void SkSVGNode::onSetAttribute(SkSVGAttribute attr, const SkSVGValue& v) { switch (attr) { - case SkSVGAttribute::fill: + case SkSVGAttribute::kFill: if (const SkSVGColorValue* color = v.as<SkSVGColorValue>()) { fPresentationAttributes.setFill(*color); } break; - case SkSVGAttribute::stroke: + case SkSVGAttribute::kStroke: if (const SkSVGColorValue* color = v.as<SkSVGColorValue>()) { fPresentationAttributes.setStroke(*color); } diff --git a/experimental/svg/model/SkSVGNode.h b/experimental/svg/model/SkSVGNode.h index de180146b7..407e69ac63 100644 --- a/experimental/svg/model/SkSVGNode.h +++ b/experimental/svg/model/SkSVGNode.h @@ -17,9 +17,9 @@ class SkSVGRenderContext; class SkSVGValue; enum class SkSVGTag { - g, - path, - svg + kG, + kPath, + kSvg }; class SkSVGNode : public SkRefCnt { diff --git a/experimental/svg/model/SkSVGPath.cpp b/experimental/svg/model/SkSVGPath.cpp index ba5e3d62ba..7d905945bc 100644 --- a/experimental/svg/model/SkSVGPath.cpp +++ b/experimental/svg/model/SkSVGPath.cpp @@ -11,7 +11,7 @@ #include "SkSVGRenderContext.h" #include "SkSVGValue.h" -SkSVGPath::SkSVGPath() : INHERITED(SkSVGTag::path) { } +SkSVGPath::SkSVGPath() : INHERITED(SkSVGTag::kPath) { } void SkSVGPath::doRender(SkCanvas* canvas, const SkPaint* paint) const { if (paint) { @@ -26,7 +26,7 @@ void SkSVGPath::onRender(SkCanvas* canvas, const SkSVGRenderContext& ctx) const void SkSVGPath::onSetAttribute(SkSVGAttribute attr, const SkSVGValue& v) { switch (attr) { - case SkSVGAttribute::d: + case SkSVGAttribute::kD: if (const auto* path = v.as<SkSVGPathValue>()) { this->setPath(*path); } diff --git a/experimental/svg/model/SkSVGSVG.cpp b/experimental/svg/model/SkSVGSVG.cpp index feae0d7cc0..aeccc7082b 100644 --- a/experimental/svg/model/SkSVGSVG.cpp +++ b/experimental/svg/model/SkSVGSVG.cpp @@ -7,4 +7,4 @@ #include "SkSVGSVG.h" -SkSVGSVG::SkSVGSVG() : INHERITED(SkSVGTag::svg) { } +SkSVGSVG::SkSVGSVG() : INHERITED(SkSVGTag::kSvg) { } diff --git a/experimental/svg/model/SkSVGTransformableNode.cpp b/experimental/svg/model/SkSVGTransformableNode.cpp index 1af89d8c73..3636754fcc 100644 --- a/experimental/svg/model/SkSVGTransformableNode.cpp +++ b/experimental/svg/model/SkSVGTransformableNode.cpp @@ -14,7 +14,7 @@ SkSVGTransformableNode::SkSVGTransformableNode(SkSVGTag tag) void SkSVGTransformableNode::onSetAttribute(SkSVGAttribute attr, const SkSVGValue& v) { switch (attr) { - case SkSVGAttribute::transform: + case SkSVGAttribute::kTransform: if (const auto* transform = v.as<SkSVGTransformValue>()) { this->setTransform(*transform); } |