From 89d5451cefc85635a804da3cc9742f76c5b40b33 Mon Sep 17 00:00:00 2001 From: Jeff Schiller Date: Tue, 26 Oct 2010 02:48:36 +0000 Subject: [PATCH] Move Utils mostly over to a separate JS file git-svn-id: http://svg-edit.googlecode.com/svn/trunk@1817 eee81c28-f429-11dd-99c0-75d572ba1ddd --- editor/svg-editor.html | 1 + editor/svgcanvas.js | 255 +++-------------------------------------- editor/svgutils.js | 251 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 265 insertions(+), 242 deletions(-) create mode 100644 editor/svgutils.js diff --git a/editor/svg-editor.html b/editor/svg-editor.html index c9b2a448..1718515f 100644 --- a/editor/svg-editor.html +++ b/editor/svg-editor.html @@ -18,6 +18,7 @@ + diff --git a/editor/svgcanvas.js b/editor/svgcanvas.js index a5d1b1d6..27b351a2 100644 --- a/editor/svgcanvas.js +++ b/editor/svgcanvas.js @@ -199,250 +199,21 @@ if(config) { } // Static class for various utility functions -var Utils = this.Utils = function() { +// See svgutils.js. +var Utils = this.Utils = SVGEditUtilities; - var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; - - return { - - // Function: Utils.toXml - // Converts characters in a string to XML-friendly entities. - // - // Example: "&" becomes "&" - // - // Parameters: - // str - The string to be converted - // - // Returns: - // The converted string - "toXml": function(str) { - return $('

').text(str).html(); - }, - - // Function: Utils.fromXml - // Converts XML entities in a string to single characters. - // Example: "&" becomes "&" - // - // Parameters: - // str - The string to be converted - // - // Returns: - // The converted string - "fromXml": function(str) { - return $('

