diff --git a/src/loaders/svg/tvgSvgLoader.cpp b/src/loaders/svg/tvgSvgLoader.cpp index 46627be7..2eff3b6f 100644 --- a/src/loaders/svg/tvgSvgLoader.cpp +++ b/src/loaders/svg/tvgSvgLoader.cpp @@ -723,6 +723,7 @@ static float _parseLength(const char* str, SvgLengthType* type) } +static bool _parseStyleAttr(void* data, const char* key, const char* value); static bool _parseStyleAttr(void* data, const char* key, const char* value, bool style); @@ -949,7 +950,6 @@ static bool _parseStyleAttr(void* data, const char* key, const char* value, bool //Trim the white space key = _skipSpace(key, nullptr); - value = _skipSpace(value, nullptr); sz = strlen(key); @@ -958,7 +958,7 @@ static bool _parseStyleAttr(void* data, const char* key, const char* value, bool if (style) { styleTags[i].tagHandler(loader, node, value); node->style->flags = (SvgStyleFlags)((int)node->style->flags | (int)styleTags[i].flag); - } else if (!((int)node->style->flags && (int)styleTags[i].flag)) { + } else if (!((int)node->style->flags & (int)styleTags[i].flag)) { styleTags[i].tagHandler(loader, node, value); } return true; @@ -968,6 +968,13 @@ static bool _parseStyleAttr(void* data, const char* key, const char* value, bool return false; } + +static bool _parseStyleAttr(void* data, const char* key, const char* value) +{ + return _parseStyleAttr(data, key, value, true); +} + + /* parse g node * https://www.w3.org/TR/SVG/struct.html#Groups */ @@ -1962,19 +1969,17 @@ static SvgStyleGradient* _createRadialGradient(SvgLoaderData* loader, const char } -static bool _attrParseStops(void* data, const char* key, const char* value, bool style) +static bool _attrParseStopsStyle(void* data, const char* key, const char* value) { SvgLoaderData* loader = (SvgLoaderData*)data; auto stop = loader->svgParse->gradStop; - if (!strcmp(key, "offset")) { - stop->offset = _toOffset(value); - } else if (!strcmp(key, "stop-opacity")) { + if (!strcmp(key, "stop-opacity")) { stop->a = _toOpacity(value); + loader->svgParse->flags = (SvgStopStyleFlags)((int)loader->svgParse->flags | (int)SvgStopStyleFlags::StopOpacity); } else if (!strcmp(key, "stop-color")) { _toColor(value, &stop->r, &stop->g, &stop->b, nullptr); - } else if (!strcmp(key, "style")) { - simpleXmlParseW3CAttribute(value, _attrParseStops, data); + loader->svgParse->flags = (SvgStopStyleFlags)((int)loader->svgParse->flags | (int)SvgStopStyleFlags::StopColor); } else { return false; } @@ -1985,7 +1990,26 @@ static bool _attrParseStops(void* data, const char* key, const char* value, bool static bool _attrParseStops(void* data, const char* key, const char* value) { - return _attrParseStops(data, key, value, false); + SvgLoaderData* loader = (SvgLoaderData*)data; + auto stop = loader->svgParse->gradStop; + + if (!strcmp(key, "offset")) { + stop->offset = _toOffset(value); + } else if (!strcmp(key, "stop-opacity")) { + if (!((int)loader->svgParse->flags & (int)SvgStopStyleFlags::StopOpacity)) { + stop->a = _toOpacity(value); + } + } else if (!strcmp(key, "stop-color")) { + if (!((int)loader->svgParse->flags & (int)SvgStopStyleFlags::StopColor)) { + _toColor(value, &stop->r, &stop->g, &stop->b, nullptr); + } + } else if (!strcmp(key, "style")) { + simpleXmlParseW3CAttribute(value, _attrParseStopsStyle, data); + } else { + return false; + } + + return true; } diff --git a/src/loaders/svg/tvgSvgLoaderCommon.h b/src/loaders/svg/tvgSvgLoaderCommon.h index 027c02f5..07b66e68 100644 --- a/src/loaders/svg/tvgSvgLoaderCommon.h +++ b/src/loaders/svg/tvgSvgLoaderCommon.h @@ -110,6 +110,12 @@ enum class SvgStyleFlags Display = 0x4000 }; +enum class SvgStopStyleFlags +{ + StopOpacity = 0x01, + StopColor = 0x02 +}; + enum class SvgFillRule { Winding = 0, @@ -314,6 +320,7 @@ struct SvgParser SvgNode* node; SvgStyleGradient* styleGrad; Fill::ColorStop* gradStop; + SvgStopStyleFlags flags; struct { int x, y; diff --git a/src/loaders/svg/tvgXmlParser.cpp b/src/loaders/svg/tvgXmlParser.cpp index 770a3279..ed2a9b84 100644 --- a/src/loaders/svg/tvgXmlParser.cpp +++ b/src/loaders/svg/tvgXmlParser.cpp @@ -463,7 +463,7 @@ bool simpleXmlParse(const char* buf, unsigned bufLength, bool strip, simpleXMLCb } -bool simpleXmlParseW3CAttribute(const char* buf, simpleXMLW3CAttributeCb func, const void* data) +bool simpleXmlParseW3CAttribute(const char* buf, simpleXMLAttributeCb func, const void* data) { const char* end; char* key; @@ -509,11 +509,11 @@ bool simpleXmlParseW3CAttribute(const char* buf, simpleXMLW3CAttributeCb func, c val[_simpleXmlUnskipWhiteSpace(val + strlen(val) , val) - val] = '\0'; #ifdef THORVG_LOG_ENABLED - if (!func((void*)data, key, val, true)) { + if (!func((void*)data, key, val)) { if (!_isIgnoreUnsupportedLogAttributes(key, val)) printf("SVG: Unsupported attributes used [Elements type: %s][Id : %s][Attribute: %s][Value: %s]\n", simpleXmlNodeTypeToString(((SvgLoaderData*)data)->svgParse->node->type).c_str(), ((SvgLoaderData*)data)->svgParse->node->id ? ((SvgLoaderData*)data)->svgParse->node->id->c_str() : "NO_ID", key, val ? val : "NONE"); } #else - func((void*)data, key, val, true); + func((void*)data, key, val); #endif } diff --git a/src/loaders/svg/tvgXmlParser.h b/src/loaders/svg/tvgXmlParser.h index df2dcf72..f7758190 100644 --- a/src/loaders/svg/tvgXmlParser.h +++ b/src/loaders/svg/tvgXmlParser.h @@ -46,11 +46,10 @@ enum class SimpleXMLType typedef bool (*simpleXMLCb)(void* data, SimpleXMLType type, const char* content, unsigned length); typedef bool (*simpleXMLAttributeCb)(void* data, const char* key, const char* value); -typedef bool (*simpleXMLW3CAttributeCb)(void* data, const char* key, const char* value, bool style); bool simpleXmlParseAttributes(const char* buf, unsigned buflen, simpleXMLAttributeCb func, const void* data); bool simpleXmlParse(const char* buf, unsigned buflen, bool strip, simpleXMLCb func, const void* data); -bool simpleXmlParseW3CAttribute(const char* buf, simpleXMLW3CAttributeCb func, const void* data); +bool simpleXmlParseW3CAttribute(const char* buf, simpleXMLAttributeCb func, const void* data); const char *simpleXmlFindAttributesTag(const char* buf, unsigned buflen); #ifdef THORVG_LOG_ENABLED