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);
@ -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;
}

View file

@ -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;

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;
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
}

View file

@ -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