if (!strcmp(key, "width")) {
doc->w = _toFloat(loader->svgParse, value, SvgParserLengthType::Horizontal);
+ doc->viewFlag = (SvgViewFlag)((uint32_t)doc->viewFlag | (uint32_t)SvgViewFlag::Width);
} else if (!strcmp(key, "height")) {
doc->h = _toFloat(loader->svgParse, value, SvgParserLengthType::Vertical);
+ doc->viewFlag = (SvgViewFlag)((uint32_t)doc->viewFlag | (uint32_t)SvgViewFlag::Height);
} else if (!strcmp(key, "viewBox")) {
if (_parseNumber(&value, &doc->vx)) {
if (_parseNumber(&value, &doc->vy)) {
if (_parseNumber(&value, &doc->vw)) {
- _parseNumber(&value, &doc->vh);
- loader->svgParse->global.h = doc->vh;
+ if (_parseNumber(&value, &doc->vh)) {
+ doc->viewFlag = (SvgViewFlag)((uint32_t)doc->viewFlag | (uint32_t)SvgViewFlag::Viewbox);
+ loader->svgParse->global.h = doc->vh;
+ }
+ loader->svgParse->global.w = doc->vw;
}
- loader->svgParse->global.w = doc->vw;
+ loader->svgParse->global.y = doc->vy;
}
- loader->svgParse->global.y = doc->vy;
+ loader->svgParse->global.x = doc->vx;
+ }
+ if (((uint32_t)doc->viewFlag & (uint32_t)SvgViewFlag::Viewbox) && (doc->vw < 0.0f || doc->vh < 0.0f)) {
+ doc->viewFlag = (SvgViewFlag)((uint32_t)doc->viewFlag & ~(uint32_t)SvgViewFlag::Viewbox);
+ TVGLOG("SVG", "Negative values of the <viewBox> width and/or height - the attribute invalidated.");
+ }
+ if (!((uint32_t)doc->viewFlag & (uint32_t)SvgViewFlag::Viewbox)) {
+ loader->svgParse->global.x = loader->svgParse->global.y = 0.0f;
+ loader->svgParse->global.w = loader->svgParse->global.h = 1.0f;
}
- loader->svgParse->global.x = doc->vx;
} else if (!strcmp(key, "preserveAspectRatio")) {
_parseAspectRatio(&value, &doc->align, &doc->meetOrSlice);
} else if (!strcmp(key, "style")) {
if (!loader->svgParse->node) return nullptr;
SvgDocNode* doc = &(loader->svgParse->node->node.doc);
- loader->svgParse->global.w = 0;
- loader->svgParse->global.h = 0;
+ loader->svgParse->global.w = 1.0f;
+ loader->svgParse->global.h = 1.0f;
doc->align = AspectRatioAlign::XMidYMid;
doc->meetOrSlice = AspectRatioMeetOrSlice::Meet;
+ doc->viewFlag = SvgViewFlag::None;
func(buf, bufLength, _attrParseSvgNode, loader);
- if (loader->svgParse->global.w == 0) {
- if (doc->w < FLT_EPSILON) loader->svgParse->global.w = 1;
- else loader->svgParse->global.w = doc->w;
- }
- if (loader->svgParse->global.h == 0) {
- if (doc->h < FLT_EPSILON) loader->svgParse->global.h = 1;
- else loader->svgParse->global.h = doc->h;
+ if (!((uint32_t)doc->viewFlag & (uint32_t)SvgViewFlag::Viewbox)) {
+ if ((uint32_t)doc->viewFlag & (uint32_t)SvgViewFlag::Width) {
+ loader->svgParse->global.w = doc->w;
+ }
+ if ((uint32_t)doc->viewFlag & (uint32_t)SvgViewFlag::Height) {
+ loader->svgParse->global.h = doc->h;
+ }
}
-
return loader->svgParse->node;
}
_updateStyle(loaderData.doc, nullptr);
}
- root = svgSceneBuild(loaderData.doc, vx, vy, vw, vh, w, h, align, meetOrSlice, svgPath);
+ root = svgSceneBuild(loaderData.doc, vx, vy, vw, vh, w, h, align, meetOrSlice, svgPath, viewFlag);
}
if (!loaderData.svgParse) return false;
loaderData.svgParse->flags = SvgStopStyleFlags::StopDefault;
+ viewFlag = SvgViewFlag::None;
simpleXmlParse(content, size, true, _svgLoaderParserForValidCheck, &(loaderData));
if (loaderData.doc && loaderData.doc->type == SvgNodeType::Doc) {
- //Return the brief resource info such as viewbox:
- vx = loaderData.doc->node.doc.vx;
- vy = loaderData.doc->node.doc.vy;
- w = vw = loaderData.doc->node.doc.vw;
- h = vh = loaderData.doc->node.doc.vh;
+ viewFlag = loaderData.doc->node.doc.viewFlag;
+ align = loaderData.doc->node.doc.align;
+ meetOrSlice = loaderData.doc->node.doc.meetOrSlice;
+ w = 1.0f;
+ h = 1.0f;
- //Override size
- if (loaderData.doc->node.doc.w > 0) {
+ //Return the brief resource info such as viewbox:
+ if ((uint32_t)viewFlag & (uint32_t)SvgViewFlag::Width) {
w = loaderData.doc->node.doc.w;
- if (vw < FLT_EPSILON) vw = w;
}
- if (loaderData.doc->node.doc.h > 0) {
+ if ((uint32_t)viewFlag & (uint32_t)SvgViewFlag::Height) {
h = loaderData.doc->node.doc.h;
- if (vh < FLT_EPSILON) vh = h;
}
-
- align = loaderData.doc->node.doc.align;
- meetOrSlice = loaderData.doc->node.doc.meetOrSlice;
+ //Override size
+ if ((uint32_t)viewFlag & (uint32_t)SvgViewFlag::Viewbox) {
+ vx = loaderData.doc->node.doc.vx;
+ vy = loaderData.doc->node.doc.vy;
+ vw = loaderData.doc->node.doc.vw;
+ vh = loaderData.doc->node.doc.vh;
+
+ if (!((uint32_t)viewFlag & (uint32_t)SvgViewFlag::Width)) w = vw;
+ if (!((uint32_t)viewFlag & (uint32_t)SvgViewFlag::Height)) h = vh;
+ } else {
+ vw = w;
+ vh = h;
+ }
} else {
TVGLOG("SVG", "No SVG File. There is no <svg/>");
return false;
{
if (!content || size == 0) return false;
+ if (((uint32_t)viewFlag & (uint32_t)SvgViewFlag::Viewbox) &&
+ (fabsf(vw) <= FLT_EPSILON || fabsf(vh) <= FLT_EPSILON)) {
+ TVGLOG("SVG", "The <viewBox> width and/or height set to 0 - rendering disabled.");
+ return false;
+ }
+
TaskScheduler::request(this);
return true;
float x, y, w, h;
};
-
static bool _appendShape(SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath);
static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, const Box& vBox, const string& svgPath, bool mask, int depth, bool* isMaskWhite = nullptr);
}
+static void _applySvgViewFlag(const Scene* scene, float& vx, float& vy, float& vw, float& vh, float& w, float& h, SvgViewFlag viewFlag)
+{
+ if (!((uint32_t)viewFlag & (uint32_t)SvgViewFlag::Viewbox)) {
+ scene->bounds(nullptr, nullptr, &vw, &vh, false);
+ vx = 0.0f;
+ vy = 0.0f;
+ if ((uint32_t)viewFlag & (uint32_t)SvgViewFlag::Width) vw = w;
+ if ((uint32_t)viewFlag & (uint32_t)SvgViewFlag::Height) vh = h;
+ }
+ if (!((uint32_t)viewFlag & (uint32_t)SvgViewFlag::Width)) w = vw;
+ if (!((uint32_t)viewFlag & (uint32_t)SvgViewFlag::Height)) h = vh;
+}
+
/************************************************************************/
/* External Class Implementation */
/************************************************************************/
-unique_ptr<Scene> svgSceneBuild(SvgNode* node, float vx, float vy, float vw, float vh, float w, float h, AspectRatioAlign align, AspectRatioMeetOrSlice meetOrSlice, const string& svgPath)
+unique_ptr<Scene> svgSceneBuild(SvgNode* node, float& vx, float& vy, float& vw, float& vh, float& w, float& h, AspectRatioAlign align, AspectRatioMeetOrSlice meetOrSlice, const string& svgPath, SvgViewFlag viewFlag)
{
//TODO: aspect ratio is valid only if viewBox was set
Box vBox = {vx, vy, vw, vh};
auto docNode = _sceneBuildHelper(node, vBox, svgPath, false, 0);
+ _applySvgViewFlag(docNode.get(), vx, vy, vw, vh, w, h, viewFlag);
if (!mathEqual(w, vw) || !mathEqual(h, vh)) {
- Matrix m = _calculateAspectRatioMatrix(align, meetOrSlice, w, h, vBox);
+ Matrix m = _calculateAspectRatioMatrix(align, meetOrSlice, w, h, {vx, vy, vw, vh});
docNode->transform(m);
} else if (!mathZero(vx) || !mathZero(vy)) {
docNode->translate(-vx, -vy);