Made lines follow 45 degree angles when holding shift, made selection box fit better on zoom, updated canvg
git-svn-id: http://svg-edit.googlecode.com/svn/trunk@1531 eee81c28-f429-11dd-99c0-75d572ba1ddd
This commit is contained in:
@@ -159,7 +159,19 @@ if(!window.console) {
|
|||||||
getDefinition: function() {
|
getDefinition: function() {
|
||||||
var name = that.value.replace(/^(url\()?#([^\)]+)\)?$/, '$2');
|
var name = that.value.replace(/^(url\()?#([^\)]+)\)?$/, '$2');
|
||||||
return svg.Definitions[name];
|
return svg.Definitions[name];
|
||||||
}
|
},
|
||||||
|
|
||||||
|
isUrl: function() {
|
||||||
|
return that.value.indexOf('url(') == 0
|
||||||
|
},
|
||||||
|
|
||||||
|
getGradient: function(e) {
|
||||||
|
var grad = this.getDefinition();
|
||||||
|
if (grad != null && grad.createGradient) {
|
||||||
|
return grad.createGradient(svg.ctx, e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// length extensions
|
// length extensions
|
||||||
@@ -171,7 +183,7 @@ if(!window.console) {
|
|||||||
EM: function(viewPort) {
|
EM: function(viewPort) {
|
||||||
var em = 12;
|
var em = 12;
|
||||||
|
|
||||||
var fontSize = new svg.Property('fontSize', svg.ctx.font.match(/[0-9][^\s\t\n\r\/]*/g)[0]);
|
var fontSize = new svg.Property('fontSize', svg.Font.Parse(svg.ctx.font).fontSize);
|
||||||
if (fontSize.hasValue()) em = fontSize.Length.toPixels(viewPort);
|
if (fontSize.hasValue()) em = fontSize.Length.toPixels(viewPort);
|
||||||
|
|
||||||
return em;
|
return em;
|
||||||
@@ -220,6 +232,41 @@ if(!window.console) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fonts
|
||||||
|
svg.Font = new (function() {
|
||||||
|
this.Styles = ['normal','italic','oblique','inherit'];
|
||||||
|
this.Variants = ['normal','small-caps','inherit'];
|
||||||
|
this.Weights = ['normal','bold','bolder','lighter','100','200','300','400','500','600','700','800','900','inherit'];
|
||||||
|
|
||||||
|
this.CreateFont = function(fontStyle, fontVariant, fontWeight, fontSize, fontFamily, inherit) {
|
||||||
|
var f = inherit != null ? this.Parse(inherit) : this.CreateFont('', '', '', '', '', svg.ctx.font);
|
||||||
|
return {
|
||||||
|
fontFamily: fontFamily || f.fontFamily,
|
||||||
|
fontSize: fontSize || f.fontSize,
|
||||||
|
fontStyle: fontStyle || f.fontStyle,
|
||||||
|
fontWeight: fontWeight || f.fontWeight,
|
||||||
|
fontVariant: fontVariant || f.fontVariant,
|
||||||
|
toString: function () { return [this.fontStyle, this.fontVariant, this.fontWeight, this.fontSize, this.fontFamily].join(' ') }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var that = this;
|
||||||
|
this.Parse = function(s) {
|
||||||
|
var f = {};
|
||||||
|
var d = svg.trim(svg.compressSpaces(s || '')).split(' ');
|
||||||
|
var set = { fontSize: false, fontStyle: false, fontWeight: false, fontVariant: false }
|
||||||
|
var ff = '';
|
||||||
|
for (var i=0; i<d.length; i++) {
|
||||||
|
if (!set.fontStyle && that.Styles.indexOf(d[i]) != -1) { if (d[i] != 'inherit') f.fontStyle = d[i]; set.fontStyle = true; }
|
||||||
|
else if (!set.fontVariant && that.Variants.indexOf(d[i]) != -1) { if (d[i] != 'inherit') f.fontVariant = d[i]; set.fontStyle = set.fontVariant = true; }
|
||||||
|
else if (!set.fontWeight && that.Weights.indexOf(d[i]) != -1) { if (d[i] != 'inherit') f.fontWeight = d[i]; set.fontStyle = set.fontVariant = set.fontWeight = true; }
|
||||||
|
else if (!set.fontSize) { if (d[i] != 'inherit') f.fontSize = d[i].split('/')[0]; set.fontStyle = set.fontVariant = set.fontWeight = set.fontSize = true; }
|
||||||
|
else { if (d[i] != 'inherit') ff += d[i]; }
|
||||||
|
} if (ff != '') f.fontFamily = ff;
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// points and paths
|
// points and paths
|
||||||
svg.ToNumberArray = function(s) {
|
svg.ToNumberArray = function(s) {
|
||||||
var a = svg.trim(svg.compressSpaces((s || '').replace(/,/g, ' '))).split(' ');
|
var a = svg.trim(svg.compressSpaces((s || '').replace(/,/g, ' '))).split(' ');
|
||||||
@@ -532,22 +579,22 @@ if(!window.console) {
|
|||||||
|
|
||||||
this.setContext = function(ctx) {
|
this.setContext = function(ctx) {
|
||||||
// fill
|
// fill
|
||||||
if (this.style('fill').value.indexOf('url(') == 0) {
|
if (this.style('fill').Definition.isUrl()) {
|
||||||
var grad = this.style('fill').Definition.getDefinition();
|
var grad = this.style('fill').Definition.getGradient(this);
|
||||||
if (grad != null && grad.createGradient) {
|
if (grad != null) ctx.fillStyle = grad;
|
||||||
ctx.fillStyle = grad.createGradient(ctx, this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else if (this.style('fill').hasValue()) {
|
||||||
if (this.style('fill').hasValue()) {
|
var fillStyle = this.style('fill');
|
||||||
var fillStyle = this.style('fill');
|
if (this.style('fill-opacity').hasValue()) fillStyle = fillStyle.Color.addOpacity(this.style('fill-opacity').value);
|
||||||
if (this.style('fill-opacity').hasValue()) fillStyle = fillStyle.Color.addOpacity(this.style('fill-opacity').value);
|
ctx.fillStyle = (fillStyle.value == 'none' ? 'rgba(0,0,0,0)' : fillStyle.value);
|
||||||
ctx.fillStyle = (fillStyle.value == 'none' ? 'rgba(0,0,0,0)' : fillStyle.value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// stroke
|
// stroke
|
||||||
if (this.style('stroke').hasValue()) {
|
if (this.style('stroke').Definition.isUrl()) {
|
||||||
|
var grad = this.style('stroke').Definition.getGradient(this);
|
||||||
|
if (grad != null) ctx.strokeStyle = grad;
|
||||||
|
}
|
||||||
|
else if (this.style('stroke').hasValue()) {
|
||||||
var strokeStyle = this.style('stroke');
|
var strokeStyle = this.style('stroke');
|
||||||
if (this.style('stroke-opacity').hasValue()) strokeStyle = strokeStyle.Color.addOpacity(this.style('stroke-opacity').value);
|
if (this.style('stroke-opacity').hasValue()) strokeStyle = strokeStyle.Color.addOpacity(this.style('stroke-opacity').value);
|
||||||
ctx.strokeStyle = (strokeStyle.value == 'none' ? 'rgba(0,0,0,0)' : strokeStyle.value);
|
ctx.strokeStyle = (strokeStyle.value == 'none' ? 'rgba(0,0,0,0)' : strokeStyle.value);
|
||||||
@@ -558,10 +605,14 @@ if(!window.console) {
|
|||||||
if (this.style('stroke-miterlimit').hasValue()) ctx.miterLimit = this.style('stroke-miterlimit').value;
|
if (this.style('stroke-miterlimit').hasValue()) ctx.miterLimit = this.style('stroke-miterlimit').value;
|
||||||
|
|
||||||
// font
|
// font
|
||||||
if (this.style('font-size').hasValue()) {
|
opera.postError('typeof(ctx.font):' + ctx.font);
|
||||||
var fontFamily = this.style('font-family').valueOrDefault('Arial');
|
if (typeof(ctx.font) != 'undefined') {
|
||||||
var fontSize = this.style('font-size').numValueOrDefault('12') + 'px';
|
ctx.font = svg.Font.CreateFont(
|
||||||
ctx.font = fontSize + ' ' + fontFamily;
|
this.style('font-style').value,
|
||||||
|
this.style('font-variant').value,
|
||||||
|
this.style('font-weight').value,
|
||||||
|
this.style('font-size').hasValue() ? this.style('font-size').Length.toPixels() + 'px' : '',
|
||||||
|
this.style('font-family').value).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// transform
|
// transform
|
||||||
@@ -596,12 +647,29 @@ if(!window.console) {
|
|||||||
this.renderChildren = function(ctx) {
|
this.renderChildren = function(ctx) {
|
||||||
this.path(ctx);
|
this.path(ctx);
|
||||||
if (ctx.fillStyle != '') ctx.fill();
|
if (ctx.fillStyle != '') ctx.fill();
|
||||||
if (ctx.strokeStyle != '') ctx.stroke();
|
if (ctx.strokeStyle != '') ctx.stroke();
|
||||||
|
|
||||||
|
if (this.attribute('marker-end').Definition.isUrl()) {
|
||||||
|
var marker = this.attribute('marker-end').Definition.getDefinition();
|
||||||
|
var endPoint = this.getEndPoint();
|
||||||
|
var endAngle = this.getEndAngle();
|
||||||
|
if (endPoint != null && endAngle != null) {
|
||||||
|
marker.render(ctx, endPoint, endAngle);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getBoundingBox = function() {
|
this.getBoundingBox = function() {
|
||||||
return this.path();
|
return this.path();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.getEndPoint = function() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getEndAngle = function() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
svg.Element.PathElementBase.prototype = new svg.Element.RenderedElementBase;
|
svg.Element.PathElementBase.prototype = new svg.Element.RenderedElementBase;
|
||||||
|
|
||||||
@@ -630,11 +698,19 @@ if(!window.console) {
|
|||||||
if (this.attribute('width').hasValue() && this.attribute('height').hasValue()) {
|
if (this.attribute('width').hasValue() && this.attribute('height').hasValue()) {
|
||||||
width = this.attribute('width').Length.toPixels('x');
|
width = this.attribute('width').Length.toPixels('x');
|
||||||
height = this.attribute('height').Length.toPixels('y');
|
height = this.attribute('height').Length.toPixels('y');
|
||||||
|
|
||||||
|
var x = 0;
|
||||||
|
var y = 0;
|
||||||
|
if (this.attribute('refX').hasValue() && this.attribute('refY').hasValue()) {
|
||||||
|
x = -this.attribute('refX').Length.toPixels('x');
|
||||||
|
y = -this.attribute('refY').Length.toPixels('y');
|
||||||
|
}
|
||||||
|
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(0, 0);
|
ctx.moveTo(x, y);
|
||||||
ctx.lineTo(width, 0);
|
ctx.lineTo(width, y);
|
||||||
ctx.lineTo(width, height);
|
ctx.lineTo(width, height);
|
||||||
ctx.lineTo(0, height);
|
ctx.lineTo(x, height);
|
||||||
ctx.closePath();
|
ctx.closePath();
|
||||||
ctx.clip();
|
ctx.clip();
|
||||||
}
|
}
|
||||||
@@ -661,24 +737,28 @@ if(!window.console) {
|
|||||||
var scaleMax = Math.max(scaleX, scaleY);
|
var scaleMax = Math.max(scaleX, scaleY);
|
||||||
if (meetOrSlice == 'meet') { width *= scaleMin; height *= scaleMin; }
|
if (meetOrSlice == 'meet') { width *= scaleMin; height *= scaleMin; }
|
||||||
if (meetOrSlice == 'slice') { width *= scaleMax; height *= scaleMax; }
|
if (meetOrSlice == 'slice') { width *= scaleMax; height *= scaleMax; }
|
||||||
|
|
||||||
// align
|
if (this.attribute('refX').hasValue() && this.attribute('refY').hasValue()) {
|
||||||
if (align.match(/^xMid/) && ((meetOrSlice == 'meet' && scaleMin == scaleY) || (meetOrSlice == 'slice' && scaleMax == scaleY))) ctx.translate(svg.ViewPort.width() / 2.0 - width / 2.0, 0);
|
ctx.translate(-scaleMin * this.attribute('refX').Length.toPixels('x'), -scaleMin * this.attribute('refY').Length.toPixels('y'));
|
||||||
if (align.match(/YMid$/) && ((meetOrSlice == 'meet' && scaleMin == scaleX) || (meetOrSlice == 'slice' && scaleMax == scaleX))) ctx.translate(0, svg.ViewPort.height() / 2.0 - height / 2.0);
|
}
|
||||||
if (align.match(/^xMax/) && ((meetOrSlice == 'meet' && scaleMin == scaleY) || (meetOrSlice == 'slice' && scaleMax == scaleY))) ctx.translate(svg.ViewPort.width() - width, 0);
|
else {
|
||||||
if (align.match(/YMax$/) && ((meetOrSlice == 'meet' && scaleMin == scaleX) || (meetOrSlice == 'slice' && scaleMax == scaleX))) ctx.translate(0, svg.ViewPort.height() - height);
|
// align
|
||||||
|
if (align.match(/^xMid/) && ((meetOrSlice == 'meet' && scaleMin == scaleY) || (meetOrSlice == 'slice' && scaleMax == scaleY))) ctx.translate(svg.ViewPort.width() / 2.0 - width / 2.0, 0);
|
||||||
|
if (align.match(/YMid$/) && ((meetOrSlice == 'meet' && scaleMin == scaleX) || (meetOrSlice == 'slice' && scaleMax == scaleX))) ctx.translate(0, svg.ViewPort.height() / 2.0 - height / 2.0);
|
||||||
|
if (align.match(/^xMax/) && ((meetOrSlice == 'meet' && scaleMin == scaleY) || (meetOrSlice == 'slice' && scaleMax == scaleY))) ctx.translate(svg.ViewPort.width() - width, 0);
|
||||||
|
if (align.match(/YMax$/) && ((meetOrSlice == 'meet' && scaleMin == scaleX) || (meetOrSlice == 'slice' && scaleMax == scaleX))) ctx.translate(0, svg.ViewPort.height() - height);
|
||||||
|
}
|
||||||
|
|
||||||
// scale
|
// scale
|
||||||
if (meetOrSlice == 'meet') ctx.scale(scaleMin, scaleMin);
|
if (meetOrSlice == 'meet') ctx.scale(scaleMin, scaleMin);
|
||||||
if (meetOrSlice == 'slice') ctx.scale(scaleMax, scaleMax);
|
if (meetOrSlice == 'slice') ctx.scale(scaleMax, scaleMax);
|
||||||
ctx.translate(-minX, -minY);
|
ctx.translate(-minX, -minY);
|
||||||
|
|
||||||
svg.ViewPort.RemoveCurrent();
|
svg.ViewPort.RemoveCurrent();
|
||||||
svg.ViewPort.SetCurrent(viewBox[2], viewBox[3]);
|
svg.ViewPort.SetCurrent(viewBox[2], viewBox[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// initial values
|
// initial values
|
||||||
ctx.fillStyle = '#000000';
|
|
||||||
ctx.strokeStyle = 'rgba(0,0,0,0)';
|
ctx.strokeStyle = 'rgba(0,0,0,0)';
|
||||||
ctx.lineCap = 'butt';
|
ctx.lineCap = 'butt';
|
||||||
ctx.lineJoin = 'miter';
|
ctx.lineJoin = 'miter';
|
||||||
@@ -788,6 +868,20 @@ if(!window.console) {
|
|||||||
|
|
||||||
return new svg.BoundingBox(x1, y1, x2, y2);
|
return new svg.BoundingBox(x1, y1, x2, y2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.getEndPoint = function() {
|
||||||
|
var x2 = this.attribute('x2').Length.toPixels('x');
|
||||||
|
var y2 = this.attribute('y2').Length.toPixels('y');
|
||||||
|
return new svg.Point(x2, y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getEndAngle = function() {
|
||||||
|
var x1 = this.attribute('x1').Length.toPixels('x');
|
||||||
|
var y1 = this.attribute('y1').Length.toPixels('y');
|
||||||
|
var x2 = this.attribute('x2').Length.toPixels('x');
|
||||||
|
var y2 = this.attribute('y2').Length.toPixels('y');
|
||||||
|
return Math.atan((y2-y1)/(x2-x1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
svg.Element.line.prototype = new svg.Element.PathElementBase;
|
svg.Element.line.prototype = new svg.Element.PathElementBase;
|
||||||
|
|
||||||
@@ -843,6 +937,7 @@ if(!window.console) {
|
|||||||
d = d.replace(/([^\s])([A-Za-z])/gm,'$1 $2'); // separate commands from points
|
d = d.replace(/([^\s])([A-Za-z])/gm,'$1 $2'); // separate commands from points
|
||||||
d = d.replace(/([0-9])([+\-])/gm,'$1 $2'); // separate digits when no comma
|
d = d.replace(/([0-9])([+\-])/gm,'$1 $2'); // separate digits when no comma
|
||||||
d = d.replace(/(\.[0-9]*)(\.)/gm,'$1 $2'); // separate digits when no comma
|
d = d.replace(/(\.[0-9]*)(\.)/gm,'$1 $2'); // separate digits when no comma
|
||||||
|
d = d.replace(/([Aa](\s+[0-9]+){3})\s+([01])\s*([01])/gm,'$1 $3 $4 '); // shorthand elliptical arc path syntax
|
||||||
d = svg.compressSpaces(d); // compress multiple spaces
|
d = svg.compressSpaces(d); // compress multiple spaces
|
||||||
d = svg.trim(d);
|
d = svg.trim(d);
|
||||||
this.PathParser = new (function(d) {
|
this.PathParser = new (function(d) {
|
||||||
@@ -852,9 +947,19 @@ if(!window.console) {
|
|||||||
this.i = -1;
|
this.i = -1;
|
||||||
this.command = '';
|
this.command = '';
|
||||||
this.control = new svg.Point(0, 0);
|
this.control = new svg.Point(0, 0);
|
||||||
|
this.last = new svg.Point(0, 0);
|
||||||
this.current = new svg.Point(0, 0);
|
this.current = new svg.Point(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.angle = function() {
|
||||||
|
return Math.atan((this.current.y - this.last.y) / (this.current.x - this.last.x));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setCurrent = function(p) {
|
||||||
|
this.last = this.current;
|
||||||
|
this.current = p;
|
||||||
|
}
|
||||||
|
|
||||||
this.isEnd = function() {
|
this.isEnd = function() {
|
||||||
return this.i == this.tokens.length - 1;
|
return this.i == this.tokens.length - 1;
|
||||||
}
|
}
|
||||||
@@ -894,7 +999,7 @@ if(!window.console) {
|
|||||||
|
|
||||||
this.getAsCurrentPoint = function() {
|
this.getAsCurrentPoint = function() {
|
||||||
var p = this.getPoint();
|
var p = this.getPoint();
|
||||||
this.current = p;
|
this.setCurrent(p);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -912,7 +1017,7 @@ if(!window.console) {
|
|||||||
}
|
}
|
||||||
})(d);
|
})(d);
|
||||||
|
|
||||||
this.path = function(ctx) {
|
this.path = function(ctx) {
|
||||||
var pp = this.PathParser;
|
var pp = this.PathParser;
|
||||||
pp.reset();
|
pp.reset();
|
||||||
|
|
||||||
@@ -940,6 +1045,7 @@ if(!window.console) {
|
|||||||
else if (pp.command.toUpperCase() == 'H') {
|
else if (pp.command.toUpperCase() == 'H') {
|
||||||
while (!pp.isCommandOrEnd()) {
|
while (!pp.isCommandOrEnd()) {
|
||||||
pp.current.x = (pp.isRelativeCommand() ? pp.current.x : 0) + pp.getScalar();
|
pp.current.x = (pp.isRelativeCommand() ? pp.current.x : 0) + pp.getScalar();
|
||||||
|
pp.setCurrent(pp.current);
|
||||||
bb.addPoint(pp.current.x, pp.current.y);
|
bb.addPoint(pp.current.x, pp.current.y);
|
||||||
if (ctx != null) ctx.lineTo(pp.current.x, pp.current.y);
|
if (ctx != null) ctx.lineTo(pp.current.x, pp.current.y);
|
||||||
}
|
}
|
||||||
@@ -947,6 +1053,7 @@ if(!window.console) {
|
|||||||
else if (pp.command.toUpperCase() == 'V') {
|
else if (pp.command.toUpperCase() == 'V') {
|
||||||
while (!pp.isCommandOrEnd()) {
|
while (!pp.isCommandOrEnd()) {
|
||||||
pp.current.y = (pp.isRelativeCommand() ? pp.current.y : 0) + pp.getScalar();
|
pp.current.y = (pp.isRelativeCommand() ? pp.current.y : 0) + pp.getScalar();
|
||||||
|
pp.setCurrent(pp.current);
|
||||||
bb.addPoint(pp.current.x, pp.current.y);
|
bb.addPoint(pp.current.x, pp.current.y);
|
||||||
if (ctx != null) ctx.lineTo(pp.current.x, pp.current.y);
|
if (ctx != null) ctx.lineTo(pp.current.x, pp.current.y);
|
||||||
}
|
}
|
||||||
@@ -1050,16 +1157,59 @@ if(!window.console) {
|
|||||||
if (ctx != null) ctx.closePath();
|
if (ctx != null) ctx.closePath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return bb;
|
return bb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.getEndPoint = function() {
|
||||||
|
return this.PathParser.current;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getEndAngle = function() {
|
||||||
|
return this.PathParser.angle();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
svg.Element.path.prototype = new svg.Element.PathElementBase;
|
svg.Element.path.prototype = new svg.Element.PathElementBase;
|
||||||
|
|
||||||
|
svg.Element.marker = function(node) {
|
||||||
|
this.base = svg.Element.ElementBase;
|
||||||
|
this.base(node);
|
||||||
|
|
||||||
|
this.baseRender = this.render;
|
||||||
|
this.render = function(ctx, endPoint, endAngle) {
|
||||||
|
ctx.translate(endPoint.x, endPoint.y);
|
||||||
|
if (this.attribute('orient').valueOrDefault('auto') == 'auto') ctx.rotate(endAngle);
|
||||||
|
if (this.attribute('markerUnits').valueOrDefault('strokeWidth') == 'strokeWidth') ctx.scale(ctx.lineWidth, ctx.lineWidth);
|
||||||
|
ctx.save();
|
||||||
|
|
||||||
|
// render me using a temporary svg element
|
||||||
|
var tempSvg = new svg.Element.svg();
|
||||||
|
tempSvg.attributes['viewBox'] = new svg.Property('viewBox', this.attribute('viewBox').value);
|
||||||
|
tempSvg.attributes['refX'] = new svg.Property('refX', this.attribute('refX').value);
|
||||||
|
tempSvg.attributes['refY'] = new svg.Property('refY', this.attribute('refY').value);
|
||||||
|
tempSvg.attributes['width'] = new svg.Property('width', this.attribute('markerWidth').value);
|
||||||
|
tempSvg.attributes['height'] = new svg.Property('height', this.attribute('markerHeight').value);
|
||||||
|
tempSvg.attributes['fill'] = new svg.Property('fill', this.attribute('fill').valueOrDefault('black'));
|
||||||
|
tempSvg.attributes['stroke'] = new svg.Property('stroke', this.attribute('stroke').valueOrDefault('none'));
|
||||||
|
tempSvg.children = this.children;
|
||||||
|
tempSvg.render(ctx);
|
||||||
|
|
||||||
|
ctx.restore();
|
||||||
|
if (this.attribute('markerUnits').valueOrDefault('strokeWidth') == 'strokeWidth') ctx.scale(1/ctx.lineWidth, 1/ctx.lineWidth);
|
||||||
|
if (this.attribute('orient').valueOrDefault('auto') == 'auto') ctx.rotate(-endAngle);
|
||||||
|
ctx.translate(-endPoint.x, -endPoint.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
svg.Element.marker.prototype = new svg.Element.ElementBase;
|
||||||
|
|
||||||
// definitions element
|
// definitions element
|
||||||
svg.Element.defs = function(node) {
|
svg.Element.defs = function(node) {
|
||||||
this.base = svg.Element.ElementBase;
|
this.base = svg.Element.ElementBase;
|
||||||
this.base(node);
|
this.base(node);
|
||||||
|
|
||||||
|
this.render = function(ctx) {
|
||||||
|
// NOOP
|
||||||
|
}
|
||||||
}
|
}
|
||||||
svg.Element.defs.prototype = new svg.Element.ElementBase;
|
svg.Element.defs.prototype = new svg.Element.ElementBase;
|
||||||
|
|
||||||
@@ -1275,7 +1425,7 @@ if(!window.console) {
|
|||||||
|
|
||||||
// text element
|
// text element
|
||||||
svg.Element.text = function(node) {
|
svg.Element.text = function(node) {
|
||||||
this.base = svg.Element.ElementBase;
|
this.base = svg.Element.RenderedElementBase;
|
||||||
this.base(node);
|
this.base(node);
|
||||||
|
|
||||||
// accumulate all the child text nodes, then trim them
|
// accumulate all the child text nodes, then trim them
|
||||||
@@ -1287,13 +1437,23 @@ if(!window.console) {
|
|||||||
}
|
}
|
||||||
this.text = svg.trim(this.text);
|
this.text = svg.trim(this.text);
|
||||||
|
|
||||||
this.render = function(ctx) {
|
this.baseSetContext = this.setContext;
|
||||||
|
this.setContext = function(ctx) {
|
||||||
|
this.baseSetContext(ctx);
|
||||||
|
if (this.attribute('text-anchor').hasValue()) {
|
||||||
|
var textAnchor = this.attribute('text-anchor').value;
|
||||||
|
ctx.textAlign = textAnchor == 'middle' ? 'center' : textAnchor;
|
||||||
|
}
|
||||||
|
if (this.attribute('alignment-baseline').hasValue()) ctx.textBaseline = this.attribute('alignment-baseline').value;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.renderChildren = function(ctx) {
|
||||||
var x = this.attribute('x').Length.toPixels('x');
|
var x = this.attribute('x').Length.toPixels('x');
|
||||||
var y = this.attribute('y').Length.toPixels('y');
|
var y = this.attribute('y').Length.toPixels('y');
|
||||||
if (ctx.fillText) ctx.fillText(this.text, x, y);
|
if (ctx.fillText) ctx.fillText(this.text, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
svg.Element.text.prototype = new svg.Element.ElementBase;
|
svg.Element.text.prototype = new svg.Element.RenderedElementBase;
|
||||||
|
|
||||||
// group element
|
// group element
|
||||||
svg.Element.g = function(node) {
|
svg.Element.g = function(node) {
|
||||||
|
|||||||
@@ -522,13 +522,13 @@ function BatchCommand(text) {
|
|||||||
var selectedBox = this.selectorRect,
|
var selectedBox = this.selectorRect,
|
||||||
selectedGrips = this.selectorGrips,
|
selectedGrips = this.selectorGrips,
|
||||||
selected = this.selectedElement,
|
selected = this.selectedElement,
|
||||||
sw = round(selected.getAttribute("stroke-width"));
|
sw = selected.getAttribute("stroke-width");
|
||||||
var offset = 1/canvas.getZoom();
|
var offset = 1/current_zoom;
|
||||||
if (selected.getAttribute("stroke") != "none" && !isNaN(sw)) {
|
if (selected.getAttribute("stroke") != "none" && !isNaN(sw)) {
|
||||||
offset += sw/2;
|
offset += (sw/2);
|
||||||
}
|
}
|
||||||
if (selected.tagName == "text") {
|
if (selected.tagName == "text") {
|
||||||
offset += 2/canvas.getZoom();
|
offset += 2/current_zoom;
|
||||||
}
|
}
|
||||||
var bbox = canvas.getBBox(selected);
|
var bbox = canvas.getBBox(selected);
|
||||||
if(selected.tagName == 'g') {
|
if(selected.tagName == 'g') {
|
||||||
@@ -550,7 +550,7 @@ function BatchCommand(text) {
|
|||||||
m.f *= current_zoom;
|
m.f *= current_zoom;
|
||||||
|
|
||||||
// apply the transforms
|
// apply the transforms
|
||||||
var l=bbox.x-offset, t=bbox.y-offset, w=bbox.width+(offset<<1), h=bbox.height+(offset<<1),
|
var l=bbox.x-offset, t=bbox.y-offset, w=bbox.width+(offset*2), h=bbox.height+(offset*2),
|
||||||
bbox = {x:l, y:t, width:w, height:h};
|
bbox = {x:l, y:t, width:w, height:h};
|
||||||
|
|
||||||
// we need to handle temporary transforms too
|
// we need to handle temporary transforms too
|
||||||
@@ -3421,8 +3421,58 @@ function BatchCommand(text) {
|
|||||||
// Opera has a problem with suspendRedraw() apparently
|
// Opera has a problem with suspendRedraw() apparently
|
||||||
var handle = null;
|
var handle = null;
|
||||||
if (!window.opera) svgroot.suspendRedraw(1000);
|
if (!window.opera) svgroot.suspendRedraw(1000);
|
||||||
shape.setAttributeNS(null, "x2", x);
|
|
||||||
shape.setAttributeNS(null, "y2", y);
|
var x2 = x;
|
||||||
|
var y2 = y;
|
||||||
|
|
||||||
|
if(evt.shiftKey) {
|
||||||
|
var diff_x = x - start_x;
|
||||||
|
var diff_y = y - start_y;
|
||||||
|
|
||||||
|
var angle = ((Math.atan2(start_y-y,start_x-x) * (180/Math.PI))-90) % 360;
|
||||||
|
angle = angle<0?(360+angle):angle
|
||||||
|
|
||||||
|
// TODO: Write all this more efficiently
|
||||||
|
var dist = Math.sqrt(diff_x * diff_x + diff_y * diff_y);
|
||||||
|
var val = Math.sqrt((dist*dist)/2);
|
||||||
|
var diagonal = false;
|
||||||
|
|
||||||
|
if(angle >= 360-22.5 || angle < 22.5) {
|
||||||
|
x2 = start_x;
|
||||||
|
} else if(angle >= 22.5 && angle < 22.5 + 45) {
|
||||||
|
diagonal = true;
|
||||||
|
} else if(angle >= 22.5 + 45 && angle < 22.5 + 90) {
|
||||||
|
y2 = start_y;
|
||||||
|
} else if(angle >= 22.5 + 90 && angle < 22.5 + 135) {
|
||||||
|
diagonal = true;
|
||||||
|
} else if(angle >= 22.5 + 135 && angle < 22.5 + 180) {
|
||||||
|
x2 = start_x;
|
||||||
|
} else if(angle >= 22.5 + 180 && angle < 22.5 + 225) {
|
||||||
|
diagonal = true;
|
||||||
|
} else if(angle >= 22.5 + 225 && angle < 22.5 + 270) {
|
||||||
|
y2 = start_y;
|
||||||
|
} else if(angle >= 22.5 + 270 && angle < 22.5 + 315) {
|
||||||
|
diagonal = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(diagonal) {
|
||||||
|
if(y2 < start_y) {
|
||||||
|
y2 = start_y - val;
|
||||||
|
} else {
|
||||||
|
y2 = start_y + val;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(x2 < start_x) {
|
||||||
|
x2 = start_x - val;
|
||||||
|
} else {
|
||||||
|
x2 = start_x + val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
shape.setAttributeNS(null, "x2", x2);
|
||||||
|
shape.setAttributeNS(null, "y2", y2);
|
||||||
if (!window.opera) svgroot.unsuspendRedraw(handle);
|
if (!window.opera) svgroot.unsuspendRedraw(handle);
|
||||||
break;
|
break;
|
||||||
case "foreignObject":
|
case "foreignObject":
|
||||||
@@ -6203,15 +6253,18 @@ function BatchCommand(text) {
|
|||||||
// Selector and notice
|
// Selector and notice
|
||||||
var issue_list = {
|
var issue_list = {
|
||||||
'feGaussianBlur': 'Blurred elements will appear as un-blurred',
|
'feGaussianBlur': 'Blurred elements will appear as un-blurred',
|
||||||
'text': 'Text may not appear as expected',
|
|
||||||
'image': 'Image elements will not appear',
|
'image': 'Image elements will not appear',
|
||||||
'foreignObject': 'foreignObject elements will not appear',
|
'foreignObject': 'foreignObject elements will not appear',
|
||||||
'marker': 'Marker elements (arrows, etc) will not appear',
|
'marker': 'Marker elements (arrows, etc) may not appear as expected', // waiting for marker-mid and marker-end support
|
||||||
'[stroke-dasharray]': 'Strokes will appear filled',
|
'[stroke-dasharray]': 'Strokes will appear filled'
|
||||||
'[stroke^=url]': 'Strokes with gradients will not appear'
|
|
||||||
};
|
};
|
||||||
var content = $(svgcontent);
|
var content = $(svgcontent);
|
||||||
|
|
||||||
|
// Add font/text check if Canvas Text API is not implemented
|
||||||
|
if(!("font" in $('<canvas>')[0].getContext('2d'))) {
|
||||||
|
issue_list['text'] = 'Text may not appear as expected';
|
||||||
|
}
|
||||||
|
|
||||||
$.each(issue_list, function(sel, descr) {
|
$.each(issue_list, function(sel, descr) {
|
||||||
if(content.find(sel).length) {
|
if(content.find(sel).length) {
|
||||||
issues.push(descr);
|
issues.push(descr);
|
||||||
|
|||||||
Reference in New Issue
Block a user