1 /* 2 * Copyright 2018 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkottiePriv_DEFINED 9 #define SkottiePriv_DEFINED 10 11 #include "Skottie.h" 12 13 #include "SkFontStyle.h" 14 #include "SkottieProperty.h" 15 #include "SkSGScene.h" 16 #include "SkString.h" 17 #include "SkTHash.h" 18 #include "SkTypeface.h" 19 #include "SkUTF.h" 20 21 #include <functional> 22 23 class SkFontMgr; 24 25 namespace skjson { 26 class ArrayValue; 27 class ObjectValue; 28 class Value; 29 } // namespace skjson 30 31 namespace sksg { 32 class Color; 33 class Path; 34 class RenderNode; 35 class Transform; 36 } // namespace sksg 37 38 namespace skottie { 39 40 namespace internal { 41 42 using AnimatorScope = sksg::AnimatorList; 43 44 class AnimationBuilder final : public SkNoncopyable { 45 public: 46 AnimationBuilder(sk_sp<ResourceProvider>, sk_sp<SkFontMgr>, sk_sp<PropertyObserver>, 47 sk_sp<Logger>, sk_sp<MarkerObserver>, 48 Animation::Builder::Stats*, float duration, float framerate); 49 50 std::unique_ptr<sksg::Scene> parse(const skjson::ObjectValue&); 51 52 sk_sp<SkTypeface> findFont(const SkString& name) const; 53 54 // This is the workhorse for property binding: depending on whether the property is animated, 55 // it will either apply immediately or instantiate and attach a keyframe animator. 56 template <typename T> 57 bool bindProperty(const skjson::Value&, 58 AnimatorScope*, 59 std::function<void(const T&)>&&, 60 const T* default_igore = nullptr) const; 61 62 template <typename T> bindProperty(const skjson::Value & jv,AnimatorScope * ascope,std::function<void (const T &)> && apply,const T & default_ignore)63 bool bindProperty(const skjson::Value& jv, 64 AnimatorScope* ascope, 65 std::function<void(const T&)>&& apply, 66 const T& default_ignore) const { 67 return this->bindProperty(jv, ascope, std::move(apply), &default_ignore); 68 } 69 70 void log(Logger::Level, const skjson::Value*, const char fmt[], ...) const; 71 72 sk_sp<sksg::Color> attachColor(const skjson::ObjectValue&, AnimatorScope*, 73 const char prop_name[]) const; 74 sk_sp<sksg::Transform> attachMatrix2D(const skjson::ObjectValue&, AnimatorScope*, 75 sk_sp<sksg::Transform>) const; 76 sk_sp<sksg::Transform> attachMatrix3D(const skjson::ObjectValue&, AnimatorScope*, 77 sk_sp<sksg::Transform>) const; 78 sk_sp<sksg::RenderNode> attachOpacity(const skjson::ObjectValue&, AnimatorScope*, 79 sk_sp<sksg::RenderNode>) const; 80 sk_sp<sksg::Path> attachPath(const skjson::Value&, AnimatorScope*) const; 81 82 private: 83 struct AttachLayerContext; 84 struct AttachShapeContext; 85 struct ImageAssetInfo; 86 struct LayerInfo; 87 88 void parseAssets(const skjson::ArrayValue*); 89 void parseFonts (const skjson::ObjectValue* jfonts, 90 const skjson::ArrayValue* jchars); 91 92 void dispatchMarkers(const skjson::ArrayValue*) const; 93 94 sk_sp<sksg::RenderNode> attachComposition(const skjson::ObjectValue&, AnimatorScope*) const; 95 sk_sp<sksg::RenderNode> attachLayer(const skjson::ObjectValue*, AttachLayerContext*) const; 96 sk_sp<sksg::RenderNode> attachLayerEffects(const skjson::ArrayValue& jeffects, AnimatorScope*, 97 sk_sp<sksg::RenderNode>) const; 98 99 sk_sp<sksg::RenderNode> attachShape(const skjson::ArrayValue*, AttachShapeContext*) const; 100 sk_sp<sksg::RenderNode> attachAssetRef(const skjson::ObjectValue&, AnimatorScope*, 101 const std::function<sk_sp<sksg::RenderNode>(const skjson::ObjectValue&, 102 AnimatorScope* ctx)>&) const; 103 const ImageAssetInfo* loadImageAsset(const skjson::ObjectValue&) const; 104 sk_sp<sksg::RenderNode> attachImageAsset(const skjson::ObjectValue&, const LayerInfo&, 105 AnimatorScope*) const; 106 107 sk_sp<sksg::RenderNode> attachNestedAnimation(const char* name, AnimatorScope* ascope) const; 108 109 sk_sp<sksg::RenderNode> attachImageLayer (const skjson::ObjectValue&, const LayerInfo&, 110 AnimatorScope*) const; 111 sk_sp<sksg::RenderNode> attachNullLayer (const skjson::ObjectValue&, const LayerInfo&, 112 AnimatorScope*) const; 113 sk_sp<sksg::RenderNode> attachPrecompLayer(const skjson::ObjectValue&, const LayerInfo&, 114 AnimatorScope*) const; 115 sk_sp<sksg::RenderNode> attachShapeLayer (const skjson::ObjectValue&, const LayerInfo&, 116 AnimatorScope*) const; 117 sk_sp<sksg::RenderNode> attachSolidLayer (const skjson::ObjectValue&, const LayerInfo&, 118 AnimatorScope*) const; 119 sk_sp<sksg::RenderNode> attachTextLayer (const skjson::ObjectValue&, const LayerInfo&, 120 AnimatorScope*) const; 121 122 bool dispatchColorProperty(const sk_sp<sksg::Color>&) const; 123 bool dispatchOpacityProperty(const sk_sp<sksg::OpacityEffect>&) const; 124 bool dispatchTransformProperty(const sk_sp<TransformAdapter2D>&) const; 125 126 // Delay resolving the fontmgr until it is actually needed. 127 struct LazyResolveFontMgr { LazyResolveFontMgrLazyResolveFontMgr128 LazyResolveFontMgr(sk_sp<SkFontMgr> fontMgr) : fFontMgr(std::move(fontMgr)) {} 129 getLazyResolveFontMgr130 const sk_sp<SkFontMgr>& get() { 131 if (!fFontMgr) { 132 fFontMgr = SkFontMgr::RefDefault(); 133 SkASSERT(fFontMgr); 134 } 135 return fFontMgr; 136 } 137 getMaybeNullLazyResolveFontMgr138 const sk_sp<SkFontMgr>& getMaybeNull() const { return fFontMgr; } 139 140 private: 141 sk_sp<SkFontMgr> fFontMgr; 142 }; 143 144 class AutoPropertyTracker { 145 public: AutoPropertyTracker(const AnimationBuilder * builder,const skjson::ObjectValue & obj)146 AutoPropertyTracker(const AnimationBuilder* builder, const skjson::ObjectValue& obj) 147 : fBuilder(builder) 148 , fPrevContext(builder->fPropertyObserverContext) { 149 if (fBuilder->fPropertyObserver) { 150 this->updateContext(builder->fPropertyObserver.get(), obj); 151 } 152 } 153 ~AutoPropertyTracker()154 ~AutoPropertyTracker() { 155 if (fBuilder->fPropertyObserver) { 156 fBuilder->fPropertyObserverContext = fPrevContext; 157 } 158 } 159 private: 160 void updateContext(PropertyObserver*, const skjson::ObjectValue&); 161 162 const AnimationBuilder* fBuilder; 163 const char* fPrevContext; 164 }; 165 166 sk_sp<ResourceProvider> fResourceProvider; 167 LazyResolveFontMgr fLazyFontMgr; 168 sk_sp<PropertyObserver> fPropertyObserver; 169 sk_sp<Logger> fLogger; 170 sk_sp<MarkerObserver> fMarkerObserver; 171 Animation::Builder::Stats* fStats; 172 const float fDuration, 173 fFrameRate; 174 175 mutable const char* fPropertyObserverContext; 176 177 struct LayerInfo { 178 float fInPoint, 179 fOutPoint; 180 }; 181 182 struct AssetInfo { 183 const skjson::ObjectValue* fAsset; 184 mutable bool fIsAttaching; // Used for cycle detection 185 }; 186 187 struct FontInfo { 188 SkString fFamily, 189 fStyle; 190 SkScalar fAscent; 191 sk_sp<SkTypeface> fTypeface; 192 193 bool matches(const char family[], const char style[]) const; 194 }; 195 196 struct ImageAssetInfo { 197 sk_sp<ImageAsset> fAsset; 198 SkISize fSize; 199 }; 200 201 SkTHashMap<SkString, AssetInfo> fAssets; 202 SkTHashMap<SkString, FontInfo> fFonts; 203 mutable SkTHashMap<SkString, ImageAssetInfo> fImageAssetCache; 204 205 using INHERITED = SkNoncopyable; 206 }; 207 208 } // namespace internal 209 } // namespace skottie 210 211 #endif // SkottiePriv_DEFINED 212