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