diff options
author | fmalita <fmalita@chromium.org> | 2016-08-12 12:15:33 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-08-12 12:15:33 -0700 |
commit | 5b31f321fcc3bb7f2ed7cf31ff4b03901228594b (patch) | |
tree | f3c65b2e0db3a9d36c448296e745d72832fe6034 /experimental/svg | |
parent | 3602d4f16a01da860d16eb36fb52eb62487495cc (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.h | 1 | ||||
-rw-r--r-- | experimental/svg/model/SkSVGAttributeParser.cpp | 38 | ||||
-rw-r--r-- | experimental/svg/model/SkSVGAttributeParser.h | 1 | ||||
-rw-r--r-- | experimental/svg/model/SkSVGDOM.cpp | 24 | ||||
-rw-r--r-- | experimental/svg/model/SkSVGNode.h | 2 | ||||
-rw-r--r-- | experimental/svg/model/SkSVGPoly.cpp | 36 | ||||
-rw-r--r-- | experimental/svg/model/SkSVGPoly.h | 42 | ||||
-rw-r--r-- | experimental/svg/model/SkSVGTypes.h | 4 | ||||
-rw-r--r-- | experimental/svg/model/SkSVGValue.h | 2 |
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 |