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 SkottieProperty_DEFINED 9 #define SkottieProperty_DEFINED 10 11 #include "include/core/SkColor.h" 12 #include "include/core/SkMatrix.h" 13 #include "include/core/SkPaint.h" 14 #include "include/core/SkPoint.h" 15 #include "include/core/SkRect.h" 16 #include "include/core/SkRefCnt.h" 17 #include "include/core/SkTypeface.h" 18 #include "include/utils/SkTextUtils.h" 19 #include "modules/skottie/src/text/SkottieShaper.h" 20 21 #include <functional> 22 #include <vector> 23 24 class SkCanvas; 25 26 namespace sksg { 27 28 class Color; 29 class OpacityEffect; 30 31 } // namespace sksg 32 33 namespace skottie { 34 35 using ColorPropertyValue = SkColor; 36 using OpacityPropertyValue = float; 37 38 enum class TextPaintOrder : uint8_t { 39 kFillStroke, 40 kStrokeFill, 41 }; 42 43 // EXPERIMENTAL 44 // Optional callback invoked when drawing text layers. 45 // Allows clients to render custom text decorations. 46 class GlyphDecorator : public SkRefCnt { 47 public: 48 struct GlyphInfo { 49 SkRect fBounds; // visual glyph bounds 50 SkMatrix fMatrix; // glyph matrix 51 size_t fCluster; // cluster index in the original text string 52 }; 53 54 virtual void onDecorate(SkCanvas*, const GlyphInfo[], size_t size) = 0; 55 }; 56 57 struct TextPropertyValue { 58 sk_sp<SkTypeface> fTypeface; 59 SkString fText; 60 float fTextSize = 0, 61 fMinTextSize = 0, // when auto-sizing 62 fMaxTextSize = std::numeric_limits<float>::max(), // when auto-sizing 63 fStrokeWidth = 0, 64 fLineHeight = 0, 65 fLineShift = 0, 66 fAscent = 0; 67 size_t fMaxLines = 0; // when auto-sizing 68 SkTextUtils::Align fHAlign = SkTextUtils::kLeft_Align; 69 Shaper::VAlign fVAlign = Shaper::VAlign::kTop; 70 Shaper::ResizePolicy fResize = Shaper::ResizePolicy::kNone; 71 Shaper::LinebreakPolicy fLineBreak = Shaper::LinebreakPolicy::kExplicit; 72 Shaper::Direction fDirection = Shaper::Direction::kLTR; 73 Shaper::Capitalization fCapitalization = Shaper::Capitalization::kNone; 74 SkRect fBox = SkRect::MakeEmpty(); 75 SkColor fFillColor = SK_ColorTRANSPARENT, 76 fStrokeColor = SK_ColorTRANSPARENT; 77 TextPaintOrder fPaintOrder = TextPaintOrder::kFillStroke; 78 SkPaint::Join fStrokeJoin = SkPaint::Join::kMiter_Join; 79 bool fHasFill = false, 80 fHasStroke = false; 81 sk_sp<GlyphDecorator> fDecorator; 82 83 bool operator==(const TextPropertyValue& other) const; 84 bool operator!=(const TextPropertyValue& other) const; 85 }; 86 87 struct TransformPropertyValue { 88 SkPoint fAnchorPoint, 89 fPosition; 90 SkVector fScale; 91 SkScalar fRotation, 92 fSkew, 93 fSkewAxis; 94 95 bool operator==(const TransformPropertyValue& other) const; 96 bool operator!=(const TransformPropertyValue& other) const; 97 }; 98 99 namespace internal { class AnimationBuilder; } 100 101 /** 102 * Property handles are adapters between user-facing AE model/values 103 * and the internal scene-graph representation. 104 */ 105 template <typename ValueT, typename NodeT> 106 class SK_API PropertyHandle final { 107 public: PropertyHandle(sk_sp<NodeT> node)108 explicit PropertyHandle(sk_sp<NodeT> node) : fNode(std::move(node)) {} 109 ~PropertyHandle(); 110 111 ValueT get() const; 112 void set(const ValueT&); 113 114 private: 115 const sk_sp<NodeT> fNode; 116 }; 117 118 namespace internal { 119 120 class TextAdapter; 121 class TransformAdapter2D; 122 123 } // namespace internal 124 125 using ColorPropertyHandle = PropertyHandle<ColorPropertyValue, 126 sksg::Color>; 127 using OpacityPropertyHandle = PropertyHandle<OpacityPropertyValue, 128 sksg::OpacityEffect>; 129 using TextPropertyHandle = PropertyHandle<TextPropertyValue, 130 internal::TextAdapter>; 131 using TransformPropertyHandle = PropertyHandle<TransformPropertyValue, 132 internal::TransformAdapter2D>; 133 134 /** 135 * A PropertyObserver can be used to track and manipulate certain properties of "interesting" 136 * Lottie nodes. 137 * 138 * When registered with an animation builder, PropertyObserver receives notifications for 139 * various properties of layer and shape nodes. The |node_name| argument corresponds to the 140 * name ("nm") node property. 141 */ 142 class SK_API PropertyObserver : public SkRefCnt { 143 public: 144 enum class NodeType {COMPOSITION, LAYER, EFFECT, OTHER}; 145 146 template <typename T> 147 using LazyHandle = std::function<std::unique_ptr<T>()>; 148 149 virtual void onColorProperty (const char node_name[], 150 const LazyHandle<ColorPropertyHandle>&); 151 virtual void onOpacityProperty (const char node_name[], 152 const LazyHandle<OpacityPropertyHandle>&); 153 virtual void onTextProperty (const char node_name[], 154 const LazyHandle<TextPropertyHandle>&); 155 virtual void onTransformProperty(const char node_name[], 156 const LazyHandle<TransformPropertyHandle>&); 157 virtual void onEnterNode(const char node_name[], NodeType node_type); 158 virtual void onLeavingNode(const char node_name[], NodeType node_type); 159 }; 160 161 } // namespace skottie 162 163 #endif // SkottieProperty_DEFINED 164