').html(str).text(); - }, - - // This code was written by Tyler Akins and has been placed in the - // public domain. It would be nice if you left this header intact. - // Base64 code from Tyler Akins -- http://rumkin.com - - // schiller: Removed string concatenation in favour of Array.join() optimization, - // also precalculate the size of the array needed. - - // Function: Utils.encode64 - // Converts a string to base64 - "encode64" : function(input) { - // base64 strings are 4/3 larger than the original string - // input = Utils.encodeUTF8(input); // convert non-ASCII characters - input = Utils.convertToXMLReferences(input); - if(window.btoa) return window.btoa(input); // Use native if available - var output = new Array( Math.floor( (input.length + 2) / 3 ) * 4 ); - var chr1, chr2, chr3; - var enc1, enc2, enc3, enc4; - var i = 0, p = 0; - - do { - chr1 = input.charCodeAt(i++); - chr2 = input.charCodeAt(i++); - chr3 = input.charCodeAt(i++); - - enc1 = chr1 >> 2; - enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); - enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); - enc4 = chr3 & 63; - - if (isNaN(chr2)) { - enc3 = enc4 = 64; - } else if (isNaN(chr3)) { - enc4 = 64; - } - - output[p++] = _keyStr.charAt(enc1); - output[p++] = _keyStr.charAt(enc2); - output[p++] = _keyStr.charAt(enc3); - output[p++] = _keyStr.charAt(enc4); - } while (i < input.length); - - return output.join(''); - }, - - // Function: Utils.decode64 - // Converts a string from base64 - "decode64" : function(input) { - if(window.atob) return window.atob(input); - var output = ""; - var chr1, chr2, chr3 = ""; - var enc1, enc2, enc3, enc4 = ""; - var i = 0; - - // remove all characters that are not A-Z, a-z, 0-9, +, /, or = - input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); - - do { - enc1 = _keyStr.indexOf(input.charAt(i++)); - enc2 = _keyStr.indexOf(input.charAt(i++)); - enc3 = _keyStr.indexOf(input.charAt(i++)); - enc4 = _keyStr.indexOf(input.charAt(i++)); - - chr1 = (enc1 << 2) | (enc2 >> 4); - chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); - chr3 = ((enc3 & 3) << 6) | enc4; - - output = output + String.fromCharCode(chr1); - - if (enc3 != 64) { - output = output + String.fromCharCode(chr2); - } - if (enc4 != 64) { - output = output + String.fromCharCode(chr3); - } - - chr1 = chr2 = chr3 = ""; - enc1 = enc2 = enc3 = enc4 = ""; - - } while (i < input.length); - return unescape(output); - }, - - // Currently not being used, so commented out for now - // based on http://phpjs.org/functions/utf8_encode:577 - // codedread:does not seem to work with webkit-based browsers on OSX -// "encodeUTF8": function(input) { -// //return unescape(encodeURIComponent(input)); //may or may not work -// var output = ''; -// for (var n = 0; n < input.length; n++){ -// var c = input.charCodeAt(n); -// if (c < 128) { -// output += input[n]; -// } -// else if (c > 127) { -// if (c < 2048){ -// output += String.fromCharCode((c >> 6) | 192); -// } -// else { -// output += String.fromCharCode((c >> 12) | 224) + String.fromCharCode((c >> 6) & 63 | 128); -// } -// output += String.fromCharCode((c & 63) | 128); -// } -// } -// return output; -// }, - - // Function: Utils.convertToXMLReferences - // Converts a string to use XML references - "convertToXMLReferences": function(input) { - var output = ''; - for (var n = 0; n < input.length; n++){ - var c = input.charCodeAt(n); - if (c < 128) { - output += input[n]; - } - else if(c > 127) { - output += ("&#" + c + ";"); - } - } - return output; - }, - - // Function: rectsIntersect - // Check if two rectangles (BBoxes objects) intersect each other - // - // Paramaters: - // r1 - The first BBox-like object - // r2 - The second BBox-like object - // - // Returns: - // Boolean that's true if rectangles intersect - "rectsIntersect": function(r1, r2) { - return r2.x < (r1.x+r1.width) && - (r2.x+r2.width) > r1.x && - r2.y < (r1.y+r1.height) && - (r2.y+r2.height) > r1.y; - }, - - // Function: snapToAngle - // Returns a 45 degree angle coordinate associated with the two given - // coordinates - // - // Parameters: - // x1 - First coordinate's x value - // x2 - Second coordinate's x value - // y1 - First coordinate's y value - // y2 - Second coordinate's y value - // - // Returns: - // Object with the following values: - // x - The angle-snapped x value - // y - The angle-snapped y value - // snapangle - The angle at which to snap - "snapToAngle": function(x1,y1,x2,y2) { - var snap = Math.PI/4; // 45 degrees - var dx = x2 - x1; - var dy = y2 - y1; - var angle = Math.atan2(dy,dx); - var dist = Math.sqrt(dx * dx + dy * dy); - var snapangle= Math.round(angle/snap)*snap; - var x = x1 + dist*Math.cos(snapangle); - var y = y1 + dist*Math.sin(snapangle); - //console.log(x1,y1,x2,y2,x,y,angle) - return {x:x, y:y, a:snapangle}; - }, - - // Function: snapToGrid - // round value to for snapping - "snapToGrid" : function(value){ - var stepSize = curConfig.snappingStep; - var unit = curConfig.baseUnit; - if(unit !== "px") { - stepSize *= unit_types[unit]; - } - value = Math.round(value/stepSize)*stepSize; - return value; - }, - - // Function: text2xml - // Cross-browser compatible method of converting a string to an XML tree - // found this function here: http://groups.google.com/group/jquery-dev/browse_thread/thread/c6d11387c580a77f - "text2xml": function(sXML) { - if(sXML.indexOf('= 0) { - sXML = sXML.replace(/<(\/?)svg:/g, '<$1').replace('xmlns:svg', 'xmlns'); - } - - var out; - try{ - var dXML = (window.DOMParser)?new DOMParser():new ActiveXObject("Microsoft.XMLDOM"); - dXML.async = false; - } catch(e){ - throw new Error("XML Parser could not be instantiated"); - }; - try{ - if(dXML.loadXML) out = (dXML.loadXML(sXML))?dXML:false; - else out = dXML.parseFromString(sXML, "text/xml"); - } - catch(e){ throw new Error("Error parsing XML string"); }; - return out; - }, - - bboxToObj: function(bbox) { - return { - x: bbox.x, - y: bbox.y, - width: bbox.width, - height: bbox.height - } - } +// Function: snapToGrid +// round value to for snapping +// NOTE: This function did not move to svgutils.js since it depends on unit_types. +Utils.snapToGrid = function(value){ + var stepSize = curConfig.snappingStep; + var unit = curConfig.baseUnit; + if(unit !== "px") { + stepSize *= unit_types[unit]; } -}(); + value = Math.round(value/stepSize)*stepSize; + return value; +}; var snapToGrid = Utils.snapToGrid; var elData = $.data; diff --git a/editor/svgutils.js b/editor/svgutils.js new file mode 100644 index 00000000..5d892332 --- /dev/null +++ b/editor/svgutils.js @@ -0,0 +1,251 @@ +/** + * SVG-edit Utilities + * + * Licensed under the Apache License, Version 2 + * + * Copyright(c) 2010 Alexis Deveria + * Copyright(c) 2010 Jeff Schiller + */ + +// NOTE: Requires jQuery to be loaded. + +SVGEditUtilities = { +}; + +// String used to encode base64. +SVGEditUtilities._keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + +// Function: SVGEditUtilities.toXml +// Converts characters in a string to XML-friendly entities. +// +// Example: "&" becomes "&" +// +// Parameters: +// str - The string to be converted +// +// Returns: +// The converted string +SVGEditUtilities.toXml = function(str) { + return $('

