mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-09 06:04:03 +00:00
svg_loader: width and height attribs of the use element applied
This commit is contained in:
parent
59399e8597
commit
2ee25ea11d
3 changed files with 22 additions and 16 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue