lottie: add TextCaps property support

This commit is contained in:
Mira Grudzinska 2024-12-03 00:32:51 +01:00 committed by Hermet Park
parent a2d2b3f07c
commit 6b416409c3
3 changed files with 20 additions and 4 deletions

View file

@ -1051,12 +1051,25 @@ void LottieBuilder::updateText(LottieLayer* layer, float frameNo)
} }
} }
/* all lowercase letters are converted to uppercase in the "t" text field, making the "ca" value irrelevant, thus AllCaps is nothing to do.
So only convert lowercase letters to uppercase (for 'SmallCaps' an extra scaling factor applied) */
auto code = p;
auto capScale = 1.0f;
char capCode;
if ((unsigned char)(p[0]) < 0x80 && doc.caps) {
if (*p >= 'a' && *p <= 'z') {
capCode = *p + 'A' - 'a';
code = &capCode;
if (doc.caps == 2) capScale = 0.7f;
}
}
//find the glyph //find the glyph
bool found = false; bool found = false;
for (auto g = text->font->chars.begin(); g < text->font->chars.end(); ++g) { for (auto g = text->font->chars.begin(); g < text->font->chars.end(); ++g) {
auto glyph = *g; auto glyph = *g;
//draw matched glyphs //draw matched glyphs
if (!strncmp(glyph->code, p, glyph->len)) { if (!strncmp(glyph->code, code, glyph->len)) {
if (textGrouping == LottieText::AlignOption::Group::Chars || textGrouping == LottieText::AlignOption::Group::All) { if (textGrouping == LottieText::AlignOption::Group::Chars || textGrouping == LottieText::AlignOption::Group::All) {
//new text group, single scene for each characters //new text group, single scene for each characters
scene->push(textGroup); scene->push(textGroup);
@ -1169,7 +1182,7 @@ void LottieBuilder::updateText(LottieLayer* layer, float frameNo)
auto& matrix = shape->transform(); auto& matrix = shape->transform();
identity(&matrix); identity(&matrix);
translate(&matrix, translation.x / scale + cursor.x - textGroupMatrix.e13, translation.y / scale + cursor.y - textGroupMatrix.e23); translate(&matrix, translation.x / scale + cursor.x - textGroupMatrix.e13, translation.y / scale + cursor.y - textGroupMatrix.e23);
tvg::scale(&matrix, scaling.x, scaling.y); tvg::scale(&matrix, scaling.x * capScale, scaling.y * capScale);
shape->transform(matrix); shape->transform(matrix);
} }
@ -1180,6 +1193,7 @@ void LottieBuilder::updateText(LottieLayer* layer, float frameNo)
auto& matrix = shape->transform(); auto& matrix = shape->transform();
matrix.e13 = cursor.x; matrix.e13 = cursor.x;
matrix.e23 = cursor.y; matrix.e23 = cursor.y;
matrix.e11 = matrix.e22 = capScale; //cases with matrix scaling factors =! 1 handled in the 'needGroup' scenario
shape->transform(matrix); shape->transform(matrix);
scene->push(shape); scene->push(shape);
} }
@ -1188,7 +1202,7 @@ void LottieBuilder::updateText(LottieLayer* layer, float frameNo)
idx += glyph->len; idx += glyph->len;
//advance the cursor position horizontally //advance the cursor position horizontally
cursor.x += glyph->width + doc.tracking; cursor.x += (glyph->width + doc.tracking) * capScale;
found = true; found = true;
break; break;

View file

@ -67,7 +67,8 @@ struct TextDocument
char* name = nullptr; char* name = nullptr;
float size; float size;
float tracking = 0.0f; float tracking = 0.0f;
uint8_t justify; uint8_t justify = 0;
uint8_t caps = 0; //0: Regular, 1: AllCaps, 2: SmallCaps
}; };

View file

@ -164,6 +164,7 @@ bool LottieParser::getValue(TextDocument& doc)
else if (KEY_AS("f")) doc.name = getStringCopy(); else if (KEY_AS("f")) doc.name = getStringCopy();
else if (KEY_AS("t")) doc.text = getStringCopy(); else if (KEY_AS("t")) doc.text = getStringCopy();
else if (KEY_AS("j")) doc.justify = getInt(); else if (KEY_AS("j")) doc.justify = getInt();
else if (KEY_AS("ca")) doc.caps = getInt();
else if (KEY_AS("tr")) doc.tracking = getFloat() * 0.1f; else if (KEY_AS("tr")) doc.tracking = getFloat() * 0.1f;
else if (KEY_AS("lh")) doc.height = getFloat(); else if (KEY_AS("lh")) doc.height = getFloat();
else if (KEY_AS("ls")) doc.shift = getFloat(); else if (KEY_AS("ls")) doc.shift = getFloat();