svg_loader: set the priority for the style attribute for stop properties

Stop properies stop-color and stop-opacity set using a style attribute should
have higher priority than properties set in a different way.
This commit is contained in:
Mira Grudzinska 2021-06-29 16:17:41 +02:00 committed by Mira Grudzinska
parent fff5bfee83
commit 1507438ecc
4 changed files with 44 additions and 14 deletions

View file

@ -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); 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 //Trim the white space
key = _skipSpace(key, nullptr); key = _skipSpace(key, nullptr);
value = _skipSpace(value, nullptr); value = _skipSpace(value, nullptr);
sz = strlen(key); sz = strlen(key);
@ -958,7 +958,7 @@ static bool _parseStyleAttr(void* data, const char* key, const char* value, bool
if (style) { if (style) {
styleTags[i].tagHandler(loader, node, value); styleTags[i].tagHandler(loader, node, value);
node->style->flags = (SvgStyleFlags)((int)node->style->flags | (int)styleTags[i].flag); 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); styleTags[i].tagHandler(loader, node, value);
} }
return true; return true;
@ -968,6 +968,13 @@ static bool _parseStyleAttr(void* data, const char* key, const char* value, bool
return false; return false;
} }
static bool _parseStyleAttr(void* data, const char* key, const char* value)
{
return _parseStyleAttr(data, key, value, true);
}
/* parse g node /* parse g node
* https://www.w3.org/TR/SVG/struct.html#Groups * 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; SvgLoaderData* loader = (SvgLoaderData*)data;
auto stop = loader->svgParse->gradStop; auto stop = loader->svgParse->gradStop;
if (!strcmp(key, "offset")) { if (!strcmp(key, "stop-opacity")) {
stop->offset = _toOffset(value);
} else if (!strcmp(key, "stop-opacity")) {
stop->a = _toOpacity(value); stop->a = _toOpacity(value);
loader->svgParse->flags = (SvgStopStyleFlags)((int)loader->svgParse->flags | (int)SvgStopStyleFlags::StopOpacity);
} else if (!strcmp(key, "stop-color")) { } else if (!strcmp(key, "stop-color")) {
_toColor(value, &stop->r, &stop->g, &stop->b, nullptr); _toColor(value, &stop->r, &stop->g, &stop->b, nullptr);
} else if (!strcmp(key, "style")) { loader->svgParse->flags = (SvgStopStyleFlags)((int)loader->svgParse->flags | (int)SvgStopStyleFlags::StopColor);
simpleXmlParseW3CAttribute(value, _attrParseStops, data);
} else { } else {
return false; 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) 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;
} }

View file

@ -110,6 +110,12 @@ enum class SvgStyleFlags
Display = 0x4000 Display = 0x4000
}; };
enum class SvgStopStyleFlags
{
StopOpacity = 0x01,
StopColor = 0x02
};
enum class SvgFillRule enum class SvgFillRule
{ {
Winding = 0, Winding = 0,
@ -314,6 +320,7 @@ struct SvgParser
SvgNode* node; SvgNode* node;
SvgStyleGradient* styleGrad; SvgStyleGradient* styleGrad;
Fill::ColorStop* gradStop; Fill::ColorStop* gradStop;
SvgStopStyleFlags flags;
struct struct
{ {
int x, y; int x, y;

View file

@ -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; const char* end;
char* key; char* key;
@ -509,11 +509,11 @@ bool simpleXmlParseW3CAttribute(const char* buf, simpleXMLW3CAttributeCb func, c
val[_simpleXmlUnskipWhiteSpace(val + strlen(val) , val) - val] = '\0'; val[_simpleXmlUnskipWhiteSpace(val + strlen(val) , val) - val] = '\0';
#ifdef THORVG_LOG_ENABLED #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"); 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 #else
func((void*)data, key, val, true); func((void*)data, key, val);
#endif #endif
} }

View file

@ -46,11 +46,10 @@ enum class SimpleXMLType
typedef bool (*simpleXMLCb)(void* data, SimpleXMLType type, const char* content, unsigned length); 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 (*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 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 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); const char *simpleXmlFindAttributesTag(const char* buf, unsigned buflen);
#ifdef THORVG_LOG_ENABLED #ifdef THORVG_LOG_ENABLED