| /* | |
| * Copyright 2023 Google LLC | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "modules/skottie/include/SlotManager.h" | |
| #include "include/core/SkImage.h" | |
| #include "include/core/SkM44.h" | |
| #include "include/core/SkMatrix.h" | |
| #include "include/core/SkSamplingOptions.h" | |
| #include "modules/skottie/include/SkottieProperty.h" | |
| #include "modules/skottie/src/SkottiePriv.h" | |
| #include "modules/skottie/src/animator/Animator.h" | |
| #include "modules/skottie/src/text/TextAdapter.h" | |
| #include "modules/skresources/include/SkResources.h" | |
| #include <utility> | |
| class skottie::SlotManager::ImageAssetProxy final : public skresources::ImageAsset { | |
| public: | |
| explicit ImageAssetProxy(sk_sp<skresources::ImageAsset> asset) | |
| : fImageAsset(std::move(asset)) {} | |
| // always returns true to force the FootageLayer to always redraw in case asset is swapped | |
| bool isMultiFrame() override { return true; } | |
| FrameData getFrameData(float t) override { | |
| if (fImageAsset) { | |
| return fImageAsset->getFrameData(t); | |
| } | |
| return {nullptr , SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNearest), | |
| SkMatrix::I(), SizeFit::kCenter}; | |
| } | |
| void setImageAsset (sk_sp<skresources::ImageAsset> asset) { | |
| fImageAsset = std::move(asset); | |
| } | |
| sk_sp<const skresources::ImageAsset> getImageAsset() const { | |
| return fImageAsset; | |
| } | |
| private: | |
| sk_sp<skresources::ImageAsset> fImageAsset; | |
| }; | |
| skottie::SlotManager::SlotManager(sk_sp<skottie::internal::SceneGraphRevalidator> revalidator) | |
| : fRevalidator(std::move(revalidator)) {} | |
| skottie::SlotManager::~SlotManager() = default; | |
| bool skottie::SlotManager::setColorSlot(const SlotID& slotID, SkColor c) { | |
| auto c4f = SkColor4f::FromColor(c); | |
| ColorValue v{c4f.fR, c4f.fG, c4f.fB, c4f.fA}; | |
| const auto valueGroup = fColorMap.find(slotID); | |
| if (valueGroup) { | |
| for (auto& cPair : *valueGroup) { | |
| *(cPair.value) = v; | |
| cPair.adapter->onSync(); | |
| } | |
| fRevalidator->revalidate(); | |
| return true; | |
| } | |
| return false; | |
| } | |
| bool skottie::SlotManager::setImageSlot(const SlotID& slotID, | |
| const sk_sp<skresources::ImageAsset>& i) { | |
| const auto imageGroup = fImageMap.find(slotID); | |
| if (imageGroup) { | |
| for (auto& imageAsset : *imageGroup) { | |
| imageAsset->setImageAsset(i); | |
| } | |
| fRevalidator->revalidate(); | |
| return true; | |
| } | |
| return false; | |
| } | |
| bool skottie::SlotManager::setScalarSlot(const SlotID& slotID, float s) { | |
| const auto valueGroup = fScalarMap.find(slotID); | |
| if (valueGroup) { | |
| for (auto& sPair : *valueGroup) { | |
| *(sPair.value) = s; | |
| sPair.adapter->onSync(); | |
| } | |
| fRevalidator->revalidate(); | |
| return true; | |
| } | |
| return false; | |
| } | |
| bool skottie::SlotManager::setVec2Slot(const SlotID& slotID, SkV2 v) { | |
| const auto valueGroup = fVec2Map.find(slotID); | |
| if (valueGroup) { | |
| for (auto& vPair : *valueGroup) { | |
| *(vPair.value) = v; | |
| vPair.adapter->onSync(); | |
| } | |
| fRevalidator->revalidate(); | |
| return true; | |
| } | |
| return false; | |
| } | |
| bool skottie::SlotManager::setTextSlot(const SlotID& slotID, const TextPropertyValue& t) { | |
| const auto adapterGroup = fTextMap.find(slotID); | |
| if (adapterGroup) { | |
| for (auto& textAdapter : *adapterGroup) { | |
| textAdapter->setText(t); | |
| } | |
| fRevalidator->revalidate(); | |
| return true; | |
| } | |
| return false; | |
| } | |
| std::optional<SkColor> skottie::SlotManager::getColorSlot(const SlotID& slotID) const { | |
| const auto valueGroup = fColorMap.find(slotID); | |
| return valueGroup && !valueGroup->empty() ? std::optional<SkColor>(*(valueGroup->at(0).value)) | |
| : std::nullopt; | |
| } | |
| sk_sp<const skresources::ImageAsset> skottie::SlotManager::getImageSlot( | |
| const SlotID& slotID) const { | |
| const auto imageGroup = fImageMap.find(slotID); | |
| return imageGroup && !imageGroup->empty() ? imageGroup->at(0)->getImageAsset() : nullptr; | |
| } | |
| std::optional<float> skottie::SlotManager::getScalarSlot(const SlotID& slotID) const { | |
| const auto valueGroup = fScalarMap.find(slotID); | |
| return valueGroup && !valueGroup->empty() ? std::optional<float>(*(valueGroup->at(0).value)) | |
| : std::nullopt; | |
| } | |
| std::optional<SkV2> skottie::SlotManager::getVec2Slot(const SlotID& slotID) const { | |
| const auto valueGroup = fVec2Map.find(slotID); | |
| return valueGroup && !valueGroup->empty() ? std::optional<SkV2>(*(valueGroup->at(0).value)) | |
| : std::nullopt; | |
| } | |
| std::optional<skottie::TextPropertyValue> skottie::SlotManager::getTextSlot( | |
| const SlotID& slotID) const { | |
| const auto adapterGroup = fTextMap.find(slotID); | |
| return adapterGroup && !adapterGroup->empty() ? | |
| std::optional<TextPropertyValue>(adapterGroup->at(0)->getText()) : | |
| std::nullopt; | |
| } | |
| void skottie::SlotManager::trackColorValue(const SlotID& slotID, ColorValue* colorValue, | |
| sk_sp<internal::AnimatablePropertyContainer> adapter) { | |
| fColorMap[slotID].push_back({colorValue, std::move(adapter)}); | |
| } | |
| sk_sp<skresources::ImageAsset> skottie::SlotManager::trackImageValue(const SlotID& slotID, | |
| sk_sp<skresources::ImageAsset> | |
| imageAsset) { | |
| auto proxy = sk_make_sp<ImageAssetProxy>(std::move(imageAsset)); | |
| fImageMap[slotID].push_back(proxy); | |
| return proxy; | |
| } | |
| void skottie::SlotManager::trackScalarValue(const SlotID& slotID, ScalarValue* scalarValue, | |
| sk_sp<internal::AnimatablePropertyContainer> adapter) { | |
| fScalarMap[slotID].push_back({scalarValue, std::move(adapter)}); | |
| } | |
| void skottie::SlotManager::trackVec2Value(const SlotID& slotID, Vec2Value* vec2Value, | |
| sk_sp<internal::AnimatablePropertyContainer> adapter) { | |
| fVec2Map[slotID].push_back({vec2Value, std::move(adapter)}); | |
| } | |
| void skottie::SlotManager::trackTextValue(const SlotID& slotID, | |
| sk_sp<internal::TextAdapter> adapter) { | |
| fTextMap[slotID].push_back(std::move(adapter)); | |
| } | |
| skottie::SlotManager::SlotInfo skottie::SlotManager::getSlotInfo() const { | |
| SlotInfo sInfo; | |
| for (const auto& c : fColorMap) { | |
| sInfo.fColorSlotIDs.push_back(c.first); | |
| } | |
| for (const auto& s : fScalarMap) { | |
| sInfo.fScalarSlotIDs.push_back(s.first); | |
| } | |
| for (const auto& v : fVec2Map) { | |
| sInfo.fVec2SlotIDs.push_back(v.first); | |
| } | |
| for (const auto& i : fImageMap) { | |
| sInfo.fImageSlotIDs.push_back(i.first); | |
| } | |
| for (const auto& t : fTextMap) { | |
| sInfo.fTextSlotIDs.push_back(t.first); | |
| } | |
| return sInfo; | |
| } |