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 SkottieTextAnimator_DEFINED
9#define SkottieTextAnimator_DEFINED
10
11#include "include/core/SkM44.h"
12#include "include/core/SkRefCnt.h"
13#include "modules/skottie/src/SkottiePriv.h"
14#include "modules/skottie/src/SkottieValue.h"
15#include "modules/sksg/include/SkSGScene.h"
16
17#include <memory>
18#include <vector>
19
20namespace skottie {
21namespace internal {
22
23class AnimatablePropertyContainer;
24class AnimationBuilder;
25class RangeSelector;
26
27class TextAnimator final : public SkNVRefCnt<TextAnimator> {
28public:
29 static sk_sp<TextAnimator> Make(const skjson::ObjectValue*,
30 const AnimationBuilder*,
31 AnimatablePropertyContainer* acontainer);
32
33 // Direct mapping of AE properties.
34 struct AnimatedProps {
35 VectorValue position,
36 scale = { 100, 100, 100 },
37 fill_color,
38 stroke_color;
39 // unlike pos/scale which are animated vectors, rotation is separated in each dimension.
40 SkV3 rotation = { 0, 0, 0 };
41 Vec2Value blur = { 0, 0 },
42 line_spacing = { 0, 0 };
43 ScalarValue opacity = 100,
44 tracking = 0;
45 };
46
47 struct ResolvedProps {
48 SkV3 position = { 0, 0, 0 },
49 scale = { 1, 1, 1 },
50 rotation = { 0, 0, 0 };
51 float opacity = 1,
52 tracking = 0;
53 SkColor fill_color = SK_ColorTRANSPARENT,
54 stroke_color = SK_ColorTRANSPARENT;
55 SkV2 blur = { 0, 0 },
56 line_spacing = { 0, 0 };
57 };
58
59 struct AnimatedPropsModulator {
60 ResolvedProps props; // accumulates properties across *all* animators
61 float coverage; // accumulates range selector coverage for a given animator
62 };
63 using ModulatorBuffer = std::vector<AnimatedPropsModulator>;
64
65 // Domain maps describe how a given index domain (words, lines, etc) relates
66 // to the full fragment index range.
67 //
68 // Each domain[i] represents a [domain[i].fOffset.. domain[i].fOffset+domain[i].fCount-1]
69 // fragment subset.
70 struct DomainSpan {
71 size_t fOffset,
72 fCount;
73 float fAdvance, // cumulative advance for all fragments in span
74 fAscent; // max ascent for all fragments in span
75 };
76 using DomainMap = std::vector<DomainSpan>;
77
78 struct DomainMaps {
79 DomainMap fNonWhitespaceMap,
80 fWordsMap,
81 fLinesMap;
82 };
83
84 void modulateProps(const DomainMaps&, ModulatorBuffer&) const;
85
86 bool hasBlur() const { return fHasBlur; }
87
88 bool requiresAnchorPoint() const { return fRequiresAnchorPoint; }
89
90private:
91 TextAnimator(std::vector<sk_sp<RangeSelector>>&&,
92 const skjson::ObjectValue&,
93 const AnimationBuilder*,
94 AnimatablePropertyContainer*);
95
96 ResolvedProps modulateProps(const ResolvedProps&, float amount) const;
97
98 const std::vector<sk_sp<RangeSelector>> fSelectors;
99
100 AnimatedProps fTextProps;
101 bool fHasFillColor : 1,
102 fHasStrokeColor : 1,
103 fHasBlur : 1,
104 fRequiresAnchorPoint : 1; // animator sensitive to transform origin?
105};
106
107} // namespace internal
108} // namespace skottie
109
110#endif // SkottieTextAnimator_DEFINED
111