lottie: add custom layer effect with expressions support

effect(name) / effect(index)

effects finds the effect by its name in the Effect Controls panel.
The name can be the default name or a user-defined name.
If multiple effects have the same name,
the effect closest to the top of the Effect Controls panel is used.

example:
- effect("Fast Blur")("Blurriness")

issue: https://github.com/thorvg/thorvg/issues/3115
This commit is contained in:
Hermet Park 2025-04-02 00:51:45 +09:00 committed by Hermet Park
parent fbe10255d7
commit d3afebfdec
10 changed files with 55154 additions and 86 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,486 @@
{
"v": "5.4.3",
"fr": 60,
"ip": 0,
"op": 100,
"w": 500,
"h": 500,
"nm": "ProgressCircle-lottie",
"ddd": 0,
"assets": [],
"layers": [
{
"ddd": 0,
"ind": 1,
"ty": 3,
"nm": "Counter",
"sr": 1,
"ks": {
"o": {
"a": 0,
"k": 0,
"ix": 11
},
"r": {
"a": 0,
"k": 0,
"ix": 10
},
"p": {
"a": 0,
"k": [
250,
250,
0
],
"ix": 2
},
"a": {
"a": 0,
"k": [
0,
0,
0
],
"ix": 1
},
"s": {
"a": 0,
"k": [
117.183,
117.183,
100
],
"ix": 6
}
},
"ao": 0,
"ef": [
{
"ty": 5,
"nm": "Slider Control",
"np": 3,
"mn": "ADBE Slider Control",
"ix": 1,
"en": 1,
"ef": [
{
"ty": 0,
"nm": "Slider",
"mn": "ADBE Slider Control-0001",
"ix": 1,
"v": {
"a": 1,
"k": [
{
"i": {
"x": [
0.833
],
"y": [
0.833
]
},
"o": {
"x": [
0.167
],
"y": [
0.167
]
},
"n": [
"0p833_0p833_0p167_0p167"
],
"t": 0,
"s": [
0
],
"e": [
100
]
},
{
"t": 100
}
],
"ix": 1
}
}
]
}
],
"ip": 0,
"op": 100,
"st": 0,
"bm": 0
},
{
"ddd": 0,
"ind": 2,
"ty": 4,
"nm": "Shape Layer 2",
"sr": 1,
"ks": {
"o": {
"a": 0,
"k": 100,
"ix": 11
},
"r": {
"a": 0,
"k": 0,
"ix": 10
},
"p": {
"a": 0,
"k": [
202,
194,
0
],
"ix": 2
},
"a": {
"a": 0,
"k": [
0,
0,
0
],
"ix": 1
},
"s": {
"a": 0,
"k": [
126.352,
126.352,
100
],
"ix": 6
}
},
"ao": 0,
"shapes": [
{
"ty": "gr",
"it": [
{
"d": 1,
"ty": "el",
"s": {
"a": 0,
"k": [
342.324,
342.324
],
"ix": 2
},
"p": {
"a": 0,
"k": [
0,
0
],
"ix": 3
},
"nm": "Ellipse Path 1",
"mn": "ADBE Vector Shape - Ellipse",
"hd": false
},
{
"ty": "st",
"c": {
"a": 0,
"k": [
1,
0.4,
0,
1
],
"ix": 3
},
"o": {
"a": 0,
"k": 100,
"ix": 4
},
"w": {
"a": 0,
"k": 20,
"ix": 5
},
"lc": 1,
"lj": 1,
"ml": 4,
"ml2": {
"a": 0,
"k": 4,
"ix": 8
},
"bm": 0,
"nm": "Stroke 1",
"mn": "ADBE Vector Graphic - Stroke",
"hd": false
},
{
"ty": "tr",
"p": {
"a": 0,
"k": [
38.162,
44.162
],
"ix": 2
},
"a": {
"a": 0,
"k": [
0,
0
],
"ix": 1
},
"s": {
"a": 0,
"k": [
100,
100
],
"ix": 3
},
"r": {
"a": 0,
"k": 0,
"ix": 6
},
"o": {
"a": 0,
"k": 100,
"ix": 7
},
"sk": {
"a": 0,
"k": 0,
"ix": 4
},
"sa": {
"a": 0,
"k": 0,
"ix": 5
},
"nm": "Transform"
}
],
"nm": "Ellipse 1",
"np": 3,
"cix": 2,
"bm": 0,
"ix": 1,
"mn": "ADBE Vector Group",
"hd": false
},
{
"ty": "tm",
"s": {
"a": 0,
"k": 0,
"ix": 1
},
"e": {
"a": 0,
"k": 100,
"ix": 2,
"x": "var $bm_rt;\n$bm_rt = thisComp.layer('Counter').effect('Slider Control')('Slider');"
},
"o": {
"a": 0,
"k": 0,
"ix": 3
},
"m": 1,
"ix": 2,
"nm": "Trim Paths 1",
"mn": "ADBE Vector Filter - Trim",
"hd": false
}
],
"ip": 0,
"op": 100,
"st": 0,
"bm": 0
},
{
"ddd": 0,
"ind": 3,
"ty": 4,
"nm": "Shape Layer 1",
"sr": 1,
"ks": {
"o": {
"a": 0,
"k": 100,
"ix": 11
},
"r": {
"a": 0,
"k": 0,
"ix": 10
},
"p": {
"a": 0,
"k": [
202,
194,
0
],
"ix": 2
},
"a": {
"a": 0,
"k": [
0,
0,
0
],
"ix": 1
},
"s": {
"a": 0,
"k": [
126.352,
126.352,
100
],
"ix": 6
}
},
"ao": 0,
"shapes": [
{
"ty": "gr",
"it": [
{
"d": 1,
"ty": "el",
"s": {
"a": 0,
"k": [
342.324,
342.324
],
"ix": 2
},
"p": {
"a": 0,
"k": [
0,
0
],
"ix": 3
},
"nm": "Ellipse Path 1",
"mn": "ADBE Vector Shape - Ellipse",
"hd": false
},
{
"ty": "st",
"c": {
"a": 0,
"k": [
0.2,
0.2,
0.2,
1
],
"ix": 3
},
"o": {
"a": 0,
"k": 100,
"ix": 4
},
"w": {
"a": 0,
"k": 20,
"ix": 5
},
"lc": 1,
"lj": 1,
"ml": 4,
"ml2": {
"a": 0,
"k": 4,
"ix": 8
},
"bm": 0,
"nm": "Stroke 1",
"mn": "ADBE Vector Graphic - Stroke",
"hd": false
},
{
"ty": "tr",
"p": {
"a": 0,
"k": [
38.162,
44.162
],
"ix": 2
},
"a": {
"a": 0,
"k": [
0,
0
],
"ix": 1
},
"s": {
"a": 0,
"k": [
100,
100
],
"ix": 3
},
"r": {
"a": 0,
"k": 0,
"ix": 6
},
"o": {
"a": 0,
"k": 100,
"ix": 7
},
"sk": {
"a": 0,
"k": 0,
"ix": 4
},
"sa": {
"a": 0,
"k": 0,
"ix": 5
},
"nm": "Transform"
}
],
"nm": "Ellipse 1",
"np": 3,
"cix": 2,
"bm": 0,
"ix": 1,
"mn": "ADBE Vector Group",
"hd": false
}
],
"ip": 0,
"op": 100,
"st": 0,
"bm": 0
}
],
"markers": []
}

