svg_loader: width and height attribs of the use element applied

This commit is contained in:
Mira Grudzinska 2022-03-07 03:32:02 +01:00 committed by GitHub
parent 59399e8597
commit 2ee25ea11d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 22 additions and 16 deletions

View file

@ -2099,10 +2099,10 @@ static constexpr struct
int sz; int sz;
size_t offset; size_t offset;
} useTags[] = { } useTags[] = {
{"x", SvgParserLengthType::Horizontal, sizeof("x"), offsetof(SvgRectNode, x)}, {"x", SvgParserLengthType::Horizontal, sizeof("x"), offsetof(SvgUseNode, x)},
{"y", SvgParserLengthType::Vertical, sizeof("y"), offsetof(SvgRectNode, y)}, {"y", SvgParserLengthType::Vertical, sizeof("y"), offsetof(SvgUseNode, y)},
{"width", SvgParserLengthType::Horizontal, sizeof("width"), offsetof(SvgRectNode, w)}, {"width", SvgParserLengthType::Horizontal, sizeof("width"), offsetof(SvgUseNode, w)},
{"height", SvgParserLengthType::Vertical, sizeof("height"), offsetof(SvgRectNode, h)} {"height", SvgParserLengthType::Vertical, sizeof("height"), offsetof(SvgUseNode, h)}
}; };
@ -2118,6 +2118,10 @@ static bool _attrParseUseNode(void* data, const char* key, const char* value)
for (unsigned int i = 0; i < sizeof(useTags) / sizeof(useTags[0]); i++) { for (unsigned int i = 0; i < sizeof(useTags) / sizeof(useTags[0]); i++) {
if (useTags[i].sz - 1 == sz && !strncmp(useTags[i].tag, key, sz)) { if (useTags[i].sz - 1 == sz && !strncmp(useTags[i].tag, key, sz)) {
*((float*)(array + useTags[i].offset)) = _toFloat(loader->svgParse, value, useTags[i].type); *((float*)(array + useTags[i].offset)) = _toFloat(loader->svgParse, value, useTags[i].type);
if (useTags[i].offset == offsetof(SvgUseNode, w)) use->isWidthSet = true;
else if (useTags[i].offset == offsetof(SvgUseNode, h)) use->isHeightSet = true;
return true; return true;
} }
} }
@ -2136,10 +2140,6 @@ static bool _attrParseUseNode(void* data, const char* key, const char* value)
//after the whole file is parsed //after the whole file is parsed
_postpone(loader->cloneNodes, node, id); _postpone(loader->cloneNodes, node, id);
} }
#ifdef THORVG_LOG_ENABLED
} else if ((!strcmp(key, "width") || !strcmp(key, "height")) && fabsf(svgUtilStrtof(value, nullptr)) > FLT_EPSILON) {
TVGLOG("SVG", "Unsupported attributes used [Elements type: Use][Attribute: %s][Value: %s]", key, value);
#endif
} else { } else {
return _attrParseGNode(data, key, value); return _attrParseGNode(data, key, value);
} }
@ -2153,6 +2153,9 @@ static SvgNode* _createUseNode(SvgLoaderData* loader, SvgNode* parent, const cha
if (!loader->svgParse->node) return nullptr; if (!loader->svgParse->node) return nullptr;
loader->svgParse->node->node.use.isWidthSet = false;
loader->svgParse->node->node.use.isHeightSet = false;
func(buf, bufLength, _attrParseUseNode, loader); func(buf, bufLength, _attrParseUseNode, loader);
return loader->svgParse->node; return loader->svgParse->node;
} }

View file

@ -178,6 +178,8 @@ struct SvgSymbolNode
struct SvgUseNode struct SvgUseNode
{ {
float x, y, w, h; float x, y, w, h;
bool isWidthSet;
bool isHeightSet;
SvgNode* symbol; SvgNode* symbol;
}; };

View file

@ -576,10 +576,15 @@ 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;
if (node->node.use.isWidthSet) width = node->node.use.w;
auto height = symbol.h;
if (node->node.use.isHeightSet) height = node->node.use.h;
Matrix mViewBox = {1, 0, 0, 0, 1, 0, 0, 0, 1}; Matrix mViewBox = {1, 0, 0, 0, 1, 0, 0, 0, 1};
if ((!mathEqual(symbol.w, symbol.vw) || !mathEqual(symbol.h, symbol.vh)) && symbol.vw > 0 && symbol.vh > 0) { if ((!mathEqual(width, symbol.vw) || !mathEqual(height, symbol.vh)) && symbol.vw > 0 && symbol.vh > 0) {
auto sx = symbol.w / symbol.vw; auto sx = width / symbol.vw;
auto sy = symbol.h / symbol.vh; auto sy = height / symbol.vh;
if (symbol.preserveAspect) { if (symbol.preserveAspect) {
if (sx < sy) sy = sx; if (sx < sy) sy = sx;
else sx = sy; else sx = sy;
@ -608,7 +613,7 @@ static unique_ptr<Scene> _useBuildHelper(const SvgNode* node, const Box& vBox, c
finalScene = move(scene); finalScene = move(scene);
} else { } else {
auto viewBoxClip = Shape::gen(); auto viewBoxClip = Shape::gen();
viewBoxClip->appendRect(0, 0, symbol.w, symbol.h, 0, 0); viewBoxClip->appendRect(0, 0, width, height, 0, 0);
// mClipTransform = mUseTransform * mSymbolTransform // mClipTransform = mUseTransform * mSymbolTransform
Matrix mClipTransform = mUseTransform; Matrix mClipTransform = mUseTransform;
@ -631,10 +636,6 @@ static unique_ptr<Scene> _useBuildHelper(const SvgNode* node, const Box& vBox, c
finalScene = move(scene); finalScene = move(scene);
} }
if (node->node.use.w > 0.0f && node->node.use.h > 0.0f) {
//TODO: handle width/height properties
}
return finalScene; return finalScene;
} }