diff --git a/src/loaders/svg/tvgSvgLoader.cpp b/src/loaders/svg/tvgSvgLoader.cpp index 4990c5cd..7def62d4 100644 --- a/src/loaders/svg/tvgSvgLoader.cpp +++ b/src/loaders/svg/tvgSvgLoader.cpp @@ -947,6 +947,15 @@ static void _handleDisplayAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, } +static void _handleCssClassAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value) +{ + auto cssClass = &node->style->cssClass; + + if (*cssClass && value) free(*cssClass); + *cssClass = _copyId(value); +} + + typedef void (*styleMethod)(SvgLoaderData* loader, SvgNode* node, const char* value); #define STYLE_DEF(Name, Name1, Flag) { #Name, sizeof(#Name), _handle##Name1##Attr, Flag } @@ -1027,6 +1036,8 @@ static bool _attrParseGNode(void* data, const char* key, const char* value) } else if (!strcmp(key, "id")) { if (node->id && value) free(node->id); node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); } else if (!strcmp(key, "clip-path")) { _handleClipPathAttr(loader, node, value); } else if (!strcmp(key, "mask")) { @@ -1054,6 +1065,8 @@ static bool _attrParseClipPathNode(void* data, const char* key, const char* valu } else if (!strcmp(key, "id")) { if (node->id && value) free(node->id); node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); } else if (!strcmp(key, "clipPathUnits")) { if (!strcmp(value, "objectBoundingBox")) clip->userSpace = false; } else { @@ -1076,6 +1089,8 @@ static bool _attrParseMaskNode(void* data, const char* key, const char* value) } else if (!strcmp(key, "id")) { if (node->id && value) free(node->id); node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); } else if (!strcmp(key, "maskContentUnits")) { if (!strcmp(value, "objectBoundingBox")) mask->userSpace = false; } else if (!strcmp(key, "mask-type")) { @@ -1229,6 +1244,8 @@ static bool _attrParsePathNode(void* data, const char* key, const char* value) } else if (!strcmp(key, "id")) { if (node->id && value) free(node->id); node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); } else { return _parseStyleAttr(loader, key, value, false); } @@ -1289,6 +1306,8 @@ static bool _attrParseCircleNode(void* data, const char* key, const char* value) } else if (!strcmp(key, "id")) { if (node->id && value) free(node->id); node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); } else { return _parseStyleAttr(loader, key, value, false); } @@ -1343,6 +1362,8 @@ static bool _attrParseEllipseNode(void* data, const char* key, const char* value if (!strcmp(key, "id")) { if (node->id && value) free(node->id); node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); } else if (!strcmp(key, "style")) { return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader); } else if (!strcmp(key, "clip-path")) { @@ -1426,6 +1447,8 @@ static bool _attrParsePolygonNode(void* data, const char* key, const char* value } else if (!strcmp(key, "id")) { if (node->id && value) free(node->id); node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); } else { return _parseStyleAttr(loader, key, value, false); } @@ -1500,6 +1523,8 @@ static bool _attrParseRectNode(void* data, const char* key, const char* value) if (!strcmp(key, "id")) { if (node->id && value) free(node->id); node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); } else if (!strcmp(key, "style")) { ret = simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader); } else if (!strcmp(key, "clip-path")) { @@ -1563,6 +1588,8 @@ static bool _attrParseLineNode(void* data, const char* key, const char* value) if (!strcmp(key, "id")) { if (node->id && value) free(node->id); node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); } else if (!strcmp(key, "style")) { return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader); } else if (!strcmp(key, "clip-path")) { @@ -1634,6 +1661,8 @@ static bool _attrParseImageNode(void* data, const char* key, const char* value) } else if (!strcmp(key, "id")) { if (node->id && value) free(node->id); node->id = _copyId(value); + } else if (!strcmp(key, "class")) { + _handleCssClassAttr(loader, node, value); } else if (!strcmp(key, "style")) { return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader); } else if (!strcmp(key, "clip-path")) { @@ -2767,6 +2796,7 @@ static void _freeNodeStyle(SvgStyleProperty* style) //style->clipPath.node and style->mask.node has only the addresses of node. Therefore, node is released from _freeNode. free(style->clipPath.url); free(style->mask.url); + free(style->cssClass); if (style->fill.paint.gradient) { style->fill.paint.gradient->clear(); diff --git a/src/loaders/svg/tvgSvgLoaderCommon.h b/src/loaders/svg/tvgSvgLoaderCommon.h index c6685c6e..04f5b342 100644 --- a/src/loaders/svg/tvgSvgLoaderCommon.h +++ b/src/loaders/svg/tvgSvgLoaderCommon.h @@ -341,6 +341,7 @@ struct SvgStyleProperty int opacity; SvgColor color; bool curColorSet; + char* cssClass; SvgStyleFlags flags; };