blob: 16aa6a7f68a9bf3c43d8370ca814d2468acff17c [file] [log] [blame]
/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkottiePriv.h"
#include "SkJSON.h"
#include "SkottieJson.h"
#include "SkottieValue.h"
#include "SkSGColor.h"
#include "SkSGColorFilter.h"
namespace skottie {
namespace internal {
namespace {
sk_sp<sksg::RenderNode> AttachFillLayerEffect(const skjson::ArrayValue* jeffect_props,
const AnimationBuilder* abuilder,
AnimatorScope* ascope,
sk_sp<sksg::RenderNode> layer) {
if (!jeffect_props) return nullptr;
// Effect properties are index-based.
enum {
kFillMask_Index = 0,
kAllMasks_Index = 1,
kColor_Index = 2,
kInvert_Index = 3,
kHFeather_Index = 4,
kVFeather_Index = 5,
kOpacity_Index = 6,
kMax_Index = kOpacity_Index,
};
if (jeffect_props->size() <= kMax_Index) {
return nullptr;
}
const skjson::ObjectValue* color_prop = (*jeffect_props)[ kColor_Index];
const skjson::ObjectValue* opacity_prop = (*jeffect_props)[kOpacity_Index];
if (!color_prop || !opacity_prop) {
return nullptr;
}
sk_sp<sksg::Color> color_node = abuilder->attachColor(*color_prop, ascope, "v");
if (!color_node) {
return nullptr;
}
abuilder->bindProperty<ScalarValue>((*opacity_prop)["v"], ascope,
[color_node](const ScalarValue& o) {
const auto c = color_node->getColor();
const auto a = sk_float_round2int_no_saturate(SkTPin(o, 0.0f, 1.0f) * 255);
color_node->setColor(SkColorSetA(c, a));
});
return sksg::ColorModeFilter::Make(std::move(layer),
std::move(color_node),
SkBlendMode::kSrcIn);
}
} // namespace
sk_sp<sksg::RenderNode> AnimationBuilder::attachLayerEffects(const skjson::ArrayValue& jeffects,
AnimatorScope* ascope,
sk_sp<sksg::RenderNode> layer) const {
for (const skjson::ObjectValue* jeffect : jeffects) {
if (!jeffect) continue;
switch (const auto ty = ParseDefault<int>((*jeffect)["ty"], -1)) {
case 21: // Fill
layer = AttachFillLayerEffect((*jeffect)["ef"], this, ascope, std::move(layer));
break;
default:
this->log(Logger::Level::kWarning, nullptr, "Unsupported layer effect type: %d.", ty);
break;
}
if (!layer) {
this->log(Logger::Level::kError, jeffect, "Invalid layer effect.");
return nullptr;
}
}
return layer;
}
} // namespace internal
} // namespace skottie