aboutsummaryrefslogtreecommitdiffhomepage
path: root/experimental/svg
diff options
context:
space:
mode:
authorGravatar fmalita <fmalita@chromium.org>2016-07-29 08:52:03 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-07-29 08:52:03 -0700
commit58649ccc75c033ea4e0c9a664b4ed178816a50c6 (patch)
tree91117fb8be83c0ee4d07d79e5a150fa11b45e333 /experimental/svg
parent5abbb44f682038abe01b8ee63fb22439af861dda (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.h10
-rw-r--r--experimental/svg/model/SkSVGDOM.cpp94
-rw-r--r--experimental/svg/model/SkSVGG.h2
-rw-r--r--experimental/svg/model/SkSVGNode.cpp4
-rw-r--r--experimental/svg/model/SkSVGNode.h6
-rw-r--r--experimental/svg/model/SkSVGPath.cpp4
-rw-r--r--experimental/svg/model/SkSVGSVG.cpp2
-rw-r--r--experimental/svg/model/SkSVGTransformableNode.cpp2
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);
}