2 * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 #ifndef LOTTIEPROXYMODEL_H
20 #define LOTTIEPROXYMODEL_H
25 #include "lottiemodel.h"
28 // Naive way to implement std::variant
29 // refactor it when we move to c++17
30 // users should make sure proper combination
31 // of id and value are passed while creating the object.
35 using ValueFunc = std::function<float(const rlottie::FrameInfo &)>;
36 using ColorFunc = std::function<rlottie::Color(const rlottie::FrameInfo &)>;
37 using PointFunc = std::function<rlottie::Point(const rlottie::FrameInfo &)>;
38 using SizeFunc = std::function<rlottie::Size(const rlottie::FrameInfo &)>;
40 LOTVariant(rlottie::Property prop, const ValueFunc &v):mPropery(prop), mTag(Value)
42 construct(impl.valueFunc, v);
45 LOTVariant(rlottie::Property prop, ValueFunc &&v):mPropery(prop), mTag(Value)
47 moveConstruct(impl.valueFunc, std::move(v));
50 LOTVariant(rlottie::Property prop, const ColorFunc &v):mPropery(prop), mTag(Color)
52 construct(impl.colorFunc, v);
55 LOTVariant(rlottie::Property prop, ColorFunc &&v):mPropery(prop), mTag(Color)
57 moveConstruct(impl.colorFunc, std::move(v));
60 LOTVariant(rlottie::Property prop, const PointFunc &v):mPropery(prop), mTag(Point)
62 construct(impl.pointFunc, v);
65 LOTVariant(rlottie::Property prop, PointFunc &&v):mPropery(prop), mTag(Point)
67 moveConstruct(impl.pointFunc, std::move(v));
70 LOTVariant(rlottie::Property prop, const SizeFunc &v):mPropery(prop), mTag(Size)
72 construct(impl.sizeFunc, v);
75 LOTVariant(rlottie::Property prop, SizeFunc &&v):mPropery(prop), mTag(Size)
77 moveConstruct(impl.sizeFunc, std::move(v));
80 rlottie::Property property() const { return mPropery; }
82 const ColorFunc& color() const
84 assert(mTag == Color);
85 return impl.colorFunc;
88 const ValueFunc& value() const
90 assert(mTag == Value);
91 return impl.valueFunc;
94 const PointFunc& point() const
96 assert(mTag == Point);
97 return impl.pointFunc;
100 const SizeFunc& size() const
102 assert(mTag == Size);
103 return impl.sizeFunc;
106 LOTVariant() = default;
107 ~LOTVariant() noexcept {Destroy();}
108 LOTVariant(const LOTVariant& other) { Copy(other);}
109 LOTVariant(LOTVariant&& other) noexcept { Move(std::move(other));}
110 LOTVariant& operator=(LOTVariant&& other) { Destroy(); Move(std::move(other)); return *this;}
111 LOTVariant& operator=(const LOTVariant& other) { Destroy(); Copy(other); return *this;}
113 template <typename T>
114 void construct(T& member, const T& val)
116 new (&member) T(val);
119 template <typename T>
120 void moveConstruct(T& member, T&& val)
122 new (&member) T(std::move(val));
125 void Move(LOTVariant&& other)
127 switch (other.mTag) {
129 moveConstruct(impl.valueFunc, std::move(other.impl.valueFunc));
132 moveConstruct(impl.colorFunc, std::move(other.impl.colorFunc));
135 moveConstruct(impl.pointFunc, std::move(other.impl.pointFunc));
138 moveConstruct(impl.sizeFunc, std::move(other.impl.sizeFunc));
144 mPropery = other.mPropery;
145 other.mTag = MonoState;
148 void Copy(const LOTVariant& other)
150 switch (other.mTag) {
152 construct(impl.valueFunc, other.impl.valueFunc);
155 construct(impl.colorFunc, other.impl.colorFunc);
158 construct(impl.pointFunc, other.impl.pointFunc);
161 construct(impl.sizeFunc, other.impl.sizeFunc);
167 mPropery = other.mPropery;
177 impl.valueFunc.~ValueFunc();
181 impl.colorFunc.~ColorFunc();
185 impl.pointFunc.~PointFunc();
189 impl.sizeFunc.~SizeFunc();
195 enum Type {MonoState, Value, Color, Point , Size};
196 rlottie::Property mPropery;
197 Type mTag{MonoState};
211 void addValue(LOTVariant &value)
213 uint index = static_cast<uint>(value.property());
214 if (mBitset.test(index)) {
215 std::replace_if(mFilters.begin(),
217 [&value](const LOTVariant &e) {return e.property() == value.property();},
221 mFilters.push_back(value);
225 void removeValue(LOTVariant &value)
227 uint index = static_cast<uint>(value.property());
228 if (mBitset.test(index)) {
229 mBitset.reset(index);
230 mFilters.erase(std::remove_if(mFilters.begin(),
232 [&value](const LOTVariant &e) {return e.property() == value.property();}),
236 bool hasFilter(rlottie::Property prop) const
238 return mBitset.test(static_cast<uint>(prop));
240 LottieColor color(rlottie::Property prop, int frame) const
242 rlottie::FrameInfo info(frame);
243 rlottie::Color col = data(prop).color()(info);
244 return LottieColor(col.r(), col.g(), col.b());
246 float opacity(rlottie::Property prop, int frame) const
248 rlottie::FrameInfo info(frame);
249 float val = data(prop).value()(info);
252 float value(rlottie::Property prop, int frame) const
254 rlottie::FrameInfo info(frame);
255 return data(prop).value()(info);
258 const LOTVariant& data(rlottie::Property prop) const
260 auto result = std::find_if(mFilters.begin(),
262 [prop](const LOTVariant &e){return e.property() == prop;});
265 std::bitset<32> mBitset{0};
266 std::vector<LOTVariant> mFilters;
269 template <typename T>
273 LOTProxyModel(T *model): _modelData(model) {}
274 LOTFilter& filter() {return mFilter;}
275 const std::string & name() const {return _modelData->name();}
276 LottieColor color(int frame) const
278 if (mFilter.hasFilter(rlottie::Property::StrokeColor)) {
279 return mFilter.color(rlottie::Property::StrokeColor, frame);
281 return _modelData->color(frame);
283 float opacity(int frame) const
285 if (mFilter.hasFilter(rlottie::Property::StrokeOpacity)) {
286 return mFilter.opacity(rlottie::Property::StrokeOpacity, frame);
288 return _modelData->opacity(frame);
290 float strokeWidth(int frame) const
292 if (mFilter.hasFilter(rlottie::Property::StrokeWidth)) {
293 return mFilter.value(rlottie::Property::StrokeWidth, frame);
295 return _modelData->strokeWidth(frame);
297 float miterLimit() const {return _modelData->miterLimit();}
298 CapStyle capStyle() const {return _modelData->capStyle();}
299 JoinStyle joinStyle() const {return _modelData->joinStyle();}
300 bool hasDashInfo() const { return _modelData->hasDashInfo();}
301 void getDashInfo(int frameNo, std::vector<float>& result) const {
302 return _modelData->getDashInfo(frameNo, result);
311 class LOTProxyModel<LOTFillData>
314 LOTProxyModel(LOTFillData *model): _modelData(model) {}
315 LOTFilter& filter() {return mFilter;}
316 const std::string & name() const {return _modelData->name();}
317 LottieColor color(int frame) const
319 if (mFilter.hasFilter(rlottie::Property::FillColor)) {
320 return mFilter.color(rlottie::Property::FillColor, frame);
322 return _modelData->color(frame);
324 float opacity(int frame) const
326 if (mFilter.hasFilter(rlottie::Property::FillOpacity)) {
327 return mFilter.opacity(rlottie::Property::FillOpacity, frame);
329 return _modelData->opacity(frame);
331 FillRule fillRule() const {return _modelData->fillRule();}
333 LOTFillData *_modelData;
337 #endif // LOTTIEITEM_H