1
0
Fork 0

SVG rect rounded corner and refactor rect helper

This commit is contained in:
Thomas Geymayer 2013-02-23 19:19:32 +01:00
parent 5d54d3c504
commit 71f3f878c6
2 changed files with 94 additions and 74 deletions

View file

@ -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)),

View file

@ -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']);