lottie: fix transformations in text range selector

Since the translate API was used while text updating,
the subsequent range selector transformations gets overwritten
when updating the shape (scale and rotate, adding another
translation will persist). This caused unexpected results.
Fixed by using the transform API when additional transformations
are needed - also fixes applying more than one range selector.
This commit is contained in:
Mira Grudzinska 2024-10-21 21:36:23 +07:00 committed by Hermet Park
parent 33cfc16569
commit a851d1706e
2 changed files with 36 additions and 29 deletions

View file

@ -1060,43 +1060,50 @@ void LottieBuilder::updateText(LottieLayer* layer, float frameNo)
shape->stroke(doc.stroke.color.rgb[0], doc.stroke.color.rgb[1], doc.stroke.color.rgb[2]); shape->stroke(doc.stroke.color.rgb[0], doc.stroke.color.rgb[1], doc.stroke.color.rgb[2]);
} }
//text range process if (!text->ranges.empty()) {
for (auto s = text->ranges.begin(); s < text->ranges.end(); ++s) { Point scaling = {1.0f, 1.0f};
float start, end; auto rotation = 0.0f;
(*s)->range(frameNo, float(totalChars), start, end); auto translation = cursor;
auto basedIdx = idx; //text range process
if ((*s)->based == LottieTextRange::Based::CharsExcludingSpaces) basedIdx = idx - space; for (auto s = text->ranges.begin(); s < text->ranges.end(); ++s) {
else if ((*s)->based == LottieTextRange::Based::Words) basedIdx = line + space; float start, end;
else if ((*s)->based == LottieTextRange::Based::Lines) basedIdx = line; (*s)->range(frameNo, float(totalChars), start, end);
if (basedIdx < start || basedIdx >= end) continue; auto basedIdx = idx;
auto matrix = shape->transform(); if ((*s)->based == LottieTextRange::Based::CharsExcludingSpaces) basedIdx = idx - space;
else if ((*s)->based == LottieTextRange::Based::Words) basedIdx = line + space;
else if ((*s)->based == LottieTextRange::Based::Lines) basedIdx = line;
shape->opacity((*s)->style.opacity(frameNo)); if (basedIdx < start || basedIdx >= end) continue;
auto color = (*s)->style.fillColor(frameNo); translation = translation + (*s)->style.position(frameNo);
shape->fill(color.rgb[0], color.rgb[1], color.rgb[2], (*s)->style.fillOpacity(frameNo)); auto temp = (*s)->style.scale(frameNo);
scaling.x *= temp.x * 0.01f;
scaling.y *= temp.y * 0.01f;
rotation += (*s)->style.rotation(frameNo);
rotate(&matrix, (*s)->style.rotation(frameNo)); shape->opacity((*s)->style.opacity(frameNo));
auto glyphScale = (*s)->style.scale(frameNo) * 0.01f; auto color = (*s)->style.fillColor(frameNo);
tvg::scale(&matrix, glyphScale.x, glyphScale.y); shape->fill(color.rgb[0], color.rgb[1], color.rgb[2], (*s)->style.fillOpacity(frameNo));
auto position = (*s)->style.position(frameNo); if (doc.stroke.render) {
translate(&matrix, position.x, position.y); auto strokeColor = (*s)->style.strokeColor(frameNo);
shape->stroke((*s)->style.strokeWidth(frameNo) / scale);
shape->stroke(strokeColor.rgb[0], strokeColor.rgb[1], strokeColor.rgb[2], (*s)->style.strokeOpacity(frameNo));
}
cursor.x += (*s)->style.letterSpacing(frameNo);
shape->transform(matrix); auto spacing = (*s)->style.lineSpacing(frameNo);
if (spacing > lineSpacing) lineSpacing = spacing;
if (doc.stroke.render) {
auto strokeColor = (*s)->style.strokeColor(frameNo);
shape->stroke((*s)->style.strokeWidth(frameNo) / scale);
shape->stroke(strokeColor.rgb[0], strokeColor.rgb[1], strokeColor.rgb[2], (*s)->style.strokeOpacity(frameNo));
} }
cursor.x += (*s)->style.letterSpacing(frameNo); Matrix matrix;
identity(&matrix);
auto spacing = (*s)->style.lineSpacing(frameNo); translate(&matrix, translation.x, translation.y);
if (spacing > lineSpacing) lineSpacing = spacing; tvg::scale(&matrix, scaling.x, scaling.y);
rotate(&matrix, rotation);
shape->transform(matrix);
} }
scene->push(cast(shape)); scene->push(cast(shape));

View file

@ -107,7 +107,7 @@ namespace tvg
bool transform(const Matrix& m) bool transform(const Matrix& m)
{ {
tr.m = m; if (&tr.m != &m) tr.m = m;
tr.overriding = true; tr.overriding = true;
renderFlag |= RenderUpdateFlag::Transform; renderFlag |= RenderUpdateFlag::Transform;