Add TextStream dumping for BasicShape types
https://bugs.webkit.org/show_bug.cgi?id=203150

Reviewed by Zalan Bujtas.

Add dumping for the classes, and make the BasicShape enum an enum class.

* css/BasicShapeFunctions.cpp:
(WebCore::valueForBasicShape):
* rendering/shapes/Shape.cpp:
(WebCore::Shape::createShape):
* rendering/style/BasicShapes.cpp:
(WebCore::BasicShapeCircle::dump const):
(WebCore::BasicShapeEllipse::dump const):
(WebCore::BasicShapePolygon::dump const):
(WebCore::BasicShapePath::dump const):
(WebCore::BasicShapeInset::dump const):
(WebCore::operator<<):
* rendering/style/BasicShapes.h:
(WebCore::BasicShapeCenterCoordinate::BasicShapeCenterCoordinate):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@251292 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 510d3d2..8187fad 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,26 @@
+2019-10-18  Simon Fraser  <simon.fraser@apple.com>
+
+        Add TextStream dumping for BasicShape types
+        https://bugs.webkit.org/show_bug.cgi?id=203150
+
+        Reviewed by Zalan Bujtas.
+
+        Add dumping for the classes, and make the BasicShape enum an enum class.
+
+        * css/BasicShapeFunctions.cpp:
+        (WebCore::valueForBasicShape):
+        * rendering/shapes/Shape.cpp:
+        (WebCore::Shape::createShape):
+        * rendering/style/BasicShapes.cpp:
+        (WebCore::BasicShapeCircle::dump const):
+        (WebCore::BasicShapeEllipse::dump const):
+        (WebCore::BasicShapePolygon::dump const):
+        (WebCore::BasicShapePath::dump const):
+        (WebCore::BasicShapeInset::dump const):
+        (WebCore::operator<<):
+        * rendering/style/BasicShapes.h:
+        (WebCore::BasicShapeCenterCoordinate::BasicShapeCenterCoordinate):
+
 2019-10-18  Antti Koivisto  <antti@apple.com>
 
         ElementRuleCollector function signature cleanups
