- [SVG] Fix error when reading multiline tags. - [SVG] Fix fill color not propagate to children.

This commit is contained in:
Tanasart 2024-06-28 12:06:34 +07:00
parent e92e0a9f3d
commit f821f552f2
7 changed files with 145 additions and 147 deletions

View File

@ -28,6 +28,7 @@ function draw_set_text(font, halign, valign) {
INLINE
if(argument_count > 3) draw_set_color(argument[3]);
if(argument_count > 4) draw_set_alpha(argument[4]);
draw_set_font(font);
draw_set_halign(halign);

View File

@ -232,19 +232,11 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc
insp2UpdateIcon = [ THEME.cache, 0, COLORS._main_icon ];
static inspector1Update = function() { onInspector1Update(); }
static onInspector1Update = function() { RenderList(nodes); }
static onInspector1Update = function() { array_foreach(NodeListSort(nodes), function(n) { if(n.hasInspector1Update()) n.inspector1Update(); }); }
static hasInspector1Update = function() { INLINE return hasInsp1; }
static inspector2Update = function() { onInspector2Update(); }
static onInspector2Update = function() { #region
var i = 0;
repeat(array_length(nodes)) {
if(nodes[i].hasInspector2Update())
nodes[i].inspector2Update();
i++;
}
} #endregion
static onInspector2Update = function() { array_foreach(NodeListSort(nodes), function(n) { if(n.hasInspector2Update()) n.inspector2Update(); }); }
static hasInspector2Update = function() { INLINE return hasInsp2; }
will_refresh = false;
@ -456,13 +448,23 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc
static onStep = function() {}
static onPreDraw = function(_x, _y, _s, _iny, _outy) { #region
static onPreDraw = function(_x, _y, _s, _iny, _outy) {
var xx = x * _s + _x;
var yy = y * _s + _y;
input_dummy.x = xx;
input_dummy.y = _iny;
} #endregion
var _hv = PANEL_GRAPH.pHOVER && PANEL_GRAPH.node_hovering == self && (!PREFERENCES.panel_graph_group_require_shift || key_mod_press(SHIFT));
bg_spr_add = 0.1 + (0.1 * _hv);
}
static drawNodeBase = function(xx, yy, _s) {
var _hv = PANEL_GRAPH.pHOVER && PANEL_GRAPH.node_hovering == self && (!PREFERENCES.panel_graph_group_require_shift || key_mod_press(SHIFT));
var _aa = (.25 + .5 * renderActive) * (.25 + .75 * isHighlightingInGraph()) + _hv * 0.1;
draw_sprite_stretched_ext(bg_spr, 0, xx, yy, w * _s, h * _s, getColor(), _aa);
}
static preConnect = function() { #region
sortIO();

View File

@ -1,8 +1,6 @@
global.loop_nodes = [ "Node_Iterate", "Node_Iterate_Each" ];
#macro INAME internalName == ""? name : internalName
#macro NODE_HAS_INSP1 (onInspector1Update != noone)
#macro NODE_HAS_INSP2 (onInspector2Update != noone)
enum CACHE_USE {
none,
@ -81,8 +79,9 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
icon = noone;
icon_24 = noone;
bg_spr = THEME.node_bg;
bg_spr_add = true;
bg_sel_spr = THEME.node_active;
bg_spr_add = 0.1;
bg_spr_add_clr = c_white;
bg_sel_spr = THEME.node_active;
name = "";
display_name = "";
@ -479,11 +478,11 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
static onInspector1Update = noone;
static inspector1Update = function() { INLINE onInspector1Update(); }
static hasInspector1Update = function() { INLINE return NODE_HAS_INSP1; }
static hasInspector1Update = function() { INLINE return onInspector1Update != noone; }
static onInspector2Update = noone;
static inspector2Update = function() { INLINE onInspector2Update(); }
static hasInspector2Update = function() { INLINE return NODE_HAS_INSP2; }
static hasInspector2Update = function() { INLINE return onInspector2Update != noone; }
static setInspector = function(index, _tooltip, _icon, _function) {
if(index == 1) {
@ -505,8 +504,8 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
doStepBegin();
if(NODE_HAS_INSP1) inspectInput1.name = insp1UpdateTooltip;
if(NODE_HAS_INSP2) inspectInput2.name = insp2UpdateTooltip;
if(hasInspector1Update()) inspectInput1.name = insp1UpdateTooltip;
if(hasInspector2Update()) inspectInput2.name = insp2UpdateTooltip;
if(attributes.show_update_trigger) {
if(updatedInTrigger.getValue()) {
@ -543,12 +542,12 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
}
}
if(NODE_HAS_INSP1 && inspectInput1.getStaticValue()) {
if(hasInspector1Update() && inspectInput1.getStaticValue()) {
onInspector1Update();
inspectInput1.setValue(false);
}
if(NODE_HAS_INSP2 && inspectInput2.getStaticValue()) {
if(hasInspector2Update() && inspectInput2.getStaticValue()) {
onInspector2Update();
inspectInput2.setValue(false);
}
@ -810,8 +809,8 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
}
}
if(NODE_HAS_INSP1 && inspectInput1.getValue()) onInspector1Update(true);
if(NODE_HAS_INSP2 && inspectInput2.getValue()) onInspector2Update(true);
if(hasInspector1Update() && inspectInput1.getValue()) onInspector1Update(true);
if(hasInspector2Update() && inspectInput2.getValue()) onInspector2Update(true);
updatedOutTrigger.setValue(true);
@ -1078,15 +1077,15 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
var yy = y * _s + _y;
var jun;
var inspCount = NODE_HAS_INSP1 + NODE_HAS_INSP2;
var inspCount = hasInspector1Update() + hasInspector2Update();
var ind = 1;
if(NODE_HAS_INSP1) {
if(hasInspector1Update()) {
inspectInput1.x = xx + w * _s * ind / (inspCount + 1);
inspectInput1.y = yy;
ind++;
}
if(NODE_HAS_INSP2) {
if(hasInspector2Update()) {
inspectInput2.x = xx + w * _s * ind / (inspCount + 1);
inspectInput2.y = yy;
ind++;
@ -1144,21 +1143,9 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
return !high || _selc;
} #endregion
static getColor = function() { #region
INLINE
return attributes.color == -1? color : attributes.color;
} #endregion
static getColor = function() { INLINE return attributes.color == -1? color : attributes.color; }
static drawNodeBase = function(xx, yy, _s) { #region
if(draw_graph_culled) return;
if(!active) return;
var aa = 0.25 + 0.5 * renderActive;
if(!isHighlightingInGraph()) aa *= 0.25;
var cc = getColor();
draw_sprite_stretched_ext(bg_spr, 0, xx, yy, w * _s, h * _s, cc, aa);
} #endregion
static drawNodeBase = function(xx, yy, _s) { INLINE draw_sprite_stretched_ext(bg_spr, 0, xx, yy, w * _s, h * _s, getColor(), (.25 + .5 * renderActive) * (.25 + .75 * isHighlightingInGraph())); }
__draw_bbox = BBOX();
static drawGetBbox = function(xx, yy, _s) { #region
@ -1188,14 +1175,13 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
} #endregion
static drawNodeName = function(xx, yy, _s) { #region
var _name = renamed? display_name : name;
if(_name == "") return;
draw_name = true;
var aa = 0.25 + 0.5 * renderActive;
if(!isHighlightingInGraph()) aa *= 0.25;
var ts = clamp(power(_s, 0.5), 0.5, 1);
var aa = (.25 + .5 * renderActive) * (.25 + .75 * isHighlightingInGraph());
var cc = getColor();
draw_sprite_stretched_ext(THEME.node_bg_name, 0, xx, yy, w * _s, ui(20), cc, aa);
@ -1204,22 +1190,13 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
if(PREFERENCES.node_show_render_status && !rendered)
cc = isRenderable()? COLORS._main_value_positive : COLORS._main_value_negative;
draw_set_text(f_p1, fa_left, fa_center, cc);
aa += 0.25;
if(NODE_HAS_INSP1) icon = THEME.refresh_16;
var ts = clamp(power(_s, 0.5), 0.5, 1);
if(icon) draw_sprite_ui_uniform(icon, 0, xx + ui(12), yy + ui(10),,, aa);
var aa = 0.5 + 0.5 * renderActive;
if(!isHighlightingInGraph()) aa *= 0.25;
draw_set_alpha(aa);
if(icon && _s > 0.75) {
draw_sprite_ui_uniform(icon, 0, xx + ui(12), yy + ui(10),,, aa);
draw_text_cut(round(xx + ui(24)), round(yy + ui(10)), _name, w * _s - ui(24), ts);
} else
draw_text_cut(round(xx + ui(8)), round(yy + ui(10)), _name, w * _s - ui(8), ts);
draw_set_text(f_p1, fa_left, fa_center, cc, aa);
var _xpd = ui(8 + (icon != noone) * 16);
draw_text_cut(round(xx + _xpd), round(yy + ui(10)), _name, w * _s - _xpd, ts);
draw_set_alpha(1);
} #endregion
@ -1315,10 +1292,10 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
hover = jun;
}
if(NODE_HAS_INSP1 && inspectInput1.drawJunction(_s, _mx, _my))
if(hasInspector1Update() && inspectInput1.drawJunction(_s, _mx, _my))
hover = inspectInput1;
if(NODE_HAS_INSP2 && inspectInput2.drawJunction(_s, _mx, _my))
if(hasInspector2Update() && inspectInput2.drawJunction(_s, _mx, _my))
hover = inspectInput2;
if(attributes.show_update_trigger) {
@ -1354,10 +1331,10 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
hover = jun;
}
if(NODE_HAS_INSP1 && inspectInput1.drawJunction_fast(_s, _mx, _my))
if(hasInspector1Update() && inspectInput1.drawJunction_fast(_s, _mx, _my))
hover = inspectInput1;
if(NODE_HAS_INSP2 && inspectInput2.drawJunction_fast(_s, _mx, _my))
if(hasInspector2Update() && inspectInput2.drawJunction_fast(_s, _mx, _my))
hover = inspectInput2;
if(attributes.show_update_trigger) {
@ -1406,12 +1383,12 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
if(outputs[| i].visible) outputs[| i].drawName(_s, _mx, _my);
}
if(NODE_HAS_INSP1 && PANEL_GRAPH.pHOVER && point_in_circle(_mx, _my, inspectInput1.x, inspectInput1.y, 10)) {
if(hasInspector1Update() && PANEL_GRAPH.pHOVER && point_in_circle(_mx, _my, inspectInput1.x, inspectInput1.y, 10)) {
inspectInput1.drawNameBG(_s);
inspectInput1.drawName(_s, _mx, _my);
}
if(NODE_HAS_INSP2 && PANEL_GRAPH.pHOVER && point_in_circle(_mx, _my, inspectInput2.x, inspectInput2.y, 10)) {
if(hasInspector2Update() && PANEL_GRAPH.pHOVER && point_in_circle(_mx, _my, inspectInput2.x, inspectInput2.y, 10)) {
inspectInput2.drawNameBG(_s);
inspectInput2.drawName(_s, _mx, _my);
}
@ -1455,12 +1432,12 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
var _len = 0;
var _jun, _hov;
if(NODE_HAS_INSP1) {
if(hasInspector1Update()) {
_hov = inspectInput1.drawConnections(params);
if(_hov) hovering = _hov;
}
if(NODE_HAS_INSP2) {
if(hasInspector2Update()) {
_hov = inspectInput2.drawConnections(params);
if(_hov) hovering = _hov;
}
@ -1668,8 +1645,7 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
catch(e) { log_warning("NODE onDrawNode", exception_print(e)); }
}
if(show_parameter)
drawJunctionWidget(xx, yy, _mx, _my, _s, _hover, _focus);
if(show_parameter) drawJunctionWidget(xx, yy, _mx, _my, _s, _hover, _focus);
draw_name = false;
if(_s >= 0.75) drawNodeName(xx, yy, _s);
@ -1692,7 +1668,7 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
draw_droppable = false;
}
if(bg_spr_add) draw_sprite_stretched_add(bg_spr, 1, xx, yy, w * _s, h * _s, c_white, 0.1);
if(bg_spr_add > 0) draw_sprite_stretched_add(bg_spr, 1, xx, yy, w * _s, h * _s, bg_spr_add_clr, bg_spr_add);
return _s > 0.5? drawJunctions(xx, yy, _mx, _my, _s) : drawJunctions_fast(xx, yy, _mx, _my, _s);
} #endregion

View File

@ -11,7 +11,7 @@ function Node_Pin(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
hover_alpha = 0;
bg_spr = THEME.node_pin_bg;
bg_spr_add = false;
bg_spr_add = 0;
bg_sel_spr = THEME.node_pin_bg_active;
inputs[| 0] = nodeValue("In", self, JUNCTION_CONNECT.input, VALUE_TYPE.any, 0 )

View File

@ -1,11 +1,11 @@
function Node_create_SVG_path(_x, _y, path) { #region
function Node_create_SVG_path(_x, _y, path) {
if(!file_exists_empty(path)) return noone;
var node = new Node_SVG(_x, _y, PANEL_GRAPH.getCurrentContext());
node.inputs[| 0].setValue(path);
node.doUpdate();
return node;
} #endregion
}
function Node_SVG(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
name = "SVG";
@ -20,9 +20,6 @@ function Node_SVG(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
outputs[| 1] = nodeValue("SVG Struct", self, JUNCTION_CONNECT.output, VALUE_TYPE.struct, {});
outputs[| 2] = nodeValue("Path", self, JUNCTION_CONNECT.output, VALUE_TYPE.path, "")
.setVisible(true, true);
attribute_surface_depth();
rawContent = noone;
@ -35,7 +32,7 @@ function Node_SVG(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
array_push(attributeEditors, [ "File Watcher", function() { return attributes.file_checker; },
new checkBox(function() { attributes.file_checker = !attributes.file_checker; }) ]);
on_drop_file = function(path) { #region
on_drop_file = function(path) {
inputs[| 0].setValue(path);
if(readFile(path)) {
@ -44,9 +41,9 @@ function Node_SVG(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
}
return false;
} #endregion
}
function readFile(path) { #region
function readFile(path) {
curr_path = path;
if(!file_exists_empty(path))
return noone;
@ -57,7 +54,7 @@ function Node_SVG(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
if(ext != ".svg") return;
var _rawContent = file_text_read_all_lines(path);
var _rawContent = file_read_all(path);
var _st = string_pos("<svg", _rawContent);
var _end = string_length(_rawContent);
_rawContent = string_copy(_rawContent, _st, _end - _st + 1);
@ -66,15 +63,15 @@ function Node_SVG(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
content = svg_parse(rawContent);
return;
} #endregion
}
insp1UpdateTooltip = __txt("Refresh");
insp1UpdateIcon = [ THEME.refresh_icon, 1, COLORS._main_value_positive ];
static onInspector1Update = function() { #region
static onInspector1Update = function() {
readFile(path_get(getInputData(0)));
triggerRender();
} #endregion
}
static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
var _scale = getInputData(1);
@ -83,7 +80,7 @@ function Node_SVG(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
content.drawOverlay(hover, active, _x, _y, _s * _scale, _mx, _my, _snx, _sny);
}
static step = function() { #region
static step = function() {
var path = path_get(getInputData(0));
if(!file_exists_empty(path)) return;
@ -92,9 +89,9 @@ function Node_SVG(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
readFile(path);
triggerRender();
}
} #endregion
}
static update = function(frame = CURRENT_FRAME) { #region
static update = function(frame = CURRENT_FRAME) {
var path = path_get(getInputData(0));
if(path != curr_path)
readFile(path);
@ -116,5 +113,5 @@ function Node_SVG(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
outputs[| 0].setValue(_outsurf);
outputs[| 1].setValue(rawContent);
} #endregion
}
}

View File

@ -13,37 +13,57 @@ function SVGElement(svgObj = noone) constructor {
stroke = undefined;
stroke_width = undefined;
static attrColor = function(attr, key) {
if(!struct_has(attr, key)) return undefined;
var str = attr[$ key];
if(is_real(str)) return str;
if(is_string(str)) return colorFromHex(string_replace(str, "#", ""));
return c_black;
}
static attrReal = function(str, def = 0) {
if(is_undefined(str)) return str;
if(is_real(str)) return str;
var e;
if(is_string(str)) {
try { return real(str); }
catch(e) { return def; }
}
return def;
}
static setAttr = function(attr) {
var box = struct_try_get(attr, "viewBox", "");
var ww = struct_try_get(attr, "width", "");
var hh = struct_try_get(attr, "height", "");
box = string_splice(box, " ");
var bx = toNumber(array_safe_get(box, 0, 0));
var by = toNumber(array_safe_get(box, 1, 0));
var bw = toNumber(array_safe_get(box, 2, 1));
var bh = toNumber(array_safe_get(box, 3, 1));
box = string_splice(box, " ");
var bx = attrReal(array_safe_get(box, 0, 0), 0);
var by = attrReal(array_safe_get(box, 1, 0), 0);
var bw = attrReal(array_safe_get(box, 2, 1), 1);
var bh = attrReal(array_safe_get(box, 3, 1), 1);
width = toNumber(ww);
height = toNumber(hh);
width = attrReal(ww, 1);
height = attrReal(hh, 1);
if(string_pos("%", ww)) width *= bw / 100;
if(string_pos("%", hh)) height *= bh / 100;
fill = struct_try_get(attr, "fill", undefined);
stroke = struct_try_get(attr, "stroke", undefined);
fill = attrColor(attr, "fill");
stroke = attrColor(attr, "stroke");
stroke_width = struct_try_get(attr, "stroke-width", undefined);
if(is_string(fill)) fill = color_from_rgb(string_replace_all(fill, "#", ""));
if(is_string(stroke)) stroke = color_from_rgb(string_replace_all(stroke, "#", ""));
shapeAttr(attr);
onSetAttr(attr);
return self;
}
static shapeAttr = function(attr) {}
static onSetAttr = function(attr) {}
static draw = function(scale = 1) {}
@ -61,17 +81,48 @@ function SVG(svgObj = noone) : SVGElement(svgObj) constructor {
static mapX = function(px) { return lerp_invert(px, bbox[0], bbox[0] + bbox[2]) * width; }
static mapY = function(py) { return lerp_invert(py, bbox[1], bbox[1] + bbox[3]) * height; }
static onSetAttr = function(attr) {
if(struct_has(attr, "viewBox")) {
var _bbox = attr.viewBox;
_bbox = string_splice(_bbox);
for (var i = 0, n = array_length(_bbox); i < n; i++)
bbox[i] = attrReal(_bbox[i]);
}
}
static setContent = function(cont) {
if(!struct_has(cont, "children")) return;
setAttr(cont.attributes);
var _ind = 0;
for (var i = 0, n = array_length(cont.children); i < n; i++) {
var _ch = cont.children[i];
switch(_ch.type) {
case "path" : contents[_ind++] = new SVG_path(self).setAttr(_ch.attributes); break;
case "rect" : contents[_ind++] = new SVG_rect(self).setAttr(_ch.attributes); break;
case "circle" : contents[_ind++] = new SVG_circle(self).setAttr(_ch.attributes); break;
case "ellipse" : contents[_ind++] = new SVG_ellipse(self).setAttr(_ch.attributes); break;
case "line" : contents[_ind++] = new SVG_line(self).setAttr(_ch.attributes); break;
case "polyline" : contents[_ind++] = new SVG_polyline(self).setAttr(_ch.attributes); break;
case "polygon" : contents[_ind++] = new SVG_polygon(self).setAttr(_ch.attributes); break;
}
}
return self;
}
static getSurface = function(scale = 1) { return surface_create(width * scale, height * scale); }
static draw = function(scale = 1) {
if(!is_undefined(fill))
draw_set_color(fill);
if(!is_undefined(fill_opacity))
draw_set_alpha(fill_opacity);
for (var i = 0, n = array_length(contents); i < n; i++)
for (var i = 0, n = array_length(contents); i < n; i++) {
if(!is_undefined(fill)) draw_set_color(fill);
if(!is_undefined(fill_opacity)) draw_set_alpha(fill_opacity);
contents[i].draw(scale);
}
}
static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
@ -181,7 +232,7 @@ function SVG_path(svgObj = noone) : SVGElement(svgObj) constructor {
// }
}
static shapeAttr = function(attr) {
static onSetAttr = function(attr) {
var def = struct_try_get(attr, "d", "");
var _mode = "";
@ -672,7 +723,7 @@ function SVG_path(svgObj = noone) : SVGElement(svgObj) constructor {
function SVG_rect(svgObj = noone) : SVGElement(svgObj) constructor {
static shapeAttr = function(attr) {
static onSetAttr = function(attr) {
x = struct_try_get(attr, "x", 0);
y = struct_try_get(attr, "y", 0);
@ -719,7 +770,7 @@ function SVG_circle(svgObj = noone) : SVGElement(svgObj) constructor {
cy = 0;
r = 0;
static shapeAttr = function(attr) {
static onSetAttr = function(attr) {
cx = struct_try_get(attr, "cx", 0);
cy = struct_try_get(attr, "cy", 0);
@ -764,7 +815,7 @@ function SVG_ellipse(svgObj = noone) : SVGElement(svgObj) constructor {
rx = 0;
ry = 0;
static shapeAttr = function(attr) {
static onSetAttr = function(attr) {
cx = struct_try_get(attr, "cx", 0);
cy = struct_try_get(attr, "cy", 0);
@ -812,7 +863,7 @@ function SVG_line(svgObj = noone) : SVGElement(svgObj) constructor {
x1 = 0;
y1 = 0;
static shapeAttr = function(attr) {
static onSetAttr = function(attr) {
x0 = struct_try_get(attr, "x0", 0);
y0 = struct_try_get(attr, "y0", 0);
@ -852,7 +903,7 @@ function SVG_line(svgObj = noone) : SVGElement(svgObj) constructor {
function SVG_polyline(svgObj = noone) : SVGElement(svgObj) constructor {
points = [];
static shapeAttr = function(attr) {
static onSetAttr = function(attr) {
points = struct_try_get(attr, "points", []);
}
@ -907,7 +958,7 @@ function SVG_polyline(svgObj = noone) : SVGElement(svgObj) constructor {
function SVG_polygon(svgObj = noone) : SVGElement(svgObj) constructor {
points = [];
static shapeAttr = function(attr) {
static onSetAttr = function(attr) {
points = struct_try_get(attr, "points", []);
}

View File

@ -1,41 +1,12 @@
function svg_parse(xmlStr) {
if(!is_struct(xmlStr)) return noone;
if(struct_try_get(xmlStr, "type") != "root") return noone;
if(array_empty(xmlStr.children)) return noone;
if(!is_struct(xmlStr)) return noone;
if(!struct_has(xmlStr, "children")) return noone;
if(struct_try_get(xmlStr, "type") != "root") return noone;
if(array_empty(xmlStr.children)) return noone;
var svg_object = xmlStr.children[0];
if(struct_try_get(svg_object, "type") != "svg") return noone;
var attr = svg_object.attributes;
var svg = new SVG().setAttr(attr);
if(struct_has(attr, "viewBox")) {
var bbox = attr.viewBox;
bbox = string_splice(bbox);
for (var i = 0, n = array_length(bbox); i < n; i++)
bbox[i] = real(bbox[i])
svg.bbox = bbox;
}
if(struct_has(svg_object, "children")) {
var _ind = 0;
for (var i = 0, n = array_length(svg_object.children); i < n; i++) {
var _ch = svg_object.children[i];
switch(_ch.type) {
case "path" : svg.contents[_ind++] = new SVG_path(svg).setAttr(_ch.attributes); break;
case "rect" : svg.contents[_ind++] = new SVG_rect(svg).setAttr(_ch.attributes); break;
case "circle" : svg.contents[_ind++] = new SVG_circle(svg).setAttr(_ch.attributes); break;
case "ellipse" : svg.contents[_ind++] = new SVG_ellipse(svg).setAttr(_ch.attributes); break;
case "line" : svg.contents[_ind++] = new SVG_line(svg).setAttr(_ch.attributes); break;
case "polyline" : svg.contents[_ind++] = new SVG_polyline(svg).setAttr(_ch.attributes); break;
case "polygon" : svg.contents[_ind++] = new SVG_polygon(svg).setAttr(_ch.attributes); break;
}
}
}
return svg;
return new SVG().setContent(svg_object);
}