mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 13:43:43 +00:00
lottie: Fixed a font/glyph parsing error.
Previously, the Lottie parser expected a specific parsing order: font followed by glyph, for optimal data processing. However, since this order is not guaranteed, we have revised the parsing logic to accommodate any order.
This commit is contained in:
parent
e7a1e6e43c
commit
5d02b3ac42
3 changed files with 32 additions and 18 deletions
|
@ -241,6 +241,8 @@ struct LottieGlyph
|
||||||
Array<LottieObject*> children; //glyph shapes.
|
Array<LottieObject*> children; //glyph shapes.
|
||||||
float width;
|
float width;
|
||||||
char* code;
|
char* code;
|
||||||
|
char* family = nullptr;
|
||||||
|
char* style = nullptr;
|
||||||
uint16_t size;
|
uint16_t size;
|
||||||
uint8_t len;
|
uint8_t len;
|
||||||
|
|
||||||
|
|
|
@ -956,26 +956,19 @@ void LottieParser::parseAssets()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LottieParser::parseChars()
|
void LottieParser::parseChars(Array<LottieGlyph*>& glyphes)
|
||||||
{
|
{
|
||||||
if (comp->fonts.count == 0) {
|
|
||||||
TVGERR("LOTTIE", "No font data?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
enterArray();
|
enterArray();
|
||||||
while (nextArrayValue()) {
|
while (nextArrayValue()) {
|
||||||
enterObject();
|
enterObject();
|
||||||
//a new glyph
|
//a new glyph
|
||||||
auto glyph = new LottieGlyph;
|
auto glyph = new LottieGlyph;
|
||||||
char* style = nullptr;
|
|
||||||
char* family = nullptr;
|
|
||||||
while (auto key = nextObjectKey()) {
|
while (auto key = nextObjectKey()) {
|
||||||
if (!strcmp("ch", key)) glyph->code = getStringCopy();
|
if (!strcmp("ch", key)) glyph->code = getStringCopy();
|
||||||
else if (!strcmp("size", key)) glyph->size = static_cast<uint16_t>(getFloat());
|
else if (!strcmp("size", key)) glyph->size = static_cast<uint16_t>(getFloat());
|
||||||
else if (!strcmp("style", key)) style = const_cast<char*>(getString());
|
else if (!strcmp("style", key)) glyph->style = getStringCopy();
|
||||||
else if (!strcmp("w", key)) glyph->width = getFloat();
|
else if (!strcmp("w", key)) glyph->width = getFloat();
|
||||||
else if (!strcmp("fFamily", key)) family = const_cast<char*>(getString());
|
else if (!strcmp("fFamily", key)) glyph->family = getStringCopy();
|
||||||
else if (!strcmp("data", key))
|
else if (!strcmp("data", key))
|
||||||
{ //glyph shapes
|
{ //glyph shapes
|
||||||
enterObject();
|
enterObject();
|
||||||
|
@ -984,13 +977,8 @@ void LottieParser::parseChars()
|
||||||
}
|
}
|
||||||
} else skip(key);
|
} else skip(key);
|
||||||
}
|
}
|
||||||
//aggregate the font characters
|
|
||||||
for (uint32_t i = 0; i < comp->fonts.count; ++i) {
|
|
||||||
auto& font = comp->fonts[i];
|
|
||||||
if (!strcmp(font->family, family) && !strcmp(font->style, style)) font->chars.push(glyph);
|
|
||||||
else TVGERR("LOTTIE", "No font data?");
|
|
||||||
}
|
|
||||||
glyph->prepare();
|
glyph->prepare();
|
||||||
|
glyphes.push(glyph);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1240,6 +1228,24 @@ LottieLayer* LottieParser::parseLayers()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LottieParser::postProcess(Array<LottieGlyph*>& glyphes)
|
||||||
|
{
|
||||||
|
//aggregate font characters
|
||||||
|
for (uint32_t g = 0; g < glyphes.count; ++g) {
|
||||||
|
auto glyph = glyphes[g];
|
||||||
|
for (uint32_t i = 0; i < comp->fonts.count; ++i) {
|
||||||
|
auto& font = comp->fonts[i];
|
||||||
|
if (!strcmp(font->family, glyph->family) && !strcmp(font->style, glyph->style)) {
|
||||||
|
font->chars.push(glyph);
|
||||||
|
free(glyph->family);
|
||||||
|
free(glyph->style);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* External Class Implementation */
|
/* External Class Implementation */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
@ -1255,6 +1261,8 @@ bool LottieParser::parse()
|
||||||
comp = new LottieComposition;
|
comp = new LottieComposition;
|
||||||
if (!comp) return false;
|
if (!comp) return false;
|
||||||
|
|
||||||
|
Array<LottieGlyph*> glyphes;
|
||||||
|
|
||||||
//assign parsing context
|
//assign parsing context
|
||||||
LottieParser::Context context;
|
LottieParser::Context context;
|
||||||
this->context = &context;
|
this->context = &context;
|
||||||
|
@ -1270,7 +1278,7 @@ bool LottieParser::parse()
|
||||||
else if (!strcmp(key, "assets")) parseAssets();
|
else if (!strcmp(key, "assets")) parseAssets();
|
||||||
else if (!strcmp(key, "layers")) comp->root = parseLayers();
|
else if (!strcmp(key, "layers")) comp->root = parseLayers();
|
||||||
else if (!strcmp(key, "fonts")) parseFonts();
|
else if (!strcmp(key, "fonts")) parseFonts();
|
||||||
else if (!strcmp(key, "chars")) parseChars();
|
else if (!strcmp(key, "chars")) parseChars(glyphes);
|
||||||
else skip(key);
|
else skip(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1278,5 +1286,8 @@ bool LottieParser::parse()
|
||||||
|
|
||||||
comp->root->inFrame = comp->startFrame;
|
comp->root->inFrame = comp->startFrame;
|
||||||
comp->root->outFrame = comp->endFrame;
|
comp->root->outFrame = comp->endFrame;
|
||||||
|
|
||||||
|
postProcess(glyphes);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
|
@ -99,7 +99,8 @@ private:
|
||||||
void parseTextRange(LottieText* text);
|
void parseTextRange(LottieText* text);
|
||||||
void parseAssets();
|
void parseAssets();
|
||||||
void parseFonts();
|
void parseFonts();
|
||||||
void parseChars();
|
void parseChars(Array<LottieGlyph*>& glyphes);
|
||||||
|
void postProcess(Array<LottieGlyph*>& glyphes);
|
||||||
|
|
||||||
//Current parsing context
|
//Current parsing context
|
||||||
struct Context {
|
struct Context {
|
||||||
|
|
Loading…
Add table
Reference in a new issue