mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 05:33:36 +00:00
svg_loader: Fix <stop> being registered in closed latestGradient
Some checks are pending
Android / build_x86_64 (push) Waiting to run
Android / build_aarch64 (push) Waiting to run
iOS / build_x86_64 (push) Waiting to run
iOS / build_arm64 (push) Waiting to run
macOS / build (push) Waiting to run
macOS / compact_test (push) Waiting to run
macOS / unit_test (push) Waiting to run
Ubuntu / build (push) Waiting to run
Ubuntu / compact_test (push) Waiting to run
Ubuntu / unit_test (push) Waiting to run
Windows / build (push) Waiting to run
Windows / compact_test (push) Waiting to run
Windows / unit_test (push) Waiting to run
Some checks are pending
Android / build_x86_64 (push) Waiting to run
Android / build_aarch64 (push) Waiting to run
iOS / build_x86_64 (push) Waiting to run
iOS / build_arm64 (push) Waiting to run
macOS / build (push) Waiting to run
macOS / compact_test (push) Waiting to run
macOS / unit_test (push) Waiting to run
Ubuntu / build (push) Waiting to run
Ubuntu / compact_test (push) Waiting to run
Ubuntu / unit_test (push) Waiting to run
Windows / build (push) Waiting to run
Windows / compact_test (push) Waiting to run
Windows / unit_test (push) Waiting to run
If stop is declared immediately after Gradient is closed, the stop is registered in latestGradient. Change latestGradient to a Stack and add a stop only to the last added gradient. When that gradient is closed, no more stops should be registered for that gradient. And gradients do not allow nested declarations, so only the earliest declared Gradient is valid.
This commit is contained in:
parent
633bcd3176
commit
c41b2c2a1c
2 changed files with 25 additions and 17 deletions
|
@ -3401,6 +3401,13 @@ static void _svgLoaderParserXmlClose(SvgLoaderData* loader, const char* content,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < sizeof(gradientTags) / sizeof(gradientTags[0]); i++) {
|
||||||
|
if (!strncmp(tagName, gradientTags[i].tag, sz)) {
|
||||||
|
loader->gradientStack.pop();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < sizeof(graphicsTags) / sizeof(graphicsTags[0]); i++) {
|
for (unsigned int i = 0; i < sizeof(graphicsTags) / sizeof(graphicsTags[0]); i++) {
|
||||||
if (!strncmp(tagName, graphicsTags[i].tag, sz)) {
|
if (!strncmp(tagName, graphicsTags[i].tag, sz)) {
|
||||||
loader->currentGraphicsNode = nullptr;
|
loader->currentGraphicsNode = nullptr;
|
||||||
|
@ -3472,7 +3479,6 @@ static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content,
|
||||||
if (node->type != SvgNodeType::Defs || !empty) {
|
if (node->type != SvgNodeType::Defs || !empty) {
|
||||||
loader->stack.push(node);
|
loader->stack.push(node);
|
||||||
}
|
}
|
||||||
loader->latestGradient = nullptr;
|
|
||||||
} else if ((method = _findGraphicsFactory(tagName))) {
|
} else if ((method = _findGraphicsFactory(tagName))) {
|
||||||
if (loader->stack.count > 0) parent = loader->stack.last();
|
if (loader->stack.count > 0) parent = loader->stack.last();
|
||||||
else parent = loader->doc;
|
else parent = loader->doc;
|
||||||
|
@ -3483,10 +3489,11 @@ static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content,
|
||||||
loader->stack.push(defs);
|
loader->stack.push(defs);
|
||||||
loader->currentGraphicsNode = node;
|
loader->currentGraphicsNode = node;
|
||||||
}
|
}
|
||||||
loader->latestGradient = nullptr;
|
|
||||||
} else if ((gradientMethod = _findGradientFactory(tagName))) {
|
} else if ((gradientMethod = _findGradientFactory(tagName))) {
|
||||||
SvgStyleGradient* gradient;
|
SvgStyleGradient* gradient;
|
||||||
gradient = gradientMethod(loader, attrs, attrsLength);
|
gradient = gradientMethod(loader, attrs, attrsLength);
|
||||||
|
//Gradients do not allow nested declarations, so only the earliest declared Gradient is valid.
|
||||||
|
if (loader->gradientStack.count == 0) {
|
||||||
//FIXME: The current parsing structure does not distinguish end tags.
|
//FIXME: The current parsing structure does not distinguish end tags.
|
||||||
// There is no way to know if the currently parsed gradient is in defs.
|
// There is no way to know if the currently parsed gradient is in defs.
|
||||||
// If a gradient is declared outside of defs after defs is set, it is included in the gradients of defs.
|
// If a gradient is declared outside of defs after defs is set, it is included in the gradients of defs.
|
||||||
|
@ -3498,9 +3505,10 @@ static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content,
|
||||||
} else {
|
} else {
|
||||||
loader->gradients.push(gradient);
|
loader->gradients.push(gradient);
|
||||||
}
|
}
|
||||||
loader->latestGradient = gradient;
|
}
|
||||||
|
if (!empty) loader->gradientStack.push(gradient);
|
||||||
} else if (STR_AS(tagName, "stop")) {
|
} else if (STR_AS(tagName, "stop")) {
|
||||||
if (!loader->latestGradient) {
|
if (loader->gradientStack.count == 0) {
|
||||||
TVGLOG("SVG", "Stop element is used outside of the Gradient element");
|
TVGLOG("SVG", "Stop element is used outside of the Gradient element");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3508,9 +3516,8 @@ static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content,
|
||||||
loader->svgParse->gradStop = {0.0f, 0, 0, 0, 255};
|
loader->svgParse->gradStop = {0.0f, 0, 0, 0, 255};
|
||||||
loader->svgParse->flags = SvgStopStyleFlags::StopDefault;
|
loader->svgParse->flags = SvgStopStyleFlags::StopDefault;
|
||||||
xmlParseAttributes(attrs, attrsLength, _attrParseStops, loader);
|
xmlParseAttributes(attrs, attrsLength, _attrParseStops, loader);
|
||||||
loader->latestGradient->stops.push(loader->svgParse->gradStop);
|
loader->gradientStack.last()->stops.push(loader->svgParse->gradStop);
|
||||||
} else {
|
} else {
|
||||||
loader->latestGradient = nullptr;
|
|
||||||
if (!isIgnoreUnsupportedLogElements(tagName)) TVGLOG("SVG", "Unsupported elements used [Elements: %s]", tagName);
|
if (!isIgnoreUnsupportedLogElements(tagName)) TVGLOG("SVG", "Unsupported elements used [Elements: %s]", tagName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3831,6 +3838,7 @@ void SvgLoader::clear(bool all)
|
||||||
tvg::free(*p);
|
tvg::free(*p);
|
||||||
}
|
}
|
||||||
loaderData.gradients.reset();
|
loaderData.gradients.reset();
|
||||||
|
loaderData.gradientStack.reset();
|
||||||
|
|
||||||
_freeNode(loaderData.doc);
|
_freeNode(loaderData.doc);
|
||||||
loaderData.doc = nullptr;
|
loaderData.doc = nullptr;
|
||||||
|
|
|
@ -590,7 +590,7 @@ struct SvgLoaderData
|
||||||
SvgNode* def = nullptr; //also used to store nested graphic nodes
|
SvgNode* def = nullptr; //also used to store nested graphic nodes
|
||||||
SvgNode* cssStyle = nullptr;
|
SvgNode* cssStyle = nullptr;
|
||||||
Array<SvgStyleGradient*> gradients;
|
Array<SvgStyleGradient*> gradients;
|
||||||
SvgStyleGradient* latestGradient = nullptr; //For stops
|
Array<SvgStyleGradient*> gradientStack; //For stops
|
||||||
SvgParser* svgParse = nullptr;
|
SvgParser* svgParse = nullptr;
|
||||||
Array<SvgNodeIdPair> cloneNodes;
|
Array<SvgNodeIdPair> cloneNodes;
|
||||||
Array<SvgNodeIdPair> nodesToStyle;
|
Array<SvgNodeIdPair> nodesToStyle;
|
||||||
|
|
Loading…
Add table
Reference in a new issue