File diff suppressed because one or more lines are too long

View file

@ -35,7 +35,10 @@
struct ExpContent
{
LottieExpression* exp;
union {
LottieObject* obj;
LottieEffect* effect;
};
float frameNo;
};
@ -58,12 +61,12 @@ static const char* EXP_EFFECT= "effect";
static LottieExpressions* exps = nullptr; //singleton instance engine
static ExpContent* _expcontent(LottieExpression* exp, float frameNo, LottieObject* obj)
static ExpContent* _expcontent(LottieExpression* exp, float frameNo, void* obj)
{
auto data = tvg::malloc<ExpContent*>(sizeof(ExpContent));
data->exp = exp;
data->frameNo = frameNo;
data->obj = obj;
data->obj = (LottieObject*)obj;
return data;
}
@ -87,6 +90,22 @@ static jerry_value_t _point2d(const Point& pt)
}
static jerry_value_t _color(RGB24 rgb)
{
auto value = jerry_object();
auto r = jerry_number(rgb.rgb[0]);
auto g = jerry_number(rgb.rgb[1]);
auto b = jerry_number(rgb.rgb[2]);
jerry_object_set_index(value, 0, r);
jerry_object_set_index(value, 1, g);
jerry_object_set_index(value, 2, b);
jerry_value_free(r);
jerry_value_free(g);
jerry_value_free(b);
return value;
}
static Point _point2d(jerry_value_t obj)
{
auto v1 = jerry_object_get_index(obj, 0);
@ -97,6 +116,21 @@ static Point _point2d(jerry_value_t obj)
return pt;
}
static RGB24 _color(jerry_value_t obj)
{
RGB24 out;
auto r = jerry_object_get_index(obj, 0);
auto g = jerry_object_get_index(obj, 1);
auto b = jerry_object_get_index(obj, 2);
out.rgb[0] = jerry_value_as_number(r);
out.rgb[1] = jerry_value_as_number(g);
out.rgb[2] = jerry_value_as_number(b);
jerry_value_free(r);
jerry_value_free(g);
jerry_value_free(b);
return out;
}
static void contentFree(void *native_p, struct jerry_object_native_info_t *info_p)
{
@ -139,26 +173,19 @@ static jerry_value_t _toComp(const jerry_call_info_t* info, const jerry_value_t
static jerry_value_t _value(float frameNo, LottieProperty* property)
{
switch (property->type) {
case LottieProperty::Type::Float: {
return jerry_number((*static_cast<LottieFloat*>(property))(frameNo));
}
case LottieProperty::Type::Scalar: {
return _point2d((*static_cast<LottieScalar*>(property))(frameNo));
}
case LottieProperty::Type::Vector: {
return _point2d((*static_cast<LottieVector*>(property))(frameNo));
}
case LottieProperty::Type::PathSet: {
case LottieProperty::Type::Integer: return jerry_number((*static_cast<LottieInteger*>(property))(frameNo));
case LottieProperty::Type::Float: return jerry_number((*static_cast<LottieFloat*>(property))(frameNo));
case LottieProperty::Type::Scalar: return _point2d((*static_cast<LottieScalar*>(property))(frameNo));
case LottieProperty::Type::Vector: return _point2d((*static_cast<LottieVector*>(property))(frameNo));
case LottieProperty::Type::PathSet:
{
auto value = jerry_object();
jerry_object_set_native_ptr(value, nullptr, property);
return value;
}
case LottieProperty::Type::Opacity: {
return jerry_number((*static_cast<LottieOpacity*>(property))(frameNo));
}
default: {
TVGERR("LOTTIE", "Non supported type for value? = %d", (int) property->type);
}
case LottieProperty::Type::Color: return _color((*static_cast<LottieColor*>(property))(frameNo));
case LottieProperty::Type::Opacity: return jerry_number((*static_cast<LottieOpacity*>(property))(frameNo));
default: TVGERR("LOTTIE", "Non supported type for value? = %d", (int) property->type);
}
return jerry_undefined();
}
@ -259,6 +286,44 @@ static jerry_value_t _buildTrimpath(LottieTrimpath* trimpath, float frameNo)
}
static jerry_value_t _effectProperty(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt)
{
auto data = static_cast<ExpContent*>(jerry_object_get_native_ptr(info->function, &freeCb));
auto name = _name(args[0]);
auto property = static_cast<LottieFxCustom*>(data->effect)->property(name);
tvg::free(name);
if (!property) return jerry_undefined();
return _value(data->frameNo, property);
}
static jerry_value_t _effect(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt)
{
auto data = static_cast<ExpContent*>(jerry_object_get_native_ptr(info->function, &freeCb));
auto layer = static_cast<LottieLayer*>(data->obj);
LottieEffect* effect = nullptr;
//either name or index
if (jerry_value_is_string(args[0])) {
auto name = _name(args[0]);
effect = layer->effectById(djb2Encode(name));
tvg::free(name);
} else {
effect = layer->effectByIdx((int16_t)jerry_value_as_int32(args[0]));
}
if (!effect) return jerry_undefined();
//find a effect property
auto obj = jerry_function_external(_effectProperty);
jerry_object_set_native_ptr(obj, &freeCb, _expcontent(data->exp, data->frameNo, effect));
jerry_object_set_sz(obj, "", obj);
return obj;
}
static void _buildLayer(jerry_value_t context, float frameNo, LottieLayer* layer, LottieLayer* comp, LottieExpression* exp)
{
auto width = jerry_number(layer->w);
@ -345,6 +410,11 @@ static void _buildLayer(jerry_value_t context, float frameNo, LottieLayer* layer
jerry_object_set_sz(context, EXP_CONTENT, content);
jerry_object_set_native_ptr(content, &freeCb, _expcontent(exp, frameNo, layer));
jerry_value_free(content);
auto effect = jerry_function_external(_effect);
jerry_object_set_sz(context, EXP_EFFECT, effect);
jerry_object_set_native_ptr(effect, &freeCb, _expcontent(exp, frameNo, layer));
jerry_value_free(effect);
}
@ -535,14 +605,6 @@ static jerry_value_t _rad2deg(const jerry_call_info_t* info, const jerry_value_t
}
static jerry_value_t _effect(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt)
{
TVGLOG("LOTTIE", "effect is not supported in expressions!");
return jerry_undefined();
}
static jerry_value_t _fromCompToSurface(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt)
{
TVGLOG("LOTTIE", "fromCompToSurface is not supported in expressions!");
@ -1060,6 +1122,11 @@ static void _buildProperty(float frameNo, jerry_value_t context, LottieExpressio
//expansions per types
if (exp->property->type == LottieProperty::Type::PathSet) _buildPath(context, exp);
auto effect = jerry_function_external(_effect);
jerry_object_set_sz(context, EXP_EFFECT, effect);
jerry_object_set_native_ptr(effect, &freeCb, _expcontent(exp, frameNo, exp->layer));
jerry_value_free(effect);
}
@ -1266,10 +1333,6 @@ jerry_value_t LottieExpressions::buildGlobal()
thisProperty = jerry_object();
jerry_object_set_sz(global, "thisProperty", thisProperty);
auto effect = jerry_function_external(_effect);
jerry_object_set_sz(global, EXP_EFFECT, effect);
jerry_value_free(effect);
auto fromCompToSurface = jerry_function_external(_fromCompToSurface);
jerry_object_set_sz(global, "fromCompToSurface", fromCompToSurface);
jerry_value_free(fromCompToSurface);
@ -1397,4 +1460,16 @@ void LottieExpressions::retrieve(LottieExpressions* instance)
}
Point LottieExpressions::toPoint2d(jerry_value_t obj)
{
return _point2d(obj);
}
RGB24 LottieExpressions::toColor(jerry_value_t obj)
{
return _color(obj);
}
#endif //THORVG_LOTTIE_EXPRESSIONS_SUPPORT

View file

@ -63,12 +63,7 @@ public:
if (auto prop = static_cast<Property*>(jerry_object_get_native_ptr(bm_rt, nullptr))) {
out = (*prop)(frameNo);
} else {
auto x = jerry_object_get_index(bm_rt, 0);
auto y = jerry_object_get_index(bm_rt, 1);
out.x = jerry_value_as_number(x);
out.y = jerry_value_as_number(y);
jerry_value_free(x);
jerry_value_free(y);
out = toPoint2d(bm_rt);
}
jerry_value_free(bm_rt);
return true;
@ -83,15 +78,7 @@ public:
if (auto color = static_cast<Property*>(jerry_object_get_native_ptr(bm_rt, nullptr))) {
out = (*color)(frameNo);
} else {
auto r = jerry_object_get_index(bm_rt, 0);
auto g = jerry_object_get_index(bm_rt, 1);
auto b = jerry_object_get_index(bm_rt, 2);
out.rgb[0] = REMAP255(jerry_value_as_number(r));
out.rgb[1] = REMAP255(jerry_value_as_number(g));
out.rgb[2] = REMAP255(jerry_value_as_number(b));
jerry_value_free(r);
jerry_value_free(g);
jerry_value_free(b);
out = toColor(bm_rt);
}
jerry_value_free(bm_rt);
return true;
@ -156,6 +143,9 @@ private:
void buildGlobal(LottieExpression* exp);
void buildWritables(LottieExpression* exp);
Point toPoint2d(jerry_value_t obj);
RGB24 toColor(jerry_value_t obj);
//global object, attributes, methods
jerry_value_t global;
jerry_value_t comp;

View file

@ -23,9 +23,9 @@
#ifndef _TVG_LOTTIE_MODEL_H_
#define _TVG_LOTTIE_MODEL_H_
#include <cstring>
#include "tvgCommon.h"
#include "tvgStr.h"
#include "tvgCompressor.h"
#include "tvgRender.h"
#include "tvgLottieProperty.h"
#include "tvgLottieRenderPooler.h"
@ -83,13 +83,63 @@ struct LottieStroke
struct LottieEffect
{
enum Type : uint8_t {Tint = 20, Fill, Stroke, Tritone, DropShadow = 25, GaussianBlur = 29};
enum Type : uint8_t {Custom = 5, Tint = 20, Fill, Stroke, Tritone, DropShadow = 25, GaussianBlur = 29};
virtual ~LottieEffect() {}
unsigned long id;
int16_t ix;
Type type;
bool enable = false;
};
struct LottieFxCustom : LottieEffect
{
char* name = nullptr;
Array<LottieProperty*> props;
LottieFxCustom()
{
type = LottieEffect::Custom;
}
~LottieFxCustom()
{
ARRAY_FOREACH(p, props) delete(*p);
}
LottieProperty* property(int type)
{
LottieProperty* prop = nullptr;
switch (type) {
case 0: //slider
case 1: prop = new LottieFloat; break; //angle
case 2: prop = new LottieColor; break; //color
case 3: prop = new LottieVector; break; //point
case 4: //checkbox
case 7: //dropdown
case 10: prop = new LottieInteger; break; //effect layer
case 6: TVGLOG("LOTTIE", "custom ignored?"); break;
default:
TVGLOG("LOTTIE", "missing custom property = %d\n", type);
return nullptr;
}
if (prop) props.push(prop);
return prop;
}
LottieProperty* property(const char* name)
{
auto ix = static_cast<uint32_t>(djb2Encode(name));
ARRAY_FOREACH(p, props) {
if ((*p)->ix == ix) return *p;
}
return nullptr;
}
};
struct LottieFxFill : LottieEffect
{
//LottieInteger mask;
@ -223,7 +273,7 @@ struct LottieObject
virtual bool mergeable() { return false; }
virtual LottieProperty* property(uint16_t ix) { return nullptr; }
unsigned long id = 0;
unsigned long id = 0; //unique id by name generated by djb2 encoding
Type type;
bool hidden = false; //remove?
};
@ -944,6 +994,23 @@ struct LottieLayer : LottieGroup
bool autoOrient = false;
bool matteSrc = false;
LottieEffect* effectById(unsigned long id)
{
ARRAY_FOREACH(p, effects) {
if (id == (*p)->id) return *p;
}
return nullptr;
}
LottieEffect* effectByIdx(int16_t ix)
{
ARRAY_FOREACH(p, effects) {
if (ix == (*p)->ix) return *p;
}
return nullptr;
}
LottieLayer* layerById(unsigned long id)
{
ARRAY_FOREACH(p, children) {

View file

@ -60,6 +60,7 @@ LottieExpression* LottieParser::getExpression(char* code, LottieComposition* com
LottieEffect* LottieParser::getEffect(int type)
{
switch (type) {
case LottieEffect::Custom: return new LottieFxCustom;
case LottieEffect::Tint: return new LottieFxTint;
case LottieEffect::Fill: return new LottieFxFill;
case LottieEffect::Stroke: return new LottieFxStroke;
@ -1255,25 +1256,60 @@ void LottieParser::parseMasks(LottieLayer* layer)
}
void LottieParser::parseEffect(LottieEffect* effect, void(LottieParser::*func)(LottieEffect*, int))
bool LottieParser::parseEffect(LottieEffect* effect, void(LottieParser::*func)(LottieEffect*, int))
{
int idx = 0;
//custom effect expects dynamic property allocations
auto custom = (effect->type == LottieEffect::Custom) ? true : false;
LottieProperty* property = nullptr;
enterArray();
int idx = 0;
while (nextArrayValue()) {
enterObject();
while (auto key = nextObjectKey()) {
if (KEY_AS("v")) {
if (custom && KEY_AS("ty")) {
property = static_cast<LottieFxCustom*>(effect)->property(getInt());
} else if (KEY_AS("v")) {
if (peekType() == kObjectType) {
enterObject();
while (auto key = nextObjectKey()) {
if (KEY_AS("k")) (this->*func)(effect, idx);
if (KEY_AS("k")) (this->*func)(effect, idx++);
else skip();
}
++idx;
} else skip();
} else if (property && KEY_AS("nm")) {
property->ix = djb2Encode(getString());
} else skip();
}
}
return true;
}
void LottieParser::parseCustom(LottieEffect* effect, int idx)
{
if ((uint32_t)idx >= static_cast<LottieFxCustom*>(effect)->props.count) {
TVGERR("LOTTIE", "Parsing error in Custom effect!");
return;
}
auto prop = static_cast<LottieFxCustom*>(effect)->props[idx];
switch (prop->type) {
case LottieProperty::Type::Integer: {
parsePropertyInternal(*static_cast<LottieInteger*>(prop)); break;
}
case LottieProperty::Type::Float: {
parsePropertyInternal(*static_cast<LottieFloat*>(prop)); break;
}
case LottieProperty::Type::Vector: {
parsePropertyInternal(*static_cast<LottieVector*>(prop)); break;
}
case LottieProperty::Type::Color: {
parsePropertyInternal(*static_cast<LottieColor*>(prop)); break;
}
default: TVGLOG("LOTTIE", "Missing Property Type? = %d", (int) prop->type); break;
}
}
@ -1348,34 +1384,17 @@ void LottieParser::parseStroke(LottieEffect* effect, int idx)
}
void LottieParser::parseEffect(LottieEffect* effect)
bool LottieParser::parseEffect(LottieEffect* effect)
{
switch (effect->type) {
case LottieEffect::Tint: {
parseEffect(effect, &LottieParser::parseTint);
break;
}
case LottieEffect::Fill: {
parseEffect(effect, &LottieParser::parseFill);
break;
}
case LottieEffect::Stroke: {
parseEffect(effect, &LottieParser::parseStroke);
break;
}
case LottieEffect::Tritone: {
parseEffect(effect, &LottieParser::parseTritone);
break;
}
case LottieEffect::DropShadow: {
parseEffect(effect, &LottieParser::parseDropShadow);
break;
}
case LottieEffect::GaussianBlur: {
parseEffect(effect, &LottieParser::parseGaussianBlur);
break;
}
default: break;
case LottieEffect::Custom: return parseEffect(effect, &LottieParser::parseCustom);
case LottieEffect::Tint: return parseEffect(effect, &LottieParser::parseTint);
case LottieEffect::Fill: return parseEffect(effect, &LottieParser::parseFill);
case LottieEffect::Stroke: return parseEffect(effect, &LottieParser::parseStroke);
case LottieEffect::Tritone: return parseEffect(effect, &LottieParser::parseTritone);
case LottieEffect::DropShadow: return parseEffect(effect, &LottieParser::parseDropShadow);
case LottieEffect::GaussianBlur: return parseEffect(effect, &LottieParser::parseGaussianBlur);
default: return false;
}
}
@ -1395,6 +1414,8 @@ void LottieParser::parseEffects(LottieLayer* layer)
if (!effect) break;
else invalid = false;
}
else if (effect && KEY_AS("nm")) effect->id = djb2Encode(getString());
else if (effect && KEY_AS("ix")) effect->ix = getInt();
else if (effect && KEY_AS("en")) effect->enable = getInt();
else if (effect && KEY_AS("ef")) parseEffect(effect);
else skip();

View file

@ -99,7 +99,8 @@ private:
void parseFontData(LottieFont* font, const char* data);
LottieMarker* parseMarker();
void parseEffect(LottieEffect* effect, void(LottieParser::*func)(LottieEffect*, int));
bool parseEffect(LottieEffect* effect, void(LottieParser::*func)(LottieEffect*, int));
void parseCustom(LottieEffect* effect, int idx);
void parseStroke(LottieEffect* effect, int idx);
void parseTritone(LottieEffect* effect, int idx);
void parseTint(LottieEffect* effect, int idx);
@ -125,7 +126,7 @@ private:
void parseFonts();
void parseChars(Array<LottieGlyph*>& glyphs);
void parseMarkers();
void parseEffect(LottieEffect* effect);
bool parseEffect(LottieEffect* effect);
void postProcess(Array<LottieGlyph*>& glyphs);
//Current parsing context

View file

@ -186,14 +186,15 @@ struct LottieExpression
//Property would have an either keyframes or single value.
struct LottieProperty
{
enum class Type : uint8_t { Invalid = 0, Float, Integer, Scalar, Vector, PathSet, Color, Opacity, ColorStop, TextDoc, Image};
enum class Type : uint8_t {Invalid = 0, Integer, Float, Scalar, Vector, PathSet, Color, Opacity, ColorStop, TextDoc, Image};
LottieExpression* exp = nullptr;
uint32_t ix; //property index (used as a name id for indexing by custom layer effect as well)
Type type;
uint8_t ix; //property index
LottieProperty(Type type = Type::Invalid) : type(type) {}
virtual ~LottieProperty() {}
virtual uint32_t frameCnt() = 0;
virtual uint32_t nearest(float frameNo) = 0;
virtual float frameNo(int32_t key) = 0;
@ -1007,5 +1008,4 @@ using LottieVector = LottieGenericProperty<LottieVectorFrame<Point>, Point, Lott
using LottieColor = LottieGenericProperty<LottieScalarFrame<RGB24>, RGB24, LottieProperty::Type::Color>;
using LottieOpacity = LottieGenericProperty<LottieScalarFrame<uint8_t>, uint8_t, LottieProperty::Type::Opacity>;
#endif //_TVG_LOTTIE_PROPERTY_H_