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/SkScalar.h" 18 #include "include/core/SkSpan.h" 19 #include "include/core/SkString.h" 20 #include "include/core/SkTypeface.h" 21 #include "include/private/base/SkAPI.h" 22 #include "include/utils/SkTextUtils.h" 23 #include "modules/skottie/include/TextShaper.h" 24 25 #include <cstddef> 26 #include <cstdint> 27 #include <functional> 28 #include <limits> 29 #include <memory> 30 #include <utility> 31 32 class SkCanvas; 33 34 namespace sksg { 35 36 class Color; 37 class OpacityEffect; 38 39 } // namespace sksg 40 41 namespace skottie { 42 43 using ColorPropertyValue = SkColor; 44 using OpacityPropertyValue = float; 45 46 enum class TextPaintOrder : uint8_t { 47 kFillStroke, 48 kStrokeFill, 49 }; 50 51 // Optional callback invoked when drawing text layers. 52 // Allows clients to render custom text decorations. 53 class GlyphDecorator : public SkRefCnt { 54 public: 55 struct GlyphInfo { 56 SkRect fBounds; // visual glyph bounds 57 SkMatrix fMatrix; // glyph matrix 58 size_t fCluster; // cluster index in the original text string 59 float fAdvance; // horizontal glyph advance 60 }; 61 62 struct TextInfo { 63 SkSpan<const GlyphInfo> fGlyphs; 64 float fScale; // Additional font scale applied by auto-sizing. 65 }; 66 67 virtual void onDecorate(SkCanvas*, const TextInfo&) = 0; 68 }; 69 70 struct TextPropertyValue { 71 sk_sp<SkTypeface> fTypeface; 72 SkString fText; 73 float fTextSize = 0, 74 fMinTextSize = 0, // when auto-sizing 75 fMaxTextSize = std::numeric_limits<float>::max(), // when auto-sizing 76 fStrokeWidth = 0, 77 fLineHeight = 0, 78 fLineShift = 0, 79 fAscent = 0; 80 size_t fMaxLines = 0; // when auto-sizing 81 SkTextUtils::Align fHAlign = SkTextUtils::kLeft_Align; 82 Shaper::VAlign fVAlign = Shaper::VAlign::kTop; 83 Shaper::ResizePolicy fResize = Shaper::ResizePolicy::kNone; 84 Shaper::LinebreakPolicy fLineBreak = Shaper::LinebreakPolicy::kExplicit; 85 Shaper::Direction fDirection = Shaper::Direction::kLTR; 86 Shaper::Capitalization fCapitalization = Shaper::Capitalization::kNone; 87 SkRect fBox = SkRect::MakeEmpty(); 88 SkColor fFillColor = SK_ColorTRANSPARENT, 89 fStrokeColor = SK_ColorTRANSPARENT; 90 TextPaintOrder fPaintOrder = TextPaintOrder::kFillStroke; 91 SkPaint::Join fStrokeJoin = SkPaint::Join::kMiter_Join; 92 bool fHasFill = false, 93 fHasStroke = false; 94 sk_sp<GlyphDecorator> fDecorator; 95 // The locale to be used for text shaping, in BCP47 form. This includes 96 // support for RFC6067 extensions, so one can e.g. select strict line 97 // breaking rules for certain scripts: ja-u-lb-strict. 98 // Pass an empty string to use the system locale. 99 SkString fLocale; 100 // Optional font family name, to be passed to the font manager for 101 // fallback. 102 SkString fFontFamily; 103 104 bool operator==(const TextPropertyValue& other) const; 105 bool operator!=(const TextPropertyValue& other) const; 106 }; 107 108 struct TransformPropertyValue { 109 SkPoint fAnchorPoint, 110 fPosition; 111 SkVector fScale; 112 SkScalar fRotation, 113 fSkew, 114 fSkewAxis; 115 116 bool operator==(const TransformPropertyValue& other) const; 117 bool operator!=(const TransformPropertyValue& other) const; 118 }; 119 120 namespace internal { class SceneGraphRevalidator; } 121 122 /** 123 * Property handles are adapters between user-facing AE model/values 124 * and the internal scene-graph representation. 125 */ 126 template <typename ValueT, typename NodeT> 127 class SK_API PropertyHandle final { 128 public: 129 explicit PropertyHandle(sk_sp<NodeT>); PropertyHandle(sk_sp<NodeT> node,sk_sp<internal::SceneGraphRevalidator> revalidator)130 PropertyHandle(sk_sp<NodeT> node, sk_sp<internal::SceneGraphRevalidator> revalidator) 131 : fNode(std::move(node)) 132 , fRevalidator(std::move(revalidator)) {} 133 ~PropertyHandle(); 134 135 PropertyHandle(const PropertyHandle&); 136 137 ValueT get() const; 138 void set(const ValueT&); 139 140 private: 141 const sk_sp<NodeT> fNode; 142 const sk_sp<internal::SceneGraphRevalidator> fRevalidator; 143 }; 144 145 namespace internal { 146 147 class TextAdapter; 148 class TransformAdapter2D; 149 150 } // namespace internal 151 152 using ColorPropertyHandle = PropertyHandle<ColorPropertyValue, 153 sksg::Color>; 154 using OpacityPropertyHandle = PropertyHandle<OpacityPropertyValue, 155 sksg::OpacityEffect>; 156 using TextPropertyHandle = PropertyHandle<TextPropertyValue, 157 internal::TextAdapter>; 158 using TransformPropertyHandle = PropertyHandle<TransformPropertyValue, 159 internal::TransformAdapter2D>; 160 161 /** 162 * A PropertyObserver can be used to track and manipulate certain properties of "interesting" 163 * Lottie nodes. 164 * 165 * When registered with an animation builder, PropertyObserver receives notifications for 166 * various properties of layer and shape nodes. The |node_name| argument corresponds to the 167 * name ("nm") node property. 168 */ 169 class SK_API PropertyObserver : public SkRefCnt { 170 public: 171 enum class NodeType {COMPOSITION, LAYER, EFFECT, OTHER}; 172 173 template <typename T> 174 using LazyHandle = std::function<std::unique_ptr<T>()>; 175 176 virtual void onColorProperty (const char node_name[], 177 const LazyHandle<ColorPropertyHandle>&); 178 virtual void onOpacityProperty (const char node_name[], 179 const LazyHandle<OpacityPropertyHandle>&); 180 virtual void onTextProperty (const char node_name[], 181 const LazyHandle<TextPropertyHandle>&); 182 virtual void onTransformProperty(const char node_name[], 183 const LazyHandle<TransformPropertyHandle>&); 184 virtual void onEnterNode(const char node_name[], NodeType node_type); 185 virtual void onLeavingNode(const char node_name[], NodeType node_type); 186 }; 187 188 } // namespace skottie 189 190 #endif // SkottieProperty_DEFINED 191