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