diff --git a/src/loaders/lottie/tvgLottieBuilder.cpp b/src/loaders/lottie/tvgLottieBuilder.cpp index 00ee2245..a08cfe5e 100644 --- a/src/loaders/lottie/tvgLottieBuilder.cpp +++ b/src/loaders/lottie/tvgLottieBuilder.cpp @@ -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 bool found = false; for (auto g = text->font->chars.begin(); g < text->font->chars.end(); ++g) { auto glyph = *g; //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) { //new text group, single scene for each characters scene->push(std::move(textGroup)); @@ -1177,7 +1190,7 @@ void LottieBuilder::updateText(LottieLayer* layer, float frameNo) Matrix matrix; identity(&matrix); 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); } @@ -1188,6 +1201,7 @@ void LottieBuilder::updateText(LottieLayer* layer, float frameNo) auto matrix = shape->transform(); matrix.e13 = cursor.x; matrix.e23 = cursor.y; + matrix.e11 = matrix.e22 = capScale; //cases with matrix scaling factors =! 1 handled in the 'needGroup' scenario shape->transform(matrix); scene->push(cast(shape)); } @@ -1196,7 +1210,7 @@ void LottieBuilder::updateText(LottieLayer* layer, float frameNo) idx += glyph->len; //advance the cursor position horizontally - cursor.x += glyph->width + doc.tracking; + cursor.x += (glyph->width + doc.tracking) * capScale; found = true; break; diff --git a/src/loaders/lottie/tvgLottieCommon.h b/src/loaders/lottie/tvgLottieCommon.h index 5cdbdc3e..80b0718a 100644 --- a/src/loaders/lottie/tvgLottieCommon.h +++ b/src/loaders/lottie/tvgLottieCommon.h @@ -67,7 +67,8 @@ struct TextDocument char* name = nullptr; float size; float tracking = 0.0f; - uint8_t justify; + uint8_t justify = 0; + uint8_t caps = 0; //0: Regular, 1: AllCaps, 2: SmallCaps }; diff --git a/src/loaders/lottie/tvgLottieParser.cpp b/src/loaders/lottie/tvgLottieParser.cpp index 110e7dfb..aa95bc37 100644 --- a/src/loaders/lottie/tvgLottieParser.cpp +++ b/src/loaders/lottie/tvgLottieParser.cpp @@ -164,6 +164,7 @@ bool LottieParser::getValue(TextDocument& doc) else if (KEY_AS("f")) doc.name = getStringCopy(); else if (KEY_AS("t")) doc.text = getStringCopy(); 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("lh")) doc.height = getFloat(); else if (KEY_AS("ls")) doc.shift = getFloat();