1 /* 2 * Copyright 2019 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 SkottieTextAdapter_DEFINED 9 #define SkottieTextAdapter_DEFINED 10 11 #include "modules/skottie/src/animator/Animator.h" 12 #include "modules/skottie/src/text/Font.h" 13 #include "modules/skottie/src/text/SkottieShaper.h" 14 #include "modules/skottie/src/text/TextAnimator.h" 15 #include "modules/skottie/src/text/TextValue.h" 16 17 #include <vector> 18 19 class SkFontMgr; 20 21 namespace sksg { 22 class BlurImageFilter; 23 class Group; 24 template <typename T> 25 class Matrix; 26 } // namespace sksg 27 28 namespace skottie { 29 namespace internal { 30 31 class TextAdapter final : public AnimatablePropertyContainer { 32 public: 33 static sk_sp<TextAdapter> Make(const skjson::ObjectValue&, 34 const AnimationBuilder*, 35 sk_sp<SkFontMgr>, 36 sk_sp<CustomFont::GlyphCompMapper>, 37 sk_sp<Logger>); 38 39 ~TextAdapter() override; 40 node()41 const sk_sp<sksg::Group>& node() const { return fRoot; } 42 getText()43 const TextValue& getText() const { return fText.fCurrentValue; } 44 void setText(const TextValue&); 45 46 protected: 47 void onSync() override; 48 49 private: 50 class GlyphDecoratorNode; 51 52 enum class AnchorPointGrouping : uint8_t { 53 kCharacter, 54 kWord, 55 kLine, 56 kAll, 57 }; 58 59 TextAdapter(sk_sp<SkFontMgr>, 60 sk_sp<CustomFont::GlyphCompMapper>, 61 sk_sp<Logger>, 62 AnchorPointGrouping); 63 64 struct FragmentRec { 65 SkPoint fOrigin; // fragment position 66 67 const Shaper::ShapedGlyphs* fGlyphs = nullptr; 68 sk_sp<sksg::Matrix<SkM44>> fMatrixNode; 69 sk_sp<sksg::Color> fFillColorNode, 70 fStrokeColorNode; 71 sk_sp<sksg::BlurImageFilter> fBlur; 72 73 float fAdvance, // used for transform anchor point calculations 74 fAscent; // ^ 75 }; 76 77 void reshape(); 78 void addFragment(Shaper::Fragment&, sksg::Group* container); 79 void buildDomainMaps(const Shaper::Result&); 80 std::vector<sk_sp<sksg::RenderNode>> buildGlyphCompNodes(Shaper::Fragment&) const; 81 82 void pushPropsToFragment(const TextAnimator::ResolvedProps&, const FragmentRec&, 83 const SkV2& frag_offset, const SkV2& grouping_alignment, 84 const TextAnimator::DomainSpan*) const; 85 86 SkV2 fragmentAnchorPoint(const FragmentRec&, const SkV2&, 87 const TextAnimator::DomainSpan*) const; 88 uint32_t shaperFlags() const; 89 90 SkM44 fragmentMatrix(const TextAnimator::ResolvedProps&, const FragmentRec&, const SkV2&) const; 91 92 const sk_sp<sksg::Group> fRoot; 93 const sk_sp<SkFontMgr> fFontMgr; 94 const sk_sp<CustomFont::GlyphCompMapper> fCustomGlyphMapper; 95 sk_sp<Logger> fLogger; 96 const AnchorPointGrouping fAnchorPointGrouping; 97 98 std::vector<sk_sp<TextAnimator>> fAnimators; 99 std::vector<FragmentRec> fFragments; 100 TextAnimator::DomainMaps fMaps; 101 102 // Helps detect external value changes. 103 struct TextValueTracker { 104 TextValue fCurrentValue; 105 hasChangedTextValueTracker106 bool hasChanged() const { 107 if (fCurrentValue != fPrevValue) { 108 fPrevValue = fCurrentValue; 109 return true; 110 } 111 return false; 112 } 113 114 const TextValue* operator->() const { return &fCurrentValue; } 115 116 private: 117 mutable TextValue fPrevValue; 118 }; 119 120 TextValueTracker fText; 121 Vec2Value fGroupingAlignment = {0,0}; 122 float fTextShapingScale = 1; // size adjustment from auto-scaling 123 124 // Optional text path. 125 struct PathInfo; 126 std::unique_ptr<PathInfo> fPathInfo; 127 128 bool fHasBlurAnimator : 1, 129 fRequiresAnchorPoint : 1, 130 fRequiresLineAdjustments : 1; 131 }; 132 133 } // namespace internal 134 } // namespace skottie 135 136 #endif // SkottieTextAdapter_DEFINED 137