From a6e30f75fcd70636b835c8fb24005b84a1dd0d25 Mon Sep 17 00:00:00 2001 From: Florin Malita Date: Fri, 23 Mar 2018 13:41:58 -0400 Subject: [skottie] Clean up SkottieProperties Split into Adapter and Value CUs. No real changes, just shuffling things around. TBR= Change-Id: I50eaeb3950f4c59e7d7027955b3f49ca2a346e59 Reviewed-on: https://skia-review.googlesource.com/116186 Reviewed-by: Florin Malita Commit-Queue: Florin Malita --- experimental/skottie/Skottie.cpp | 123 ++++++++-------- experimental/skottie/SkottieAdapter.cpp | 164 +++++++++++++++++++++ experimental/skottie/SkottieAdapter.h | 164 +++++++++++++++++++++ experimental/skottie/SkottieAnimator.cpp | 2 +- experimental/skottie/SkottieProperties.cpp | 227 ----------------------------- experimental/skottie/SkottieProperties.h | 185 ----------------------- experimental/skottie/SkottieValue.cpp | 74 ++++++++++ experimental/skottie/SkottieValue.h | 32 ++++ 8 files changed, 497 insertions(+), 474 deletions(-) create mode 100644 experimental/skottie/SkottieAdapter.cpp create mode 100644 experimental/skottie/SkottieAdapter.h delete mode 100644 experimental/skottie/SkottieProperties.cpp delete mode 100644 experimental/skottie/SkottieProperties.h create mode 100644 experimental/skottie/SkottieValue.cpp create mode 100644 experimental/skottie/SkottieValue.h (limited to 'experimental') diff --git a/experimental/skottie/Skottie.cpp b/experimental/skottie/Skottie.cpp index 5a04e5a719..9c5849ffa6 100644 --- a/experimental/skottie/Skottie.cpp +++ b/experimental/skottie/Skottie.cpp @@ -9,9 +9,10 @@ #include "SkCanvas.h" #include "SkJSONCPP.h" +#include "SkottieAdapter.h" #include "SkottieAnimator.h" #include "SkottieParser.h" -#include "SkottieProperties.h" +#include "SkottieValue.h" #include "SkData.h" #include "SkImage.h" #include "SkMakeUnique.h" @@ -71,18 +72,18 @@ sk_sp AttachMatrix(const Json::Value& t, AttachContext* ctx, return nullptr; auto matrix = sksg::Matrix::Make(SkMatrix::I(), std::move(parentMatrix)); - auto composite = sk_make_sp(matrix); + auto adapter = sk_make_sp(matrix); auto anchor_attached = BindProperty(t["a"], &ctx->fAnimators, - [composite](const VectorValue& a) { - composite->setAnchorPoint(ValueTraits::As(a)); + [adapter](const VectorValue& a) { + adapter->setAnchorPoint(ValueTraits::As(a)); }); auto position_attached = BindProperty(t["p"], &ctx->fAnimators, - [composite](const VectorValue& p) { - composite->setPosition(ValueTraits::As(p)); + [adapter](const VectorValue& p) { + adapter->setPosition(ValueTraits::As(p)); }); auto scale_attached = BindProperty(t["s"], &ctx->fAnimators, - [composite](const VectorValue& s) { - composite->setScale(ValueTraits::As(s)); + [adapter](const VectorValue& s) { + adapter->setScale(ValueTraits::As(s)); }); auto* jrotation = &t["r"]; @@ -92,16 +93,16 @@ sk_sp AttachMatrix(const Json::Value& t, AttachContext* ctx, jrotation = &t["rz"]; } auto rotation_attached = BindProperty(*jrotation, &ctx->fAnimators, - [composite](const ScalarValue& r) { - composite->setRotation(r); + [adapter](const ScalarValue& r) { + adapter->setRotation(r); }); auto skew_attached = BindProperty(t["sk"], &ctx->fAnimators, - [composite](const ScalarValue& sk) { - composite->setSkew(sk); + [adapter](const ScalarValue& sk) { + adapter->setSkew(sk); }); auto skewaxis_attached = BindProperty(t["sa"], &ctx->fAnimators, - [composite](const ScalarValue& sa) { - composite->setSkewAxis(sa); + [adapter](const ScalarValue& sa) { + adapter->setSkewAxis(sa); }); if (!anchor_attached && @@ -162,19 +163,19 @@ sk_sp AttachRRectGeometry(const Json::Value& jrect, AttachCo SkASSERT(jrect.isObject()); auto rect_node = sksg::RRect::Make(); - auto composite = sk_make_sp(rect_node); + auto adapter = sk_make_sp(rect_node); auto p_attached = BindProperty(jrect["p"], &ctx->fAnimators, - [composite](const VectorValue& p) { - composite->setPosition(ValueTraits::As(p)); + [adapter](const VectorValue& p) { + adapter->setPosition(ValueTraits::As(p)); }); auto s_attached = BindProperty(jrect["s"], &ctx->fAnimators, - [composite](const VectorValue& s) { - composite->setSize(ValueTraits::As(s)); + [adapter](const VectorValue& s) { + adapter->setSize(ValueTraits::As(s)); }); auto r_attached = BindProperty(jrect["r"], &ctx->fAnimators, - [composite](const ScalarValue& r) { - composite->setRadius(SkSize::Make(r, r)); + [adapter](const ScalarValue& r) { + adapter->setRadius(SkSize::Make(r, r)); }); if (!p_attached && !s_attached && !r_attached) { @@ -188,17 +189,17 @@ sk_sp AttachEllipseGeometry(const Json::Value& jellipse, Att SkASSERT(jellipse.isObject()); auto rect_node = sksg::RRect::Make(); - auto composite = sk_make_sp(rect_node); + auto adapter = sk_make_sp(rect_node); auto p_attached = BindProperty(jellipse["p"], &ctx->fAnimators, - [composite](const VectorValue& p) { - composite->setPosition(ValueTraits::As(p)); + [adapter](const VectorValue& p) { + adapter->setPosition(ValueTraits::As(p)); }); auto s_attached = BindProperty(jellipse["s"], &ctx->fAnimators, - [composite](const VectorValue& s) { + [adapter](const VectorValue& s) { const auto sz = ValueTraits::As(s); - composite->setSize(sz); - composite->setRadius(SkSize::Make(sz.width() / 2, sz.height() / 2)); + adapter->setSize(sz); + adapter->setRadius(SkSize::Make(sz.width() / 2, sz.height() / 2)); }); if (!p_attached && !s_attached) { @@ -211,9 +212,9 @@ sk_sp AttachEllipseGeometry(const Json::Value& jellipse, Att 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 + static constexpr PolyStarAdapter::Type gTypes[] = { + PolyStarAdapter::Type::kStar, // "sy": 1 + PolyStarAdapter::Type::kPoly, // "sy": 2 }; const auto type = ParseDefault(jstar["sy"], 0) - 1; @@ -223,35 +224,35 @@ sk_sp AttachPolystarGeometry(const Json::Value& jstar, Attac } auto path_node = sksg::Path::Make(); - auto composite = sk_make_sp(path_node, gTypes[type]); + auto adapter = sk_make_sp(path_node, gTypes[type]); BindProperty(jstar["p"], &ctx->fAnimators, - [composite](const VectorValue& p) { - composite->setPosition(ValueTraits::As(p)); + [adapter](const VectorValue& p) { + adapter->setPosition(ValueTraits::As(p)); }); BindProperty(jstar["pt"], &ctx->fAnimators, - [composite](const ScalarValue& pt) { - composite->setPointCount(pt); + [adapter](const ScalarValue& pt) { + adapter->setPointCount(pt); }); BindProperty(jstar["ir"], &ctx->fAnimators, - [composite](const ScalarValue& ir) { - composite->setInnerRadius(ir); + [adapter](const ScalarValue& ir) { + adapter->setInnerRadius(ir); }); BindProperty(jstar["or"], &ctx->fAnimators, - [composite](const ScalarValue& otr) { - composite->setOuterRadius(otr); + [adapter](const ScalarValue& otr) { + adapter->setOuterRadius(otr); }); BindProperty(jstar["is"], &ctx->fAnimators, - [composite](const ScalarValue& is) { - composite->setInnerRoundness(is); + [adapter](const ScalarValue& is) { + adapter->setInnerRoundness(is); }); BindProperty(jstar["os"], &ctx->fAnimators, - [composite](const ScalarValue& os) { - composite->setOuterRoundness(os); + [adapter](const ScalarValue& os) { + adapter->setOuterRoundness(os); }); BindProperty(jstar["r"], &ctx->fAnimators, - [composite](const ScalarValue& r) { - composite->setRotation(r); + [adapter](const ScalarValue& r) { + adapter->setRotation(r); }); return path_node; @@ -281,31 +282,31 @@ sk_sp AttachGradient(const Json::Value& obj, AttachContext* ctx) return nullptr; sk_sp gradient_node; - sk_sp composite; + sk_sp adapter; if (ParseDefault(obj["t"], 1) == 1) { auto linear_node = sksg::LinearGradient::Make(); - composite = sk_make_sp(linear_node, stopCount); + adapter = sk_make_sp(linear_node, stopCount); gradient_node = std::move(linear_node); } else { auto radial_node = sksg::RadialGradient::Make(); - composite = sk_make_sp(radial_node, stopCount); + adapter = sk_make_sp(radial_node, stopCount); // TODO: highlight, angle gradient_node = std::move(radial_node); } BindProperty(stops["k"], &ctx->fAnimators, - [composite](const VectorValue& stops) { - composite->setColorStops(stops); + [adapter](const VectorValue& stops) { + adapter->setColorStops(stops); }); BindProperty(obj["s"], &ctx->fAnimators, - [composite](const VectorValue& s) { - composite->setStartPoint(ValueTraits::As(s)); + [adapter](const VectorValue& s) { + adapter->setStartPoint(ValueTraits::As(s)); }); BindProperty(obj["e"], &ctx->fAnimators, - [composite](const VectorValue& e) { - composite->setEndPoint(ValueTraits::As(e)); + [adapter](const VectorValue& e) { + adapter->setEndPoint(ValueTraits::As(e)); }); return gradient_node; @@ -430,18 +431,18 @@ std::vector> AttachTrimGeometryEffect( const auto trimEffect = sksg::TrimEffect::Make(i); trimmed.push_back(trimEffect); - const auto trimComposite = sk_make_sp(std::move(trimEffect)); + const auto adapter = sk_make_sp(std::move(trimEffect)); BindProperty(jtrim["s"], &ctx->fAnimators, - [trimComposite](const ScalarValue& s) { - trimComposite->setStart(s); + [adapter](const ScalarValue& s) { + adapter->setStart(s); }); BindProperty(jtrim["e"], &ctx->fAnimators, - [trimComposite](const ScalarValue& e) { - trimComposite->setEnd(e); + [adapter](const ScalarValue& e) { + adapter->setEnd(e); }); BindProperty(jtrim["o"], &ctx->fAnimators, - [trimComposite](const ScalarValue& o) { - trimComposite->setOffset(o); + [adapter](const ScalarValue& o) { + adapter->setOffset(o); }); } diff --git a/experimental/skottie/SkottieAdapter.cpp b/experimental/skottie/SkottieAdapter.cpp new file mode 100644 index 0000000000..5186e2c2f8 --- /dev/null +++ b/experimental/skottie/SkottieAdapter.cpp @@ -0,0 +1,164 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkottieAdapter.h" + +#include "SkMatrix.h" +#include "SkottieValue.h" +#include "SkPath.h" +#include "SkRRect.h" +#include "SkSGGradient.h" +#include "SkSGPath.h" +#include "SkSGRect.h" +#include "SkSGTransform.h" +#include "SkSGTrimEffect.h" + +#include + +namespace skottie { + +RRectAdapter::RRectAdapter(sk_sp wrapped_node) + : fRRectNode(std::move(wrapped_node)) {} + +void RRectAdapter::apply() { + // BM "position" == "center position" + auto rr = SkRRect::MakeRectXY(SkRect::MakeXYWH(fPosition.x() - fSize.width() / 2, + fPosition.y() - fSize.height() / 2, + fSize.width(), fSize.height()), + fRadius.width(), + fRadius.height()); + fRRectNode->setRRect(rr); +} + +TransformAdapter::TransformAdapter(sk_sp matrix) + : fMatrixNode(std::move(matrix)) {} + +void TransformAdapter::apply() { + SkMatrix t = SkMatrix::MakeTrans(-fAnchorPoint.x(), -fAnchorPoint.y()); + + t.postScale(fScale.x() / 100, fScale.y() / 100); // 100% based + t.postRotate(fRotation); + t.postTranslate(fPosition.x(), fPosition.y()); + // TODO: skew + + fMatrixNode->setMatrix(t); +} + +PolyStarAdapter::PolyStarAdapter(sk_sp wrapped_node, Type t) + : fPathNode(std::move(wrapped_node)) + , fType(t) {} + +void PolyStarAdapter::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); +} + +GradientAdapter::GradientAdapter(sk_sp grad, size_t stopCount) + : fGradient(std::move(grad)) + , fStopCount(stopCount) {} + +void GradientAdapter::apply() { + this->onApply(); + + // |fColorStops| holds |fStopCount| x [ pos, r, g, g ] + ? x [ pos, alpha ] + + if (fColorStops.size() < fStopCount * 4 || ((fColorStops.size() - fStopCount * 4) % 2)) { + SkDebugf("!! Invalid gradient stop array size: %zu", fColorStops.size()); + return; + } + + std::vector stops; + + // TODO: merge/lerp opacity stops + const auto csEnd = fColorStops.cbegin() + fStopCount * 4; + for (auto cs = fColorStops.cbegin(); cs != csEnd; cs += 4) { + const auto pos = cs[0]; + const VectorValue rgb({ cs[1], cs[2], cs[3] }); + + stops.push_back({ pos, ValueTraits::As(rgb) }); + } + + fGradient->setColorStops(std::move(stops)); +} + +LinearGradientAdapter::LinearGradientAdapter(sk_sp grad, size_t stopCount) + : INHERITED(std::move(grad), stopCount) {} + +void LinearGradientAdapter::onApply() { + auto* grad = static_cast(fGradient.get()); + grad->setStartPoint(this->startPoint()); + grad->setEndPoint(this->endPoint()); +} + +RadialGradientAdapter::RadialGradientAdapter(sk_sp grad, size_t stopCount) + : INHERITED(std::move(grad), stopCount) {} + +void RadialGradientAdapter::onApply() { + auto* grad = static_cast(fGradient.get()); + grad->setStartCenter(this->startPoint()); + grad->setEndCenter(this->startPoint()); + grad->setStartRadius(0); + grad->setEndRadius(SkPoint::Distance(this->startPoint(), this->endPoint())); +} + +TrimEffectAdapter::TrimEffectAdapter(sk_sp trimEffect) + : fTrimEffect(std::move(trimEffect)) { + SkASSERT(fTrimEffect); +} + +void TrimEffectAdapter::apply() { + // BM semantics: start/end are percentages, offset is "degrees" (?!). + const auto start = fStart / 100, + end = fEnd / 100, + offset = fOffset / 360; + + auto startT = SkTMin(start, end) + offset, + stopT = SkTMax(start, end) + offset; + auto mode = SkTrimPathEffect::Mode::kNormal; + + if (stopT - startT < 1) { + startT -= SkScalarFloorToScalar(startT); + stopT -= SkScalarFloorToScalar(stopT); + + if (startT > stopT) { + SkTSwap(startT, stopT); + mode = SkTrimPathEffect::Mode::kInverted; + } + } else { + startT = 0; + stopT = 1; + } + + fTrimEffect->setStart(startT); + fTrimEffect->setStop(stopT); + fTrimEffect->setMode(mode); +} + +} // namespace skottie diff --git a/experimental/skottie/SkottieAdapter.h b/experimental/skottie/SkottieAdapter.h new file mode 100644 index 0000000000..e96c616fcf --- /dev/null +++ b/experimental/skottie/SkottieAdapter.h @@ -0,0 +1,164 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkottieAdapter_DEFINED +#define SkottieAdapter_DEFINED + +#include "SkPoint.h" +#include "SkRefCnt.h" +#include "SkSize.h" + +#include + +namespace sksg { + +class Gradient; +class LinearGradient; +class Matrix; +class Path; +class RadialGradient; +class RRect; +class TrimEffect; + +}; + +namespace skottie { + +#define ADAPTER_PROPERTY(p_name, p_type, p_default) \ + void set##p_name(const p_type& p) { \ + if (p == f##p_name) return; \ + f##p_name = p; \ + this->apply(); \ + } \ + private: \ + p_type f##p_name = p_default; \ + public: + +class RRectAdapter final : public SkRefCnt { +public: + explicit RRectAdapter(sk_sp); + + ADAPTER_PROPERTY(Position, SkPoint , SkPoint::Make(0, 0)) + ADAPTER_PROPERTY(Size , SkSize , SkSize::Make(0, 0)) + ADAPTER_PROPERTY(Radius , SkSize , SkSize::Make(0, 0)) + +private: + void apply(); + + sk_sp fRRectNode; + + using INHERITED = SkRefCnt; +}; + +class PolyStarAdapter final : public SkRefCnt { +public: + enum class Type { + kStar, kPoly, + }; + + PolyStarAdapter(sk_sp, Type); + + ADAPTER_PROPERTY(Position , SkPoint , SkPoint::Make(0, 0)) + ADAPTER_PROPERTY(PointCount , SkScalar, 0) + ADAPTER_PROPERTY(InnerRadius , SkScalar, 0) + ADAPTER_PROPERTY(OuterRadius , SkScalar, 0) + ADAPTER_PROPERTY(InnerRoundness, SkScalar, 0) + ADAPTER_PROPERTY(OuterRoundness, SkScalar, 0) + ADAPTER_PROPERTY(Rotation , SkScalar, 0) + +private: + void apply(); + + sk_sp fPathNode; + Type fType; + + using INHERITED = SkRefCnt; +}; + +class TransformAdapter final : public SkRefCnt { +public: + explicit TransformAdapter(sk_sp); + + ADAPTER_PROPERTY(AnchorPoint, SkPoint , SkPoint::Make(0, 0)) + ADAPTER_PROPERTY(Position , SkPoint , SkPoint::Make(0, 0)) + ADAPTER_PROPERTY(Scale , SkVector, SkPoint::Make(100, 100)) + ADAPTER_PROPERTY(Rotation , SkScalar, 0) + ADAPTER_PROPERTY(Skew , SkScalar, 0) + ADAPTER_PROPERTY(SkewAxis , SkScalar, 0) + +private: + void apply(); + + sk_sp fMatrixNode; + + using INHERITED = SkRefCnt; +}; + +class GradientAdapter : public SkRefCnt { +public: + ADAPTER_PROPERTY(StartPoint, SkPoint , SkPoint::Make(0, 0) ) + ADAPTER_PROPERTY(EndPoint , SkPoint , SkPoint::Make(0, 0) ) + ADAPTER_PROPERTY(ColorStops, std::vector, std::vector()) + +protected: + GradientAdapter(sk_sp, size_t stopCount); + + const SkPoint& startPoint() const { return fStartPoint; } + const SkPoint& endPoint() const { return fEndPoint; } + + sk_sp fGradient; + size_t fStopCount; + + virtual void onApply() = 0; + +private: + void apply(); + + using INHERITED = SkRefCnt; +}; + +class LinearGradientAdapter final : public GradientAdapter { +public: + LinearGradientAdapter(sk_sp, size_t stopCount); + +private: + void onApply() override; + + using INHERITED = GradientAdapter; +}; + +class RadialGradientAdapter final : public GradientAdapter { +public: + RadialGradientAdapter(sk_sp, size_t stopCount); + +private: + void onApply() override; + + using INHERITED = GradientAdapter; +}; + +class TrimEffectAdapter final : public SkRefCnt { +public: + explicit TrimEffectAdapter(sk_sp); + + ADAPTER_PROPERTY(Start , SkScalar, 0) + ADAPTER_PROPERTY(End , SkScalar, 100) + ADAPTER_PROPERTY(Offset, SkScalar, 0) + +private: + void apply(); + + sk_sp fTrimEffect; + + using INHERITED = SkRefCnt; +}; + +#undef ADAPTER_PROPERTY + +} // namespace skottie + +#endif // SkottieAdapter_DEFINED diff --git a/experimental/skottie/SkottieAnimator.cpp b/experimental/skottie/SkottieAnimator.cpp index e189ebcd56..5f8d0db89e 100644 --- a/experimental/skottie/SkottieAnimator.cpp +++ b/experimental/skottie/SkottieAnimator.cpp @@ -9,7 +9,7 @@ #include "SkCubicMap.h" #include "SkJSONCPP.h" -#include "SkottieProperties.h" +#include "SkottieValue.h" #include "SkottieParser.h" #include "SkTArray.h" diff --git a/experimental/skottie/SkottieProperties.cpp b/experimental/skottie/SkottieProperties.cpp deleted file mode 100644 index a774217a8c..0000000000 --- a/experimental/skottie/SkottieProperties.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright 2017 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "SkottieProperties.h" - -#include "SkColor.h" -#include "SkJSONCPP.h" -#include "SkPath.h" -#include "SkSGColor.h" -#include "SkSGGradient.h" -#include "SkSGPath.h" -#include "SkSGRect.h" -#include "SkSGTransform.h" -#include "SkSGTrimEffect.h" - -#include - -namespace skottie { - -namespace { - -SkColor VecToColor(const float* v, size_t size) { - // best effort to turn this into a color - const auto r = size > 0 ? v[0] : 0, - g = size > 1 ? v[1] : 0, - b = size > 2 ? v[2] : 0, - a = size > 3 ? v[3] : 1; - - return SkColorSetARGB(SkTPin(a, 0, 1) * 255, - SkTPin(r, 0, 1) * 255, - SkTPin(g, 0, 1) * 255, - SkTPin(b, 0, 1) * 255); -} - -} // namespace - -template <> -size_t ValueTraits::Cardinality(const ScalarValue&) { - return 1; -} - -template <> -template <> -SkScalar ValueTraits::As(const ScalarValue& v) { - return v; -} - -template <> -size_t ValueTraits::Cardinality(const VectorValue& vec) { - return vec.size(); -} - -template <> -template <> -SkColor ValueTraits::As(const VectorValue& vec) { - return VecToColor(vec.data(), vec.size()); -} - -template <> -template <> -SkPoint ValueTraits::As(const VectorValue& vec) { - // best effort to turn this into a point - const auto x = vec.size() > 0 ? vec[0] : 0, - y = vec.size() > 1 ? vec[1] : 0; - return SkPoint::Make(x, y); -} - -template <> -template <> -SkSize ValueTraits::As(const VectorValue& vec) { - const auto pt = ValueTraits::As(vec); - return SkSize::Make(pt.x(), pt.y()); -} - -template <> -size_t ValueTraits::Cardinality(const ShapeValue& path) { - return SkTo(path.countVerbs()); -} - -template <> -template <> -SkPath ValueTraits::As(const ShapeValue& path) { - return path; -} - -CompositeRRect::CompositeRRect(sk_sp wrapped_node) - : fRRectNode(std::move(wrapped_node)) {} - -void CompositeRRect::apply() { - // BM "position" == "center position" - auto rr = SkRRect::MakeRectXY(SkRect::MakeXYWH(fPosition.x() - fSize.width() / 2, - fPosition.y() - fSize.height() / 2, - fSize.width(), fSize.height()), - fRadius.width(), - fRadius.height()); - fRRectNode->setRRect(rr); -} - -CompositeTransform::CompositeTransform(sk_sp matrix) - : fMatrixNode(std::move(matrix)) {} - -void CompositeTransform::apply() { - SkMatrix t = SkMatrix::MakeTrans(-fAnchorPoint.x(), -fAnchorPoint.y()); - - t.postScale(fScale.x() / 100, fScale.y() / 100); // 100% based - t.postRotate(fRotation); - t.postTranslate(fPosition.x(), fPosition.y()); - // TODO: skew - - fMatrixNode->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); -} - -CompositeGradient::CompositeGradient(sk_sp grad, size_t stopCount) - : fGradient(std::move(grad)) - , fStopCount(stopCount) {} - -void CompositeGradient::apply() { - this->onApply(); - - // |fColorStops| holds |fStopCount| x [ pos, r, g, g ] + ? x [ pos, alpha ] - - if (fColorStops.size() < fStopCount * 4 || ((fColorStops.size() - fStopCount * 4) % 2)) { - SkDebugf("!! Invalid gradient stop array size: %zu", fColorStops.size()); - return; - } - - std::vector stops; - - // TODO: merge/lerp opacity stops - const auto csEnd = fColorStops.cbegin() + fStopCount * 4; - for (auto cs = fColorStops.cbegin(); cs != csEnd; cs += 4) { - stops.push_back({ *cs, VecToColor(&*(cs + 1), 3) }); - } - - fGradient->setColorStops(std::move(stops)); -} - -CompositeLinearGradient::CompositeLinearGradient(sk_sp grad, size_t stopCount) - : INHERITED(std::move(grad), stopCount) {} - -void CompositeLinearGradient::onApply() { - auto* grad = static_cast(fGradient.get()); - grad->setStartPoint(this->startPoint()); - grad->setEndPoint(this->endPoint()); -} - -CompositeRadialGradient::CompositeRadialGradient(sk_sp grad, size_t stopCount) - : INHERITED(std::move(grad), stopCount) {} - -void CompositeRadialGradient::onApply() { - auto* grad = static_cast(fGradient.get()); - grad->setStartCenter(this->startPoint()); - grad->setEndCenter(this->startPoint()); - grad->setStartRadius(0); - grad->setEndRadius(SkPoint::Distance(this->startPoint(), this->endPoint())); -} - -CompositeTrimEffect::CompositeTrimEffect(sk_sp trimEffect) - : fTrimEffect(std::move(trimEffect)) { - SkASSERT(fTrimEffect); -} - -void CompositeTrimEffect::apply() { - // BM semantics: start/end are percentages, offset is "degrees" (?!). - const auto start = fStart / 100, - end = fEnd / 100, - offset = fOffset / 360; - - auto startT = SkTMin(start, end) + offset, - stopT = SkTMax(start, end) + offset; - auto mode = SkTrimPathEffect::Mode::kNormal; - - if (stopT - startT < 1) { - startT -= SkScalarFloorToScalar(startT); - stopT -= SkScalarFloorToScalar(stopT); - - if (startT > stopT) { - SkTSwap(startT, stopT); - mode = SkTrimPathEffect::Mode::kInverted; - } - } else { - startT = 0; - stopT = 1; - } - - fTrimEffect->setStart(startT); - fTrimEffect->setStop(stopT); - fTrimEffect->setMode(mode); -} - -} // namespace skottie diff --git a/experimental/skottie/SkottieProperties.h b/experimental/skottie/SkottieProperties.h deleted file mode 100644 index 5e3fad0d9a..0000000000 --- a/experimental/skottie/SkottieProperties.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright 2017 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkottieProperties_DEFINED -#define SkottieProperties_DEFINED - -#include "SkColor.h" -#include "SkPath.h" -#include "SkPoint.h" -#include "SkSize.h" -#include "SkRefCnt.h" -#include "SkTArray.h" -#include "SkTypes.h" - -#include -#include - -namespace sksg { -class Color; -class Gradient; -class LinearGradient; -class Matrix; -class Path; -class RadialGradient; -class RRect; -class RenderNode;; -class TrimEffect; -} - -namespace Json { class Value; } - -namespace skottie { - -template -struct ValueTraits { - static size_t Cardinality(const T&); - - template - static U As(const T&); -}; - -using ScalarValue = SkScalar; -using VectorValue = std::vector; -using ShapeValue = SkPath; - -// Composite properties. - -#define COMPOSITE_PROPERTY(p_name, p_type, p_default) \ - void set##p_name(const p_type& p) { \ - if (p == f##p_name) return; \ - f##p_name = p; \ - this->apply(); \ - } \ - private: \ - p_type f##p_name = p_default; \ - public: - -class CompositeRRect final : public SkRefCnt { -public: - explicit CompositeRRect(sk_sp); - - COMPOSITE_PROPERTY(Position, SkPoint , SkPoint::Make(0, 0)) - COMPOSITE_PROPERTY(Size , SkSize , SkSize::Make(0, 0)) - COMPOSITE_PROPERTY(Radius , SkSize , SkSize::Make(0, 0)) - -private: - void apply(); - - sk_sp fRRectNode; - - 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); - - COMPOSITE_PROPERTY(AnchorPoint, SkPoint , SkPoint::Make(0, 0)) - COMPOSITE_PROPERTY(Position , SkPoint , SkPoint::Make(0, 0)) - COMPOSITE_PROPERTY(Scale , SkVector, SkPoint::Make(100, 100)) - COMPOSITE_PROPERTY(Rotation , SkScalar, 0) - COMPOSITE_PROPERTY(Skew , SkScalar, 0) - COMPOSITE_PROPERTY(SkewAxis , SkScalar, 0) - -private: - void apply(); - - sk_sp fMatrixNode; - - using INHERITED = SkRefCnt; -}; - -class CompositeGradient : public SkRefCnt { -public: - COMPOSITE_PROPERTY(StartPoint, SkPoint , SkPoint::Make(0, 0) ) - COMPOSITE_PROPERTY(EndPoint , SkPoint , SkPoint::Make(0, 0) ) - COMPOSITE_PROPERTY(ColorStops, std::vector, std::vector()) - -protected: - CompositeGradient(sk_sp, size_t stopCount); - - const SkPoint& startPoint() const { return fStartPoint; } - const SkPoint& endPoint() const { return fEndPoint; } - - sk_sp fGradient; - size_t fStopCount; - - virtual void onApply() = 0; - -private: - void apply(); - - using INHERITED = SkRefCnt; -}; - -class CompositeLinearGradient final : public CompositeGradient { -public: - CompositeLinearGradient(sk_sp, size_t stopCount); - -private: - void onApply() override; - - using INHERITED = CompositeGradient; -}; - -class CompositeRadialGradient final : public CompositeGradient { -public: - CompositeRadialGradient(sk_sp, size_t stopCount); - -private: - void onApply() override; - - using INHERITED = CompositeGradient; -}; - -class CompositeTrimEffect final : public SkRefCnt { -public: - explicit CompositeTrimEffect(sk_sp); - - COMPOSITE_PROPERTY(Start , SkScalar, 0) - COMPOSITE_PROPERTY(End , SkScalar, 100) - COMPOSITE_PROPERTY(Offset, SkScalar, 0) - -private: - void apply(); - - sk_sp fTrimEffect; - - using INHERITED = SkRefCnt; -}; - -#undef COMPOSITE_PROPERTY - -} // namespace skottie - -#endif // SkottieProperties_DEFINED diff --git a/experimental/skottie/SkottieValue.cpp b/experimental/skottie/SkottieValue.cpp new file mode 100644 index 0000000000..386c8ab623 --- /dev/null +++ b/experimental/skottie/SkottieValue.cpp @@ -0,0 +1,74 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkottieValue.h" + +#include "SkColor.h" +#include "SkPoint.h" +#include "SkSize.h" + +namespace skottie { + +template <> +size_t ValueTraits::Cardinality(const ScalarValue&) { + return 1; +} + +template <> +template <> +SkScalar ValueTraits::As(const ScalarValue& v) { + return v; +} + +template <> +size_t ValueTraits::Cardinality(const VectorValue& vec) { + return vec.size(); +} + +template <> +template <> +SkColor ValueTraits::As(const VectorValue& v) { + // best effort to turn this into a color + const auto r = v.size() > 0 ? v[0] : 0, + g = v.size() > 1 ? v[1] : 0, + b = v.size() > 2 ? v[2] : 0, + a = v.size() > 3 ? v[3] : 1; + + return SkColorSetARGB(SkTPin(a, 0, 1) * 255, + SkTPin(r, 0, 1) * 255, + SkTPin(g, 0, 1) * 255, + SkTPin(b, 0, 1) * 255); +} + +template <> +template <> +SkPoint ValueTraits::As(const VectorValue& vec) { + // best effort to turn this into a point + const auto x = vec.size() > 0 ? vec[0] : 0, + y = vec.size() > 1 ? vec[1] : 0; + return SkPoint::Make(x, y); +} + +template <> +template <> +SkSize ValueTraits::As(const VectorValue& vec) { + const auto pt = ValueTraits::As(vec); + return SkSize::Make(pt.x(), pt.y()); +} + +template <> +size_t ValueTraits::Cardinality(const ShapeValue& path) { + return SkTo(path.countVerbs()); +} + +template <> +template <> +SkPath ValueTraits::As(const ShapeValue& path) { + return path; +} + +} // namespace skottie diff --git a/experimental/skottie/SkottieValue.h b/experimental/skottie/SkottieValue.h new file mode 100644 index 0000000000..6d6d94a7a3 --- /dev/null +++ b/experimental/skottie/SkottieValue.h @@ -0,0 +1,32 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkottieValue_DEFINED +#define SkottieValue_DEFINED + +#include "SkPath.h" +#include "SkScalar.h" + +#include + +namespace skottie { + +template +struct ValueTraits { + static size_t Cardinality(const T&); + + template + static U As(const T&); +}; + +using ScalarValue = SkScalar; +using VectorValue = std::vector; +using ShapeValue = SkPath; + +} // namespace skottie + +#endif // SkottieValue_DEFINED -- cgit v1.2.3