[skottie] Add support for text animator blur

In adition to transforms/opacity/etc, text animators can target
per-glyph opacity.

Change-Id: I6ab63a6e49a64beaf63fc955f0b672a5b8ba84ba
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/272886
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Florin Malita <fmalita@chromium.org>
This commit is contained in:
Florin Malita 2020-02-23 19:00:01 -05:00 committed by Skia Commit-Bot
parent cc5415a8ce
commit 9642b31a71
9 changed files with 36 additions and 14 deletions

View File

@ -38,6 +38,9 @@ class Transform;
namespace skottie {
namespace internal {
// Close-enough to AE.
static constexpr float kBlurSizeToSigma = 0.3f;
class TextAdapter;
class TransformAdapter2D;
class TransformAdapter3D;

View File

@ -60,9 +60,7 @@ private:
fDropShadow->setOffset(SkVector::Make( fDistance * SkScalarCos(rad),
-fDistance * SkScalarSin(rad)));
// Close enough to AE.
static constexpr SkScalar kSoftnessToSigmaFactor = 0.3f;
const auto sigma = fSoftness * kSoftnessToSigmaFactor;
const auto sigma = fSoftness * kBlurSizeToSigma;
fDropShadow->setSigma(SkVector::Make(sigma, sigma));
fDropShadow->setMode(SkToBool(fShdwOnly)

View File

@ -56,9 +56,7 @@ private:
const auto dim_index = SkTPin<size_t>(static_cast<size_t>(fDimensions),
1, SK_ARRAY_COUNT(kDimensionsMap)) - 1;
// Close enough to AE.
static constexpr SkScalar kBlurrinessToSigmaFactor = 0.3f;
const auto sigma = fBlurriness * kBlurrinessToSigmaFactor;
const auto sigma = fBlurriness * kBlurSizeToSigma;
fBlur->setSigma({ sigma * kDimensionsMap[dim_index].x(),
sigma * kDimensionsMap[dim_index].y() });

View File

@ -48,8 +48,7 @@ protected:
fMaskSigma = 0;
fMaskFilter = nullptr;
} else {
static constexpr float kFeatherToSigma = 0.3f; // close enough to AE
fMaskSigma = std::max(fFeather, 0.0f) * kFeatherToSigma;
fMaskSigma = std::max(fFeather, 0.0f) * kBlurSizeToSigma;
// The gradient is inverted between non-blurred and blurred (latter requires dstOut).
const SkColor c0 = fMaskSigma > 0 ? 0xffffffff : 0x00000000,

View File

@ -16,6 +16,7 @@
#include "modules/sksg/include/SkSGGroup.h"
#include "modules/sksg/include/SkSGPaint.h"
#include "modules/sksg/include/SkSGRect.h"
#include "modules/sksg/include/SkSGRenderEffect.h"
#include "modules/sksg/include/SkSGText.h"
#include "modules/sksg/include/SkSGTransform.h"
@ -69,6 +70,7 @@ sk_sp<TextAdapter> TextAdapter::Make(const skjson::ObjectValue& jlayer,
for (const skjson::ObjectValue* janimator : *janimators) {
if (auto animator = TextAnimator::Make(janimator, abuilder, adapter.get())) {
adapter->fHasBlur |= animator->hasBlur();
adapter->fAnimators.push_back(std::move(animator));
}
}
@ -125,6 +127,12 @@ void TextAdapter::addFragment(const Shaper::Fragment& frag) {
? sksg::Group::Make(std::move(draws))
: std::move(draws[0]);
if (fHasBlur) {
// Optional blur effect.
rec.fBlur = sksg::BlurImageFilter::Make();
draws_node = sksg::ImageFilterEffect::Make(std::move(draws_node), rec.fBlur);
}
fRoot->addChild(sksg::TransformEffect::Make(std::move(draws_node), rec.fMatrixNode));
fFragments.push_back(std::move(rec));
}
@ -307,6 +315,9 @@ void TextAdapter::pushPropsToFragment(const TextAnimator::ResolvedProps& props,
if (rec.fStrokeColorNode) {
rec.fStrokeColorNode->setColor(scale_alpha(props.stroke_color, props.opacity));
}
if (rec.fBlur) {
rec.fBlur->setSigma(props.blur * kBlurSizeToSigma);
}
}
void TextAdapter::adjustLineTracking(const TextAnimator::ModulatorBuffer& buf,

View File

@ -18,6 +18,7 @@
class SkFontMgr;
namespace sksg {
class BlurImageFilter;
class Group;
template <typename T>
class Matrix;
@ -50,6 +51,7 @@ private:
sk_sp<sksg::Matrix<SkM44>> fMatrixNode;
sk_sp<sksg::Color> fFillColorNode,
fStrokeColorNode;
sk_sp<sksg::BlurImageFilter> fBlur;
};
void reshape();
@ -89,6 +91,7 @@ private:
};
TextValueTracker fText;
bool fHasBlur = false; // tracks whether any animator targets blur
};
} // namespace internal

View File

@ -123,6 +123,9 @@ TextAnimator::ResolvedProps TextAnimator::modulateProps(const ResolvedProps& pro
modulated_props.scale *= SkV3{1,1,1} +
(ValueTraits<VectorValue>::As<SkV3>(fTextProps.scale) * 0.01f - SkV3{1,1,1}) * amount;
// ... as does blur
modulated_props.blur += ValueTraits<VectorValue>::As<SkVector>(fTextProps.blur) * amount;
const auto lerp_color = [](SkColor c0, SkColor c1, float t) {
const auto c0_4f = SkNx_cast<float>(Sk4b::Load(&c0)),
c1_4f = SkNx_cast<float>(Sk4b::Load(&c1)),
@ -167,6 +170,7 @@ TextAnimator::TextAnimator(std::vector<sk_sp<RangeSelector>>&& selectors,
fHasFillColor = acontainer->bind(*abuilder, jprops["fc"], &fTextProps.fill_color );
fHasStrokeColor = acontainer->bind(*abuilder, jprops["sc"], &fTextProps.stroke_color);
fHasBlur = acontainer->bind(*abuilder, jprops["bl"], &fTextProps.blur );
}
} // namespace internal

View File

@ -35,7 +35,8 @@ public:
VectorValue position,
scale = { 100, 100, 100 },
fill_color,
stroke_color;
stroke_color,
blur;
// unlike pos/scale which are animated vectors, rotation is separated in each dimension.
SkV3 rotation = { 0, 0, 0 };
ScalarValue opacity = 100,
@ -50,6 +51,7 @@ public:
tracking = 0;
SkColor fill_color = SK_ColorTRANSPARENT,
stroke_color = SK_ColorTRANSPARENT;
SkVector blur = { 0, 0 };
};
struct AnimatedPropsModulator {
@ -76,6 +78,8 @@ public:
void modulateProps(const DomainMaps&, ModulatorBuffer&) const;
bool hasBlur() const { return fHasBlur; }
private:
TextAnimator(std::vector<sk_sp<RangeSelector>>&&,
const skjson::ObjectValue&,
@ -88,7 +92,8 @@ private:
AnimatedProps fTextProps;
bool fHasFillColor : 1,
fHasStrokeColor : 1;
fHasStrokeColor : 1,
fHasBlur : 1;
};
} // namespace internal

File diff suppressed because one or more lines are too long