diff --git a/experimental/skotty/Skotty.cpp b/experimental/skotty/Skotty.cpp index 093d7f68e4..e84abcd4a8 100644 --- a/experimental/skotty/Skotty.cpp +++ b/experimental/skotty/Skotty.cpp @@ -194,6 +194,41 @@ sk_sp AttachEllipseGeometry(const Json::Value& jellipse, Att return rect_node; } +sk_sp AttachPolystarGeometry(const Json::Value& jstar, AttachContext* ctx) { + SkASSERT(jstar.isObject()); + + static constexpr CompositePolyStar::Type gTypes[] = { + CompositePolyStar::Type::kStar, // "sy": 1 + CompositePolyStar::Type::kPoly, // "sy": 2 + }; + + const auto type = ParseInt(jstar["sy"], 0) - 1; + if (type < 0 || type >= SkTo(SK_ARRAY_COUNT(gTypes))) { + LogFail(jstar, "Unknown polystar type"); + return nullptr; + } + + auto path_node = sksg::Path::Make(); + auto composite = sk_make_sp(path_node, gTypes[type]); + + AttachProperty(jstar["p"], ctx, composite, + [](const sk_sp& node, const SkPoint& p) { node->setPosition(p); }); + AttachProperty(jstar["pt"], ctx, composite, + [](const sk_sp& node, SkScalar pt) { node->setPointCount(pt); }); + AttachProperty(jstar["ir"], ctx, composite, + [](const sk_sp& node, SkScalar ir) { node->setInnerRadius(ir); }); + AttachProperty(jstar["or"], ctx, composite, + [](const sk_sp& node, SkScalar otr) { node->setOuterRadius(otr); }); + AttachProperty(jstar["is"], ctx, composite, + [](const sk_sp& node, SkScalar is) { node->setInnerRoundness(is); }); + AttachProperty(jstar["os"], ctx, composite, + [](const sk_sp& node, SkScalar os) { node->setOuterRoundness(os); }); + AttachProperty(jstar["r"], ctx, composite, + [](const sk_sp& node, SkScalar r) { node->setRotation(r); }); + + return path_node; +} + sk_sp AttachColorPaint(const Json::Value& obj, AttachContext* ctx) { SkASSERT(obj.isObject()); @@ -278,6 +313,7 @@ static constexpr GeometryAttacherT gGeometryAttachers[] = { AttachPathGeometry, AttachRRectGeometry, AttachEllipseGeometry, + AttachPolystarGeometry, }; using PaintAttacherT = sk_sp (*)(const Json::Value&, AttachContext*); @@ -325,8 +361,9 @@ const ShapeInfo* FindShapeInfo(const Json::Value& shape) { { "fl", ShapeType::kPaint , 0 }, // fill -> AttachFillPaint { "gr", ShapeType::kGroup , 0 }, // group -> AttachShapeGroup { "mm", ShapeType::kGeometryEffect, 0 }, // merge -> AttachMergeGeometryEffect - { "rc", ShapeType::kGeometry , 1 }, // shape -> AttachRRectGeometry + { "rc", ShapeType::kGeometry , 1 }, // rrect -> AttachRRectGeometry { "sh", ShapeType::kGeometry , 0 }, // shape -> AttachPathGeometry + { "sr", ShapeType::kGeometry , 3 }, // polystar -> AttachPolyStarGeometry { "st", ShapeType::kPaint , 1 }, // stroke -> AttachStrokePaint { "tr", ShapeType::kTransform , 0 }, // transform -> AttachTransform }; diff --git a/experimental/skotty/SkottyProperties.cpp b/experimental/skotty/SkottyProperties.cpp index 241b659c9d..3029409f6c 100644 --- a/experimental/skotty/SkottyProperties.cpp +++ b/experimental/skotty/SkottyProperties.cpp @@ -10,9 +10,12 @@ #include "SkColor.h" #include "SkottyPriv.h" #include "SkPath.h" +#include "SkSGPath.h" #include "SkSGRect.h" #include "SkSGTransform.h" +#include + namespace skotty { namespace { @@ -185,4 +188,36 @@ void CompositeTransform::apply() { fTransformNode->setMatrix(t); } +CompositePolyStar::CompositePolyStar(sk_sp wrapped_node, Type t) + : fPathNode(std::move(wrapped_node)) + , fType(t) {} + +void CompositePolyStar::apply() { + const auto count = SkScalarTruncToInt(fPointCount); + const auto arc = SK_ScalarPI * 2 / count; + + const auto pt_on_circle = [](const SkPoint& c, SkScalar r, SkScalar a) { + return SkPoint::Make(c.x() + r * std::cos(a), + c.y() + r * std::sin(a)); + }; + + // TODO: inner/outer "roundness"? + + SkPath poly; + + auto angle = SkDegreesToRadians(fRotation); + poly.moveTo(pt_on_circle(fPosition, fOuterRadius, angle)); + + for (int i = 0; i < count; ++i) { + if (fType == Type::kStar) { + poly.lineTo(pt_on_circle(fPosition, fInnerRadius, angle + arc * 0.5f)); + } + angle += arc; + poly.lineTo(pt_on_circle(fPosition, fOuterRadius, angle)); + } + + poly.close(); + fPathNode->setPath(poly); +} + } // namespace skotty diff --git a/experimental/skotty/SkottyProperties.h b/experimental/skotty/SkottyProperties.h index 6147dd4d63..8730f61352 100644 --- a/experimental/skotty/SkottyProperties.h +++ b/experimental/skotty/SkottyProperties.h @@ -21,6 +21,7 @@ class SkPath; namespace sksg { +class Path; class RRect; class RenderNode; class Transform; @@ -111,6 +112,31 @@ private: using INHERITED = SkRefCnt; }; +class CompositePolyStar final : public SkRefCnt { +public: + enum class Type { + kStar, kPoly, + }; + + CompositePolyStar(sk_sp, Type); + + COMPOSITE_PROPERTY(Position , SkPoint , SkPoint::Make(0, 0)) + COMPOSITE_PROPERTY(PointCount , SkScalar, 0) + COMPOSITE_PROPERTY(InnerRadius , SkScalar, 0) + COMPOSITE_PROPERTY(OuterRadius , SkScalar, 0) + COMPOSITE_PROPERTY(InnerRoundness, SkScalar, 0) + COMPOSITE_PROPERTY(OuterRoundness, SkScalar, 0) + COMPOSITE_PROPERTY(Rotation , SkScalar, 0) + +private: + void apply(); + + sk_sp fPathNode; + Type fType; + + using INHERITED = SkRefCnt; +}; + class CompositeTransform final : public SkRefCnt { public: explicit CompositeTransform(sk_sp);