aboutsummaryrefslogtreecommitdiffhomepage
path: root/experimental/svg
diff options
context:
space:
mode:
authorGravatar fmalita <fmalita@chromium.org>2016-08-12 12:15:33 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-08-12 12:15:33 -0700
commit5b31f321fcc3bb7f2ed7cf31ff4b03901228594b (patch)
treef3c65b2e0db3a9d36c448296e745d72832fe6034 /experimental/svg
parent3602d4f16a01da860d16eb36fb52eb62487495cc (diff)
[SVGDom] <polygon> & <polyline> support
R=robertphillips@google.com,stephana@google.com GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2235273003 Review-Url: https://codereview.chromium.org/2235273003
Diffstat (limited to 'experimental/svg')
-rw-r--r--experimental/svg/model/SkSVGAttribute.h1
-rw-r--r--experimental/svg/model/SkSVGAttributeParser.cpp38
-rw-r--r--experimental/svg/model/SkSVGAttributeParser.h1
-rw-r--r--experimental/svg/model/SkSVGDOM.cpp24
-rw-r--r--experimental/svg/model/SkSVGNode.h2
-rw-r--r--experimental/svg/model/SkSVGPoly.cpp36
-rw-r--r--experimental/svg/model/SkSVGPoly.h42
-rw-r--r--experimental/svg/model/SkSVGTypes.h4
-rw-r--r--experimental/svg/model/SkSVGValue.h2
9 files changed, 146 insertions, 4 deletions
diff --git a/experimental/svg/model/SkSVGAttribute.h b/experimental/svg/model/SkSVGAttribute.h
index 4ac595d526..d2f0cf2600 100644
--- a/experimental/svg/model/SkSVGAttribute.h
+++ b/experimental/svg/model/SkSVGAttribute.h
@@ -18,6 +18,7 @@ enum class SkSVGAttribute {
kFill,
kFillOpacity,
kHeight,
+ kPoints,
kRx,
kRy,
kStroke,
diff --git a/experimental/svg/model/SkSVGAttributeParser.cpp b/experimental/svg/model/SkSVGAttributeParser.cpp
index 308eb62ba6..f8bfa2033f 100644
--- a/experimental/svg/model/SkSVGAttributeParser.cpp
+++ b/experimental/svg/model/SkSVGAttributeParser.cpp
@@ -427,3 +427,41 @@ bool SkSVGAttributeParser::parseLineJoin(SkSVGLineJoin* join) {
return parsedValue && this->parseEOSToken();
}
+
+// https://www.w3.org/TR/SVG/shapes.html#PolygonElementPointsAttribute
+bool SkSVGAttributeParser::parsePoints(SkSVGPointsType* points) {
+ SkTDArray<SkPoint> pts;
+
+ bool parsedValue = false;
+ for (;;) {
+ this->parseWSToken();
+
+ SkScalar x, y;
+ if (!this->parseScalarToken(&x)) {
+ break;
+ }
+
+ // comma-wsp:
+ // (wsp+ comma? wsp*) | (comma wsp*)
+ bool wsp = this->parseWSToken();
+ bool comma = this->parseExpectedStringToken(",");
+ if (!(wsp || comma)) {
+ break;
+ }
+ this->parseWSToken();
+
+ if (!this->parseScalarToken(&y)) {
+ break;
+ }
+
+ pts.push(SkPoint::Make(x, y));
+ parsedValue = true;
+ }
+
+ if (parsedValue && this->parseEOSToken()) {
+ *points = pts;
+ return true;
+ }
+
+ return false;
+}
diff --git a/experimental/svg/model/SkSVGAttributeParser.h b/experimental/svg/model/SkSVGAttributeParser.h
index 637bf4a260..d1ead39223 100644
--- a/experimental/svg/model/SkSVGAttributeParser.h
+++ b/experimental/svg/model/SkSVGAttributeParser.h
@@ -22,6 +22,7 @@ public:
bool parsePaint(SkSVGPaint*);
bool parseLineCap(SkSVGLineCap*);
bool parseLineJoin(SkSVGLineJoin*);
+ bool parsePoints(SkSVGPointsType*);
private:
// Stack-only
diff --git a/experimental/svg/model/SkSVGDOM.cpp b/experimental/svg/model/SkSVGDOM.cpp
index 6e4bc49a9f..4ae5fedd3e 100644
--- a/experimental/svg/model/SkSVGDOM.cpp
+++ b/experimental/svg/model/SkSVGDOM.cpp
@@ -14,6 +14,7 @@
#include "SkSVGG.h"
#include "SkSVGNode.h"
#include "SkSVGPath.h"
+#include "SkSVGPoly.h"
#include "SkSVGRect.h"
#include "SkSVGRenderContext.h"
#include "SkSVGSVG.h"
@@ -122,6 +123,18 @@ bool SetLineJoinAttribute(const sk_sp<SkSVGNode>& node, SkSVGAttribute attr,
return true;
}
+bool SetPointsAttribute(const sk_sp<SkSVGNode>& node, SkSVGAttribute attr,
+ const char* stringValue) {
+ SkSVGPointsType points;
+ SkSVGAttributeParser parser(stringValue);
+ if (!parser.parsePoints(&points)) {
+ return false;
+ }
+
+ node->setAttribute(attr, SkSVGPointsValue(points));
+ return true;
+}
+
SkString TrimmedString(const char* first, const char* last) {
SkASSERT(first);
SkASSERT(last);
@@ -204,6 +217,7 @@ SortedDictionaryEntry<AttrParseInfo> gAttributeParseInfo[] = {
{ "fill" , { SkSVGAttribute::kFill , SetPaintAttribute }},
{ "fill-opacity" , { SkSVGAttribute::kFillOpacity , SetNumberAttribute }},
{ "height" , { SkSVGAttribute::kHeight , SetLengthAttribute }},
+ { "points" , { SkSVGAttribute::kPoints , SetPointsAttribute }},
{ "rx" , { SkSVGAttribute::kRx , SetLengthAttribute }},
{ "ry" , { SkSVGAttribute::kRy , SetLengthAttribute }},
{ "stroke" , { SkSVGAttribute::kStroke , SetPaintAttribute }},
@@ -220,10 +234,12 @@ SortedDictionaryEntry<AttrParseInfo> gAttributeParseInfo[] = {
};
SortedDictionaryEntry<sk_sp<SkSVGNode>(*)()> gTagFactories[] = {
- { "g" , []() -> sk_sp<SkSVGNode> { return SkSVGG::Make(); }},
- { "path", []() -> sk_sp<SkSVGNode> { return SkSVGPath::Make(); }},
- { "rect", []() -> sk_sp<SkSVGNode> { return SkSVGRect::Make(); }},
- { "svg" , []() -> sk_sp<SkSVGNode> { return SkSVGSVG::Make(); }},
+ { "g" , []() -> sk_sp<SkSVGNode> { return SkSVGG::Make(); }},
+ { "path" , []() -> sk_sp<SkSVGNode> { return SkSVGPath::Make(); }},
+ { "polygon" , []() -> sk_sp<SkSVGNode> { return SkSVGPoly::MakePolygon(); }},
+ { "polyline", []() -> sk_sp<SkSVGNode> { return SkSVGPoly::MakePolyline(); }},
+ { "rect" , []() -> sk_sp<SkSVGNode> { return SkSVGRect::Make(); }},
+ { "svg" , []() -> sk_sp<SkSVGNode> { return SkSVGSVG::Make(); }},
};
struct ConstructionContext {
diff --git a/experimental/svg/model/SkSVGNode.h b/experimental/svg/model/SkSVGNode.h
index 38a17d8633..1e5c3be50f 100644
--- a/experimental/svg/model/SkSVGNode.h
+++ b/experimental/svg/model/SkSVGNode.h
@@ -19,6 +19,8 @@ class SkSVGValue;
enum class SkSVGTag {
kG,
kPath,
+ kPolygon,
+ kPolyline,
kRect,
kSvg
};
diff --git a/experimental/svg/model/SkSVGPoly.cpp b/experimental/svg/model/SkSVGPoly.cpp
new file mode 100644
index 0000000000..bcc716f362
--- /dev/null
+++ b/experimental/svg/model/SkSVGPoly.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkCanvas.h"
+#include "SkSVGRenderContext.h"
+#include "SkSVGPoly.h"
+#include "SkSVGValue.h"
+
+SkSVGPoly::SkSVGPoly(SkSVGTag t) : INHERITED(t) {}
+
+void SkSVGPoly::setPoints(const SkSVGPointsType& pts) {
+ fPath.reset();
+ fPath.addPoly(pts.value().begin(),
+ pts.value().count(),
+ this->tag() == SkSVGTag::kPolygon); // only polygons are auto-closed
+}
+
+void SkSVGPoly::onSetAttribute(SkSVGAttribute attr, const SkSVGValue& v) {
+ switch (attr) {
+ case SkSVGAttribute::kPoints:
+ if (const auto* pts = v.as<SkSVGPointsValue>()) {
+ this->setPoints(*pts);
+ }
+ break;
+ default:
+ this->INHERITED::onSetAttribute(attr, v);
+ }
+}
+
+void SkSVGPoly::onDraw(SkCanvas* canvas, const SkSVGLengthContext&, const SkPaint& paint) const {
+ canvas->drawPath(fPath, paint);
+}
diff --git a/experimental/svg/model/SkSVGPoly.h b/experimental/svg/model/SkSVGPoly.h
new file mode 100644
index 0000000000..3ae8dc6f02
--- /dev/null
+++ b/experimental/svg/model/SkSVGPoly.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkSVGPoly_DEFINED
+#define SkSVGPoly_DEFINED
+
+#include "SkPath.h"
+#include "SkSVGShape.h"
+
+// Handles <polygon> and <polyline> elements.
+class SkSVGPoly final : public SkSVGShape {
+public:
+ virtual ~SkSVGPoly() = default;
+
+ static sk_sp<SkSVGPoly> MakePolygon() {
+ return sk_sp<SkSVGPoly>(new SkSVGPoly(SkSVGTag::kPolygon));
+ }
+
+ static sk_sp<SkSVGPoly> MakePolyline() {
+ return sk_sp<SkSVGPoly>(new SkSVGPoly(SkSVGTag::kPolyline));
+ }
+
+ void setPoints(const SkSVGPointsType&);
+
+protected:
+ void onSetAttribute(SkSVGAttribute, const SkSVGValue&) override;
+
+ void onDraw(SkCanvas*, const SkSVGLengthContext&, const SkPaint&) const override;
+
+private:
+ SkSVGPoly(SkSVGTag);
+
+ SkPath fPath;
+
+ typedef SkSVGShape INHERITED;
+};
+
+#endif // SkSVGPoly_DEFINED
diff --git a/experimental/svg/model/SkSVGTypes.h b/experimental/svg/model/SkSVGTypes.h
index c8330e1088..18ec3ce3cf 100644
--- a/experimental/svg/model/SkSVGTypes.h
+++ b/experimental/svg/model/SkSVGTypes.h
@@ -10,8 +10,10 @@
#include "SkColor.h"
#include "SkMatrix.h"
+#include "SkPoint.h"
#include "SkRect.h"
#include "SkScalar.h"
+#include "SkTDArray.h"
#include "SkTypes.h"
template <typename T>
@@ -22,6 +24,7 @@ public:
SkSVGPrimitiveTypeWrapper(const SkSVGPrimitiveTypeWrapper&) = default;
SkSVGPrimitiveTypeWrapper& operator=(const SkSVGPrimitiveTypeWrapper&) = default;
+ SkSVGPrimitiveTypeWrapper& operator=(const T& v) { fValue = v; return *this; }
bool operator==(const SkSVGPrimitiveTypeWrapper<T>& other) const {
return fValue == other.fValue;
@@ -41,6 +44,7 @@ using SkSVGColorType = SkSVGPrimitiveTypeWrapper<SkColor >;
using SkSVGNumberType = SkSVGPrimitiveTypeWrapper<SkScalar>;
using SkSVGViewBoxType = SkSVGPrimitiveTypeWrapper<SkRect >;
using SkSVGTransformType = SkSVGPrimitiveTypeWrapper<SkMatrix>;
+using SkSVGPointsType = SkSVGPrimitiveTypeWrapper<SkTDArray<SkPoint>>;
class SkSVGLength {
public:
diff --git a/experimental/svg/model/SkSVGValue.h b/experimental/svg/model/SkSVGValue.h
index 583e60291d..8f93bd8046 100644
--- a/experimental/svg/model/SkSVGValue.h
+++ b/experimental/svg/model/SkSVGValue.h
@@ -24,6 +24,7 @@ public:
kNumber,
kPaint,
kPath,
+ kPoints,
kTransform,
kViewBox,
};
@@ -75,5 +76,6 @@ using SkSVGPaintValue = SkSVGWrapperValue<SkSVGPaint , SkSVGValue::Ty
using SkSVGLineCapValue = SkSVGWrapperValue<SkSVGLineCap , SkSVGValue::Type::kLineCap >;
using SkSVGLineJoinValue = SkSVGWrapperValue<SkSVGLineJoin , SkSVGValue::Type::kLineJoin >;
using SkSVGNumberValue = SkSVGWrapperValue<SkSVGNumberType , SkSVGValue::Type::kNumber >;
+using SkSVGPointsValue = SkSVGWrapperValue<SkSVGPointsType , SkSVGValue::Type::kPoints >;
#endif // SkSVGValue_DEFINED