lottie: support Layer Effect Fill type

During the fill properties, only color/opacity is available.
Not support other properties since they are unclear spec now.

issue: https://github.com/thorvg/thorvg/issues/2718
This commit is contained in:
Hermet Park 2024-12-11 19:40:26 +09:00
parent 666dcbcb38
commit a0a7ec25a2
4 changed files with 69 additions and 17 deletions

View file

@ -1314,14 +1314,20 @@ void LottieBuilder::updateEffect(LottieLayer* layer, float frameNo)
for (auto ef = layer->effects.begin(); ef < layer->effects.end(); ++ef) { for (auto ef = layer->effects.begin(); ef < layer->effects.end(); ++ef) {
if (!(*ef)->enable) continue; if (!(*ef)->enable) continue;
switch ((*ef)->type) { switch ((*ef)->type) {
case LottieEffect::Fill: {
auto effect = static_cast<LottieFxFill*>(*ef);
auto color = effect->color(frameNo);
layer->scene->push(SceneEffect::Fill, color.rgb[0], color.rgb[1], color.rgb[2], (int)(255.0f *effect->opacity(frameNo)));
break;
}
case LottieEffect::DropShadow: { case LottieEffect::DropShadow: {
auto effect = static_cast<LottieDropShadow*>(*ef); auto effect = static_cast<LottieFxDropShadow*>(*ef);
auto color = effect->color(frameNo); auto color = effect->color(frameNo);
layer->scene->push(SceneEffect::DropShadow, color.rgb[0], color.rgb[1], color.rgb[2], (int)effect->opacity(frameNo), effect->angle(frameNo), effect->distance(frameNo), effect->blurness(frameNo) * BLUR_TO_SIGMA, QUALITY); layer->scene->push(SceneEffect::DropShadow, color.rgb[0], color.rgb[1], color.rgb[2], (int)effect->opacity(frameNo), effect->angle(frameNo), effect->distance(frameNo), effect->blurness(frameNo) * BLUR_TO_SIGMA, QUALITY);
break; break;
} }
case LottieEffect::GaussianBlur: { case LottieEffect::GaussianBlur: {
auto effect = static_cast<LottieGaussianBlur*>(*ef); auto effect = static_cast<LottieFxGaussianBlur*>(*ef);
layer->scene->push(SceneEffect::GaussianBlur, effect->blurness(frameNo) * BLUR_TO_SIGMA, effect->direction(frameNo) - 1, effect->wrap(frameNo), QUALITY); layer->scene->push(SceneEffect::GaussianBlur, effect->blurness(frameNo) * BLUR_TO_SIGMA, effect->direction(frameNo) - 1, effect->wrap(frameNo), QUALITY);
break; break;
} }

View file

@ -83,6 +83,7 @@ struct LottieEffect
{ {
DropShadow = 0, DropShadow = 0,
GaussianBlur = 1, GaussianBlur = 1,
Fill = 2,
}; };
virtual ~LottieEffect() {} virtual ~LottieEffect() {}
@ -92,28 +93,45 @@ struct LottieEffect
}; };
struct LottieDropShadow : LottieEffect struct LottieFxFill : LottieEffect
{
//LottieFloat fillMask?
//LottieDropDown allMask?
LottieColor color;
//LottieDropDown inverted
//LottieSlider horizontalFeather
//LottieSlider verticalFeather
LottieSlider opacity = 0;
LottieFxFill()
{
type = Fill;
}
};
struct LottieFxDropShadow : LottieEffect
{ {
LottieColor color; LottieColor color;
LottieFloat opacity = 0; LottieSlider opacity = 0;
LottieAngle angle = 0.0f; LottieAngle angle = 0.0f;
LottieSlider distance = 0.0f; LottieSlider distance = 0.0f;
LottieSlider blurness = 0.0f; LottieSlider blurness = 0.0f;
LottieDropShadow() LottieFxDropShadow()
{ {
type = DropShadow; type = DropShadow;
} }
}; };
struct LottieGaussianBlur : LottieEffect struct LottieFxGaussianBlur : LottieEffect
{ {
LottieSlider blurness = 0.0f; LottieSlider blurness = 0.0f;
LottieCheckbox direction = 0; LottieCheckbox direction = 0;
LottieCheckbox wrap = 0; LottieCheckbox wrap = 0;
LottieGaussianBlur() LottieFxGaussianBlur()
{ {
type = GaussianBlur; type = GaussianBlur;
} }

View file

@ -60,8 +60,9 @@ static unsigned long _int2str(int num)
LottieEffect* LottieParser::getEffect(int type) LottieEffect* LottieParser::getEffect(int type)
{ {
switch (type) { switch (type) {
case 25: return new LottieDropShadow; case 21: return new LottieFxFill;
case 29: return new LottieGaussianBlur; case 25: return new LottieFxDropShadow;
case 29: return new LottieFxGaussianBlur;
default: return nullptr; default: return nullptr;
} }
} }
@ -1268,7 +1269,30 @@ void LottieParser::parseMasks(LottieLayer* layer)
} }
void LottieParser::parseGaussianBlur(LottieGaussianBlur* effect) void LottieParser::parseFill(LottieFxFill* effect)
{
int idx = 0; //fill mask -> all mask -> color -> invert -> h feather -> v feather -> opacity
enterArray();
while (nextArrayValue()) {
enterObject();
while (auto key = nextObjectKey()) {
if (KEY_AS("v")) {
enterObject();
while (auto key = nextObjectKey()) {
if (KEY_AS("k")) {
if (idx == 2) parsePropertyInternal(effect->color);
else if (idx == 6) parsePropertyInternal(effect->opacity);
else skip();
} else skip();
}
++idx;
} else skip();
}
}
}
void LottieParser::parseGaussianBlur(LottieFxGaussianBlur* effect)
{ {
int idx = 0; //blurness -> direction -> wrap int idx = 0; //blurness -> direction -> wrap
enterArray(); enterArray();
@ -1292,7 +1316,7 @@ void LottieParser::parseGaussianBlur(LottieGaussianBlur* effect)
} }
void LottieParser::parseDropShadow(LottieDropShadow* effect) void LottieParser::parseDropShadow(LottieFxDropShadow* effect)
{ {
int idx = 0; //color -> opacity -> angle -> distance -> blur int idx = 0; //color -> opacity -> angle -> distance -> blur
enterArray(); enterArray();
@ -1321,12 +1345,16 @@ void LottieParser::parseDropShadow(LottieDropShadow* effect)
void LottieParser::parseEffect(LottieEffect* effect) void LottieParser::parseEffect(LottieEffect* effect)
{ {
switch (effect->type) { switch (effect->type) {
case LottieEffect::Fill: {
parseFill(static_cast<LottieFxFill*>(effect));
break;
}
case LottieEffect::GaussianBlur: { case LottieEffect::GaussianBlur: {
parseGaussianBlur(static_cast<LottieGaussianBlur*>(effect)); parseGaussianBlur(static_cast<LottieFxGaussianBlur*>(effect));
break; break;
} }
case LottieEffect::DropShadow: { case LottieEffect::DropShadow: {
parseDropShadow(static_cast<LottieDropShadow*>(effect)); parseDropShadow(static_cast<LottieFxDropShadow*>(effect));
break; break;
} }
default: break; default: break;
@ -1336,11 +1364,10 @@ void LottieParser::parseEffect(LottieEffect* effect)
void LottieParser::parseEffects(LottieLayer* layer) void LottieParser::parseEffects(LottieLayer* layer)
{ {
auto invalid = true;
enterArray(); enterArray();
while (nextArrayValue()) { while (nextArrayValue()) {
LottieEffect* effect = nullptr; LottieEffect* effect = nullptr;
auto invalid = true;
enterObject(); enterObject();
while (auto key = nextObjectKey()) { while (auto key = nextObjectKey()) {
//type must be priortized. //type must be priortized.

View file

@ -98,8 +98,9 @@ private:
LottieFont* parseFont(); LottieFont* parseFont();
LottieMarker* parseMarker(); LottieMarker* parseMarker();
void parseGaussianBlur(LottieGaussianBlur* effect); void parseFill(LottieFxFill* effect);
void parseDropShadow(LottieDropShadow* effect); void parseGaussianBlur(LottieFxGaussianBlur* effect);
void parseDropShadow(LottieFxDropShadow* effect);
bool parseDirection(LottieShape* shape, const char* key); bool parseDirection(LottieShape* shape, const char* key);
bool parseCommon(LottieObject* obj, const char* key); bool parseCommon(LottieObject* obj, const char* key);