lottie: fix text stroke's 'of' property

The text stroke's 'of' property determines whether
the stroke appears above (true) or below (false)
the fill.
Previously, it was incorrectly used to decide whether
the stroke would render.

@Issue: https://github.com/thorvg/thorvg/issues/3126
This commit is contained in:
Mira Grudzinska 2025-01-14 12:35:17 +01:00 committed by Hermet Park
parent 8f98681ea7
commit 096b834771
3 changed files with 7 additions and 5 deletions

View file

@ -1092,10 +1092,11 @@ void LottieBuilder::updateText(LottieLayer* layer, float frameNo)
shape->translate(cursor.x - textGroupMatrix.e13, cursor.y - textGroupMatrix.e23); shape->translate(cursor.x - textGroupMatrix.e13, cursor.y - textGroupMatrix.e23);
shape->opacity(255); shape->opacity(255);
if (doc.stroke.render) { if (doc.stroke.width > 0.0f) {
shape->strokeJoin(StrokeJoin::Round); shape->strokeJoin(StrokeJoin::Round);
shape->strokeWidth(doc.stroke.width / scale); shape->strokeWidth(doc.stroke.width / scale);
shape->strokeFill(doc.stroke.color.rgb[0], doc.stroke.color.rgb[1], doc.stroke.color.rgb[2]); shape->strokeFill(doc.stroke.color.rgb[0], doc.stroke.color.rgb[1], doc.stroke.color.rgb[2]);
shape->order(doc.stroke.below);
} }
auto needGroup = false; auto needGroup = false;
@ -1137,8 +1138,8 @@ void LottieBuilder::updateText(LottieLayer* layer, float frameNo)
fillOpacity = (uint8_t)(fillOpacity - f * (fillOpacity - (*s)->style.fillOpacity(frameNo))); fillOpacity = (uint8_t)(fillOpacity - f * (fillOpacity - (*s)->style.fillOpacity(frameNo)));
shape->fill(color.rgb[0], color.rgb[1], color.rgb[2], fillOpacity); shape->fill(color.rgb[0], color.rgb[1], color.rgb[2], fillOpacity);
if (doc.stroke.render) {
shape->strokeWidth(f * (*s)->style.strokeWidth(frameNo) / scale); shape->strokeWidth(f * (*s)->style.strokeWidth(frameNo) / scale);
if (shape->strokeWidth() > 0.0f) {
auto rangeColor = (*s)->style.strokeColor(frameNo); //TODO: use flag to check whether it was really set auto rangeColor = (*s)->style.strokeColor(frameNo); //TODO: use flag to check whether it was really set
if (tvg::equal(f, 1.0f)) strokeColor = rangeColor; if (tvg::equal(f, 1.0f)) strokeColor = rangeColor;
else { else {
@ -1148,6 +1149,7 @@ void LottieBuilder::updateText(LottieLayer* layer, float frameNo)
} }
strokeOpacity = (uint8_t)(strokeOpacity - f * (strokeOpacity - (*s)->style.strokeOpacity(frameNo))); strokeOpacity = (uint8_t)(strokeOpacity - f * (strokeOpacity - (*s)->style.strokeOpacity(frameNo)));
shape->strokeFill(strokeColor.rgb[0], strokeColor.rgb[1], strokeColor.rgb[2], strokeOpacity); shape->strokeFill(strokeColor.rgb[0], strokeColor.rgb[1], strokeColor.rgb[2], strokeOpacity);
shape->order(doc.stroke.below);
} }
cursor.x += f * (*s)->style.letterSpacing(frameNo); cursor.x += f * (*s)->style.letterSpacing(frameNo);

View file

@ -62,7 +62,7 @@ struct TextDocument
struct { struct {
RGB24 color; RGB24 color;
float width; float width;
bool render = false; bool below = false;
} stroke; } stroke;
char* name = nullptr; char* name = nullptr;
float size; float size;

View file

@ -136,7 +136,7 @@ bool LottieParser::getValue(TextDocument& doc)
else if (KEY_AS("sz")) getValue(doc.bbox.size); else if (KEY_AS("sz")) getValue(doc.bbox.size);
else if (KEY_AS("sc")) getValue(doc.stroke.color); else if (KEY_AS("sc")) getValue(doc.stroke.color);
else if (KEY_AS("sw")) doc.stroke.width = getFloat(); else if (KEY_AS("sw")) doc.stroke.width = getFloat();
else if (KEY_AS("of")) doc.stroke.render = getBool(); else if (KEY_AS("of")) doc.stroke.below = !getBool();
else skip(); else skip();
} }
return false; return false;