diff --git a/Nasal/canvas/api.nas b/Nasal/canvas/api.nas index 7a104911d..1971bffbf 100644 --- a/Nasal/canvas/api.nas +++ b/Nasal/canvas/api.nas @@ -326,76 +326,7 @@ var Group = { # @param cfg Optional settings (eg. {"border-top-radius": 5}) rect: func(x, y, w, h, cfg = nil) { - var opts = (cfg != nil) ? cfg : {}; - - # resolve border-[top-,bottom-][left-,right-]radius - var br = opts["border-radius"]; - if( typeof(br) == 'scalar' ) - br = [br, br]; - - var _parseRadius = func(id) - { - if( (var r = opts["border-" ~ id ~ "-radius"]) == nil ) - { - # parse top, bottom, left, right separate if no value specified for - # single corner - foreach(var s; ["top", "bottom", "left", "right"]) - { - if( id.starts_with(s ~ "-") ) - { - r = opts["border-" ~ s ~ "-radius"]; - break; - } - } - } - - if( r == nil ) - return br; - else if( typeof(r) == 'scalar' ) - return [r, r]; - else - return r; - }; - - var path = me.createChild("path"); - - # top-left - if( (var r = _parseRadius("top-left")) != nil ) - { - path.moveTo(x, y + r[1]) - .arcSmallCWTo(r[0], r[1], 0, x + r[0], y); - } - else - path.moveTo(x, y); - - # top-right - if( (r = _parseRadius("top-right")) != nil ) - { - path.horizTo(x + w - r[0]) - .arcSmallCWTo(r[0], r[1], 0, x + w, y + r[1]); - } - else - path.horizTo(x + w); - - # bottom-right - if( (r = _parseRadius("bottom-right")) != nil ) - { - path.vertTo(y + h - r[1]) - .arcSmallCWTo(r[0], r[1], 0, x + w - r[0], y + h); - } - else - path.vertTo(y + h); - - # bottom-left - if( (r = _parseRadius("bottom-left")) != nil ) - { - path.horizTo(x + r[0]) - .arcSmallCWTo(r[0], r[1], 0, x, y + h - r[1]); - } - else - path.horizTo(x); - - return path.close(); + return me.createChild("path").rect(x, y, w, h, cfg); }, # Get a vector of all child elements getChildren: func() @@ -698,6 +629,85 @@ var Path = { # Close the path (implicit lineTo to first point of path) close: func me.addSegment(me.VG_CLOSE_PATH), + # Add a (rounded) rectangle to the path + # + # @param x Position of left border + # @param y Position of top border + # @param w Width + # @param h Height + # @param cfg Optional settings (eg. {"border-top-radius": 5}) + rect: func(x, y, w, h, cfg = nil) + { + var opts = (cfg != nil) ? cfg : {}; + + # resolve border-[top-,bottom-][left-,right-]radius + var br = opts["border-radius"]; + if( typeof(br) == 'scalar' ) + br = [br, br]; + + var _parseRadius = func(id) + { + if( (var r = opts["border-" ~ id ~ "-radius"]) == nil ) + { + # parse top, bottom, left, right separate if no value specified for + # single corner + foreach(var s; ["top", "bottom", "left", "right"]) + { + if( id.starts_with(s ~ "-") ) + { + r = opts["border-" ~ s ~ "-radius"]; + break; + } + } + } + + if( r == nil ) + return br; + else if( typeof(r) == 'scalar' ) + return [r, r]; + else + return r; + }; + + # top-left + if( (var r = _parseRadius("top-left")) != nil ) + { + me.moveTo(x, y + r[1]) + .arcSmallCWTo(r[0], r[1], 0, x + r[0], y); + } + else + me.moveTo(x, y); + + # top-right + if( (r = _parseRadius("top-right")) != nil ) + { + me.horizTo(x + w - r[0]) + .arcSmallCWTo(r[0], r[1], 0, x + w, y + r[1]); + } + else + me.horizTo(x + w); + + # bottom-right + if( (r = _parseRadius("bottom-right")) != nil ) + { + me.vertTo(y + h - r[1]) + .arcSmallCWTo(r[0], r[1], 0, x + w - r[0], y + h); + } + else + me.vertTo(y + h); + + # bottom-left + if( (r = _parseRadius("bottom-left")) != nil ) + { + me.horizTo(x + r[0]) + .arcSmallCWTo(r[0], r[1], 0, x, y + h - r[1]); + } + else + me.horizTo(x); + + return me.close(); + }, + setColor: func me.setStroke(_getColor(arg)), setColorFill: func me.setFill(_getColor(arg)), diff --git a/Nasal/canvas/svg.nas b/Nasal/canvas/svg.nas index cfc4f1ff8..1de33a7ac 100644 --- a/Nasal/canvas/svg.nas +++ b/Nasal/canvas/svg.nas @@ -374,7 +374,6 @@ var parsesvg = func(group, path, options = nil) else if( name == "path" or name == "rect" ) { pushElement('path', attr['id']); - var d = attr['d']; if( name == "rect" ) { @@ -382,11 +381,22 @@ var parsesvg = func(group, path, options = nil) var height = attr['height']; var x = attr['x']; var y = attr['y']; + var rx = attr['rx']; + var ry = attr['ry']; - d = sprintf("M%f,%f v%f h%f v%fz", x, y, height, width, -height); + if( ry == nil ) + ry = rx; + else if( rx == nil ) + rx = ry; + + var cfg = {}; + if( rx != nil ) + cfg["border-radius"] = [rx, ry]; + + stack[-1].rect(x, y, width, height, cfg); } - - parsePath(d); + else + parsePath(attr['d']); stack[-1].set('fill', style['fill']);