aboutsummaryrefslogtreecommitdiffhomepage
path: root/experimental/skottie/Skottie.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'experimental/skottie/Skottie.cpp')
-rw-r--r--experimental/skottie/Skottie.cpp84
1 files changed, 44 insertions, 40 deletions
diff --git a/experimental/skottie/Skottie.cpp b/experimental/skottie/Skottie.cpp
index c8144e446d..53f1c88037 100644
--- a/experimental/skottie/Skottie.cpp
+++ b/experimental/skottie/Skottie.cpp
@@ -9,7 +9,7 @@
#include "SkCanvas.h"
#include "SkottieAnimator.h"
-#include "SkottiePriv.h"
+#include "SkottieParser.h"
#include "SkottieProperties.h"
#include "SkData.h"
#include "SkImage.h"
@@ -46,6 +46,8 @@
namespace skottie {
+#define LOG SkDebugf
+
namespace {
using AssetMap = SkTHashMap<SkString, const Json::Value*>;
@@ -75,9 +77,9 @@ bool BindProperty(const Json::Value& jprop, AttachContext* ctx,
// Older Json versions don't have an "a" animation marker.
// For those, we attempt to parse both ways.
- if (jpropA.isNull() || !ParseBool(jpropA, "false")) {
+ if (!ParseDefault(jpropA, false)) {
T val;
- if (ValueTraits<T>::Parse(jpropK, &val)) {
+ if (Parse<T>(jpropK, &val)) {
// Static property.
apply(val);
return true;
@@ -154,8 +156,8 @@ sk_sp<sksg::RenderNode> AttachOpacity(const Json::Value& jtransform, AttachConte
// nodes for the extremely common case of static opaciy == 100.
const auto& opacity = jtransform["o"];
if (opacity.isObject() &&
- !ParseBool(opacity["a"], true) &&
- ParseScalar(opacity["k"], -1) == 100) {
+ !ParseDefault(opacity["a"], true) &&
+ ParseDefault(opacity["k"], -1) == 100) {
// Ignoring static full opacity.
return childNode;
}
@@ -248,7 +250,7 @@ sk_sp<sksg::GeometryNode> AttachPolystarGeometry(const Json::Value& jstar, Attac
CompositePolyStar::Type::kPoly, // "sy": 2
};
- const auto type = ParseInt(jstar["sy"], 0) - 1;
+ const auto type = ParseDefault(jstar["sy"], 0) - 1;
if (type < 0 || type >= SkTo<int>(SK_ARRAY_COUNT(gTypes))) {
LogFail(jstar, "Unknown polystar type");
return nullptr;
@@ -308,14 +310,14 @@ sk_sp<sksg::Gradient> AttachGradient(const Json::Value& obj, AttachContext* ctx)
if (!stops.isObject())
return nullptr;
- const auto stopCount = ParseInt(stops["p"], -1);
+ const auto stopCount = ParseDefault(stops["p"], -1);
if (stopCount < 0)
return nullptr;
sk_sp<sksg::Gradient> gradient_node;
sk_sp<CompositeGradient> composite;
- if (ParseInt(obj["t"], 1) == 1) {
+ if (ParseDefault(obj["t"], 1) == 1) {
auto linear_node = sksg::LinearGradient::Make();
composite = sk_make_sp<CompositeLinearGradient>(linear_node, stopCount);
gradient_node = std::move(linear_node);
@@ -374,14 +376,14 @@ sk_sp<sksg::PaintNode> AttachStroke(const Json::Value& jstroke, AttachContext* c
if (!width_attached)
return nullptr;
- stroke_node->setStrokeMiter(ParseScalar(jstroke["ml"], 4));
+ stroke_node->setStrokeMiter(ParseDefault(jstroke["ml"], 4.0f));
static constexpr SkPaint::Join gJoins[] = {
SkPaint::kMiter_Join,
SkPaint::kRound_Join,
SkPaint::kBevel_Join,
};
- stroke_node->setStrokeJoin(gJoins[SkTPin<int>(ParseInt(jstroke["lj"], 1) - 1,
+ stroke_node->setStrokeJoin(gJoins[SkTPin<int>(ParseDefault(jstroke["lj"], 1) - 1,
0, SK_ARRAY_COUNT(gJoins) - 1)]);
static constexpr SkPaint::Cap gCaps[] = {
@@ -389,7 +391,7 @@ sk_sp<sksg::PaintNode> AttachStroke(const Json::Value& jstroke, AttachContext* c
SkPaint::kRound_Cap,
SkPaint::kSquare_Cap,
};
- stroke_node->setStrokeCap(gCaps[SkTPin<int>(ParseInt(jstroke["lc"], 1) - 1,
+ stroke_node->setStrokeCap(gCaps[SkTPin<int>(ParseDefault(jstroke["lc"], 1) - 1,
0, SK_ARRAY_COUNT(gCaps) - 1)]);
return stroke_node;
@@ -431,7 +433,7 @@ std::vector<sk_sp<sksg::GeometryNode>> AttachMergeGeometryEffect(
sksg::Merge::Mode::kXOR , // "mm": 5
};
- const auto mode = gModes[SkTPin<int>(ParseInt(jmerge["mm"], 1) - 1,
+ const auto mode = gModes[SkTPin<int>(ParseDefault(jmerge["mm"], 1) - 1,
0, SK_ARRAY_COUNT(gModes) - 1)];
merged.push_back(sksg::Merge::Make(std::move(geos), mode));
@@ -448,7 +450,7 @@ std::vector<sk_sp<sksg::GeometryNode>> AttachTrimGeometryEffect(
kSeparate, // "m": 2
} gModes[] = { Mode::kMerged, Mode::kSeparate };
- const auto mode = gModes[SkTPin<int>(ParseInt(jtrim["m"], 1) - 1,
+ const auto mode = gModes[SkTPin<int>(ParseDefault(jtrim["m"], 1) - 1,
0, SK_ARRAY_COUNT(gModes) - 1)];
std::vector<sk_sp<sksg::GeometryNode>> inputs;
@@ -714,8 +716,8 @@ sk_sp<sksg::RenderNode> AttachShape(const Json::Value& jshape, AttachShapeContex
sk_sp<sksg::RenderNode> AttachCompLayer(const Json::Value& layer, AttachContext* ctx) {
SkASSERT(layer.isObject());
- auto refId = ParseString(layer["refId"], "");
- if (refId.isEmpty()) {
+ SkString refId;
+ if (!Parse(layer["refId"], &refId) || refId.isEmpty()) {
LOG("!! Comp layer missing refId\n");
return nullptr;
}
@@ -733,9 +735,9 @@ sk_sp<sksg::RenderNode> AttachCompLayer(const Json::Value& layer, AttachContext*
sk_sp<sksg::RenderNode> AttachSolidLayer(const Json::Value& jlayer, AttachContext*) {
SkASSERT(jlayer.isObject());
- const auto size = SkSize::Make(ParseScalar(jlayer["sw"], -1),
- ParseScalar(jlayer["sh"], -1));
- const auto hex = ParseString(jlayer["sc"], "");
+ const auto size = SkSize::Make(ParseDefault(jlayer["sw"], 0.0f),
+ ParseDefault(jlayer["sh"], 0.0f));
+ const auto hex = ParseDefault(jlayer["sc"], SkString());
uint32_t c;
if (size.isEmpty() ||
!hex.startsWith("#") ||
@@ -753,8 +755,8 @@ sk_sp<sksg::RenderNode> AttachSolidLayer(const Json::Value& jlayer, AttachContex
sk_sp<sksg::RenderNode> AttachImageAsset(const Json::Value& jimage, AttachContext* ctx) {
SkASSERT(jimage.isObject());
- const auto name = ParseString(jimage["p"], ""),
- path = ParseString(jimage["u"], "");
+ const auto name = ParseDefault(jimage["p"], SkString()),
+ path = ParseDefault(jimage["u"], SkString());
if (name.isEmpty())
return nullptr;
@@ -774,8 +776,8 @@ sk_sp<sksg::RenderNode> AttachImageAsset(const Json::Value& jimage, AttachContex
sk_sp<sksg::RenderNode> AttachImageLayer(const Json::Value& layer, AttachContext* ctx) {
SkASSERT(layer.isObject());
- auto refId = ParseString(layer["refId"], "");
- if (refId.isEmpty()) {
+ SkString refId;
+ if (!Parse(layer["refId"], &refId) || refId.isEmpty()) {
LOG("!! Image layer missing refId\n");
return nullptr;
}
@@ -800,8 +802,6 @@ sk_sp<sksg::RenderNode> AttachNullLayer(const Json::Value& layer, AttachContext*
sk_sp<sksg::RenderNode> AttachShapeLayer(const Json::Value& layer, AttachContext* ctx) {
SkASSERT(layer.isObject());
- LOG("** Attaching shape layer ind: %d\n", ParseInt(layer["ind"], 0));
-
std::vector<sk_sp<sksg::GeometryNode>> geometryStack;
std::vector<GeometryEffectRec> geometryEffectStack;
AttachShapeContext shapeCtx(ctx, &geometryStack, &geometryEffectStack, ctx->fAnimators.size());
@@ -851,7 +851,7 @@ struct AttachLayerContext {
continue;
}
- if (ParseInt(l["ind"], -1) == index) {
+ if (ParseDefault(l["ind"], -1) == index) {
fLayerIndexCache.insert(std::make_pair(index, &l));
return &l;
}
@@ -868,7 +868,7 @@ struct AttachLayerContext {
return cached->second;
}
- const auto* parentLayer = this->findLayer(ParseInt(jlayer["parent"], -1));
+ const auto* parentLayer = this->findLayer(ParseDefault(jlayer["parent"], -1));
// TODO: cycle detection?
auto parentMatrix = (parentLayer && parentLayer != &jlayer)
@@ -907,7 +907,7 @@ sk_sp<sksg::RenderNode> AttachMask(const Json::Value& jmask,
if (!m.isObject())
continue;
- const auto inverted = ParseBool(m["inv"], false);
+ const auto inverted = ParseDefault(m["inv"], false);
// TODO
if (inverted) {
LogFail(m, "Unsupported inverse mask");
@@ -920,9 +920,12 @@ sk_sp<sksg::RenderNode> AttachMask(const Json::Value& jmask,
continue;
}
- auto mode = ParseString(m["mode"], "");
- if (mode.size() != 1 || !strcmp(mode.c_str(), "n")) // "None" masks have no effect.
+ SkString mode;
+ if (!Parse(m["mode"], &mode) ||
+ mode.size() != 1 ||
+ !strcmp(mode.c_str(), "n")) { // "None" masks have no effect.
continue;
+ }
auto mask_paint = sksg::Color::Make(SK_ColorBLACK);
mask_paint->setBlendMode(MaskBlendMode(mode.c_str()[0]));
@@ -952,7 +955,7 @@ sk_sp<sksg::RenderNode> AttachLayer(const Json::Value& jlayer,
AttachTextLayer, // 'ty': 5
};
- int type = ParseInt(jlayer["ty"], -1);
+ int type = ParseDefault(jlayer["ty"], -1);
if (type < 0 || type >= SkTo<int>(SK_ARRAY_COUNT(gLayerAttachers))) {
return nullptr;
}
@@ -989,15 +992,15 @@ sk_sp<sksg::RenderNode> AttachLayer(const Json::Value& jlayer,
};
auto layerControl = sksg::OpacityEffect::Make(std::move(layer));
- const auto in = ParseScalar(jlayer["ip"], 0),
- out = ParseScalar(jlayer["op"], in);
+ const auto in = ParseDefault(jlayer["ip"], 0.0f),
+ out = ParseDefault(jlayer["op"], in);
if (in >= out || ! layerControl)
return nullptr;
layerCtx->fCtx->fAnimators.push_back(skstd::make_unique<Activator>(layerControl, in, out));
- if (ParseBool(jlayer["td"], false)) {
+ if (ParseDefault(jlayer["td"], false)) {
// This layer is a matte. We apply it as a mask to the next layer.
layerCtx->fCurrentMatte = std::move(layerControl);
return nullptr;
@@ -1039,7 +1042,7 @@ sk_sp<sksg::RenderNode> AttachComposition(const Json::Value& comp, AttachContext
}
LOG("** Attached composition '%s': %d layers.\n",
- ParseString(comp["id"], "").c_str(), layers.count());
+ ParseDefault(comp["id"], SkString()).c_str(), layers.count());
return comp_group;
}
@@ -1070,9 +1073,10 @@ std::unique_ptr<Animation> Animation::Make(SkStream* stream, const ResourceProvi
}
}
- const auto version = ParseString(json["v"], "");
- const auto size = SkSize::Make(ParseScalar(json["w"], -1), ParseScalar(json["h"], -1));
- const auto fps = ParseScalar(json["fr"], -1);
+ const auto version = ParseDefault(json["v"], SkString());
+ const auto size = SkSize::Make(ParseDefault(json["w"], 0.0f),
+ ParseDefault(json["h"], 0.0f));
+ const auto fps = ParseDefault(json["fr"], -1.0f);
if (size.isEmpty() || version.isEmpty() || fps < 0) {
LOG("!! invalid animation params (version: %s, size: [%f %f], frame rate: %f)",
@@ -1114,8 +1118,8 @@ Animation::Animation(const ResourceProvider& resources,
: fVersion(std::move(version))
, fSize(size)
, fFrameRate(fps)
- , fInPoint(ParseScalar(json["ip"], 0))
- , fOutPoint(SkTMax(ParseScalar(json["op"], SK_ScalarMax), fInPoint)) {
+ , fInPoint(ParseDefault(json["ip"], 0.0f))
+ , fOutPoint(SkTMax(ParseDefault(json["op"], SK_ScalarMax), fInPoint)) {
AssetMap assets;
for (const auto& asset : json["assets"]) {
@@ -1123,7 +1127,7 @@ Animation::Animation(const ResourceProvider& resources,
continue;
}
- assets.set(ParseString(asset["id"], ""), &asset);
+ assets.set(ParseDefault(asset["id"], SkString()), &asset);
}
sksg::Scene::AnimatorList animators;