').text(str).html(); +}; + +// Function: SVGEditUtilities.fromXml +// Converts XML entities in a string to single characters. +// Example: "&" becomes "&" +// +// Parameters: +// str - The string to be converted +// +// Returns: +// The converted string +SVGEditUtilities.fromXml = function(str) { + return $('

').html(str).text(); +}; + + +// This code was written by Tyler Akins and has been placed in the +// public domain. It would be nice if you left this header intact. +// Base64 code from Tyler Akins -- http://rumkin.com + +// schiller: Removed string concatenation in favour of Array.join() optimization, +// also precalculate the size of the array needed. + +// Function: Utils.encode64 +// Converts a string to base64 +SVGEditUtilities.encode64 = function(input) { + // base64 strings are 4/3 larger than the original string +// input = Utils.encodeUTF8(input); // convert non-ASCII characters + input = Utils.convertToXMLReferences(input); + if(window.btoa) return window.btoa(input); // Use native if available + var _keyStr = SVGEditUtilities._keyStr; + var output = new Array( Math.floor( (input.length + 2) / 3 ) * 4 ); + var chr1, chr2, chr3; + var enc1, enc2, enc3, enc4; + var i = 0, p = 0; + + do { + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } else if (isNaN(chr3)) { + enc4 = 64; + } + + output[p++] = _keyStr.charAt(enc1); + output[p++] = _keyStr.charAt(enc2); + output[p++] = _keyStr.charAt(enc3); + output[p++] = _keyStr.charAt(enc4); + } while (i < input.length); + + return output.join(''); +}; + +// Function: Utils.decode64 +// Converts a string from base64 +SVGEditUtilities.decode64 = function(input) { + if(window.atob) return window.atob(input); + var output = ""; + var chr1, chr2, chr3 = ""; + var enc1, enc2, enc3, enc4 = ""; + var i = 0; + + // remove all characters that are not A-Z, a-z, 0-9, +, /, or = + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + + do { + enc1 = _keyStr.indexOf(input.charAt(i++)); + enc2 = _keyStr.indexOf(input.charAt(i++)); + enc3 = _keyStr.indexOf(input.charAt(i++)); + enc4 = _keyStr.indexOf(input.charAt(i++)); + + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + + output = output + String.fromCharCode(chr1); + + if (enc3 != 64) { + output = output + String.fromCharCode(chr2); + } + if (enc4 != 64) { + output = output + String.fromCharCode(chr3); + } + + chr1 = chr2 = chr3 = ""; + enc1 = enc2 = enc3 = enc4 = ""; + + } while (i < input.length); + return unescape(output); +}; + +// Currently not being used, so commented out for now +// based on http://phpjs.org/functions/utf8_encode:577 +// codedread:does not seem to work with webkit-based browsers on OSX +// "encodeUTF8": function(input) { +// //return unescape(encodeURIComponent(input)); //may or may not work +// var output = ''; +// for (var n = 0; n < input.length; n++){ +// var c = input.charCodeAt(n); +// if (c < 128) { +// output += input[n]; +// } +// else if (c > 127) { +// if (c < 2048){ +// output += String.fromCharCode((c >> 6) | 192); +// } +// else { +// output += String.fromCharCode((c >> 12) | 224) + String.fromCharCode((c >> 6) & 63 | 128); +// } +// output += String.fromCharCode((c & 63) | 128); +// } +// } +// return output; +// }, + +// Function: Utils.convertToXMLReferences +// Converts a string to use XML references +SVGEditUtilities.convertToXMLReferences = function(input) { + var output = ''; + for (var n = 0; n < input.length; n++){ + var c = input.charCodeAt(n); + if (c < 128) { + output += input[n]; + } + else if(c > 127) { + output += ("&#" + c + ";"); + } + } + return output; +}; + +// Function: rectsIntersect +// Check if two rectangles (BBoxes objects) intersect each other +// +// Paramaters: +// r1 - The first BBox-like object +// r2 - The second BBox-like object +// +// Returns: +// Boolean that's true if rectangles intersect +SVGEditUtilities.rectsIntersect = function(r1, r2) { + return r2.x < (r1.x+r1.width) && + (r2.x+r2.width) > r1.x && + r2.y < (r1.y+r1.height) && + (r2.y+r2.height) > r1.y; +}; + +// Function: snapToAngle +// Returns a 45 degree angle coordinate associated with the two given +// coordinates +// +// Parameters: +// x1 - First coordinate's x value +// x2 - Second coordinate's x value +// y1 - First coordinate's y value +// y2 - Second coordinate's y value +// +// Returns: +// Object with the following values: +// x - The angle-snapped x value +// y - The angle-snapped y value +// snapangle - The angle at which to snap +SVGEditUtilities.snapToAngle = function(x1,y1,x2,y2) { + var snap = Math.PI/4; // 45 degrees + var dx = x2 - x1; + var dy = y2 - y1; + var angle = Math.atan2(dy,dx); + var dist = Math.sqrt(dx * dx + dy * dy); + var snapangle= Math.round(angle/snap)*snap; + var x = x1 + dist*Math.cos(snapangle); + var y = y1 + dist*Math.sin(snapangle); + //console.log(x1,y1,x2,y2,x,y,angle) + return {x:x, y:y, a:snapangle}; +}, + +// Function: text2xml +// Cross-browser compatible method of converting a string to an XML tree +// found this function here: http://groups.google.com/group/jquery-dev/browse_thread/thread/c6d11387c580a77f +SVGEditUtilities.text2xml = function(sXML) { + if(sXML.indexOf('= 0) { + sXML = sXML.replace(/<(\/?)svg:/g, '<$1').replace('xmlns:svg', 'xmlns'); + } + + var out; + try{ + var dXML = (window.DOMParser)?new DOMParser():new ActiveXObject("Microsoft.XMLDOM"); + dXML.async = false; + } catch(e){ + throw new Error("XML Parser could not be instantiated"); + }; + try{ + if(dXML.loadXML) out = (dXML.loadXML(sXML))?dXML:false; + else out = dXML.parseFromString(sXML, "text/xml"); + } + catch(e){ throw new Error("Error parsing XML string"); }; + return out; +}; + +// Function: bboxToObj +// Converts a SVGRect into an object. +// +// Parameters: +// bbox - a SVGRect +// +// Returns: +// An object with properties names x, y, width, height. +SVGEditUtilities.bboxToObj = function(bbox) { + return { + x: bbox.x, + y: bbox.y, + width: bbox.width, + height: bbox.height + } +};