From ef349ea322ef393a541d302ff5c57e31b46c9a72 Mon Sep 17 00:00:00 2001 From: Mira Grudzinska <67589014+mgrudzinska@users.noreply.github.com> Date: Mon, 7 Mar 2022 03:32:02 +0100 Subject: [PATCH] svg_loader: width and height attribs of the use element applied Change-Id: Ic08932e9a46498e71259d64ff8ac2ad20d3ab9d5 --- src/loaders/svg/tvgSvgLoader.cpp | 19 +++++++++++-------- src/loaders/svg/tvgSvgLoaderCommon.h | 2 ++ src/loaders/svg/tvgSvgSceneBuilder.cpp | 17 +++++++++-------- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/loaders/svg/tvgSvgLoader.cpp b/src/loaders/svg/tvgSvgLoader.cpp index 37711d4..a0b6332 100644 --- a/src/loaders/svg/tvgSvgLoader.cpp +++ b/src/loaders/svg/tvgSvgLoader.cpp @@ -2099,10 +2099,10 @@ static constexpr struct int sz; size_t offset; } useTags[] = { - {"x", SvgParserLengthType::Horizontal, sizeof("x"), offsetof(SvgRectNode, x)}, - {"y", SvgParserLengthType::Vertical, sizeof("y"), offsetof(SvgRectNode, y)}, - {"width", SvgParserLengthType::Horizontal, sizeof("width"), offsetof(SvgRectNode, w)}, - {"height", SvgParserLengthType::Vertical, sizeof("height"), offsetof(SvgRectNode, h)} + {"x", SvgParserLengthType::Horizontal, sizeof("x"), offsetof(SvgUseNode, x)}, + {"y", SvgParserLengthType::Vertical, sizeof("y"), offsetof(SvgUseNode, y)}, + {"width", SvgParserLengthType::Horizontal, sizeof("width"), offsetof(SvgUseNode, w)}, + {"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++) { if (useTags[i].sz - 1 == sz && !strncmp(useTags[i].tag, key, sz)) { *((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; } } @@ -2136,10 +2140,6 @@ static bool _attrParseUseNode(void* data, const char* key, const char* value) //after the whole file is parsed _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 { return _attrParseGNode(data, key, value); } @@ -2153,6 +2153,9 @@ static SvgNode* _createUseNode(SvgLoaderData* loader, SvgNode* parent, const cha 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); return loader->svgParse->node; } diff --git a/src/loaders/svg/tvgSvgLoaderCommon.h b/src/loaders/svg/tvgSvgLoaderCommon.h index 1bb5405..1f25e82 100644 --- a/src/loaders/svg/tvgSvgLoaderCommon.h +++ b/src/loaders/svg/tvgSvgLoaderCommon.h @@ -178,6 +178,8 @@ struct SvgSymbolNode struct SvgUseNode { float x, y, w, h; + bool isWidthSet; + bool isHeightSet; SvgNode* symbol; }; diff --git a/src/loaders/svg/tvgSvgSceneBuilder.cpp b/src/loaders/svg/tvgSvgSceneBuilder.cpp index 6fbaee9..90705f2 100644 --- a/src/loaders/svg/tvgSvgSceneBuilder.cpp +++ b/src/loaders/svg/tvgSvgSceneBuilder.cpp @@ -576,10 +576,15 @@ static unique_ptr _useBuildHelper(const SvgNode* node, const Box& vBox, c if (node->node.use.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}; - if ((!mathEqual(symbol.w, symbol.vw) || !mathEqual(symbol.h, symbol.vh)) && symbol.vw > 0 && symbol.vh > 0) { - auto sx = symbol.w / symbol.vw; - auto sy = symbol.h / symbol.vh; + if ((!mathEqual(width, symbol.vw) || !mathEqual(height, symbol.vh)) && symbol.vw > 0 && symbol.vh > 0) { + auto sx = width / symbol.vw; + auto sy = height / symbol.vh; if (symbol.preserveAspect) { if (sx < sy) sy = sx; else sx = sy; @@ -608,7 +613,7 @@ static unique_ptr _useBuildHelper(const SvgNode* node, const Box& vBox, c finalScene = move(scene); } else { 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 Matrix mClipTransform = mUseTransform; @@ -631,10 +636,6 @@ static unique_ptr _useBuildHelper(const SvgNode* node, const Box& vBox, c finalScene = move(scene); } - if (node->node.use.w > 0.0f && node->node.use.h > 0.0f) { - //TODO: handle width/height properties - } - return finalScene; } -- 2.7.4