mirror of
https://github.com/thorvg/thorvg.git
synced 2025-07-23 14:48:24 +00:00
SVG: Support geometry properties of use tag
This patch adds a support for geometry properties (x, y) of <use> tag
This commit is contained in:
parent
4db3087c45
commit
00dfd55f18
3 changed files with 48 additions and 1 deletions
|
@ -1818,12 +1818,36 @@ static void _clonePostponedNodes(Array<SvgNodeIdPair>* cloneNodes) {
|
|||
}
|
||||
|
||||
|
||||
static constexpr struct
|
||||
{
|
||||
const char* tag;
|
||||
SvgParserLengthType type;
|
||||
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)}
|
||||
};
|
||||
|
||||
|
||||
static bool _attrParseUseNode(void* data, const char* key, const char* value)
|
||||
{
|
||||
SvgLoaderData* loader = (SvgLoaderData*)data;
|
||||
SvgNode *defs, *nodeFrom, *node = loader->svgParse->node;
|
||||
string* id;
|
||||
|
||||
SvgUseNode* use = &(node->node.use);
|
||||
int sz = strlen(key);
|
||||
unsigned char* array = (unsigned char*)use;
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) {
|
||||
id = _idFromHref(value);
|
||||
defs = _getDefsNode(node);
|
||||
|
|
|
@ -157,6 +157,11 @@ struct SvgDefsNode
|
|||
Array<SvgStyleGradient*> gradients;
|
||||
};
|
||||
|
||||
struct SvgUseNode
|
||||
{
|
||||
float x, y, w, h;
|
||||
};
|
||||
|
||||
|
||||
struct SvgEllipseNode
|
||||
{
|
||||
|
@ -334,6 +339,7 @@ struct SvgNode
|
|||
SvgGNode g;
|
||||
SvgDocNode doc;
|
||||
SvgDefsNode defs;
|
||||
SvgUseNode use;
|
||||
SvgCircleNode circle;
|
||||
SvgEllipseNode ellipse;
|
||||
SvgPolygonNode polygon;
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#include <float.h>
|
||||
|
||||
static bool _appendShape(SvgNode* node, Shape* shape, float vx, float vy, float vw, float vh);
|
||||
static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, float vx, float vy, float vw, float vh, const string& svgPath);
|
||||
|
||||
/************************************************************************/
|
||||
/* Internal Class Implementation */
|
||||
|
@ -550,6 +551,19 @@ static unique_ptr<Picture> _imageBuildHelper(SvgNode* node, float vx, float vy,
|
|||
}
|
||||
|
||||
|
||||
static unique_ptr<Scene> _useBuildHelper(const SvgNode* node, float vx, float vy, float vw, float vh, const string& svgPath)
|
||||
{
|
||||
auto scene = _sceneBuildHelper(node, vx, vy, vw, vh, svgPath);
|
||||
if (node->node.use.x != 0.0f || node->node.use.y != 0.0f) {
|
||||
scene->translate(node->node.use.x, node->node.use.y);
|
||||
}
|
||||
if (node->node.use.w > 0.0f && node->node.use.h > 0.0f) {
|
||||
//TODO: handle width/height properties
|
||||
}
|
||||
return scene;
|
||||
}
|
||||
|
||||
|
||||
static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, float vx, float vy, float vw, float vh, const string& svgPath)
|
||||
{
|
||||
if (_isGroupType(node->type)) {
|
||||
|
@ -560,7 +574,10 @@ static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, float vx, float
|
|||
auto child = node->child.data;
|
||||
for (uint32_t i = 0; i < node->child.count; ++i, ++child) {
|
||||
if (_isGroupType((*child)->type)) {
|
||||
scene->push(_sceneBuildHelper(*child, vx, vy, vw, vh, svgPath));
|
||||
if ((*child)->type == SvgNodeType::Use)
|
||||
scene->push(_useBuildHelper(*child, vx, vy, vw, vh, svgPath));
|
||||
else
|
||||
scene->push(_sceneBuildHelper(*child, vx, vy, vw, vh, svgPath));
|
||||
} else if ((*child)->type == SvgNodeType::Image) {
|
||||
auto image = _imageBuildHelper(*child, vx, vy, vw, vh, svgPath);
|
||||
if (image) scene->push(move(image));
|
||||
|
|
Loading…
Add table
Reference in a new issue