fixed getRefElem and smoothControlPoints leaking variables
git-svn-id: http://svg-edit.googlecode.com/svn/trunk@2402 eee81c28-f429-11dd-99c0-75d572ba1dddmaster
parent
d5dca6b4a3
commit
7a36f90eb6
|
@ -356,7 +356,7 @@ svgedit.path.getSegSelector = function(seg, update) {
|
||||||
//
|
//
|
||||||
// Returns:
|
// Returns:
|
||||||
// Array of two "smoothed" point objects
|
// Array of two "smoothed" point objects
|
||||||
svgedit.path.smoothControlPoints = this.smoothControlPoints = function(ct1, ct2, pt) {
|
svgedit.path.smoothControlPoints = function(ct1, ct2, pt) {
|
||||||
// each point must not be the origin
|
// each point must not be the origin
|
||||||
var x1 = ct1.x - pt.x,
|
var x1 = ct1.x - pt.x,
|
||||||
y1 = ct1.y - pt.y,
|
y1 = ct1.y - pt.y,
|
||||||
|
|
|
@ -723,7 +723,7 @@
|
||||||
|
|
||||||
// Call when part of element is in process of changing, generally
|
// Call when part of element is in process of changing, generally
|
||||||
// on mousemove actions like rotate, move, etc.
|
// on mousemove actions like rotate, move, etc.
|
||||||
var elementTransition = function(window,elems) {
|
var elementTransition = function(window, elems) {
|
||||||
var mode = svgCanvas.getMode();
|
var mode = svgCanvas.getMode();
|
||||||
var elem = elems[0];
|
var elem = elems[0];
|
||||||
|
|
||||||
|
@ -970,7 +970,7 @@
|
||||||
flyout_funcs[opt]();
|
flyout_funcs[opt]();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// $('#tools_rect').mouseleave(function(){$('#tools_rect').fadeOut();});
|
// $('#tools_rect').mouseleave(function(){$('#tools_rect').fadeOut();});
|
||||||
});
|
});
|
||||||
setFlyoutTitles();
|
setFlyoutTitles();
|
||||||
};
|
};
|
||||||
|
@ -1728,7 +1728,7 @@
|
||||||
|
|
||||||
// Set up editor background functionality
|
// Set up editor background functionality
|
||||||
// TODO add checkerboard as "pattern"
|
// TODO add checkerboard as "pattern"
|
||||||
var color_blocks = ['#FFF','#888','#000']; // ,'url(data:image/gif;base64,R0lGODlhEAAQAIAAAP%2F%2F%2F9bW1iH5BAAAAAAALAAAAAAQABAAAAIfjG%2Bgq4jM3IFLJgpswNly%2FXkcBpIiVaInlLJr9FZWAQA7)'];
|
var color_blocks = ['#FFF', '#888', '#000']; // ,'url(data:image/gif;base64,R0lGODlhEAAQAIAAAP%2F%2F%2F9bW1iH5BAAAAAAALAAAAAAQABAAAAIfjG%2Bgq4jM3IFLJgpswNly%2FXkcBpIiVaInlLJr9FZWAQA7)'];
|
||||||
var str = '';
|
var str = '';
|
||||||
$.each(color_blocks, function() {
|
$.each(color_blocks, function() {
|
||||||
str += '<div class="color_block" style="background-color:' + this + ';"></div>';
|
str += '<div class="color_block" style="background-color:' + this + ';"></div>';
|
||||||
|
@ -1842,7 +1842,7 @@
|
||||||
var promptMoveLayerOnce = false;
|
var promptMoveLayerOnce = false;
|
||||||
$('#selLayerNames').change(function(){
|
$('#selLayerNames').change(function(){
|
||||||
var destLayer = this.options[this.selectedIndex].value;
|
var destLayer = this.options[this.selectedIndex].value;
|
||||||
var confirm_str = uiStrings.notification.QmoveElemsToLayer.replace('%s',destLayer);
|
var confirmStr = uiStrings.notification.QmoveElemsToLayer.replace('%s', destLayer);
|
||||||
var moveToLayer = function(ok) {
|
var moveToLayer = function(ok) {
|
||||||
if (!ok) return;
|
if (!ok) return;
|
||||||
promptMoveLayerOnce = true;
|
promptMoveLayerOnce = true;
|
||||||
|
@ -1854,7 +1854,7 @@
|
||||||
if (promptMoveLayerOnce) {
|
if (promptMoveLayerOnce) {
|
||||||
moveToLayer(true);
|
moveToLayer(true);
|
||||||
} else {
|
} else {
|
||||||
$.confirm(confirm_str, moveToLayer);
|
$.confirm(confirmStr, moveToLayer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -39,7 +39,7 @@ if (window.opera) {
|
||||||
|
|
||||||
// See http://api.jquery.com/attr/ for basic documentation of .attr()
|
// See http://api.jquery.com/attr/ for basic documentation of .attr()
|
||||||
|
|
||||||
// Additional functionality:
|
// Additional functionality:
|
||||||
// - When getting attributes, a string that's a number is return as type number.
|
// - When getting attributes, a string that's a number is return as type number.
|
||||||
// - If an array is supplied as first parameter, multiple values are returned
|
// - If an array is supplied as first parameter, multiple values are returned
|
||||||
// as an object with values for each given attributes
|
// as an object with values for each given attributes
|
||||||
|
@ -71,7 +71,6 @@ if (window.opera) {
|
||||||
obj[aname] = attr;
|
obj[aname] = attr;
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
|
|
||||||
} else if (typeof key === "object") {
|
} else if (typeof key === "object") {
|
||||||
// Setting attributes form object
|
// Setting attributes form object
|
||||||
for (var v in key) {
|
for (var v in key) {
|
||||||
|
@ -91,7 +90,6 @@ if (window.opera) {
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
|
||||||
// Class: SvgCanvas
|
// Class: SvgCanvas
|
||||||
|
@ -345,7 +343,6 @@ canvas.undoMgr = new svgedit.history.UndoManager({
|
||||||
var elems = cmd.elements();
|
var elems = cmd.elements();
|
||||||
canvas.pathActions.clear();
|
canvas.pathActions.clear();
|
||||||
call("changed", elems);
|
call("changed", elems);
|
||||||
|
|
||||||
var cmdType = cmd.type();
|
var cmdType = cmd.type();
|
||||||
var isApply = (eventType == EventTypes.AFTER_APPLY);
|
var isApply = (eventType == EventTypes.AFTER_APPLY);
|
||||||
if (cmdType == MoveElementCommand.type()) {
|
if (cmdType == MoveElementCommand.type()) {
|
||||||
|
@ -363,7 +360,6 @@ canvas.undoMgr = new svgedit.history.UndoManager({
|
||||||
} else {
|
} else {
|
||||||
if (!isApply) restoreRefElems(cmd.elem);
|
if (!isApply) restoreRefElems(cmd.elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd.elem.tagName === 'use') {
|
if (cmd.elem.tagName === 'use') {
|
||||||
setUseData(cmd.elem);
|
setUseData(cmd.elem);
|
||||||
}
|
}
|
||||||
|
@ -655,12 +651,12 @@ getStrokedBBox = this.getStrokedBBox = function(elems) {
|
||||||
if (!elems.length) return false;
|
if (!elems.length) return false;
|
||||||
// Make sure the expected BBox is returned if the element is a group
|
// Make sure the expected BBox is returned if the element is a group
|
||||||
var getCheckedBBox = function(elem) {
|
var getCheckedBBox = function(elem) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// TODO: Fix issue with rotated groups. Currently they work
|
// TODO: Fix issue with rotated groups. Currently they work
|
||||||
// fine in FF, but not in other browsers (same problem mentioned
|
// fine in FF, but not in other browsers (same problem mentioned
|
||||||
// in Issue 339 comment #2).
|
// in Issue 339 comment #2).
|
||||||
|
|
||||||
var bb = svgedit.utilities.getBBox(elem);
|
var bb = svgedit.utilities.getBBox(elem);
|
||||||
var angle = svgedit.utilities.getRotationAngle(elem);
|
var angle = svgedit.utilities.getRotationAngle(elem);
|
||||||
|
|
||||||
|
@ -668,9 +664,7 @@ getStrokedBBox = this.getStrokedBBox = function(elems) {
|
||||||
svgedit.math.hasMatrixTransform(svgedit.transformlist.getTransformList(elem))) {
|
svgedit.math.hasMatrixTransform(svgedit.transformlist.getTransformList(elem))) {
|
||||||
// Accurate way to get BBox of rotated element in Firefox:
|
// Accurate way to get BBox of rotated element in Firefox:
|
||||||
// Put element in group and get its BBox
|
// Put element in group and get its BBox
|
||||||
|
|
||||||
var good_bb = false;
|
var good_bb = false;
|
||||||
|
|
||||||
// Get the BBox from the raw path for these elements
|
// Get the BBox from the raw path for these elements
|
||||||
var elemNames = ['ellipse', 'path', 'line', 'polyline', 'polygon'];
|
var elemNames = ['ellipse', 'path', 'line', 'polyline', 'polygon'];
|
||||||
if (elemNames.indexOf(elem.tagName) >= 0) {
|
if (elemNames.indexOf(elem.tagName) >= 0) {
|
||||||
|
@ -683,10 +677,10 @@ getStrokedBBox = this.getStrokedBBox = function(elems) {
|
||||||
bb = good_bb = canvas.convertToPath(elem, true);
|
bb = good_bb = canvas.convertToPath(elem, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!good_bb) {
|
if (!good_bb) {
|
||||||
// Must use clone else FF freaks out
|
// Must use clone else FF freaks out
|
||||||
var clone = elem.cloneNode(true);
|
var clone = elem.cloneNode(true);
|
||||||
var g = document.createElementNS(svgns, "g");
|
var g = document.createElementNS(svgns, "g");
|
||||||
var parent = elem.parentNode;
|
var parent = elem.parentNode;
|
||||||
parent.appendChild(g);
|
parent.appendChild(g);
|
||||||
|
@ -694,7 +688,7 @@ getStrokedBBox = this.getStrokedBBox = function(elems) {
|
||||||
bb = svgedit.utilities.bboxToObj(g.getBBox());
|
bb = svgedit.utilities.bboxToObj(g.getBBox());
|
||||||
parent.removeChild(g);
|
parent.removeChild(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Old method: Works by giving the rotated BBox,
|
// Old method: Works by giving the rotated BBox,
|
||||||
// this is (unfortunately) what Opera and Safari do
|
// this is (unfortunately) what Opera and Safari do
|
||||||
// natively when getting the BBox of the parent group
|
// natively when getting the BBox of the parent group
|
||||||
|
@ -729,10 +723,10 @@ getStrokedBBox = this.getStrokedBBox = function(elems) {
|
||||||
// bb.height = rmaxy - rminy;
|
// bb.height = rmaxy - rminy;
|
||||||
}
|
}
|
||||||
return bb;
|
return bb;
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
console.log(elem, e);
|
console.log(elem, e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var full_bb;
|
var full_bb;
|
||||||
|
@ -741,18 +735,18 @@ getStrokedBBox = this.getStrokedBBox = function(elems) {
|
||||||
if (!this.parentNode) return;
|
if (!this.parentNode) return;
|
||||||
full_bb = getCheckedBBox(this);
|
full_bb = getCheckedBBox(this);
|
||||||
});
|
});
|
||||||
|
|
||||||
// This shouldn't ever happen...
|
// This shouldn't ever happen...
|
||||||
if (full_bb == null) return null;
|
if (full_bb == null) return null;
|
||||||
|
|
||||||
// full_bb doesn't include the stoke, so this does no good!
|
// full_bb doesn't include the stoke, so this does no good!
|
||||||
// if (elems.length == 1) return full_bb;
|
// if (elems.length == 1) return full_bb;
|
||||||
|
|
||||||
var max_x = full_bb.x + full_bb.width;
|
var max_x = full_bb.x + full_bb.width;
|
||||||
var max_y = full_bb.y + full_bb.height;
|
var max_y = full_bb.y + full_bb.height;
|
||||||
var min_x = full_bb.x;
|
var min_x = full_bb.x;
|
||||||
var min_y = full_bb.y;
|
var min_y = full_bb.y;
|
||||||
|
|
||||||
// FIXME: same re-creation problem with this function as getCheckedBBox() above
|
// FIXME: same re-creation problem with this function as getCheckedBBox() above
|
||||||
var getOffset = function(elem) {
|
var getOffset = function(elem) {
|
||||||
var sw = elem.getAttribute("stroke-width");
|
var sw = elem.getAttribute("stroke-width");
|
||||||
|
@ -913,7 +907,7 @@ var getId, getNextId, call;
|
||||||
|
|
||||||
getId = c.getId = function() { return getCurrentDrawing().getId(); };
|
getId = c.getId = function() { return getCurrentDrawing().getId(); };
|
||||||
getNextId = c.getNextId = function() { return getCurrentDrawing().getNextId(); };
|
getNextId = c.getNextId = function() { return getCurrentDrawing().getNextId(); };
|
||||||
|
|
||||||
// Function: call
|
// Function: call
|
||||||
// Run the callback function associated with the given event
|
// Run the callback function associated with the given event
|
||||||
//
|
//
|
||||||
|
@ -925,14 +919,14 @@ var getId, getNextId, call;
|
||||||
return events[event](this, arg);
|
return events[event](this, arg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function: bind
|
// Function: bind
|
||||||
// Attaches a callback function to an event
|
// Attaches a callback function to an event
|
||||||
//
|
//
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// event - String indicating the name of the event
|
// event - String indicating the name of the event
|
||||||
// f - The callback function to bind to the event
|
// f - The callback function to bind to the event
|
||||||
//
|
//
|
||||||
// Return:
|
// Return:
|
||||||
// The previous event
|
// The previous event
|
||||||
c.bind = function(event, f) {
|
c.bind = function(event, f) {
|
||||||
|
@ -940,7 +934,7 @@ var getId, getNextId, call;
|
||||||
events[event] = f;
|
events[event] = f;
|
||||||
return old;
|
return old;
|
||||||
};
|
};
|
||||||
|
|
||||||
}(canvas));
|
}(canvas));
|
||||||
|
|
||||||
// Function: canvas.prepareSvg
|
// Function: canvas.prepareSvg
|
||||||
|
@ -1093,7 +1087,7 @@ var remapElement = this.remapElement = function(selected, changes, m) {
|
||||||
assignAttributes(selected, changes, 1000, true);
|
assignAttributes(selected, changes, 1000, true);
|
||||||
}
|
}
|
||||||
box = svgedit.utilities.getBBox(selected);
|
box = svgedit.utilities.getBBox(selected);
|
||||||
|
|
||||||
for (var i = 0; i < 2; i++) {
|
for (var i = 0; i < 2; i++) {
|
||||||
var type = i === 0 ? 'fill' : 'stroke';
|
var type = i === 0 ? 'fill' : 'stroke';
|
||||||
var attrVal = selected.getAttribute(type);
|
var attrVal = selected.getAttribute(type);
|
||||||
|
@ -1101,15 +1095,15 @@ var remapElement = this.remapElement = function(selected, changes, m) {
|
||||||
if (m.a < 0 || m.d < 0) {
|
if (m.a < 0 || m.d < 0) {
|
||||||
var grad = svgedit.utilities.getRefElem(attrVal);
|
var grad = svgedit.utilities.getRefElem(attrVal);
|
||||||
var newgrad = grad.cloneNode(true);
|
var newgrad = grad.cloneNode(true);
|
||||||
|
|
||||||
if (m.a < 0) {
|
if (m.a < 0) {
|
||||||
//flip x
|
//flip x
|
||||||
var x1 = newgrad.getAttribute('x1');
|
var x1 = newgrad.getAttribute('x1');
|
||||||
var x2 = newgrad.getAttribute('x2');
|
var x2 = newgrad.getAttribute('x2');
|
||||||
newgrad.setAttribute('x1', -(x1 - 1));
|
newgrad.setAttribute('x1', -(x1 - 1));
|
||||||
newgrad.setAttribute('x2', -(x2 - 1));
|
newgrad.setAttribute('x2', -(x2 - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m.d < 0) {
|
if (m.d < 0) {
|
||||||
//flip y
|
//flip y
|
||||||
var y1 = newgrad.getAttribute('y1');
|
var y1 = newgrad.getAttribute('y1');
|
||||||
|
@ -1369,14 +1363,12 @@ var remapElement = this.remapElement = function(selected, changes, m) {
|
||||||
// ty - The translation's y value
|
// ty - The translation's y value
|
||||||
var updateClipPath = function(attr, tx, ty) {
|
var updateClipPath = function(attr, tx, ty) {
|
||||||
var path = getRefElem(attr).firstChild;
|
var path = getRefElem(attr).firstChild;
|
||||||
|
|
||||||
var cp_xform = svgedit.transformlist.getTransformList(path);
|
var cp_xform = svgedit.transformlist.getTransformList(path);
|
||||||
|
|
||||||
var newxlate = svgroot.createSVGTransform();
|
var newxlate = svgroot.createSVGTransform();
|
||||||
newxlate.setTranslate(tx, ty);
|
newxlate.setTranslate(tx, ty);
|
||||||
|
|
||||||
cp_xform.appendItem(newxlate);
|
cp_xform.appendItem(newxlate);
|
||||||
|
|
||||||
// Update clipPath's dimensions
|
// Update clipPath's dimensions
|
||||||
recalculateDimensions(path);
|
recalculateDimensions(path);
|
||||||
};
|
};
|
||||||
|
|
|
@ -58,15 +58,15 @@ svgedit.utilities.init = function(editorContext) {
|
||||||
svgedit.utilities.toXml = function(str) {
|
svgedit.utilities.toXml = function(str) {
|
||||||
return $('<p/>').text(str).html();
|
return $('<p/>').text(str).html();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function: svgedit.utilities.fromXml
|
// Function: svgedit.utilities.fromXml
|
||||||
// Converts XML entities in a string to single characters.
|
// Converts XML entities in a string to single characters.
|
||||||
// Example: '&' becomes '&'
|
// Example: '&' becomes '&'
|
||||||
//
|
//
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// str - The string to be converted
|
// str - The string to be converted
|
||||||
//
|
//
|
||||||
// Returns:
|
// Returns:
|
||||||
// The converted string
|
// The converted string
|
||||||
svgedit.utilities.fromXml = function(str) {
|
svgedit.utilities.fromXml = function(str) {
|
||||||
return $('<p/>').html(str).text();
|
return $('<p/>').html(str).text();
|
||||||
|
@ -168,7 +168,7 @@ svgedit.utilities.decode64 = function(input) {
|
||||||
// else if (c > 127) {
|
// else if (c > 127) {
|
||||||
// if (c < 2048){
|
// if (c < 2048){
|
||||||
// output += String.fromCharCode((c >> 6) | 192);
|
// output += String.fromCharCode((c >> 6) | 192);
|
||||||
// }
|
// }
|
||||||
// else {
|
// else {
|
||||||
// output += String.fromCharCode((c >> 12) | 224) + String.fromCharCode((c >> 6) & 63 | 128);
|
// output += String.fromCharCode((c >> 12) | 224) + String.fromCharCode((c >> 6) & 63 | 128);
|
||||||
// }
|
// }
|
||||||
|
@ -178,7 +178,7 @@ svgedit.utilities.decode64 = function(input) {
|
||||||
// return output;
|
// return output;
|
||||||
// },
|
// },
|
||||||
|
|
||||||
// Function: svgedit.utilities.convertToXMLReferences
|
// Function: svgedit.utilities.convertToXMLReferences
|
||||||
// Converts a string to use XML references
|
// Converts a string to use XML references
|
||||||
svgedit.utilities.convertToXMLReferences = function(input) {
|
svgedit.utilities.convertToXMLReferences = function(input) {
|
||||||
var output = '';
|
var output = '';
|
||||||
|
@ -205,8 +205,8 @@ svgedit.utilities.text2xml = function(sXML) {
|
||||||
try{
|
try{
|
||||||
var dXML = (window.DOMParser)?new DOMParser():new ActiveXObject('Microsoft.XMLDOM');
|
var dXML = (window.DOMParser)?new DOMParser():new ActiveXObject('Microsoft.XMLDOM');
|
||||||
dXML.async = false;
|
dXML.async = false;
|
||||||
} catch(e){
|
} catch(e){
|
||||||
throw new Error('XML Parser could not be instantiated');
|
throw new Error('XML Parser could not be instantiated');
|
||||||
};
|
};
|
||||||
try{
|
try{
|
||||||
if(dXML.loadXML) out = (dXML.loadXML(sXML))?dXML:false;
|
if(dXML.loadXML) out = (dXML.loadXML(sXML))?dXML:false;
|
||||||
|
@ -267,7 +267,7 @@ svgedit.utilities.walkTreePost = function(elem, cbFn) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function: svgedit.utilities.getUrlFromAttr
|
// Function: svgedit.utilities.getUrlFromAttr
|
||||||
// Extracts the URL from the url(...) syntax of some attributes.
|
// Extracts the URL from the url(...) syntax of some attributes.
|
||||||
// Three variants:
|
// Three variants:
|
||||||
// * <circle fill="url(someFile.svg#foo)" />
|
// * <circle fill="url(someFile.svg#foo)" />
|
||||||
// * <circle fill="url('someFile.svg#foo')" />
|
// * <circle fill="url('someFile.svg#foo')" />
|
||||||
|
@ -275,11 +275,11 @@ svgedit.utilities.walkTreePost = function(elem, cbFn) {
|
||||||
//
|
//
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// attrVal - The attribute value as a string
|
// attrVal - The attribute value as a string
|
||||||
//
|
//
|
||||||
// Returns:
|
// Returns:
|
||||||
// String with just the URL, like someFile.svg#foo
|
// String with just the URL, like someFile.svg#foo
|
||||||
svgedit.utilities.getUrlFromAttr = function(attrVal) {
|
svgedit.utilities.getUrlFromAttr = function(attrVal) {
|
||||||
if (attrVal) {
|
if (attrVal) {
|
||||||
// url("#somegrad")
|
// url("#somegrad")
|
||||||
if (attrVal.indexOf('url("') === 0) {
|
if (attrVal.indexOf('url("') === 0) {
|
||||||
return attrVal.substring(5, attrVal.indexOf('"',6));
|
return attrVal.substring(5, attrVal.indexOf('"',6));
|
||||||
|
@ -316,8 +316,7 @@ svgedit.utilities.findDefs = function() {
|
||||||
var defs = svgElement.getElementsByTagNameNS(SVGNS, 'defs');
|
var defs = svgElement.getElementsByTagNameNS(SVGNS, 'defs');
|
||||||
if (defs.length > 0) {
|
if (defs.length > 0) {
|
||||||
defs = defs[0];
|
defs = defs[0];
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
defs = svgElement.ownerDocument.createElementNS(SVGNS, 'defs');
|
defs = svgElement.ownerDocument.createElementNS(SVGNS, 'defs');
|
||||||
if (svgElement.firstChild) {
|
if (svgElement.firstChild) {
|
||||||
// first child is a comment, so call nextSibling
|
// first child is a comment, so call nextSibling
|
||||||
|
@ -335,7 +334,7 @@ svgedit.utilities.findDefs = function() {
|
||||||
// Get correct BBox for a path in Webkit
|
// Get correct BBox for a path in Webkit
|
||||||
// Converted from code found here:
|
// Converted from code found here:
|
||||||
// http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html
|
// http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html
|
||||||
//
|
//
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// path - The path DOM element to get the BBox for
|
// path - The path DOM element to get the BBox for
|
||||||
//
|
//
|
||||||
|
@ -344,7 +343,7 @@ svgedit.utilities.findDefs = function() {
|
||||||
svgedit.utilities.getPathBBox = function(path) {
|
svgedit.utilities.getPathBBox = function(path) {
|
||||||
var seglist = path.pathSegList;
|
var seglist = path.pathSegList;
|
||||||
var tot = seglist.numberOfItems;
|
var tot = seglist.numberOfItems;
|
||||||
|
|
||||||
var bounds = [[], []];
|
var bounds = [[], []];
|
||||||
var start = seglist.getItem(0);
|
var start = seglist.getItem(0);
|
||||||
var P0 = [start.x, start.y];
|
var P0 = [start.x, start.y];
|
||||||
|
@ -357,7 +356,7 @@ svgedit.utilities.getPathBBox = function(path) {
|
||||||
// Add actual points to limits
|
// Add actual points to limits
|
||||||
bounds[0].push(P0[0]);
|
bounds[0].push(P0[0]);
|
||||||
bounds[1].push(P0[1]);
|
bounds[1].push(P0[1]);
|
||||||
|
|
||||||
if(seg.x1) {
|
if(seg.x1) {
|
||||||
var P1 = [seg.x1, seg.y1],
|
var P1 = [seg.x1, seg.y1],
|
||||||
P2 = [seg.x2, seg.y2],
|
P2 = [seg.x2, seg.y2],
|
||||||
|
@ -366,7 +365,7 @@ svgedit.utilities.getPathBBox = function(path) {
|
||||||
for(var j=0; j < 2; j++) {
|
for(var j=0; j < 2; j++) {
|
||||||
|
|
||||||
var calc = function(t) {
|
var calc = function(t) {
|
||||||
return Math.pow(1-t,3) * P0[j]
|
return Math.pow(1-t,3) * P0[j]
|
||||||
+ 3 * Math.pow(1-t,2) * t * P1[j]
|
+ 3 * Math.pow(1-t,2) * t * P1[j]
|
||||||
+ 3 * (1-t) * Math.pow(t, 2) * P2[j]
|
+ 3 * (1-t) * Math.pow(t, 2) * P2[j]
|
||||||
+ Math.pow(t,3) * P3[j];
|
+ Math.pow(t,3) * P3[j];
|
||||||
|
@ -375,7 +374,7 @@ svgedit.utilities.getPathBBox = function(path) {
|
||||||
var b = 6 * P0[j] - 12 * P1[j] + 6 * P2[j];
|
var b = 6 * P0[j] - 12 * P1[j] + 6 * P2[j];
|
||||||
var a = -3 * P0[j] + 9 * P1[j] - 9 * P2[j] + 3 * P3[j];
|
var a = -3 * P0[j] + 9 * P1[j] - 9 * P2[j] + 3 * P3[j];
|
||||||
var c = 3 * P1[j] - 3 * P0[j];
|
var c = 3 * P1[j] - 3 * P0[j];
|
||||||
|
|
||||||
if(a == 0) {
|
if(a == 0) {
|
||||||
if(b == 0) {
|
if(b == 0) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -386,7 +385,6 @@ svgedit.utilities.getPathBBox = function(path) {
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var b2ac = Math.pow(b,2) - 4 * c * a;
|
var b2ac = Math.pow(b,2) - 4 * c * a;
|
||||||
if(b2ac < 0) continue;
|
if(b2ac < 0) continue;
|
||||||
var t1 = (-b + Math.sqrt(b2ac))/(2 * a);
|
var t1 = (-b + Math.sqrt(b2ac))/(2 * a);
|
||||||
|
@ -400,7 +398,7 @@ svgedit.utilities.getPathBBox = function(path) {
|
||||||
bounds[1].push(seg.y);
|
bounds[1].push(seg.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var x = Math.min.apply(null, bounds[0]);
|
var x = Math.min.apply(null, bounds[0]);
|
||||||
var w = Math.max.apply(null, bounds[0]) - x;
|
var w = Math.max.apply(null, bounds[0]) - x;
|
||||||
var y = Math.min.apply(null, bounds[1]);
|
var y = Math.min.apply(null, bounds[1]);
|
||||||
|
@ -419,15 +417,15 @@ svgedit.utilities.getPathBBox = function(path) {
|
||||||
// Note that performance is currently terrible, so some way to improve would
|
// Note that performance is currently terrible, so some way to improve would
|
||||||
// be great.
|
// be great.
|
||||||
//
|
//
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// selected - Container or <use> DOM element
|
// selected - Container or <use> DOM element
|
||||||
function groupBBFix(selected) {
|
function groupBBFix(selected) {
|
||||||
if(svgedit.browser.supportsHVLineContainerBBox()) {
|
if(svgedit.browser.supportsHVLineContainerBBox()) {
|
||||||
try { return selected.getBBox();} catch(e){}
|
try { return selected.getBBox();} catch(e){}
|
||||||
}
|
}
|
||||||
var ref = $.data(selected, 'ref');
|
var ref = $.data(selected, 'ref');
|
||||||
var matched = null;
|
var matched = null;
|
||||||
|
|
||||||
if(ref) {
|
if(ref) {
|
||||||
var copy = $(ref).children().clone().attr('visibility', 'hidden');
|
var copy = $(ref).children().clone().attr('visibility', 'hidden');
|
||||||
$(svgroot_).append(copy);
|
$(svgroot_).append(copy);
|
||||||
|
@ -435,7 +433,7 @@ function groupBBFix(selected) {
|
||||||
} else {
|
} else {
|
||||||
matched = $(selected).find('line, path');
|
matched = $(selected).find('line, path');
|
||||||
}
|
}
|
||||||
|
|
||||||
var issue = false;
|
var issue = false;
|
||||||
if(matched.length) {
|
if(matched.length) {
|
||||||
matched.each(function() {
|
matched.each(function() {
|
||||||
|
@ -470,7 +468,7 @@ svgedit.utilities.getBBox = function(elem) {
|
||||||
if (elem.nodeType != 1) return null;
|
if (elem.nodeType != 1) return null;
|
||||||
var ret = null;
|
var ret = null;
|
||||||
var elname = selected.nodeName;
|
var elname = selected.nodeName;
|
||||||
|
|
||||||
switch ( elname ) {
|
switch ( elname ) {
|
||||||
case 'text':
|
case 'text':
|
||||||
if(selected.textContent === '') {
|
if(selected.textContent === '') {
|
||||||
|
@ -497,7 +495,6 @@ svgedit.utilities.getBBox = function(elem) {
|
||||||
if(elname === 'use') {
|
if(elname === 'use') {
|
||||||
ret = groupBBFix(selected, true);
|
ret = groupBBFix(selected, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(elname === 'use' || ( elname === 'foreignObject' && svgedit.browser.isWebkit() ) ) {
|
if(elname === 'use' || ( elname === 'foreignObject' && svgedit.browser.isWebkit() ) ) {
|
||||||
if(!ret) ret = selected.getBBox();
|
if(!ret) ret = selected.getBBox();
|
||||||
// This is resolved in later versions of webkit, perhaps we should
|
// This is resolved in later versions of webkit, perhaps we should
|
||||||
|
@ -512,8 +509,8 @@ svgedit.utilities.getBBox = function(elem) {
|
||||||
ret = bb;
|
ret = bb;
|
||||||
//}
|
//}
|
||||||
} else if(~visElems_arr.indexOf(elname)) {
|
} else if(~visElems_arr.indexOf(elname)) {
|
||||||
try { ret = selected.getBBox();}
|
try { ret = selected.getBBox();}
|
||||||
catch(e) {
|
catch(e) {
|
||||||
// Check if element is child of a foreignObject
|
// Check if element is child of a foreignObject
|
||||||
var fo = $(selected).closest('foreignObject');
|
var fo = $(selected).closest('foreignObject');
|
||||||
if(fo.length) {
|
if(fo.length) {
|
||||||
|
@ -528,7 +525,6 @@ svgedit.utilities.getBBox = function(elem) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ret) {
|
if(ret) {
|
||||||
ret = svgedit.utilities.bboxToObj(ret);
|
ret = svgedit.utilities.bboxToObj(ret);
|
||||||
}
|
}
|
||||||
|
@ -566,7 +562,7 @@ svgedit.utilities.getRotationAngle = function(elem, to_rad) {
|
||||||
//
|
//
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// attrVal - The attribute value as a string
|
// attrVal - The attribute value as a string
|
||||||
svgedit.utilities.getRefElem = this.getRefElem = function(attrVal) {
|
svgedit.utilities.getRefElem = function(attrVal) {
|
||||||
return svgedit.utilities.getElem(svgedit.utilities.getUrlFromAttr(attrVal).substr(1));
|
return svgedit.utilities.getElem(svgedit.utilities.getUrlFromAttr(attrVal).substr(1));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -585,7 +581,7 @@ if (svgedit.browser.supportsSelectors()) {
|
||||||
// xpath lookup
|
// xpath lookup
|
||||||
return domdoc_.evaluate(
|
return domdoc_.evaluate(
|
||||||
'svg:svg[@id="svgroot"]//svg:*[@id="'+id+'"]',
|
'svg:svg[@id="svgroot"]//svg:*[@id="'+id+'"]',
|
||||||
domcontainer_,
|
domcontainer_,
|
||||||
function() { return 'http://www.w3.org/2000/svg'; },
|
function() { return 'http://www.w3.org/2000/svg'; },
|
||||||
9,
|
9,
|
||||||
null).singleNodeValue;
|
null).singleNodeValue;
|
||||||
|
@ -612,9 +608,9 @@ svgedit.utilities.assignAttributes = function(node, attrs, suspendLength, unitCh
|
||||||
if (!svgedit.browser.isOpera()) svgroot_.suspendRedraw(suspendLength);
|
if (!svgedit.browser.isOpera()) svgroot_.suspendRedraw(suspendLength);
|
||||||
|
|
||||||
for (var i in attrs) {
|
for (var i in attrs) {
|
||||||
var ns = (i.substr(0,4) === 'xml:' ? XMLNS :
|
var ns = (i.substr(0,4) === 'xml:' ? XMLNS :
|
||||||
i.substr(0,6) === 'xlink:' ? XLINKNS : null);
|
i.substr(0,6) === 'xlink:' ? XLINKNS : null);
|
||||||
|
|
||||||
if(ns) {
|
if(ns) {
|
||||||
node.setAttributeNS(ns, i, attrs[i]);
|
node.setAttributeNS(ns, i, attrs[i]);
|
||||||
} else if(!unitCheck) {
|
} else if(!unitCheck) {
|
||||||
|
@ -622,9 +618,7 @@ svgedit.utilities.assignAttributes = function(node, attrs, suspendLength, unitCh
|
||||||
} else {
|
} else {
|
||||||
svgedit.units.setUnitAttr(node, i, attrs[i]);
|
svgedit.units.setUnitAttr(node, i, attrs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!svgedit.browser.isOpera()) svgroot_.unsuspendRedraw(handle);
|
if (!svgedit.browser.isOpera()) svgroot_.unsuspendRedraw(handle);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -648,16 +642,15 @@ svgedit.utilities.cleanupElement = function(element) {
|
||||||
'rx':0,
|
'rx':0,
|
||||||
'ry':0
|
'ry':0
|
||||||
}
|
}
|
||||||
|
|
||||||
for(var attr in defaults) {
|
for(var attr in defaults) {
|
||||||
var val = defaults[attr];
|
var val = defaults[attr];
|
||||||
if(element.getAttribute(attr) == val) {
|
if(element.getAttribute(attr) == val) {
|
||||||
element.removeAttribute(attr);
|
element.removeAttribute(attr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
svgroot_.unsuspendRedraw(handle);
|
svgroot_.unsuspendRedraw(handle);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -225,17 +225,16 @@ svgedit.units.convertToNum = function(attr, val) {
|
||||||
|
|
||||||
if (wAttrs.indexOf(attr) >= 0) {
|
if (wAttrs.indexOf(attr) >= 0) {
|
||||||
return num * width;
|
return num * width;
|
||||||
} else if (hAttrs.indexOf(attr) >= 0) {
|
|
||||||
return num * height;
|
|
||||||
} else {
|
|
||||||
return num * Math.sqrt((width*width) + (height*height))/Math.sqrt(2);
|
|
||||||
}
|
}
|
||||||
} else {
|
if (hAttrs.indexOf(attr) >= 0) {
|
||||||
var unit = val.substr(-2);
|
return num * height;
|
||||||
var num = val.substr(0, val.length-2);
|
}
|
||||||
// Note that this multiplication turns the string into a number
|
return num * Math.sqrt((width*width) + (height*height))/Math.sqrt(2);
|
||||||
return num * typeMap_[unit];
|
|
||||||
}
|
}
|
||||||
|
var unit = val.substr(-2);
|
||||||
|
var num = val.substr(0, val.length-2);
|
||||||
|
// Note that this multiplication turns the string into a number
|
||||||
|
return num * typeMap_[unit];
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function: svgedit.units.isValidUnit
|
// Function: svgedit.units.isValidUnit
|
||||||
|
|
Loading…
Reference in New Issue