lottie: code refactoring

- aligned the property types with the class types.
- removed tempaltes, since property types are deterministic.
This commit is contained in:
Hermet Park 2025-04-01 19:32:05 +09:00 committed by Hermet Park
parent dadd7a93dd
commit a9cd630dfd
7 changed files with 167 additions and 166 deletions

View file

@ -139,22 +139,22 @@ 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::Point: {
return _point2d((*static_cast<LottieScalar*>(property))(frameNo));
}
case LottieProperty::Type::Float: {
return jerry_number((*static_cast<LottieFloat*>(property))(frameNo));
}
case LottieProperty::Type::Opacity: {
return jerry_number((*static_cast<LottieOpacity*>(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::Position: {
return _point2d((*static_cast<LottieVector*>(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);
@ -668,21 +668,21 @@ static jerry_value_t _velocityAtTime(const jerry_call_info_t* info, const jerry_
//compute the velocity
switch (exp->property->type) {
case LottieProperty::Type::Point: {
auto prv = (*static_cast<LottieScalar*>(exp->property))(pframe);
auto cur = (*static_cast<LottieScalar*>(exp->property))(cframe);
return _velocity(prv, cur, elapsed);
}
case LottieProperty::Type::Position: {
auto prv = (*static_cast<LottieVector*>(exp->property))(pframe);
auto cur = (*static_cast<LottieVector*>(exp->property))(cframe);
return _velocity(prv, cur, elapsed);
}
case LottieProperty::Type::Float: {
auto prv = (*static_cast<LottieFloat*>(exp->property))(pframe);
auto cur = (*static_cast<LottieFloat*>(exp->property))(cframe);
return jerry_number((cur - prv) / elapsed);
}
case LottieProperty::Type::Scalar: {
auto prv = (*static_cast<LottieScalar*>(exp->property))(pframe);
auto cur = (*static_cast<LottieScalar*>(exp->property))(cframe);
return _velocity(prv, cur, elapsed);
}
case LottieProperty::Type::Vector: {
auto prv = (*static_cast<LottieVector*>(exp->property))(pframe);
auto cur = (*static_cast<LottieVector*>(exp->property))(cframe);
return _velocity(prv, cur, elapsed);
}
default: TVGLOG("LOTTIE", "Non supported type for velocityAtTime?");
}
return jerry_undefined();
@ -700,12 +700,12 @@ static jerry_value_t _speedAtTime(const jerry_call_info_t* info, const jerry_val
//compute the velocity
switch (exp->property->type) {
case LottieProperty::Type::Point: {
case LottieProperty::Type::Scalar: {
prv = (*static_cast<LottieScalar*>(exp->property))(pframe);
cur = (*static_cast<LottieScalar*>(exp->property))(cframe);
break;
}
case LottieProperty::Type::Position: {
case LottieProperty::Type::Vector: {
prv = (*static_cast<LottieVector*>(exp->property))(pframe);
cur = (*static_cast<LottieVector*>(exp->property))(cframe);
break;
@ -891,7 +891,7 @@ static jerry_value_t _key(const jerry_call_info_t* info, const jerry_value_t arg
//direct access, key[0], key[1]
if (exp->property->type == LottieProperty::Type::Float) {
jerry_object_set_index(obj, 0, value);
} else if (exp->property->type == LottieProperty::Type::Point || exp->property->type == LottieProperty::Type::Position) {
} else if (exp->property->type == LottieProperty::Type::Scalar || exp->property->type == LottieProperty::Type::Vector) {
jerry_object_set_index(obj, 0, jerry_object_get_index(value, 0));
jerry_object_set_index(obj, 1, jerry_object_get_index(value, 1));
}

View file

@ -319,9 +319,7 @@ bool LottieLoader::override(const char* slots, bool byDefault)
return rebuild;
//reset slots
} else if (overridden) {
ARRAY_FOREACH(p, comp->slots) {
(*p)->reset();
}
ARRAY_FOREACH(p, comp->slots) (*p)->reset();
overridden = false;
rebuild = true;
}

View file

@ -182,19 +182,24 @@ void LottieSlot::assign(LottieObject* target, bool byDefault)
ARRAY_FOREACH(pair, pairs) {
//backup the original properties before overwriting
switch (type) {
case LottieProperty::Type::Position: {
if (copy) pair->prop = new LottieVector(static_cast<LottieTransform*>(pair->obj)->position);
pair->obj->override(&static_cast<LottieTransform*>(target)->position, shallow, !copy);
case LottieProperty::Type::Float: {
if (copy) pair->prop = new LottieFloat(static_cast<LottieTransform*>(pair->obj)->rotation);
pair->obj->override(&static_cast<LottieTransform*>(target)->rotation, shallow, !copy);
break;
}
case LottieProperty::Type::Point: {
case LottieProperty::Type::Scalar: {
if (copy) pair->prop = new LottieScalar(static_cast<LottieTransform*>(pair->obj)->scale);
pair->obj->override(&static_cast<LottieTransform*>(target)->scale, shallow, !copy);
break;
}
case LottieProperty::Type::Float: {
if (copy) pair->prop = new LottieFloat(static_cast<LottieTransform*>(pair->obj)->rotation);
pair->obj->override(&static_cast<LottieTransform*>(target)->rotation, shallow, !copy);
case LottieProperty::Type::Vector: {
if (copy) pair->prop = new LottieVector(static_cast<LottieTransform*>(pair->obj)->position);
pair->obj->override(&static_cast<LottieTransform*>(target)->position, shallow, !copy);
break;
}
case LottieProperty::Type::Color: {
if (copy) pair->prop = new LottieColor(static_cast<LottieSolid*>(pair->obj)->color);
pair->obj->override(&static_cast<LottieSolid*>(target)->color, shallow, !copy);
break;
}
case LottieProperty::Type::Opacity: {
@ -205,11 +210,6 @@ void LottieSlot::assign(LottieObject* target, bool byDefault)
pair->obj->override(&static_cast<LottieSolid*>(target)->opacity, shallow, !copy);
break;
}
case LottieProperty::Type::Color: {
if (copy) pair->prop = new LottieColor(static_cast<LottieSolid*>(pair->obj)->color);
pair->obj->override(&static_cast<LottieSolid*>(target)->color, shallow, !copy);
break;
}
case LottieProperty::Type::ColorStop: {
if (copy) pair->prop = new LottieColorStop(static_cast<LottieGradient*>(pair->obj)->colorStops);
pair->obj->override(&static_cast<LottieGradient*>(target)->colorStops, shallow, !copy);

View file

@ -591,21 +591,21 @@ struct LottieTransform : LottieObject
void override(LottieProperty* prop, bool shallow, bool release) override
{
switch (prop->type) {
case LottieProperty::Type::Position: {
if (release) position.release();
position.copy(*static_cast<LottieVector*>(prop), shallow);
break;
}
case LottieProperty::Type::Float: {
if (release) rotation.release();
rotation.copy(*static_cast<LottieFloat*>(prop), shallow);
break;
}
case LottieProperty::Type::Point: {
case LottieProperty::Type::Scalar: {
if (release) scale.release();
scale.copy(*static_cast<LottieScalar*>(prop), shallow);
break;
}
case LottieProperty::Type::Vector: {
if (release) position.release();
position.copy(*static_cast<LottieVector*>(prop), shallow);
break;
}
case LottieProperty::Type::Opacity: {
if (release) opacity.release();
opacity.copy(*static_cast<LottieOpacity*>(prop), shallow);
@ -676,12 +676,12 @@ struct LottieSolidFill : LottieSolid
void override(LottieProperty* prop, bool shallow, bool release) override
{
if (prop->type == LottieProperty::Type::Opacity) {
if (release) opacity.release();
opacity.copy(*static_cast<LottieOpacity*>(prop), shallow);
} else if (prop->type == LottieProperty::Type::Color) {
if (prop->type == LottieProperty::Type::Color) {
if (release) color.release();
color.copy(*static_cast<LottieColor*>(prop), shallow);
} else if (prop->type == LottieProperty::Type::Opacity) {
if (release) opacity.release();
opacity.copy(*static_cast<LottieOpacity*>(prop), shallow);
}
}

View file

@ -341,11 +341,11 @@ void LottieParser::getInterpolatorPoint(Point& pt)
}
template<LottieProperty::Type type, typename T>
template<typename T>
void LottieParser::parseSlotProperty(T& prop)
{
while (auto key = nextObjectKey()) {
if (KEY_AS("p")) parseProperty<type>(prop);
if (KEY_AS("p")) parseProperty(prop);
else skip();
}
}
@ -462,8 +462,7 @@ void LottieParser::parsePropertyInternal(T& prop)
}
template<LottieProperty::Type type>
void LottieParser::registerSlot(LottieObject* obj, const char* sid)
void LottieParser::registerSlot(LottieObject* obj, const char* sid, LottieProperty::Type type)
{
//append object if the slot already exists.
ARRAY_FOREACH(p, comp->slots) {
@ -475,18 +474,17 @@ void LottieParser::registerSlot(LottieObject* obj, const char* sid)
}
template<LottieProperty::Type type, typename T>
template<typename T>
void LottieParser::parseProperty(T& prop, LottieObject* obj)
{
enterObject();
while (auto key = nextObjectKey()) {
if (KEY_AS("k")) parsePropertyInternal(prop);
else if (obj && KEY_AS("sid")) registerSlot<type>(obj, getString());
else if (obj && KEY_AS("sid")) registerSlot(obj, getString(), prop.type);
else if (KEY_AS("x") && expressions) prop.exp = getExpression(getStringCopy(), comp, context.layer, context.parent, &prop);
else if (KEY_AS("ix")) prop.ix = getInt();
else skip();
}
prop.type = type;
}
@ -522,9 +520,9 @@ LottieRect* LottieParser::parseRect()
while (auto key = nextObjectKey()) {
if (parseCommon(rect, key)) continue;
else if (KEY_AS("s")) parseProperty<LottieProperty::Type::Point>(rect->size);
else if (KEY_AS("p")) parseProperty<LottieProperty::Type::Position>(rect->position);
else if (KEY_AS("r")) parseProperty<LottieProperty::Type::Float>(rect->radius);
else if (KEY_AS("s")) parseProperty(rect->size);
else if (KEY_AS("p")) parseProperty(rect->position);
else if (KEY_AS("r")) parseProperty(rect->radius);
else if (parseDirection(rect, key)) continue;
else skip();
}
@ -540,8 +538,8 @@ LottieEllipse* LottieParser::parseEllipse()
while (auto key = nextObjectKey()) {
if (parseCommon(ellipse, key)) continue;
else if (KEY_AS("p")) parseProperty<LottieProperty::Type::Position>(ellipse->position);
else if (KEY_AS("s")) parseProperty<LottieProperty::Type::Point>(ellipse->size);
else if (KEY_AS("p")) parseProperty(ellipse->position);
else if (KEY_AS("s")) parseProperty(ellipse->size);
else if (parseDirection(ellipse, key)) continue;
else skip();
}
@ -569,24 +567,23 @@ LottieTransform* LottieParser::parseTransform(bool ddd)
if (KEY_AS("k")) parsePropertyInternal(transform->position);
else if (KEY_AS("s") && getBool()) transform->coords = new LottieTransform::SeparateCoord;
//check separateCoord to figure out whether "x(expression)" / "x(coord)"
else if (transform->coords && KEY_AS("x")) parseProperty<LottieProperty::Type::Float>(transform->coords->x);
else if (transform->coords && KEY_AS("y")) parseProperty<LottieProperty::Type::Float>(transform->coords->y);
else if (transform->coords && KEY_AS("x")) parseProperty(transform->coords->x);
else if (transform->coords && KEY_AS("y")) parseProperty(transform->coords->y);
else if (KEY_AS("x") && expressions) transform->position.exp = getExpression(getStringCopy(), comp, context.layer, context.parent, &transform->position);
else if (KEY_AS("sid")) registerSlot<LottieProperty::Type::Position>(transform, getString());
else if (KEY_AS("sid")) registerSlot(transform, getString(), LottieProperty::Type::Vector);
else if (KEY_AS("ix")) transform->position.ix = getInt();
else skip();
}
transform->position.type = LottieProperty::Type::Position;
}
else if (KEY_AS("a")) parseProperty<LottieProperty::Type::Point>(transform->anchor);
else if (KEY_AS("s")) parseProperty<LottieProperty::Type::Point>(transform->scale, transform);
else if (KEY_AS("r")) parseProperty<LottieProperty::Type::Float>(transform->rotation, transform);
else if (KEY_AS("o")) parseProperty<LottieProperty::Type::Opacity>(transform->opacity, transform);
else if (transform->rotationEx && KEY_AS("rx")) parseProperty<LottieProperty::Type::Float>(transform->rotationEx->x);
else if (transform->rotationEx && KEY_AS("ry")) parseProperty<LottieProperty::Type::Float>(transform->rotationEx->y);
else if (transform->rotationEx && KEY_AS("rz")) parseProperty<LottieProperty::Type::Float>(transform->rotation);
else if (KEY_AS("sk")) parseProperty<LottieProperty::Type::Float>(transform->skewAngle);
else if (KEY_AS("sa")) parseProperty<LottieProperty::Type::Float>(transform->skewAxis);
else if (KEY_AS("a")) parseProperty(transform->anchor);
else if (KEY_AS("s")) parseProperty(transform->scale, transform);
else if (KEY_AS("r")) parseProperty(transform->rotation, transform);
else if (KEY_AS("o")) parseProperty(transform->opacity, transform);
else if (transform->rotationEx && KEY_AS("rx")) parseProperty(transform->rotationEx->x);
else if (transform->rotationEx && KEY_AS("ry")) parseProperty(transform->rotationEx->y);
else if (transform->rotationEx && KEY_AS("rz")) parseProperty(transform->rotation);
else if (KEY_AS("sk")) parseProperty(transform->skewAngle);
else if (KEY_AS("sa")) parseProperty(transform->skewAxis);
else skip();
}
return transform;
@ -601,8 +598,8 @@ LottieSolidFill* LottieParser::parseSolidFill()
while (auto key = nextObjectKey()) {
if (parseCommon(fill, key)) continue;
else if (KEY_AS("c")) parseProperty<LottieProperty::Type::Color>(fill->color, fill);
else if (KEY_AS("o")) parseProperty<LottieProperty::Type::Opacity>(fill->opacity, fill);
else if (KEY_AS("c")) parseProperty(fill->color, fill);
else if (KEY_AS("o")) parseProperty(fill->opacity, fill);
else if (KEY_AS("fillEnabled")) fill->hidden |= !getBool();
else if (KEY_AS("r")) fill->rule = (getInt() == 1) ? FillRule::NonZero : FillRule::EvenOdd;
else skip();
@ -620,8 +617,8 @@ void LottieParser::parseStrokeDash(LottieStroke* stroke)
while (auto key = nextObjectKey()) {
if (KEY_AS("n")) style = getString();
else if (KEY_AS("v")) {
if (style && !strcmp("o", style)) parseProperty<LottieProperty::Type::Float>(stroke->dashOffset());
else parseProperty<LottieProperty::Type::Float>(stroke->dashValue());
if (style && !strcmp("o", style)) parseProperty(stroke->dashOffset());
else parseProperty(stroke->dashValue());
} else skip();
}
}
@ -636,9 +633,9 @@ LottieSolidStroke* LottieParser::parseSolidStroke()
while (auto key = nextObjectKey()) {
if (parseCommon(stroke, key)) continue;
else if (KEY_AS("c")) parseProperty<LottieProperty::Type::Color>(stroke->color, stroke);
else if (KEY_AS("o")) parseProperty<LottieProperty::Type::Opacity>(stroke->opacity, stroke);
else if (KEY_AS("w")) parseProperty<LottieProperty::Type::Float>(stroke->width, stroke);
else if (KEY_AS("c")) parseProperty(stroke->color, stroke);
else if (KEY_AS("o")) parseProperty(stroke->opacity, stroke);
else if (KEY_AS("w")) parseProperty(stroke->width, stroke);
else if (KEY_AS("lc")) stroke->cap = (StrokeCap) getInt();
else if (KEY_AS("lj")) stroke->join = (StrokeJoin) getInt();
else if (KEY_AS("ml")) stroke->miterLimit = getFloat();
@ -691,13 +688,13 @@ LottiePolyStar* LottieParser::parsePolyStar()
while (auto key = nextObjectKey()) {
if (parseCommon(star, key)) continue;
else if (KEY_AS("p")) parseProperty<LottieProperty::Type::Position>(star->position);
else if (KEY_AS("pt")) parseProperty<LottieProperty::Type::Float>(star->ptsCnt);
else if (KEY_AS("ir")) parseProperty<LottieProperty::Type::Float>(star->innerRadius);
else if (KEY_AS("is")) parseProperty<LottieProperty::Type::Float>(star->innerRoundness);
else if (KEY_AS("or")) parseProperty<LottieProperty::Type::Float>(star->outerRadius);
else if (KEY_AS("os")) parseProperty<LottieProperty::Type::Float>(star->outerRoundness);
else if (KEY_AS("r")) parseProperty<LottieProperty::Type::Float>(star->rotation);
else if (KEY_AS("p")) parseProperty(star->position);
else if (KEY_AS("pt")) parseProperty(star->ptsCnt);
else if (KEY_AS("ir")) parseProperty(star->innerRadius);
else if (KEY_AS("is")) parseProperty(star->innerRoundness);
else if (KEY_AS("or")) parseProperty(star->outerRadius);
else if (KEY_AS("os")) parseProperty(star->outerRoundness);
else if (KEY_AS("r")) parseProperty(star->rotation);
else if (KEY_AS("sy")) star->type = (LottiePolyStar::Type) getInt();
else if (parseDirection(star, key)) continue;
else skip();
@ -714,7 +711,7 @@ LottieRoundedCorner* LottieParser::parseRoundedCorner()
while (auto key = nextObjectKey()) {
if (parseCommon(corner, key)) continue;
else if (KEY_AS("r")) parseProperty<LottieProperty::Type::Float>(corner->radius);
else if (KEY_AS("r")) parseProperty(corner->radius);
else skip();
}
return corner;
@ -726,8 +723,8 @@ void LottieParser::parseColorStop(LottieGradient* gradient)
enterObject();
while (auto key = nextObjectKey()) {
if (KEY_AS("p")) gradient->colorStops.count = getInt();
else if (KEY_AS("k")) parseProperty<LottieProperty::Type::ColorStop>(gradient->colorStops, gradient);
else if (KEY_AS("sid")) registerSlot<LottieProperty::Type::ColorStop>(gradient, getString());
else if (KEY_AS("k")) parseProperty(gradient->colorStops, gradient);
else if (KEY_AS("sid")) registerSlot(gradient, getString(), LottieProperty::Type::ColorStop);
else skip();
}
}
@ -736,12 +733,12 @@ void LottieParser::parseColorStop(LottieGradient* gradient)
void LottieParser::parseGradient(LottieGradient* gradient, const char* key)
{
if (KEY_AS("t")) gradient->id = getInt();
else if (KEY_AS("o")) parseProperty<LottieProperty::Type::Opacity>(gradient->opacity, gradient);
else if (KEY_AS("o")) parseProperty(gradient->opacity, gradient);
else if (KEY_AS("g")) parseColorStop(gradient);
else if (KEY_AS("s")) parseProperty<LottieProperty::Type::Point>(gradient->start, gradient);
else if (KEY_AS("e")) parseProperty<LottieProperty::Type::Point>(gradient->end, gradient);
else if (KEY_AS("h")) parseProperty<LottieProperty::Type::Float>(gradient->height, gradient);
else if (KEY_AS("a")) parseProperty<LottieProperty::Type::Float>(gradient->angle, gradient);
else if (KEY_AS("s")) parseProperty(gradient->start, gradient);
else if (KEY_AS("e")) parseProperty(gradient->end, gradient);
else if (KEY_AS("h")) parseProperty(gradient->height, gradient);
else if (KEY_AS("a")) parseProperty(gradient->angle, gradient);
else skip();
}
@ -775,7 +772,7 @@ LottieGradientStroke* LottieParser::parseGradientStroke()
else if (KEY_AS("lc")) stroke->cap = (StrokeCap) getInt();
else if (KEY_AS("lj")) stroke->join = (StrokeJoin) getInt();
else if (KEY_AS("ml")) stroke->miterLimit = getFloat();
else if (KEY_AS("w")) parseProperty<LottieProperty::Type::Float>(stroke->width);
else if (KEY_AS("w")) parseProperty(stroke->width);
else if (KEY_AS("d")) parseStrokeDash(stroke);
else parseGradient(stroke, key);
}
@ -793,9 +790,9 @@ LottieTrimpath* LottieParser::parseTrimpath()
while (auto key = nextObjectKey()) {
if (parseCommon(trim, key)) continue;
else if (KEY_AS("s")) parseProperty<LottieProperty::Type::Float>(trim->start);
else if (KEY_AS("e")) parseProperty<LottieProperty::Type::Float>(trim->end);
else if (KEY_AS("o")) parseProperty<LottieProperty::Type::Float>(trim->offset);
else if (KEY_AS("s")) parseProperty(trim->start);
else if (KEY_AS("e")) parseProperty(trim->end);
else if (KEY_AS("o")) parseProperty(trim->offset);
else if (KEY_AS("m")) trim->type = static_cast<LottieTrimpath::Type>(getInt());
else skip();
}
@ -811,19 +808,19 @@ LottieRepeater* LottieParser::parseRepeater()
while (auto key = nextObjectKey()) {
if (parseCommon(repeater, key)) continue;
else if (KEY_AS("c")) parseProperty<LottieProperty::Type::Float>(repeater->copies);
else if (KEY_AS("o")) parseProperty<LottieProperty::Type::Float>(repeater->offset);
else if (KEY_AS("c")) parseProperty(repeater->copies);
else if (KEY_AS("o")) parseProperty(repeater->offset);
else if (KEY_AS("m")) repeater->inorder = getInt() == 2;
else if (KEY_AS("tr"))
{
enterObject();
while (auto key = nextObjectKey()) {
if (KEY_AS("a")) parseProperty<LottieProperty::Type::Point>(repeater->anchor);
else if (KEY_AS("p")) parseProperty<LottieProperty::Type::Position>(repeater->position);
else if (KEY_AS("r")) parseProperty<LottieProperty::Type::Float>(repeater->rotation);
else if (KEY_AS("s")) parseProperty<LottieProperty::Type::Point>(repeater->scale);
else if (KEY_AS("so")) parseProperty<LottieProperty::Type::Opacity>(repeater->startOpacity);
else if (KEY_AS("eo")) parseProperty<LottieProperty::Type::Opacity>(repeater->endOpacity);
if (KEY_AS("a")) parseProperty(repeater->anchor);
else if (KEY_AS("p")) parseProperty(repeater->position);
else if (KEY_AS("r")) parseProperty(repeater->rotation);
else if (KEY_AS("s")) parseProperty(repeater->scale);
else if (KEY_AS("so")) parseProperty(repeater->startOpacity);
else if (KEY_AS("eo")) parseProperty(repeater->endOpacity);
else skip();
}
}
@ -841,9 +838,9 @@ LottieOffsetPath* LottieParser::parseOffsetPath()
while (auto key = nextObjectKey()) {
if (parseCommon(offsetPath, key)) continue;
else if (KEY_AS("a")) parseProperty<LottieProperty::Type::Float>(offsetPath->offset);
else if (KEY_AS("a")) parseProperty(offsetPath->offset);
else if (KEY_AS("lj")) offsetPath->join = (StrokeJoin) getInt();
else if (KEY_AS("ml")) parseProperty<LottieProperty::Type::Float>(offsetPath->miterLimit);
else if (KEY_AS("ml")) parseProperty(offsetPath->miterLimit);
else skip();
}
return offsetPath;
@ -953,7 +950,7 @@ LottieObject* LottieParser::parseAsset()
if (data) {
obj = new LottieImage;
parseImage(static_cast<LottieImage*>(obj), data, subPath, embedded, width, height);
if (sid) registerSlot<LottieProperty::Type::Image>(obj, sid);
if (sid) registerSlot(obj, sid, LottieProperty::Type::Image);
}
if (obj) obj->id = id;
return obj;
@ -1087,7 +1084,7 @@ LottieObject* LottieParser::parseGroup()
void LottieParser::parseTimeRemap(LottieLayer* layer)
{
parseProperty<LottieProperty::Type::Float>(layer->timeRemap);
parseProperty(layer->timeRemap);
}
@ -1116,7 +1113,7 @@ void LottieParser::parseTextAlignmentOption(LottieText* text)
enterObject();
while (auto key = nextObjectKey()) {
if (KEY_AS("g")) text->alignOption.grouping = (LottieText::AlignOption::Group) getInt();
else if (KEY_AS("a")) parseProperty<LottieProperty::Type::Point>(text->alignOption.anchor);
else if (KEY_AS("a")) parseProperty(text->alignOption.anchor);
else skip();
}
}
@ -1136,35 +1133,35 @@ void LottieParser::parseTextRange(LottieText* text)
while (auto key = nextObjectKey()) {
if (KEY_AS("t")) selector->expressible = (bool) getInt();
else if (KEY_AS("xe")) {
parseProperty<LottieProperty::Type::Float>(selector->maxEase);
parseProperty(selector->maxEase);
selector->interpolator = tvg::malloc<LottieInterpolator*>(sizeof(LottieInterpolator));
}
else if (KEY_AS("ne")) parseProperty<LottieProperty::Type::Float>(selector->minEase);
else if (KEY_AS("a")) parseProperty<LottieProperty::Type::Float>(selector->maxAmount);
else if (KEY_AS("ne")) parseProperty(selector->minEase);
else if (KEY_AS("a")) parseProperty(selector->maxAmount);
else if (KEY_AS("b")) selector->based = (LottieTextRange::Based) getInt();
else if (KEY_AS("rn")) selector->random = getInt() ? rand() : 0;
else if (KEY_AS("sh")) selector->shape = (LottieTextRange::Shape) getInt();
else if (KEY_AS("o")) parseProperty<LottieProperty::Type::Float>(selector->offset);
else if (KEY_AS("o")) parseProperty(selector->offset);
else if (KEY_AS("r")) selector->rangeUnit = (LottieTextRange::Unit) getInt();
else if (KEY_AS("sm")) parseProperty<LottieProperty::Type::Float>(selector->smoothness);
else if (KEY_AS("s")) parseProperty<LottieProperty::Type::Float>(selector->start);
else if (KEY_AS("e")) parseProperty<LottieProperty::Type::Float>(selector->end);
else if (KEY_AS("sm")) parseProperty(selector->smoothness);
else if (KEY_AS("s")) parseProperty(selector->start);
else if (KEY_AS("e")) parseProperty(selector->end);
else skip();
}
} else if (KEY_AS("a")) { // text style
enterObject();
while (auto key = nextObjectKey()) {
if (KEY_AS("t")) parseProperty<LottieProperty::Type::Float>(selector->style.letterSpacing);
else if (KEY_AS("ls")) parseProperty<LottieProperty::Type::Color>(selector->style.lineSpacing);
else if (KEY_AS("fc")) parseProperty<LottieProperty::Type::Color>(selector->style.fillColor);
else if (KEY_AS("fo")) parseProperty<LottieProperty::Type::Color>(selector->style.fillOpacity);
else if (KEY_AS("sw")) parseProperty<LottieProperty::Type::Float>(selector->style.strokeWidth);
else if (KEY_AS("sc")) parseProperty<LottieProperty::Type::Color>(selector->style.strokeColor);
else if (KEY_AS("so")) parseProperty<LottieProperty::Type::Opacity>(selector->style.strokeOpacity);
else if (KEY_AS("o")) parseProperty<LottieProperty::Type::Opacity>(selector->style.opacity);
else if (KEY_AS("p")) parseProperty<LottieProperty::Type::Position>(selector->style.position);
else if (KEY_AS("s")) parseProperty<LottieProperty::Type::Position>(selector->style.scale);
else if (KEY_AS("r")) parseProperty<LottieProperty::Type::Float>(selector->style.rotation);
if (KEY_AS("t")) parseProperty(selector->style.letterSpacing);
else if (KEY_AS("ls")) parseProperty(selector->style.lineSpacing);
else if (KEY_AS("fc")) parseProperty(selector->style.fillColor);
else if (KEY_AS("fo")) parseProperty(selector->style.fillOpacity);
else if (KEY_AS("sw")) parseProperty(selector->style.strokeWidth);
else if (KEY_AS("sc")) parseProperty(selector->style.strokeColor);
else if (KEY_AS("so")) parseProperty(selector->style.strokeOpacity);
else if (KEY_AS("o")) parseProperty(selector->style.opacity);
else if (KEY_AS("p")) parseProperty(selector->style.position);
else if (KEY_AS("s")) parseProperty(selector->style.scale);
else if (KEY_AS("r")) parseProperty(selector->style.rotation);
else skip();
}
} else skip();
@ -1183,7 +1180,7 @@ void LottieParser::parseTextFollowPath(LottieText* text)
if (!text->followPath) text->followPath = new LottieTextFollowPath;
do {
if (KEY_AS("m")) text->followPath->maskIdx = getInt();
else if (KEY_AS("f")) parseProperty<LottieProperty::Type::Float>(text->followPath->firstMargin);
else if (KEY_AS("f")) parseProperty(text->followPath->firstMargin);
else skip();
} while ((key = nextObjectKey()));
}
@ -1196,7 +1193,7 @@ void LottieParser::parseText(Array<LottieObject*>& parent)
auto text = new LottieText;
while (auto key = nextObjectKey()) {
if (KEY_AS("d")) parseProperty<LottieProperty::Type::TextDoc>(text->doc, text);
if (KEY_AS("d")) parseProperty(text->doc, text);
else if (KEY_AS("a")) parseTextRange(text);
else if (KEY_AS("m")) parseTextAlignmentOption(text);
else if (KEY_AS("p")) parseTextFollowPath(text);
@ -1226,8 +1223,8 @@ LottieMask* LottieParser::parseMask()
if (KEY_AS("inv")) mask->inverse = getBool();
else if (KEY_AS("mode")) mask->method = getMaskMethod(mask->inverse);
else if (KEY_AS("pt")) getPathSet(mask->pathset);
else if (KEY_AS("o")) parseProperty<LottieProperty::Type::Opacity>(mask->opacity);
else if (KEY_AS("x")) parseProperty<LottieProperty::Type::Float>(mask->expand);
else if (KEY_AS("o")) parseProperty(mask->opacity);
else if (KEY_AS("x")) parseProperty(mask->expand);
else skip();
}
return mask;
@ -1512,29 +1509,29 @@ bool LottieParser::apply(LottieSlot* slot, bool byDefault)
context = {slot->context.layer, slot->context.parent};
switch (slot->type) {
case LottieProperty::Type::Position: {
obj = new LottieTransform;
parseSlotProperty<LottieProperty::Type::Position>(static_cast<LottieTransform*>(obj)->position);
break;
}
case LottieProperty::Type::Point: {
obj = new LottieTransform;
parseSlotProperty<LottieProperty::Type::Point>(static_cast<LottieTransform*>(obj)->scale);
break;
}
case LottieProperty::Type::Float: {
obj = new LottieTransform;
parseSlotProperty<LottieProperty::Type::Float>(static_cast<LottieTransform*>(obj)->rotation);
parseSlotProperty(static_cast<LottieTransform*>(obj)->rotation);
break;
}
case LottieProperty::Type::Scalar: {
obj = new LottieTransform;
parseSlotProperty(static_cast<LottieTransform*>(obj)->scale);
break;
}
case LottieProperty::Type::Vector: {
obj = new LottieTransform;
parseSlotProperty(static_cast<LottieTransform*>(obj)->position);
break;
}
case LottieProperty::Type::Opacity: {
obj = new LottieSolid;
parseSlotProperty<LottieProperty::Type::Opacity>(static_cast<LottieSolid*>(obj)->opacity);
parseSlotProperty(static_cast<LottieSolid*>(obj)->opacity);
break;
}
case LottieProperty::Type::Color: {
obj = new LottieSolid;
parseSlotProperty<LottieProperty::Type::Color>(static_cast<LottieSolid*>(obj)->color);
parseSlotProperty(static_cast<LottieSolid*>(obj)->color);
break;
}
case LottieProperty::Type::ColorStop: {
@ -1547,7 +1544,7 @@ bool LottieParser::apply(LottieSlot* slot, bool byDefault)
}
case LottieProperty::Type::TextDoc: {
obj = new LottieText;
parseSlotProperty<LottieProperty::Type::TextDoc>(static_cast<LottieText*>(obj)->doc);
parseSlotProperty(static_cast<LottieText*>(obj)->doc);
break;
}
case LottieProperty::Type::Image: {

View file

@ -40,7 +40,7 @@ public:
bool apply(LottieSlot* slot, bool byDefault);
const char* sid(bool first = false);
void captureSlots(const char* key);
template<LottieProperty::Type type = LottieProperty::Type::Invalid> void registerSlot(LottieObject* obj, const char* sid);
void registerSlot(LottieObject* obj, const char* sid, LottieProperty::Type type);
LottieComposition* comp = nullptr;
const char* dirName = nullptr; //base resource directory
@ -72,8 +72,8 @@ private:
template<typename T> bool parseTangent(const char *key, LottieScalarFrame<T>& value);
template<typename T> void parseKeyFrame(T& prop);
template<typename T> void parsePropertyInternal(T& prop);
template<LottieProperty::Type type = LottieProperty::Type::Invalid, typename T> void parseProperty(T& prop, LottieObject* obj = nullptr);
template<LottieProperty::Type type = LottieProperty::Type::Invalid, typename T> void parseSlotProperty(T& prop);
template<typename T> void parseProperty(T& prop, LottieObject* obj = nullptr);
template<typename T> void parseSlotProperty(T& prop);
LottieObject* parseObject();
LottieObject* parseAsset();

View file

@ -186,13 +186,13 @@ struct LottieExpression
//Property would have an either keyframes or single value.
struct LottieProperty
{
enum class Type : uint8_t { Point = 0, Float, Opacity, Color, PathSet, ColorStop, Position, TextDoc, Image, Invalid };
enum class Type : uint8_t { Invalid = 0, Float, Integer, Scalar, Vector, PathSet, Color, Opacity, ColorStop, TextDoc, Image};
LottieExpression* exp = nullptr;
Type type;
uint8_t ix; //property index
//TODO: Apply common bodies?
LottieProperty(Type type = Type::Invalid) : type(type) {}
virtual ~LottieProperty() {}
virtual uint32_t frameCnt() = 0;
virtual uint32_t nearest(float frameNo) = 0;
@ -316,15 +316,16 @@ float _loop(T* frames, float frameNo, LottieExpression* exp)
}
template<typename Frame, typename Value, bool Scalar = 1>
template<typename Frame, typename Value, LottieProperty::Type PType = LottieProperty::Type::Invalid, bool Scalar = 1>
struct LottieGenericProperty : LottieProperty
{
//Property has an either keyframes or single value.
Array<Frame>* frames = nullptr;
Value value;
LottieGenericProperty(Value v) : value(v) {}
LottieGenericProperty() {}
LottieGenericProperty(Value v) : LottieProperty(PType), value(v) {}
LottieGenericProperty() : LottieProperty(PType) {}
LottieGenericProperty(const LottieGenericProperty<Frame, Value>& rhs)
{
@ -402,7 +403,7 @@ struct LottieGenericProperty : LottieProperty
return tvg::lerp(operator()(frameNo, exps), operator()(tween.frameNo, exps), tween.progress);
}
void copy(LottieGenericProperty<Frame, Value, Scalar>& rhs, bool shallow = true)
void copy(LottieGenericProperty<Frame, Value, PType, Scalar>& rhs, bool shallow = true)
{
if (LottieProperty::copy(&rhs, shallow)) return;
@ -414,7 +415,10 @@ struct LottieGenericProperty : LottieProperty
frames = new Array<Frame>;
*frames = *rhs.frames;
}
} else value = rhs.value;
} else {
frames = nullptr;
value = rhs.value;
}
}
float angle(float frameNo)
@ -453,6 +457,8 @@ struct LottiePathSet : LottieProperty
Array<LottieScalarFrame<PathSet>>* frames = nullptr;
PathSet value;
LottiePathSet() : LottieProperty(LottieProperty::Type::PathSet) {}
~LottiePathSet()
{
release();
@ -638,7 +644,7 @@ struct LottieColorStop : LottieProperty
uint16_t count = 0; //colorstop count
bool populated = false;
LottieColorStop() {}
LottieColorStop() : LottieProperty(LottieProperty::Type::ColorStop) {}
LottieColorStop(const LottieColorStop& rhs)
{
@ -801,6 +807,7 @@ struct LottieColorStop : LottieProperty
*frames = *rhs.frames;
}
} else {
frames = nullptr;
value = rhs.value;
rhs.value = ColorStop();
}
@ -817,7 +824,7 @@ struct LottieTextDoc : LottieProperty
Array<LottieScalarFrame<TextDocument>>* frames = nullptr;
TextDocument value;
LottieTextDoc() {}
LottieTextDoc() : LottieProperty(LottieProperty::Type::TextDoc) {}
LottieTextDoc(const LottieTextDoc& rhs)
{
@ -923,6 +930,7 @@ struct LottieTextDoc : LottieProperty
*frames = *rhs.frames;
}
} else {
frames = nullptr;
value = rhs.value;
rhs.value.text = nullptr;
rhs.value.name = nullptr;
@ -944,7 +952,7 @@ struct LottieBitmap : LottieProperty
float width = 0.0f;
float height = 0.0f;
LottieBitmap() {}
LottieBitmap() : LottieProperty(LottieProperty::Type::Image) {}
LottieBitmap(const LottieBitmap& rhs)
{
@ -976,7 +984,6 @@ struct LottieBitmap : LottieProperty
if (shallow) {
b64Data = rhs.b64Data;
mimeType = rhs.mimeType;
rhs.b64Data = nullptr;
rhs.mimeType = nullptr;
} else {
@ -985,19 +992,18 @@ struct LottieBitmap : LottieProperty
b64Data = duplicate(rhs.b64Data);
if (rhs.mimeType) mimeType = duplicate(rhs.mimeType);
}
size = rhs.size;
width = rhs.width;
height = rhs.height;
}
};
using LottieFloat = LottieGenericProperty<LottieScalarFrame<float>, float, LottieProperty::Type::Float>;
using LottieInteger = LottieGenericProperty<LottieScalarFrame<int8_t>, int8_t, LottieProperty::Type::Integer>;
using LottieScalar = LottieGenericProperty<LottieScalarFrame<Point>, Point, LottieProperty::Type::Scalar>;
using LottieVector = LottieGenericProperty<LottieVectorFrame<Point>, Point, LottieProperty::Type::Vector, 0>;
using LottieColor = LottieGenericProperty<LottieScalarFrame<RGB24>, RGB24, LottieProperty::Type::Color>;
using LottieOpacity = LottieGenericProperty<LottieScalarFrame<uint8_t>, uint8_t, LottieProperty::Type::Opacity>;
using LottieScalar = LottieGenericProperty<LottieScalarFrame<Point>, Point>;
using LottieFloat = LottieGenericProperty<LottieScalarFrame<float>, float>;
using LottieOpacity = LottieGenericProperty<LottieScalarFrame<uint8_t>, uint8_t>;
using LottieColor = LottieGenericProperty<LottieScalarFrame<RGB24>, RGB24>;
using LottieInteger = LottieGenericProperty<LottieScalarFrame<int8_t>, int8_t>;
using LottieVector = LottieGenericProperty<LottieVectorFrame<Point>, Point, 0>;
#endif //_TVG_LOTTIE_PROPERTY_H_