Home | History | Annotate | Download | only in utils
      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 SkottieUtils_DEFINED
      9 #define SkottieUtils_DEFINED
     10 
     11 #include "SkColor.h"
     12 #include "Skottie.h"
     13 #include "SkottieProperty.h"
     14 #include "SkString.h"
     15 #include "SkTHash.h"
     16 
     17 #include <memory>
     18 #include <string>
     19 #include <unordered_map>
     20 #include <vector>
     21 
     22 class SkAnimCodecPlayer;
     23 class SkData;
     24 class SkImage;
     25 
     26 namespace skottie_utils {
     27 
     28 class MultiFrameImageAsset final : public skottie::ImageAsset {
     29 public:
     30     static sk_sp<MultiFrameImageAsset> Make(sk_sp<SkData>);
     31 
     32     bool isMultiFrame() override;
     33 
     34     sk_sp<SkImage> getFrame(float t) override;
     35 
     36 private:
     37     explicit MultiFrameImageAsset(std::unique_ptr<SkAnimCodecPlayer>);
     38 
     39     std::unique_ptr<SkAnimCodecPlayer> fPlayer;
     40 
     41     using INHERITED = skottie::ImageAsset;
     42 };
     43 
     44 class FileResourceProvider final : public skottie::ResourceProvider {
     45 public:
     46     static sk_sp<FileResourceProvider> Make(SkString base_dir);
     47 
     48     sk_sp<SkData> load(const char resource_path[], const char resource_name[]) const override;
     49 
     50     sk_sp<skottie::ImageAsset> loadImageAsset(const char[], const char []) const override;
     51 
     52 private:
     53     explicit FileResourceProvider(SkString);
     54 
     55     const SkString fDir;
     56 
     57     using INHERITED = skottie::ResourceProvider;
     58 };
     59 
     60 /**
     61  * CustomPropertyManager implements a property management scheme where color/opacity/transform
     62  * attributes are grouped and manipulated by name (one-to-many mapping).
     63  *
     64  *   - setters apply the value to all properties in a named group
     65  *
     66  *   - getters return all the managed property groups, and the first value within each of them
     67  *     (unchecked assumption: all properties within the same group have the same value)
     68  *
     69  * Attach to an Animation::Builder using the utility methods below to intercept properties and
     70  * markers at build time.
     71  */
     72 class CustomPropertyManager final {
     73 public:
     74     CustomPropertyManager();
     75     ~CustomPropertyManager();
     76 
     77     using PropKey = std::string;
     78 
     79     std::vector<PropKey> getColorProps() const;
     80     skottie::ColorPropertyValue getColor(const PropKey&) const;
     81     bool setColor(const PropKey&, const skottie::ColorPropertyValue&);
     82 
     83     std::vector<PropKey> getOpacityProps() const;
     84     skottie::OpacityPropertyValue getOpacity(const PropKey&) const;
     85     bool setOpacity(const PropKey&, const skottie::OpacityPropertyValue&);
     86 
     87     std::vector<PropKey> getTransformProps() const;
     88     skottie::TransformPropertyValue getTransform(const PropKey&) const;
     89     bool setTransform(const PropKey&, const skottie::TransformPropertyValue&);
     90 
     91     struct MarkerInfo {
     92         std::string name;
     93         float       t0, t1;
     94     };
     95     const std::vector<MarkerInfo>& markers() const { return fMarkers; }
     96 
     97     // Returns a property observer to be attached to an animation builder.
     98     sk_sp<skottie::PropertyObserver> getPropertyObserver() const;
     99 
    100     // Returns a marker observer to be attached to an animation builder.
    101     sk_sp<skottie::MarkerObserver> getMarkerObserver() const;
    102 
    103 private:
    104     class PropertyInterceptor;
    105     class MarkerInterceptor;
    106 
    107     static std::string acceptKey(const char* name) {
    108         static constexpr char kPrefix = '$';
    109 
    110         return (name[0] == kPrefix && name[1] != '\0')
    111             ? std::string(name + 1)
    112             : std::string();
    113     }
    114 
    115     sk_sp<PropertyInterceptor> fPropertyInterceptor;
    116     sk_sp<MarkerInterceptor>   fMarkerInterceptor;
    117 
    118     template <typename T>
    119     using PropGroup = std::vector<std::unique_ptr<T>>;
    120 
    121     template <typename T>
    122     using PropMap = std::unordered_map<PropKey, PropGroup<T>>;
    123 
    124     template <typename T>
    125     std::vector<PropKey> getProps(const PropMap<T>& container) const;
    126 
    127     template <typename V, typename T>
    128     V get(const PropKey&, const PropMap<T>& container) const;
    129 
    130     template <typename V, typename T>
    131     bool set(const PropKey&, const V&, const PropMap<T>& container);
    132 
    133     PropMap<skottie::ColorPropertyHandle>     fColorMap;
    134     PropMap<skottie::OpacityPropertyHandle>   fOpacityMap;
    135     PropMap<skottie::TransformPropertyHandle> fTransformMap;
    136     std::vector<MarkerInfo>                   fMarkers;
    137 };
    138 
    139 } // namespace skottie_utils
    140 
    141 #endif // SkottieUtils_DEFINED
    142