mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-13 11:36:25 +00:00
SvgLoader: Verify SVG resource
Only <svg> tag is parsed first before data get in file open function. If the <svg> tag is found, the loaded file is valid and stores viewbox information. After that, the remaining content data is parsed in order with async. Change-Id: Idb934fbd5e190c7c523abe601a80745ccc767af1
This commit is contained in:
parent
2501c50506
commit
1b48bf10fe
1 changed files with 78 additions and 9 deletions
|
@ -1982,6 +1982,7 @@ static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content,
|
||||||
node = method(loader, nullptr, attrs, attrsLength);
|
node = method(loader, nullptr, attrs, attrsLength);
|
||||||
loader->doc = node;
|
loader->doc = node;
|
||||||
} else {
|
} else {
|
||||||
|
if (!strcmp(tagName, "svg")) return; //Already loadded <svg>(SvgNodeType::Doc) tag
|
||||||
if (loader->stack.size() > 0) parent = loader->stack.at(loader->stack.size() - 1);
|
if (loader->stack.size() > 0) parent = loader->stack.at(loader->stack.size() - 1);
|
||||||
node = method(loader, parent, attrs, attrsLength);
|
node = method(loader, parent, attrs, attrsLength);
|
||||||
}
|
}
|
||||||
|
@ -2223,6 +2224,64 @@ static void _freeSvgNode(SvgNode* node)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool _svgLoaderParserForValidCheckXmlOpen(SvgLoaderData* loader, const char* content, unsigned int length)
|
||||||
|
{
|
||||||
|
const char* attrs = nullptr;
|
||||||
|
int sz = length;
|
||||||
|
char tagName[20] = "";
|
||||||
|
FactoryMethod method;
|
||||||
|
SvgNode *node = nullptr;
|
||||||
|
int attrsLength = 0;
|
||||||
|
loader->level++;
|
||||||
|
attrs = simpleXmlFindAttributesTag(content, length);
|
||||||
|
|
||||||
|
if (!attrs) {
|
||||||
|
//Parse the empty tag
|
||||||
|
attrs = content;
|
||||||
|
while ((attrs != nullptr) && *attrs != '>') attrs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attrs) {
|
||||||
|
sz = attrs - content;
|
||||||
|
attrsLength = length - sz;
|
||||||
|
while ((sz > 0) && (isspace(content[sz - 1]))) sz--;
|
||||||
|
strncpy(tagName, content, sz);
|
||||||
|
tagName[sz] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((method = _findGroupFactory(tagName))) {
|
||||||
|
if (!loader->doc) {
|
||||||
|
if (strcmp(tagName, "svg")) return true; //Not a valid svg document
|
||||||
|
node = method(loader, nullptr, attrs, attrsLength);
|
||||||
|
loader->doc = node;
|
||||||
|
loader->stack.push_back(node);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool _svgLoaderParserForValidCheck(void* data, SimpleXMLType type, const char* content, unsigned int offset, unsigned int length)
|
||||||
|
{
|
||||||
|
SvgLoaderData* loader = (SvgLoaderData*)data;
|
||||||
|
bool res = true;;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case SimpleXMLType::Open:
|
||||||
|
case SimpleXMLType::OpenEmpty: {
|
||||||
|
//If 'res' is false, it means <svg> tag is found.
|
||||||
|
res = _svgLoaderParserForValidCheckXmlOpen(loader, content, length);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* External Class Implementation */
|
/* External Class Implementation */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
@ -2254,12 +2313,25 @@ bool SvgLoader::open(const char* path)
|
||||||
if (content.empty()) return false;
|
if (content.empty()) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//FIXME: Verify this resource is normal SVG, otherwise return false
|
//For valid check, only <svg> tag is parsed first.
|
||||||
//Also, return the brief resource info such as viewbox:
|
//If the <svg> tag is found, the loaded file is valid and stores viewbox information.
|
||||||
//this->vx = ?
|
//After that, the remaining content data is parsed in order with async.
|
||||||
//this->vy = ?
|
loaderData.svgParse = (SvgParser*)malloc(sizeof(SvgParser));
|
||||||
//this->vw = ?
|
if (!loaderData.svgParse) return false;
|
||||||
//this->vh = ?
|
|
||||||
|
simpleXmlParse(content.c_str(), content.size(), true, _svgLoaderParserForValidCheck, &(loaderData));
|
||||||
|
|
||||||
|
if (loaderData.doc && loaderData.doc->type == SvgNodeType::Doc) {
|
||||||
|
//Return the brief resource info such as viewbox:
|
||||||
|
this->vx = loaderData.doc->node.doc.vx;
|
||||||
|
this->vy = loaderData.doc->node.doc.vy;
|
||||||
|
this->vw = loaderData.doc->node.doc.vw;
|
||||||
|
this->vh = loaderData.doc->node.doc.vh;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
cout << "ERROR : No SVG File. There is no <svg/>" <<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2270,9 +2342,6 @@ bool SvgLoader::read()
|
||||||
if (content.empty()) return false;
|
if (content.empty()) return false;
|
||||||
|
|
||||||
auto asyncTask = [](SvgLoader *loader) {
|
auto asyncTask = [](SvgLoader *loader) {
|
||||||
|
|
||||||
loader->loaderData.svgParse = (SvgParser*)malloc(sizeof(SvgParser));
|
|
||||||
|
|
||||||
bool res = simpleXmlParse(loader->content.c_str(), loader->content.size(), true, _svgLoaderParser, &(loader->loaderData));
|
bool res = simpleXmlParse(loader->content.c_str(), loader->content.size(), true, _svgLoaderParser, &(loader->loaderData));
|
||||||
|
|
||||||
if (!res) return unique_ptr<Scene>(nullptr);
|
if (!res) return unique_ptr<Scene>(nullptr);
|
||||||
|
|
Loading…
Add table
Reference in a new issue