lottie: parsing embedded fonts data (#3220)

Only parsing and font loading is added with
a very basic text update while building the scene.

@Issue: https://github.com/thorvg/thorvg/issues/3184
This commit is contained in:
Mira Grudzinska 2025-02-14 15:52:10 +01:00
parent 7a1df343cc
commit 589e93fa74
5 changed files with 56 additions and 0 deletions

View file

@ -994,6 +994,21 @@ void LottieBuilder::updateImage(LottieGroup* layer)
}
void _fontURLText(LottieText* text, Scene* main, float frameNo, LottieExpressions* exps)
{
auto& doc = text->doc(frameNo);
if (!doc.text) return;
const float ptPerPx = 0.75f; //1 pt = 1/72; 1 in = 96 px; -> 72/96 = 0.75
auto txt = Text::gen();
txt->font(doc.name, doc.size * 100.0f * ptPerPx);
txt->translate(0.0f, -doc.size * 100.0f);
txt->text(doc.text);
txt->fill(doc.color.rgb[0], doc.color.rgb[1], doc.color.rgb[2]);
main->push(std::move(txt));
}
void LottieBuilder::updateText(LottieLayer* layer, float frameNo)
{
auto text = static_cast<LottieText*>(layer->children.first());
@ -1003,6 +1018,11 @@ void LottieBuilder::updateText(LottieLayer* layer, float frameNo)
if (!p || !text->font) return;
if (text->font->origin == LottieFont::Origin::FontURL) {
_fontURLText(text, layer->scene, frameNo, exps);
return;
}
auto scale = doc.size;
Point cursor = {0.0f, 0.0f};
auto scene = Scene::gen();

View file

@ -197,6 +197,16 @@ float LottieTextRange::factor(float frameNo, float totalLen, float idx)
}
void LottieFont::prepare()
{
if (!data.b64src || !name) return;
TaskScheduler::async(false);
Text::load(name, data.b64src, data.size, "ttf", false);
TaskScheduler::async(true);
}
void LottieImage::prepare()
{
LottieObject::type = LottieObject::Image;

View file

@ -303,14 +303,23 @@ struct LottieFont
free(style);
free(family);
free(name);
free(data.b64src);
}
struct {
char* b64src = nullptr;
uint32_t size = 0;
} data;
Array<LottieGlyph*> chars;
char* name = nullptr;
char* family = nullptr;
char* style = nullptr;
size_t dataSize = 0;
float ascent = 0.0f;
Origin origin = Embedded;
void prepare();
};
struct LottieMarker

View file

@ -995,6 +995,19 @@ LottieObject* LottieParser::parseAsset()
}
void LottieParser::parseFontData(LottieFont* font, const char* data)
{
if (!data) return;
if (strncmp(data, "data:font/ttf;base64,", sizeof("data:font/ttf;base64,") - 1) != 0) {
TVGLOG("LOTTIE", "Unsupported embeded font data format");
return;
}
auto ttf = data + sizeof("data:font/ttf;base64,") - 1;
font->data.size = b64Decode(ttf, strlen(ttf), &font->data.b64src);
}
LottieFont* LottieParser::parseFont()
{
enterObject();
@ -1005,10 +1018,13 @@ LottieFont* LottieParser::parseFont()
if (KEY_AS("fName")) font->name = getStringCopy();
else if (KEY_AS("fFamily")) font->family = getStringCopy();
else if (KEY_AS("fStyle")) font->style = getStringCopy();
else if (KEY_AS("fPath")) parseFontData(font, getString());
else if (KEY_AS("ascent")) font->ascent = getFloat();
else if (KEY_AS("origin")) font->origin = (LottieFont::Origin) getInt();
else skip(key);
}
font->prepare();
return font;
}

View file

@ -96,6 +96,7 @@ private:
LottieRepeater* parseRepeater();
LottieOffsetPath* parseOffsetPath();
LottieFont* parseFont();
void parseFontData(LottieFont* font, const char* data);
LottieMarker* parseMarker();
void parseEffect(LottieEffect* effect, void(LottieParser::*func)(LottieEffect*, int));