diff --git a/Source/WebCore/css/BasicShapeFunctions.cpp b/Source/WebCore/css/BasicShapeFunctions.cpp
index 15c8560..c1257ed 100644
--- a/Source/WebCore/css/BasicShapeFunctions.cpp
+++ b/Source/WebCore/css/BasicShapeFunctions.cpp
@@ -71,7 +71,7 @@
 
     RefPtr<CSSBasicShape> basicShapeValue;
     switch (basicShape.type()) {
-    case BasicShape::BasicShapeCircleType: {
+    case BasicShape::Type::Circle: {
         auto& circle = downcast<BasicShapeCircle>(basicShape);
         auto circleValue = CSSBasicShapeCircle::create();
 
@@ -82,7 +82,7 @@
         basicShapeValue = WTFMove(circleValue);
         break;
     }
-    case BasicShape::BasicShapeEllipseType: {
+    case BasicShape::Type::Ellipse: {
         auto& ellipse = downcast<BasicShapeEllipse>(basicShape);
         auto ellipseValue = CSSBasicShapeEllipse::create();
 
@@ -94,7 +94,7 @@
         basicShapeValue = WTFMove(ellipseValue);
         break;
     }
-    case BasicShape::BasicShapePolygonType: {
+    case BasicShape::Type::Polygon: {
         auto& polygon = downcast<BasicShapePolygon>(basicShape);
         auto polygonValue = CSSBasicShapePolygon::create();
 
@@ -106,7 +106,7 @@
         basicShapeValue = WTFMove(polygonValue);
         break;
     }
-    case BasicShape::BasicShapePathType: {
+    case BasicShape::Type::Path: {
         auto& pathShape = downcast<BasicShapePath>(basicShape);
         auto pathShapeValue = CSSBasicShapePath::create(pathShape.pathData()->copy());
         pathShapeValue->setWindRule(pathShape.windRule());
@@ -114,7 +114,7 @@
         basicShapeValue = WTFMove(pathShapeValue);
         break;
     }
-    case BasicShape::BasicShapeInsetType: {
+    case BasicShape::Type::Inset: {
         auto& inset = downcast<BasicShapeInset>(basicShape);
         auto insetValue = CSSBasicShapeInset::create();
 
diff --git a/Source/WebCore/rendering/shapes/Shape.cpp b/Source/WebCore/rendering/shapes/Shape.cpp
index f5efefd..16aa905 100644
--- a/Source/WebCore/rendering/shapes/Shape.cpp
+++ b/Source/WebCore/rendering/shapes/Shape.cpp
@@ -100,7 +100,7 @@
 
     switch (basicShape.type()) {
 
-    case BasicShape::BasicShapeCircleType: {
+    case BasicShape::Type::Circle: {
         const auto& circle = downcast<BasicShapeCircle>(basicShape);
         float centerX = floatValueForCenterCoordinate(circle.centerX(), boxWidth);
         float centerY = floatValueForCenterCoordinate(circle.centerY(), boxHeight);
@@ -111,7 +111,7 @@
         break;
     }
 
-    case BasicShape::BasicShapeEllipseType: {
+    case BasicShape::Type::Ellipse: {
         const auto& ellipse = downcast<BasicShapeEllipse>(basicShape);
         float centerX = floatValueForCenterCoordinate(ellipse.centerX(), boxWidth);
         float centerY = floatValueForCenterCoordinate(ellipse.centerY(), boxHeight);
@@ -123,7 +123,7 @@
         break;
     }
 
-    case BasicShape::BasicShapePolygonType: {
+    case BasicShape::Type::Polygon: {
         const auto& polygon = downcast<BasicShapePolygon>(basicShape);
         const Vector<Length>& values = polygon.values();
         size_t valuesSize = values.size();
@@ -140,7 +140,7 @@
         break;
     }
 
-    case BasicShape::BasicShapeInsetType: {
+    case BasicShape::Type::Inset: {
         const auto& inset = downcast<BasicShapeInset>(basicShape);
         float left = floatValueForLength(inset.left(), boxWidth);
         float top = floatValueForLength(inset.top(), boxHeight);
diff --git a/Source/WebCore/rendering/style/BasicShapes.cpp b/Source/WebCore/rendering/style/BasicShapes.cpp
index 744c90b..ca681af 100644
--- a/Source/WebCore/rendering/style/BasicShapes.cpp
+++ b/Source/WebCore/rendering/style/BasicShapes.cpp
@@ -43,6 +43,7 @@
 
 #include <wtf/NeverDestroyed.h>
 #include <wtf/TinyLRUCache.h>
+#include <wtf/text/TextStream.h>
 
 namespace WebCore {
 
@@ -201,6 +202,13 @@
     return result;
 }
 
+void BasicShapeCircle::dump(TextStream& ts) const
+{
+    ts.dumpProperty("center-x", centerX());
+    ts.dumpProperty("center-y", centerY());
+    ts.dumpProperty("radius", radius());
+}
+
 bool BasicShapeEllipse::operator==(const BasicShape& other) const
 {
     if (type() != other.type())
@@ -267,6 +275,14 @@
     return result;
 }
 
+void BasicShapeEllipse::dump(TextStream& ts) const
+{
+    ts.dumpProperty("center-x", centerX());
+    ts.dumpProperty("center-y", centerY());
+    ts.dumpProperty("radius-x", radiusX());
+    ts.dumpProperty("radius-y", radiusY());
+}
+
 bool BasicShapePolygon::operator==(const BasicShape& other) const
 {
     if (type() != other.type())
@@ -324,6 +340,12 @@
     return result;
 }
 
+void BasicShapePolygon::dump(TextStream& ts) const
+{
+    ts.dumpProperty("wind-rule", windRule());
+    ts.dumpProperty("path", values());
+}
+
 BasicShapePath::BasicShapePath(std::unique_ptr<SVGPathByteStream>&& byteStream)
     : m_byteStream(WTFMove(byteStream))
 {
@@ -366,6 +388,12 @@
     return result;
 }
 
+void BasicShapePath::dump(TextStream& ts) const
+{
+    ts.dumpProperty("wind-rule", windRule());
+    // FIXME: print the byte stream?
+}
+
 bool BasicShapeInset::operator==(const BasicShape& other) const
 {
     if (type() != other.type())
@@ -427,4 +455,49 @@
 
     return result;
 }
+
+void BasicShapeInset::dump(TextStream& ts) const
+{
+    ts.dumpProperty("top", top());
+    ts.dumpProperty("right", right());
+    ts.dumpProperty("bottom", bottom());
+    ts.dumpProperty("left", left());
+
+    ts.dumpProperty("top-left-radius", topLeftRadius());
+    ts.dumpProperty("top-right-radius", topRightRadius());
+    ts.dumpProperty("bottom-right-radius", bottomRightRadius());
+    ts.dumpProperty("bottom-left-radius", bottomLeftRadius());
 }
+
+static TextStream& operator<<(TextStream& ts, BasicShapeRadius::Type radiusType)
+{
+    switch (radiusType) {
+    case BasicShapeRadius::Value: ts << "value"; break;
+    case BasicShapeRadius::ClosestSide: ts << "closest-side"; break;
+    case BasicShapeRadius::FarthestSide: ts << "farthest-side"; break;
+    }
+    return ts;
+}
+
+TextStream& operator<<(TextStream& ts, const BasicShapeRadius& radius)
+{
+    ts.dumpProperty("value", radius.value());
+    ts.dumpProperty("type", radius.type());
+    return ts;
+}
+
+TextStream& operator<<(TextStream& ts, const BasicShapeCenterCoordinate& coordinate)
+{
+    ts.dumpProperty("direction", coordinate.direction() == BasicShapeCenterCoordinate::TopLeft ? "top left" : "bottom right");
+    ts.dumpProperty("length", coordinate.length());
+    return ts;
+}
+
+TextStream& operator<<(TextStream& ts, const BasicShape& shape)
+{
+    shape.dump(ts);
+    return ts;
+}
+
+} // namespace WebCore
+
diff --git a/Source/WebCore/rendering/style/BasicShapes.h b/Source/WebCore/rendering/style/BasicShapes.h
index d08fdf4..b9dc4e7 100644
--- a/Source/WebCore/rendering/style/BasicShapes.h
+++ b/Source/WebCore/rendering/style/BasicShapes.h
@@ -37,6 +37,10 @@
 #include <wtf/TypeCasts.h>
 #include <wtf/Vector.h>
 
+namespace WTF {
+class TextStream;
+}
+
 namespace WebCore {
 
 class FloatRect;
@@ -48,12 +52,12 @@
 public:
     virtual ~BasicShape() = default;
 
-    enum Type {
-        BasicShapePolygonType,
-        BasicShapePathType,
-        BasicShapeCircleType,
-        BasicShapeEllipseType,
-        BasicShapeInsetType
+    enum class Type {
+        Polygon,
+        Path,
+        Circle,
+        Ellipse,
+        Inset
     };
 
     virtual Type type() const = 0;
@@ -65,6 +69,8 @@
     virtual Ref<BasicShape> blend(const BasicShape& from, double) const = 0;
 
     virtual bool operator==(const BasicShape&) const = 0;
+    
+    virtual void dump(TextStream&) const = 0;
 };
 
 class BasicShapeCenterCoordinate {
@@ -75,8 +81,6 @@
     };
 
     BasicShapeCenterCoordinate()
-        : m_direction(TopLeft)
-        , m_length(Undefined)
     {
         updateComputedLength();
     }
@@ -107,8 +111,8 @@
 private:
     void updateComputedLength();
 
-    Direction m_direction;
-    Length m_length;
+    Direction m_direction { TopLeft };
+    Length m_length { Undefined };
     Length m_computedLength;
 };
 
@@ -119,10 +123,8 @@
         ClosestSide,
         FarthestSide
     };
-    BasicShapeRadius()
-        : m_value(Undefined),
-        m_type(ClosestSide)
-    { }
+
+    BasicShapeRadius() = default;
 
     explicit BasicShapeRadius(Length v)
         : m_value(v)
@@ -156,9 +158,8 @@
     }
 
 private:
-    Length m_value;
-    Type m_type;
-
+    Length m_value { Undefined };
+    Type m_type { ClosestSide };
 };
 
 class BasicShapeCircle final : public BasicShape {
@@ -177,7 +178,7 @@
 private:
     BasicShapeCircle() = default;
 
-    Type type() const override { return BasicShapeCircleType; }
+    Type type() const override { return Type::Circle; }
 
     const Path& path(const FloatRect&) override;
 
@@ -186,6 +187,8 @@
 
     bool operator==(const BasicShape&) const override;
 
+    void dump(TextStream&) const final;
+
     BasicShapeCenterCoordinate m_centerX;
     BasicShapeCenterCoordinate m_centerY;
     BasicShapeRadius m_radius;
@@ -209,7 +212,7 @@
 private:
     BasicShapeEllipse() = default;
 
-    Type type() const override { return BasicShapeEllipseType; }
+    Type type() const override { return Type::Ellipse; }
 
     const Path& path(const FloatRect&) override;
 
@@ -218,6 +221,8 @@
 
     bool operator==(const BasicShape&) const override;
 
+    void dump(TextStream&) const final;
+
     BasicShapeCenterCoordinate m_centerX;
     BasicShapeCenterCoordinate m_centerY;
     BasicShapeRadius m_radiusX;
@@ -240,7 +245,7 @@
 private:
     BasicShapePolygon() = default;
 
-    Type type() const override { return BasicShapePolygonType; }
+    Type type() const override { return Type::Polygon; }
 
     const Path& path(const FloatRect&) override;
 
@@ -249,6 +254,8 @@
 
     bool operator==(const BasicShape&) const override;
 
+    void dump(TextStream&) const final;
+
     WindRule m_windRule { WindRule::NonZero };
     Vector<Length> m_values;
 };
@@ -268,7 +275,7 @@
 private:
     BasicShapePath(std::unique_ptr<SVGPathByteStream>&&);
 
-    Type type() const override { return BasicShapePathType; }
+    Type type() const override { return Type::Path; }
 
     const Path& path(const FloatRect&) override;
 
@@ -277,6 +284,8 @@
 
     bool operator==(const BasicShape&) const override;
 
+    void dump(TextStream&) const final;
+
     std::unique_ptr<SVGPathByteStream> m_byteStream;
     WindRule m_windRule { WindRule::NonZero };
 };
@@ -308,7 +317,7 @@
 private:
     BasicShapeInset() = default;
 
-    Type type() const override { return BasicShapeInsetType; }
+    Type type() const override { return Type::Inset; }
 
     const Path& path(const FloatRect&) override;
 
@@ -317,6 +326,8 @@
 
     bool operator==(const BasicShape&) const override;
 
+    void dump(TextStream&) const final;
+
     Length m_right;
     Length m_top;
     Length m_bottom;
@@ -328,6 +339,10 @@
     LengthSize m_bottomLeftRadius;
 };
 
+WTF::TextStream& operator<<(WTF::TextStream&, const BasicShapeRadius&);
+WTF::TextStream& operator<<(WTF::TextStream&, const BasicShapeCenterCoordinate&);
+WTF::TextStream& operator<<(WTF::TextStream&, const BasicShape&);
+
 } // namespace WebCore
 
 #define SPECIALIZE_TYPE_TRAITS_BASIC_SHAPE(ToValueTypeName, predicate) \
@@ -335,8 +350,8 @@
     static bool isType(const WebCore::BasicShape& basicShape) { return basicShape.type() == WebCore::predicate; } \
 SPECIALIZE_TYPE_TRAITS_END()
 
-SPECIALIZE_TYPE_TRAITS_BASIC_SHAPE(BasicShapeCircle, BasicShape::BasicShapeCircleType)
-SPECIALIZE_TYPE_TRAITS_BASIC_SHAPE(BasicShapeEllipse, BasicShape::BasicShapeEllipseType)
-SPECIALIZE_TYPE_TRAITS_BASIC_SHAPE(BasicShapePolygon, BasicShape::BasicShapePolygonType)
-SPECIALIZE_TYPE_TRAITS_BASIC_SHAPE(BasicShapePath, BasicShape::BasicShapePathType)
-SPECIALIZE_TYPE_TRAITS_BASIC_SHAPE(BasicShapeInset, BasicShape::BasicShapeInsetType)
+SPECIALIZE_TYPE_TRAITS_BASIC_SHAPE(BasicShapeCircle, BasicShape::Type::Circle)
+SPECIALIZE_TYPE_TRAITS_BASIC_SHAPE(BasicShapeEllipse, BasicShape::Type::Ellipse)
+SPECIALIZE_TYPE_TRAITS_BASIC_SHAPE(BasicShapePolygon, BasicShape::Type::Polygon)
+SPECIALIZE_TYPE_TRAITS_BASIC_SHAPE(BasicShapePath, BasicShape::Type::Path)
+SPECIALIZE_TYPE_TRAITS_BASIC_SHAPE(BasicShapeInset, BasicShape::Type::Inset)