svg_loader: symbol node without any viewbox/width/height info handled properly

This commit is contained in:
mgrudzinska 2022-03-20 18:27:34 +01:00 committed by Hermet Park
parent bc5c29dd69
commit 1e8b8cbb53
3 changed files with 21 additions and 7 deletions

View file

@ -1145,10 +1145,13 @@ static bool _attrParseSymbolNode(void* data, const char* key, const char* value)
if (!strcmp(key, "viewBox")) { if (!strcmp(key, "viewBox")) {
if (!_parseNumber(&value, &symbol->vx) || !_parseNumber(&value, &symbol->vy)) return false; if (!_parseNumber(&value, &symbol->vx) || !_parseNumber(&value, &symbol->vy)) return false;
if (!_parseNumber(&value, &symbol->vw) || !_parseNumber(&value, &symbol->vh)) return false; if (!_parseNumber(&value, &symbol->vw) || !_parseNumber(&value, &symbol->vh)) return false;
symbol->hasViewBox = true;
} else if (!strcmp(key, "width")) { } else if (!strcmp(key, "width")) {
symbol->w = _toFloat(loader->svgParse, value, SvgParserLengthType::Horizontal); symbol->w = _toFloat(loader->svgParse, value, SvgParserLengthType::Horizontal);
symbol->hasWidth = true;
} else if (!strcmp(key, "height")) { } else if (!strcmp(key, "height")) {
symbol->h = _toFloat(loader->svgParse, value, SvgParserLengthType::Vertical); symbol->h = _toFloat(loader->svgParse, value, SvgParserLengthType::Vertical);
symbol->hasHeight = true;
} else if (!strcmp(key, "preserveAspectRatio")) { } else if (!strcmp(key, "preserveAspectRatio")) {
if (!strcmp(value, "none")) symbol->preserveAspect = false; if (!strcmp(value, "none")) symbol->preserveAspect = false;
} else if (!strcmp(key, "overflow")) { } else if (!strcmp(key, "overflow")) {
@ -1306,6 +1309,12 @@ static SvgNode* _createSymbolNode(SvgLoaderData* loader, SvgNode* parent, const
loader->svgParse->node->node.symbol.preserveAspect = true; loader->svgParse->node->node.symbol.preserveAspect = true;
loader->svgParse->node->node.symbol.overflowVisible = false; loader->svgParse->node->node.symbol.overflowVisible = false;
loader->svgParse->node->node.symbol.hasViewBox = false;
loader->svgParse->node->node.symbol.hasWidth = false;
loader->svgParse->node->node.symbol.hasHeight = false;
loader->svgParse->node->node.symbol.vx = 0.0f;
loader->svgParse->node->node.symbol.vy = 0.0f;
func(buf, bufLength, _attrParseSymbolNode, loader); func(buf, bufLength, _attrParseSymbolNode, loader);
return loader->svgParse->node; return loader->svgParse->node;

View file

@ -173,6 +173,9 @@ struct SvgSymbolNode
float vx, vy, vw, vh; float vx, vy, vw, vh;
bool preserveAspect; bool preserveAspect;
bool overflowVisible; bool overflowVisible;
bool hasViewBox;
bool hasWidth;
bool hasHeight;
}; };
struct SvgUseNode struct SvgUseNode

View file

@ -576,15 +576,17 @@ static unique_ptr<Scene> _useBuildHelper(const SvgNode* node, const Box& vBox, c
if (node->node.use.symbol) { if (node->node.use.symbol) {
auto symbol = node->node.use.symbol->node.symbol; auto symbol = node->node.use.symbol->node.symbol;
auto width = symbol.w; auto width = (symbol.hasWidth ? symbol.w : vBox.w);
if (node->node.use.isWidthSet) width = node->node.use.w; if (node->node.use.isWidthSet) width = node->node.use.w;
auto height = symbol.h; auto height = (symbol.hasHeight ? symbol.h : vBox.h);;
if (node->node.use.isHeightSet) height = node->node.use.h; if (node->node.use.isHeightSet) height = node->node.use.h;
auto vw = (symbol.hasViewBox ? symbol.vw : width);
auto vh = (symbol.hasViewBox ? symbol.vh : height);
Matrix mViewBox = {1, 0, 0, 0, 1, 0, 0, 0, 1}; Matrix mViewBox = {1, 0, 0, 0, 1, 0, 0, 0, 1};
if ((!mathEqual(width, symbol.vw) || !mathEqual(height, symbol.vh)) && symbol.vw > 0 && symbol.vh > 0) { if ((!mathEqual(width, vw) || !mathEqual(height, vh)) && vw > 0 && vh > 0) {
auto sx = width / symbol.vw; auto sx = width / vw;
auto sy = height / symbol.vh; auto sy = height / vh;
if (symbol.preserveAspect) { if (symbol.preserveAspect) {
if (sx < sy) sy = sx; if (sx < sy) sy = sx;
else sx = sy; else sx = sy;
@ -592,8 +594,8 @@ static unique_ptr<Scene> _useBuildHelper(const SvgNode* node, const Box& vBox, c
auto tvx = symbol.vx * sx; auto tvx = symbol.vx * sx;
auto tvy = symbol.vy * sy; auto tvy = symbol.vy * sy;
auto tvw = symbol.vw * sx; auto tvw = vw * sx;
auto tvh = symbol.vh * sy; auto tvh = vh * sy;
tvy -= (symbol.h - tvh) * 0.5f; tvy -= (symbol.h - tvh) * 0.5f;
tvx -= (symbol.w - tvw) * 0.5f; tvx -= (symbol.w - tvw) * 0.5f;
mViewBox = {sx, 0, -tvx, 0, sy, -tvy, 0, 0, 1}; mViewBox = {sx, 0, -tvx, 0, sy, -tvy, 0, 0, 1};