lottie: add TextCaps property support

This commit is contained in:
Mira Grudzinska 2024-12-03 00:32:51 +01:00
parent 36e5f68222
commit f3cc245b37
3 changed files with 20 additions and 4 deletions

View file

@ -1049,12 +1049,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(std::move(textGroup)); scene->push(std::move(textGroup));
@ -1177,7 +1190,7 @@ void LottieBuilder::updateText(LottieLayer* layer, float frameNo)
Matrix matrix; Matrix matrix;
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);
} }
@ -1188,6 +1201,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(cast(shape)); scene->push(cast(shape));
} }
@ -1196,7 +1210,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();