aboutsummaryrefslogtreecommitdiffhomepage
path: root/experimental/skotty/Skotty.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'experimental/skotty/Skotty.cpp')
-rw-r--r--experimental/skotty/Skotty.cpp79
1 files changed, 71 insertions, 8 deletions
diff --git a/experimental/skotty/Skotty.cpp b/experimental/skotty/Skotty.cpp
index b331547316..077640b695 100644
--- a/experimental/skotty/Skotty.cpp
+++ b/experimental/skotty/Skotty.cpp
@@ -12,14 +12,17 @@
#include "SkottyPriv.h"
#include "SkottyProperties.h"
#include "SkData.h"
+#include "SkImage.h"
#include "SkMakeUnique.h"
+#include "SkOSPath.h"
#include "SkPaint.h"
#include "SkPath.h"
#include "SkPoint.h"
#include "SkSGColor.h"
#include "SkSGDraw.h"
-#include "SkSGInvalidationController.h"
#include "SkSGGroup.h"
+#include "SkSGImage.h"
+#include "SkSGInvalidationController.h"
#include "SkSGMerge.h"
#include "SkSGPath.h"
#include "SkSGRect.h"
@@ -42,6 +45,7 @@ namespace {
using AssetMap = SkTHashMap<SkString, const Json::Value*>;
struct AttachContext {
+ const ResourceProvider& fResources;
const AssetMap& fAssets;
SkTArray<std::unique_ptr<AnimatorBase>>& fAnimators;
};
@@ -550,11 +554,43 @@ sk_sp<sksg::RenderNode> AttachSolidLayer(const Json::Value& layer, AttachContext
return nullptr;
}
-sk_sp<sksg::RenderNode> AttachImageLayer(const Json::Value& layer, AttachContext*) {
+sk_sp<sksg::RenderNode> AttachImageAsset(const Json::Value& jimage, AttachContext* ctx) {
+ SkASSERT(jimage.isObject());
+
+ const auto name = ParseString(jimage["p"], ""),
+ path = ParseString(jimage["u"], "");
+ if (name.isEmpty())
+ return nullptr;
+
+ // TODO: plumb resource paths explicitly to ResourceProvider?
+ const auto resName = path.isEmpty() ? name : SkOSPath::Join(path.c_str(), name.c_str());
+ const auto resStream = ctx->fResources.openStream(resName.c_str());
+ if (!resStream || !resStream->hasLength()) {
+ LOG("!! Could not load image resource: %s\n", resName.c_str());
+ return nullptr;
+ }
+
+ // TODO: non-intrisic image sizing
+ return sksg::Image::Make(
+ SkImage::MakeFromEncoded(SkData::MakeFromStream(resStream.get(), resStream->getLength())));
+}
+
+sk_sp<sksg::RenderNode> AttachImageLayer(const Json::Value& layer, AttachContext* ctx) {
SkASSERT(layer.isObject());
- LOG("?? Image layer stub\n");
- return nullptr;
+ auto refId = ParseString(layer["refId"], "");
+ if (refId.isEmpty()) {
+ LOG("!! Image layer missing refId\n");
+ return nullptr;
+ }
+
+ const auto* jimage = ctx->fAssets.find(refId);
+ if (!jimage) {
+ LOG("!! Image asset not found: '%s'\n", refId.c_str());
+ return nullptr;
+ }
+
+ return AttachImageAsset(**jimage, ctx);
}
sk_sp<sksg::RenderNode> AttachNullLayer(const Json::Value& layer, AttachContext*) {
@@ -699,7 +735,7 @@ sk_sp<sksg::RenderNode> AttachComposition(const Json::Value& comp, AttachContext
} // namespace
-std::unique_ptr<Animation> Animation::Make(SkStream* stream) {
+std::unique_ptr<Animation> Animation::Make(SkStream* stream, const ResourceProvider& res) {
if (!stream->hasLength()) {
// TODO: handle explicit buffering?
LOG("!! cannot parse streaming content\n");
@@ -733,10 +769,37 @@ std::unique_ptr<Animation> Animation::Make(SkStream* stream) {
return nullptr;
}
- return std::unique_ptr<Animation>(new Animation(std::move(version), size, fps, json));
+ return std::unique_ptr<Animation>(new Animation(res, std::move(version), size, fps, json));
+}
+
+std::unique_ptr<Animation> Animation::MakeFromFile(const char path[], const ResourceProvider* res) {
+ class DirectoryResourceProvider final : public ResourceProvider {
+ public:
+ explicit DirectoryResourceProvider(SkString dir) : fDir(std::move(dir)) {}
+
+ std::unique_ptr<SkStream> openStream(const char resource[]) const override {
+ const auto resPath = SkOSPath::Join(fDir.c_str(), resource);
+ return SkStream::MakeFromFile(resPath.c_str());
+ }
+
+ private:
+ const SkString fDir;
+ };
+
+ const auto jsonStream = SkStream::MakeFromFile(path);
+ if (!jsonStream)
+ return nullptr;
+
+ std::unique_ptr<ResourceProvider> defaultProvider;
+ if (!res) {
+ defaultProvider = skstd::make_unique<DirectoryResourceProvider>(SkOSPath::Dirname(path));
+ }
+
+ return Make(jsonStream.get(), res ? *res : *defaultProvider);
}
-Animation::Animation(SkString version, const SkSize& size, SkScalar fps, const Json::Value& json)
+Animation::Animation(const ResourceProvider& resources,
+ SkString version, const SkSize& size, SkScalar fps, const Json::Value& json)
: fVersion(std::move(version))
, fSize(size)
, fFrameRate(fps)
@@ -752,7 +815,7 @@ Animation::Animation(SkString version, const SkSize& size, SkScalar fps, const J
assets.set(ParseString(asset["id"], ""), &asset);
}
- AttachContext ctx = { assets, fAnimators };
+ AttachContext ctx = { resources, assets, fAnimators };
fDom = AttachComposition(json, &ctx);
LOG("** Attached %d animators\n", fAnimators.count());