mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-20 06:52:03 +00:00
parent
ca86907739
commit
fff5bfee83
4 changed files with 74 additions and 34 deletions
|
@ -723,7 +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 _attrParseSvgNode(void* data, const char* key, const char* value)
|
static bool _attrParseSvgNode(void* data, const char* key, const char* value)
|
||||||
|
@ -761,7 +761,7 @@ static bool _attrParseSvgNode(void* data, const char* key, const char* value)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else {
|
else {
|
||||||
return _parseStyleAttr(loader, key, value);
|
return _parseStyleAttr(loader, key, value, false);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -912,33 +912,35 @@ static void _handleDisplayAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node,
|
||||||
|
|
||||||
typedef void (*styleMethod)(SvgLoaderData* loader, SvgNode* node, const char* value);
|
typedef void (*styleMethod)(SvgLoaderData* loader, SvgNode* node, const char* value);
|
||||||
|
|
||||||
#define STYLE_DEF(Name, Name1) { #Name, sizeof(#Name), _handle##Name1##Attr }
|
#define STYLE_DEF(Name, Name1, Flag) { #Name, sizeof(#Name), _handle##Name1##Attr, Flag }
|
||||||
|
|
||||||
|
|
||||||
static constexpr struct
|
static constexpr struct
|
||||||
{
|
{
|
||||||
const char* tag;
|
const char* tag;
|
||||||
int sz;
|
int sz;
|
||||||
styleMethod tagHandler;
|
styleMethod tagHandler;
|
||||||
|
SvgStyleFlags flag;
|
||||||
} styleTags[] = {
|
} styleTags[] = {
|
||||||
STYLE_DEF(color, Color),
|
STYLE_DEF(color, Color, SvgStyleFlags::Color),
|
||||||
STYLE_DEF(fill, Fill),
|
STYLE_DEF(fill, Fill, SvgStyleFlags::Fill),
|
||||||
STYLE_DEF(fill-rule, FillRule),
|
STYLE_DEF(fill-rule, FillRule, SvgStyleFlags::FillRule),
|
||||||
STYLE_DEF(fill-opacity, FillOpacity),
|
STYLE_DEF(fill-opacity, FillOpacity, SvgStyleFlags::FillOpacity),
|
||||||
STYLE_DEF(opacity, Opacity),
|
STYLE_DEF(opacity, Opacity, SvgStyleFlags::Opacity),
|
||||||
STYLE_DEF(stroke, Stroke),
|
STYLE_DEF(stroke, Stroke, SvgStyleFlags::Stroke),
|
||||||
STYLE_DEF(stroke-width, StrokeWidth),
|
STYLE_DEF(stroke-width, StrokeWidth, SvgStyleFlags::StrokeWidth),
|
||||||
STYLE_DEF(stroke-linejoin, StrokeLineJoin),
|
STYLE_DEF(stroke-linejoin, StrokeLineJoin, SvgStyleFlags::StrokeLineJoin),
|
||||||
STYLE_DEF(stroke-linecap, StrokeLineCap),
|
STYLE_DEF(stroke-linecap, StrokeLineCap, SvgStyleFlags::StrokeLineCap),
|
||||||
STYLE_DEF(stroke-opacity, StrokeOpacity),
|
STYLE_DEF(stroke-opacity, StrokeOpacity, SvgStyleFlags::StrokeOpacity),
|
||||||
STYLE_DEF(stroke-dasharray, StrokeDashArray),
|
STYLE_DEF(stroke-dasharray, StrokeDashArray, SvgStyleFlags::StrokeDashArray),
|
||||||
STYLE_DEF(transform, Transform),
|
STYLE_DEF(transform, Transform, SvgStyleFlags::Transform),
|
||||||
STYLE_DEF(clip-path, ClipPath),
|
STYLE_DEF(clip-path, ClipPath, SvgStyleFlags::ClipPath),
|
||||||
STYLE_DEF(mask, Mask),
|
STYLE_DEF(mask, Mask, SvgStyleFlags::Mask),
|
||||||
STYLE_DEF(display, Display)
|
STYLE_DEF(display, Display, SvgStyleFlags::Display)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static bool _parseStyleAttr(void* data, const char* key, const char* value)
|
static bool _parseStyleAttr(void* data, const char* key, const char* value, bool style)
|
||||||
{
|
{
|
||||||
SvgLoaderData* loader = (SvgLoaderData*)data;
|
SvgLoaderData* loader = (SvgLoaderData*)data;
|
||||||
SvgNode* node = loader->svgParse->node;
|
SvgNode* node = loader->svgParse->node;
|
||||||
|
@ -953,7 +955,12 @@ static bool _parseStyleAttr(void* data, const char* key, const char* value)
|
||||||
sz = strlen(key);
|
sz = strlen(key);
|
||||||
for (unsigned int i = 0; i < sizeof(styleTags) / sizeof(styleTags[0]); i++) {
|
for (unsigned int i = 0; i < sizeof(styleTags) / sizeof(styleTags[0]); i++) {
|
||||||
if (styleTags[i].sz - 1 == sz && !strncmp(styleTags[i].tag, key, sz)) {
|
if (styleTags[i].sz - 1 == sz && !strncmp(styleTags[i].tag, key, sz)) {
|
||||||
styleTags[i].tagHandler(loader, node, value);
|
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)) {
|
||||||
|
styleTags[i].tagHandler(loader, node, value);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -980,7 +987,7 @@ static bool _attrParseGNode(void* data, const char* key, const char* value)
|
||||||
} else if (!strcmp(key, "mask")) {
|
} else if (!strcmp(key, "mask")) {
|
||||||
_handleMaskAttr(loader, node, value);
|
_handleMaskAttr(loader, node, value);
|
||||||
} else {
|
} else {
|
||||||
return _parseStyleAttr(loader, key, value);
|
return _parseStyleAttr(loader, key, value, false);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1001,7 +1008,7 @@ static bool _attrParseClipPathNode(void* data, const char* key, const char* valu
|
||||||
} else if (!strcmp(key, "id")) {
|
} else if (!strcmp(key, "id")) {
|
||||||
node->id = _copyId(value);
|
node->id = _copyId(value);
|
||||||
} else {
|
} else {
|
||||||
return _parseStyleAttr(loader, key, value);
|
return _parseStyleAttr(loader, key, value, false);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1019,7 +1026,7 @@ static bool _attrParseMaskNode(void* data, const char* key, const char* value)
|
||||||
} else if (!strcmp(key, "id")) {
|
} else if (!strcmp(key, "id")) {
|
||||||
node->id = _copyId(value);
|
node->id = _copyId(value);
|
||||||
} else {
|
} else {
|
||||||
return _parseStyleAttr(loader, key, value);
|
return _parseStyleAttr(loader, key, value, false);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1161,7 +1168,7 @@ static bool _attrParsePathNode(void* data, const char* key, const char* value)
|
||||||
} else if (!strcmp(key, "id")) {
|
} else if (!strcmp(key, "id")) {
|
||||||
node->id = _copyId(value);
|
node->id = _copyId(value);
|
||||||
} else {
|
} else {
|
||||||
return _parseStyleAttr(loader, key, value);
|
return _parseStyleAttr(loader, key, value, false);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1220,7 +1227,7 @@ static bool _attrParseCircleNode(void* data, const char* key, const char* value)
|
||||||
} else if (!strcmp(key, "id")) {
|
} else if (!strcmp(key, "id")) {
|
||||||
node->id = _copyId(value);
|
node->id = _copyId(value);
|
||||||
} else {
|
} else {
|
||||||
return _parseStyleAttr(loader, key, value);
|
return _parseStyleAttr(loader, key, value, false);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1279,7 +1286,7 @@ static bool _attrParseEllipseNode(void* data, const char* key, const char* value
|
||||||
} else if (!strcmp(key, "mask")) {
|
} else if (!strcmp(key, "mask")) {
|
||||||
_handleMaskAttr(loader, node, value);
|
_handleMaskAttr(loader, node, value);
|
||||||
} else {
|
} else {
|
||||||
return _parseStyleAttr(loader, key, value);
|
return _parseStyleAttr(loader, key, value, false);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1356,7 +1363,7 @@ static bool _attrParsePolygonNode(void* data, const char* key, const char* value
|
||||||
} else if (!strcmp(key, "id")) {
|
} else if (!strcmp(key, "id")) {
|
||||||
node->id = _copyId(value);
|
node->id = _copyId(value);
|
||||||
} else {
|
} else {
|
||||||
return _parseStyleAttr(loader, key, value);
|
return _parseStyleAttr(loader, key, value, false);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1435,7 +1442,7 @@ static bool _attrParseRectNode(void* data, const char* key, const char* value)
|
||||||
} else if (!strcmp(key, "mask")) {
|
} else if (!strcmp(key, "mask")) {
|
||||||
_handleMaskAttr(loader, node, value);
|
_handleMaskAttr(loader, node, value);
|
||||||
} else {
|
} else {
|
||||||
ret = _parseStyleAttr(loader, key, value);
|
ret = _parseStyleAttr(loader, key, value, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1497,7 +1504,7 @@ static bool _attrParseLineNode(void* data, const char* key, const char* value)
|
||||||
} else if (!strcmp(key, "mask")) {
|
} else if (!strcmp(key, "mask")) {
|
||||||
_handleMaskAttr(loader, node, value);
|
_handleMaskAttr(loader, node, value);
|
||||||
} else {
|
} else {
|
||||||
return _parseStyleAttr(loader, key, value);
|
return _parseStyleAttr(loader, key, value, false);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1955,7 +1962,7 @@ static SvgStyleGradient* _createRadialGradient(SvgLoaderData* loader, const char
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool _attrParseStops(void* data, const char* key, const char* value)
|
static bool _attrParseStops(void* data, const char* key, const char* value, bool style)
|
||||||
{
|
{
|
||||||
SvgLoaderData* loader = (SvgLoaderData*)data;
|
SvgLoaderData* loader = (SvgLoaderData*)data;
|
||||||
auto stop = loader->svgParse->gradStop;
|
auto stop = loader->svgParse->gradStop;
|
||||||
|
@ -1976,6 +1983,12 @@ 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void _handleLinearX1Attr(SvgLoaderData* loader, SvgLinearGradient* linear, const char* value)
|
static void _handleLinearX1Attr(SvgLoaderData* loader, SvgLinearGradient* linear, const char* value)
|
||||||
{
|
{
|
||||||
linear->x1 = _gradientToFloat(loader->svgParse, value, SvgParserLengthType::Horizontal);
|
linear->x1 = _gradientToFloat(loader->svgParse, value, SvgParserLengthType::Horizontal);
|
||||||
|
|
|
@ -91,6 +91,31 @@ enum class SvgGradientType
|
||||||
Radial
|
Radial
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class SvgStyleFlags
|
||||||
|
{
|
||||||
|
Color = 0x01,
|
||||||
|
Fill = 0x02,
|
||||||
|
FillRule = 0x04,
|
||||||
|
FillOpacity = 0x08,
|
||||||
|
Opacity = 0x010,
|
||||||
|
Stroke = 0x20,
|
||||||
|
StrokeWidth = 0x40,
|
||||||
|
StrokeLineJoin = 0x80,
|
||||||
|
StrokeLineCap = 0x100,
|
||||||
|
StrokeOpacity = 0x200,
|
||||||
|
StrokeDashArray = 0x400,
|
||||||
|
Transform = 0x800,
|
||||||
|
ClipPath = 0x1000,
|
||||||
|
Mask = 0x2000,
|
||||||
|
Display = 0x4000
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class SvgFillRule
|
||||||
|
{
|
||||||
|
Winding = 0,
|
||||||
|
OddEven = 1
|
||||||
|
};
|
||||||
|
|
||||||
//Length type to recalculate %, pt, pc, mm, cm etc
|
//Length type to recalculate %, pt, pc, mm, cm etc
|
||||||
enum class SvgParserLengthType
|
enum class SvgParserLengthType
|
||||||
{
|
{
|
||||||
|
@ -258,6 +283,7 @@ struct SvgStyleProperty
|
||||||
int opacity;
|
int opacity;
|
||||||
SvgColor color;
|
SvgColor color;
|
||||||
bool curColorSet;
|
bool curColorSet;
|
||||||
|
SvgStyleFlags flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SvgNode
|
struct SvgNode
|
||||||
|
|
|
@ -463,7 +463,7 @@ bool simpleXmlParse(const char* buf, unsigned bufLength, bool strip, simpleXMLCb
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool simpleXmlParseW3CAttribute(const char* buf, simpleXMLAttributeCb func, const void* data)
|
bool simpleXmlParseW3CAttribute(const char* buf, simpleXMLW3CAttributeCb func, const void* data)
|
||||||
{
|
{
|
||||||
const char* end;
|
const char* end;
|
||||||
char* key;
|
char* key;
|
||||||
|
@ -509,11 +509,11 @@ bool simpleXmlParseW3CAttribute(const char* buf, simpleXMLAttributeCb func, cons
|
||||||
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)) {
|
if (!func((void*)data, key, val, true)) {
|
||||||
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);
|
func((void*)data, key, val, true);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,10 +46,11 @@ 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, simpleXMLAttributeCb func, const void* data);
|
bool simpleXmlParseW3CAttribute(const char* buf, simpleXMLW3CAttributeCb 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
|
||||||
|
|
Loading…
Add table
Reference in a new issue