/* * 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