[skottie] Add support for multiple range selectors

Text animators can have more than one range selector.

(depends on https://github.com/bodymovin/bodymovin-extension/pull/21)

TBR=
Change-Id: Id7f73386853f0e0f9e3c0f15d5a87ec1653ba873
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/234319
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@chromium.org>
This commit is contained in:
Florin Malita 2019-08-13 12:37:41 -04:00 committed by Skia Commit-Bot
parent 143987ef8f
commit feacb0fb34
3 changed files with 40 additions and 10 deletions

View File

@ -182,6 +182,22 @@ sk_sp<RangeSelector> RangeSelector::Make(const skjson::ObjectValue* jrange,
return nullptr; return nullptr;
} }
enum : int32_t {
kRange_SelectorType = 0,
kExpression_SelectorType = 1,
// kWiggly_SelectorType = ? (not exported)
};
{
const auto type = ParseDefault<int>((*jrange)["t"], kRange_SelectorType);
if (type != kRange_SelectorType) {
abuilder->log(Logger::Level::kWarning, nullptr,
"Ignoring unsupported selector type '%d'", type);
return nullptr;
}
}
static constexpr Units gUnitMap[] = { static constexpr Units gUnitMap[] = {
Units::kPercentage, // 'r': 1 Units::kPercentage, // 'r': 1
Units::kIndex, // 'r': 2 Units::kIndex, // 'r': 2

View File

@ -40,7 +40,7 @@ namespace internal {
* "t": { // text node * "t": { // text node
* "a": [ // animators list * "a": [ // animators list
* { // animator node * { // animator node
* "s": {...}, // selector node (TODO) * "s": {...}, // selector node
* "a": { // animator properties node * "a": { // animator properties node
* "a": {} // optional anchor point value * "a": {} // optional anchor point value
* "p": {}, // optional position value * "p": {}, // optional position value
@ -63,26 +63,39 @@ sk_sp<TextAnimator> TextAnimator::Make(const skjson::ObjectValue* janimator,
return nullptr; return nullptr;
} }
const skjson::ObjectValue* jprops = (*janimator)["a"];
if (!jprops) {
return nullptr;
}
std::vector<sk_sp<RangeSelector>> selectors; std::vector<sk_sp<RangeSelector>> selectors;
if (const skjson::ObjectValue* jselector = (*janimator)["s"]) {
// Single range selector for now. // Depending on compat mode and whether more than one selector is present,
if (auto sel = RangeSelector::Make(jselector, abuilder)) { // BM exports either an array or a single object.
if (const skjson::ArrayValue* jselectors = (*janimator)["s"]) {
selectors.reserve(jselectors->size());
for (const skjson::ObjectValue* jselector : *jselectors) {
if (auto sel = RangeSelector::Make(*jselector, abuilder)) {
selectors.push_back(std::move(sel));
}
}
} else {
if (auto sel = RangeSelector::Make((*janimator)["s"], abuilder)) {
selectors.reserve(1); selectors.reserve(1);
selectors.push_back(std::move(sel)); selectors.push_back(std::move(sel));
} }
} }
const skjson::ObjectValue* jprops = (*janimator)["a"]; return sk_sp<TextAnimator>(new TextAnimator(std::move(selectors), *jprops, abuilder));
return jprops
? sk_sp<TextAnimator>(new TextAnimator(std::move(selectors), *jprops, abuilder))
: nullptr;
} }
void TextAnimator::modulateProps(const DomainMaps& maps, ModulatorBuffer& buf) const { void TextAnimator::modulateProps(const DomainMaps& maps, ModulatorBuffer& buf) const {
// No selectors -> full coverage.
const auto initial_coverage = fSelectors.empty() ? 1.f : 0.f;
// Coverage is scoped per animator. // Coverage is scoped per animator.
for (auto& mod : buf) { for (auto& mod : buf) {
mod.coverage = 0; mod.coverage = initial_coverage;
} }
// Accumulate selector coverage. // Accumulate selector coverage.

File diff suppressed because one or more lines are too long