blob: 122f5e7861a4159a36c8ad5d8fb012970492df32 [file] [log] [blame]
/*
* Copyright 2019 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkottieTextAnimator_DEFINED
#define SkottieTextAnimator_DEFINED
#include "include/core/SkM44.h"
#include "include/core/SkRefCnt.h"
#include "modules/skottie/src/SkottiePriv.h"
#include "modules/skottie/src/SkottieValue.h"
#include <memory>
#include <vector>
namespace skottie {
namespace internal {
class AnimatablePropertyContainer;
class AnimationBuilder;
class RangeSelector;
class TextAnimator final : public SkNVRefCnt<TextAnimator> {
public:
static sk_sp<TextAnimator> Make(const skjson::ObjectValue*,
const AnimationBuilder*,
AnimatablePropertyContainer* acontainer);
// Direct mapping of AE properties.
struct AnimatedProps {
VectorValue position,
scale = { 100, 100, 100 };
ColorValue fill_color,
stroke_color;
// unlike pos/scale which are animated vectors, rotation is separated in each dimension.
SkV3 rotation = { 0, 0, 0 };
Vec2Value blur = { 0, 0 },
line_spacing = { 0, 0 };
ScalarValue opacity = 100,
fill_opacity = 100,
stroke_opacity = 100,
tracking = 0,
stroke_width = 0;
};
struct ResolvedProps {
SkV3 position = { 0, 0, 0 },
scale = { 1, 1, 1 },
rotation = { 0, 0, 0 };
float opacity = 1,
tracking = 0,
stroke_width = 0;
SkColor fill_color = SK_ColorTRANSPARENT,
stroke_color = SK_ColorTRANSPARENT;
SkV2 blur = { 0, 0 },
line_spacing = { 0, 0 };
};
struct AnimatedPropsModulator {
ResolvedProps props; // accumulates properties across *all* animators
float coverage; // accumulates range selector coverage for a given animator
};
using ModulatorBuffer = std::vector<AnimatedPropsModulator>;
// Domain maps describe how a given index domain (words, lines, etc) relates
// to the full fragment index range.
//
// Each domain[i] represents a [domain[i].fOffset.. domain[i].fOffset+domain[i].fCount-1]
// fragment subset.
struct DomainSpan {
size_t fOffset,
fCount;
float fAdvance, // cumulative advance for all fragments in span
fAscent; // max ascent for all fragments in span
};
using DomainMap = std::vector<DomainSpan>;
struct DomainMaps {
DomainMap fNonWhitespaceMap,
fWordsMap,
fLinesMap;
};
void modulateProps(const DomainMaps&, ModulatorBuffer&) const;
bool hasBlur() const { return fHasBlur; }
bool requiresAnchorPoint() const { return fRequiresAnchorPoint; }
bool requiresLineAdjustments() const { return fRequiresLineAdjustments; }
private:
TextAnimator(std::vector<sk_sp<RangeSelector>>&&,
const skjson::ObjectValue&,
const AnimationBuilder*,
AnimatablePropertyContainer*);
ResolvedProps modulateProps(const ResolvedProps&, float amount) const;
const std::vector<sk_sp<RangeSelector>> fSelectors;
AnimatedProps fTextProps;
bool fHasFillColor : 1,
fHasStrokeColor : 1,
fHasFillOpacity : 1,
fHasStrokeOpacity : 1,
fHasOpacity : 1,
fHasBlur : 1,
fRequiresAnchorPoint : 1, // animator sensitive to transform origin?
fRequiresLineAdjustments : 1; // animator effects line-wide fragment adjustments
};
} // namespace internal
} // namespace skottie
#endif // SkottieTextAnimator_DEFINED