diff --git a/editor/browsersupport.js b/editor/browsersupport.js index a8b3f1df..8da0a95f 100644 --- a/editor/browsersupport.js +++ b/editor/browsersupport.js @@ -1,5 +1,5 @@ /** - * Browser Support module for SVG-edit + * Package: svgedit.browsersupport * * Licensed under the Apache License, Version 2 * @@ -16,17 +16,17 @@ if (!window.svgedit) { window.svgedit = {}; } -if (!svgedit.BrowserSupport) { - svgedit.BrowserSupport = {}; +if (!svgedit.browsersupport) { + svgedit.browsersupport = {}; } var svgns = 'http://www.w3.org/2000/svg'; var userAgent = navigator.userAgent; // Note: Browser sniffing should only be used if no other detection method is possible -svgedit.BrowserSupport.isOpera = !!window.opera; -svgedit.BrowserSupport.isWebkit = userAgent.indexOf("AppleWebKit") >= 0; -svgedit.BrowserSupport.isGecko = userAgent.indexOf('Gecko/') >= 0; +svgedit.browsersupport.isOpera = !!window.opera; +svgedit.browsersupport.isWebkit = userAgent.indexOf("AppleWebKit") >= 0; +svgedit.browsersupport.isGecko = userAgent.indexOf('Gecko/') >= 0; // segList functions (for FF1.5 and 2.0) function supportPathReplaceItem() { @@ -71,7 +71,7 @@ function supportTextCharPos() { function supportEditableText() { // TODO: Find better way to check support for this - return svgedit.BrowserSupport.isOpera; + return svgedit.browsersupport.isOpera; } function supportGoodDecimals() { @@ -93,11 +93,11 @@ function supportNonScalingStroke() { return rect.style.vectorEffect === 'non-scaling-stroke'; } -svgedit.BrowserSupport.pathReplaceItem = supportPathReplaceItem(); -svgedit.BrowserSupport.pathInsertItemBefore = supportPathInsertItemBefore(); -svgedit.BrowserSupport.textCharPos = supportTextCharPos(); -svgedit.BrowserSupport.editableText = supportEditableText(); -svgedit.BrowserSupport.goodDecimals = supportGoodDecimals(); -svgedit.BrowserSupport.nonScalingStroke = supportNonScalingStroke(); +svgedit.browsersupport.pathReplaceItem = supportPathReplaceItem(); +svgedit.browsersupport.pathInsertItemBefore = supportPathInsertItemBefore(); +svgedit.browsersupport.textCharPos = supportTextCharPos(); +svgedit.browsersupport.editableText = supportEditableText(); +svgedit.browsersupport.goodDecimals = supportGoodDecimals(); +svgedit.browsersupport.nonScalingStroke = supportNonScalingStroke(); })(); \ No newline at end of file diff --git a/editor/math.js b/editor/math.js index b77f249c..08f253b3 100644 --- a/editor/math.js +++ b/editor/math.js @@ -1,5 +1,5 @@ /** - * SVG-edit Math Utilities + * Package: svedit.math * * Licensed under the Apache License, Version 2 * diff --git a/editor/svg-editor.html b/editor/svg-editor.html index 25eb034e..153121ad 100644 --- a/editor/svg-editor.html +++ b/editor/svg-editor.html @@ -21,6 +21,7 @@ + diff --git a/editor/svgcanvas.js b/editor/svgcanvas.js index f76a58c9..4dbbcea1 100644 --- a/editor/svgcanvas.js +++ b/editor/svgcanvas.js @@ -15,6 +15,7 @@ // 3) svgtransformlist.js // 4) math.js // 5) svgutils.js +// 6) units.js if(!window.console) { window.console = {}; @@ -96,10 +97,49 @@ if(window.opera) { // config - An object that contains configuration data $.SvgCanvas = function(container, config) { -var support = svgedit.BrowserSupport, - isOpera = support.isOpera, - isWebkit = support.isWebkit, - isGecko = support.isGecko, + +// import svgtransformlist.js +var getTransformList = this.getTransformList = svgedit.transformlist.getTransformList; + +// import from math.js. +var transformPoint = svgedit.math.transformPoint; +var isIdentity = svgedit.math.isIdentity; +var matrixMultiply = this.matrixMultiply = svgedit.math.matrixMultiply; +var hasMatrixTransform = this.hasMatrixTransform = svgedit.math.hasMatrixTransform; +var transformBox = this.transformBox = svgedit.math.transformBox; +var transformListToTransform = this.transformListToTransform = svgedit.math.transformListToTransform; +var snapToAngle = svgedit.math.snapToAngle; + +// import from units.js +svgedit.units.init(); +var unit_types = svgedit.units.typeMap; + +// import from svgutils.js +var getUrlFromAttr = this.getUrlFromAttr = svgedit.utilities.getUrlFromAttr; +var getHref = this.getHref = svgedit.utilities.getHref; +var setHref = this.setHref = svgedit.utilities.setHref; +var getPathBBox = svgedit.utilities.getPathBBox; +var getBBox = this.getBBox = svgedit.utilities.getBBox; +var getRotationAngle = this.getRotationAngle = svgedit.utilities.getRotationAngle; + +// Function: snapToGrid +// round value to for snapping +// NOTE: This function did not move to svgutils.js since it depends on curConfig. +svgedit.utilities.snapToGrid = function(value){ + var stepSize = curConfig.snappingStep; + var unit = curConfig.baseUnit; + if(unit !== "px") { + stepSize *= svgedit.units.typeMap[unit]; + } + value = Math.round(value/stepSize)*stepSize; + return value; +}; +var snapToGrid = svgedit.utilities.snapToGrid; + + +var isOpera = svgedit.browsersupport.isOpera, + isWebkit = svgedit.browsersupport.isWebkit, + isGecko = svgedit.browsersupport.isGecko, // this defines which elements and attributes that we support svgWhiteList = { @@ -186,13 +226,10 @@ var support = svgedit.BrowserSupport, show_outside_canvas: true, dimensions: [640, 480] }; - var visElems = 'a,circle,ellipse,foreignObject,g,image,line,path,polygon,polyline,rect,svg,text,tspan,use'; - var ref_attrs = ["clip-path", "fill", "filter", "marker-end", "marker-mid", "marker-start", "mask", "stroke"]; - // Update config with new one if given if(config) { $.extend(curConfig, config); @@ -212,9 +249,6 @@ var canvas = this, se_ns = "http://svg-edit.googlecode.com", htmlns = "http://www.w3.org/1999/xhtml", mathns = "http://www.w3.org/1998/Math/MathML", - - // Map of units, updated later based on px conversion. - unit_types = {px: 1}, //nonce to uniquify id's nonce = Math.floor(Math.random()*100001), @@ -229,7 +263,7 @@ var canvas = this, dimensions = curConfig.dimensions; // Create Root SVG element. This is a container for the document being edited, not the document itself. - var svgroot = svgdoc.importNode(svgedit.Utilities.text2xml( + var svgroot = svgdoc.importNode(svgedit.utilities.text2xml( '' + '' + @@ -255,7 +289,7 @@ $(svgcontent).attr({ height: dimensions[1], x: dimensions[0], y: dimensions[1], - overflow: curConfig.show_outside_canvas?'visible':'hidden', + overflow: curConfig.show_outside_canvas ? 'visible' : 'hidden', xmlns: svgns, "xmlns:se": se_ns, "xmlns:xlink": xlinkns @@ -312,7 +346,7 @@ var convertToNum, convertToUnit, setUnitAttr, unitConvertAttrs; var w_attrs = ['x', 'x1', 'cx', 'rx', 'width']; var h_attrs = ['y', 'y1', 'cy', 'ry', 'height']; var unit_attrs = $.merge(['r','radius'], w_attrs); - + var unitNumMap = { '%': 2, em: 3, @@ -324,7 +358,6 @@ var convertToNum, convertToUnit, setUnitAttr, unitConvertAttrs; pt: 9, pc: 10 }; - $.merge(unit_attrs, h_attrs); @@ -400,7 +433,7 @@ var convertToNum, convertToUnit, setUnitAttr, unitConvertAttrs; // } } elem.setAttribute(attr, val); - } + }; // Function: isValidUnit // Check if an attribute's value is in a valid format @@ -440,13 +473,13 @@ var convertToNum, convertToUnit, setUnitAttr, unitConvertAttrs; } else valid = true; return valid; - } - + }; + // Function: getUnits // Returns the unit object with values for each unit canvas.getUnits = function() { return unit_types; - } + }; // Function: convertUnit // Converts the number to given unit or baseUnit @@ -456,7 +489,7 @@ var convertToNum, convertToUnit, setUnitAttr, unitConvertAttrs; // var val = baseVal.valueInSpecifiedUnits; // baseVal.convertToSpecifiedUnits(1); return shortFloat(val / unit_types[unit]); - } + }; // Function: unitConvertAttrs // Converts all applicable attributes to the given baseUnit @@ -498,9 +531,7 @@ var convertToNum, convertToUnit, setUnitAttr, unitConvertAttrs; } } } - - - } + }; })(); @@ -1412,41 +1443,6 @@ var SelectorManager; }; }()); - -// import svgtransformlist.js -var getTransformList = this.getTransformList = svgedit.transformlist.getTransformList; - -// import from svgutils.js -var getUrlFromAttr = this.getUrlFromAttr = svgedit.Utilities.getUrlFromAttr; -var getHref = this.getHref = svgedit.Utilities.getHref; -var setHref = this.setHref = svgedit.Utilities.setHref; -var getPathBBox = svgedit.Utilities.getPathBBox; -var getBBox = this.getBBox = svgedit.Utilities.getBBox; -var getRotationAngle = this.getRotationAngle = svgedit.Utilities.getRotationAngle; - -// Function: snapToGrid -// round value to for snapping -// NOTE: This function did not move to svgutils.js since it depends on unit_types and curConfig. -svgedit.Utilities.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 = svgedit.Utilities.snapToGrid; - -// import from math.js. -var transformPoint = svgedit.math.transformPoint; -var isIdentity = svgedit.math.isIdentity; -var matrixMultiply = this.matrixMultiply = svgedit.math.matrixMultiply; -var hasMatrixTransform = this.hasMatrixTransform = svgedit.math.hasMatrixTransform; -var transformBox = this.transformBox = svgedit.math.transformBox; -var transformListToTransform = this.transformListToTransform = svgedit.math.transformListToTransform; -var snapToAngle = svgedit.math.snapToAngle; - // Function: assignAttributes // Assigns multiple attributes to an element. // @@ -1782,7 +1778,7 @@ var getIntersectionList = this.getIntersectionList = function(rect) { var i = curBBoxes.length; while (i--) { if(!rubberBBox.width || !rubberBBox.width) continue; - if (svgedit.Utilities.rectsIntersect(rubberBBox, curBBoxes[i].bbox)) { + if (svgedit.utilities.rectsIntersect(rubberBBox, curBBoxes[i].bbox)) { resultList.push(curBBoxes[i].elem); } } @@ -1842,7 +1838,7 @@ var getStrokedBBox = this.getStrokedBBox = function(elems) { var parent = elem.parentNode; parent.appendChild(g); g.appendChild(clone); - bb = svgedit.Utilities.bboxToObj(g.getBBox()); + bb = svgedit.utilities.bboxToObj(g.getBBox()); parent.removeChild(g); } @@ -3865,7 +3861,7 @@ var getMouseTarget = this.getMouseTarget = function(evt) { tlist.appendItem(svgroot.createSVGTransform()); tlist.appendItem(svgroot.createSVGTransform()); - if(support.nonScalingStroke) { + if(svgedit.browsersupport.nonScalingStroke) { mouse_target.style.vectorEffect = 'non-scaling-stroke'; var all = mouse_target.getElementsByTagName('*'), len = all.length; for(var i = 0; i < all.length; i++) { @@ -4525,10 +4521,10 @@ var getMouseTarget = this.getMouseTarget = function(evt) { } // no change in mouse position // Remove non-scaling stroke - if(support.nonScalingStroke) { + if(svgedit.browsersupport.nonScalingStroke) { var elem = selectedElements[0]; elem.removeAttribute('style'); - svgedit.Utilities.walkTree(elem, function(elem) { + svgedit.utilities.walkTree(elem, function(elem) { elem.removeAttribute('style'); }); } @@ -5086,7 +5082,7 @@ var textActions = canvas.textActions = function() { // TODO: Find a way to make this work: Use transformed BBox instead of evt.target // if(last_x === mouse_x && last_y === mouse_y -// && !svgedit.Utilities.rectsIntersect(transbb, {x: pt.x, y: pt.y, width:0, height:0})) { +// && !svgedit.utilities.rectsIntersect(transbb, {x: pt.x, y: pt.y, width:0, height:0})) { // textActions.toSelectMode(true); // } if(last_x === mouse_x && last_y === mouse_y && evt.target !== curtext) { @@ -5106,7 +5102,7 @@ var textActions = canvas.textActions = function() { $(curtext).css('cursor', 'text'); -// if(support.editableText) { +// if(svgedit.browsersupport.editableText) { // curtext.setAttribute('editable', 'simple'); // return; // } @@ -5146,7 +5142,7 @@ var textActions = canvas.textActions = function() { curtext = false; -// if(support.editableText) { +// if(svgedit.browsersupport.editableText) { // curtext.removeAttribute('editable'); // } }, @@ -5162,7 +5158,7 @@ var textActions = canvas.textActions = function() { init: function(inputElem) { if(!curtext) return; -// if(support.editableText) { +// if(svgedit.browsersupport.editableText) { // curtext.select(); // return; // } @@ -5250,7 +5246,7 @@ var pathActions = this.pathActions = function() { // Support insertItemBefore on paths for FF2 var list = elem.pathSegList; - if(support.pathInsertItemBefore) { + if(svgedit.browsersupport.pathInsertItemBefore) { list.insertItemBefore(newseg, index); return; } @@ -6097,7 +6093,7 @@ var pathActions = this.pathActions = function() { var func = 'createSVGPathSeg' + pathFuncs[type]; var seg = path[func].apply(path, pts); - if(support.pathReplaceItem) { + if(svgedit.browsersupport.pathReplaceItem) { path.pathSegList.replaceItem(seg, index); } else { var segList = path.pathSegList; @@ -6549,7 +6545,7 @@ var pathActions = this.pathActions = function() { height: 0 }; - var sel = svgedit.Utilities.rectsIntersect(rbb, pt_bb); + var sel = svgedit.utilities.rectsIntersect(rbb, pt_bb); this.select(sel); //Note that addPtsToSelection is not being run @@ -7286,9 +7282,8 @@ var svgCanvasToString = this.svgCanvasToString = function() { // Returns: // String with the given element as an SVG tag var svgToString = this.svgToString = function(elem, indent) { - var out = new Array(), toXml = svgedit.Utilities.toXml; - - var unit = curConfig.baseUnit + var out = new Array(), toXml = svgedit.utilities.toXml; + var unit = curConfig.baseUnit; var unit_re = new RegExp('^-?[\\d\\.]+' + unit + '$'); if (elem) { @@ -7299,7 +7294,7 @@ var svgToString = this.svgToString = function(elem, indent) { childs = elem.childNodes; for (var i=0; i').text(str).html(); }; -// Function: svgedit.Utilities.fromXml +// Function: svgedit.utilities.fromXml // Converts XML entities in a string to single characters. // Example: "&" becomes "&" // @@ -56,7 +56,7 @@ svgedit.Utilities.toXml = function(str) { // // Returns: // The converted string -svgedit.Utilities.fromXml = function(str) { +svgedit.utilities.fromXml = function(str) { return $('

').html(str).text(); }; @@ -68,12 +68,12 @@ svgedit.Utilities.fromXml = function(str) { // schiller: Removed string concatenation in favour of Array.join() optimization, // also precalculate the size of the array needed. -// Function: svgedit.Utilities.encode64 +// Function: svgedit.utilities.encode64 // Converts a string to base64 -svgedit.Utilities.encode64 = function(input) { +svgedit.utilities.encode64 = function(input) { // base64 strings are 4/3 larger than the original string -// input = svgedit.Utilities.encodeUTF8(input); // convert non-ASCII characters - input = svgedit.Utilities.convertToXMLReferences(input); +// input = svgedit.utilities.encodeUTF8(input); // convert non-ASCII characters + input = svgedit.utilities.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; @@ -105,9 +105,9 @@ svgedit.Utilities.encode64 = function(input) { return output.join(''); }; -// Function: svgedit.Utilities.decode64 +// Function: svgedit.utilities.decode64 // Converts a string from base64 -svgedit.Utilities.decode64 = function(input) { +svgedit.utilities.decode64 = function(input) { if(window.atob) return window.atob(input); var output = ""; var chr1, chr2, chr3 = ""; @@ -167,9 +167,9 @@ svgedit.Utilities.decode64 = function(input) { // return output; // }, -// Function: svgedit.Utilities.convertToXMLReferences +// Function: svgedit.utilities.convertToXMLReferences // Converts a string to use XML references -svgedit.Utilities.convertToXMLReferences = function(input) { +svgedit.utilities.convertToXMLReferences = function(input) { var output = ''; for (var n = 0; n < input.length; n++){ var c = input.charCodeAt(n); @@ -192,7 +192,7 @@ svgedit.Utilities.convertToXMLReferences = function(input) { // // Returns: // Boolean that's true if rectangles intersect -svgedit.Utilities.rectsIntersect = function(r1, r2) { +svgedit.utilities.rectsIntersect = function(r1, r2) { return r2.x < (r1.x+r1.width) && (r2.x+r2.width) > r1.x && r2.y < (r1.y+r1.height) && @@ -202,7 +202,7 @@ svgedit.Utilities.rectsIntersect = function(r1, r2) { // 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 -svgedit.Utilities.text2xml = function(sXML) { +svgedit.utilities.text2xml = function(sXML) { if(sXML.indexOf('= 0) { sXML = sXML.replace(/<(\/?)svg:/g, '<$1').replace('xmlns:svg', 'xmlns'); } @@ -230,7 +230,7 @@ svgedit.Utilities.text2xml = function(sXML) { // // Returns: // An object with properties names x, y, width, height. -svgedit.Utilities.bboxToObj = function(bbox) { +svgedit.utilities.bboxToObj = function(bbox) { return { x: bbox.x, y: bbox.y, @@ -245,12 +245,12 @@ svgedit.Utilities.bboxToObj = function(bbox) { // Parameters: // elem - DOM element to traverse // cbFn - Callback function to run on each element -svgedit.Utilities.walkTree = function(elem, cbFn){ +svgedit.utilities.walkTree = function(elem, cbFn){ if (elem && elem.nodeType == 1) { cbFn(elem); var i = elem.childNodes.length; while (i--) { - svgedit.Utilities.walkTree(elem.childNodes.item(i), cbFn); + svgedit.utilities.walkTree(elem.childNodes.item(i), cbFn); } } }; @@ -262,17 +262,17 @@ svgedit.Utilities.walkTree = function(elem, cbFn){ // Parameters: // elem - DOM element to traverse // cbFn - Callback function to run on each element -svgedit.Utilities.walkTreePost = function(elem, cbFn) { +svgedit.utilities.walkTreePost = function(elem, cbFn) { if (elem && elem.nodeType == 1) { var i = elem.childNodes.length; while (i--) { - svgedit.Utilities.walkTree(elem.childNodes.item(i), cbFn); + svgedit.utilities.walkTree(elem.childNodes.item(i), cbFn); } cbFn(elem); } }; -// Function: svgedit.Utilities.getUrlFromAttr +// Function: svgedit.utilities.getUrlFromAttr // Extracts the URL from the url(...) syntax of some attributes. // Three variants: // * @@ -284,7 +284,7 @@ svgedit.Utilities.walkTreePost = function(elem, cbFn) { // // Returns: // String with just the URL, like someFile.svg#foo -svgedit.Utilities.getUrlFromAttr = function(attrVal) { +svgedit.utilities.getUrlFromAttr = function(attrVal) { if (attrVal) { // url("#somegrad") if (attrVal.indexOf('url("') === 0) { @@ -301,15 +301,15 @@ svgedit.Utilities.getUrlFromAttr = function(attrVal) { return null; }; -// Function: svgedit.Utilities.getHref +// Function: svgedit.utilities.getHref // Returns the given element's xlink:href value -svgedit.Utilities.getHref = function(elem) { +svgedit.utilities.getHref = function(elem) { return elem.getAttributeNS(XLINKNS, "href"); } -// Function: svgedit.Utilities.setHref +// Function: svgedit.utilities.setHref // Sets the given element's xlink:href value -svgedit.Utilities.setHref = function(elem, val) { +svgedit.utilities.setHref = function(elem, val) { elem.setAttributeNS(XLINKNS, "xlink:href", val); } @@ -319,7 +319,7 @@ svgedit.Utilities.setHref = function(elem, val) { // // Returns: // The document's element, create it first if necessary -svgedit.Utilities.findDefs = function(svgElement) { +svgedit.utilities.findDefs = function(svgElement) { var svgElement = svgDoc.documentElement; var defs = svgElement.getElementsByTagNameNS(svgns, "defs"); if (defs.length > 0) { @@ -332,7 +332,7 @@ svgedit.Utilities.findDefs = function(svgElement) { return defs; }; -// Function: svgedit.Utilities.getPathBBox +// Function: svgedit.utilities.getPathBBox // Get correct BBox for a path in Webkit // Converted from code found here: // http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html @@ -342,7 +342,7 @@ svgedit.Utilities.findDefs = function(svgElement) { // // Returns: // A BBox-like object -svgedit.Utilities.getPathBBox = function(path) { +svgedit.utilities.getPathBBox = function(path) { var seglist = path.pathSegList; var tot = seglist.numberOfItems; @@ -413,13 +413,13 @@ svgedit.Utilities.getPathBBox = function(path) { }; }; -// Function: svgedit.Utilities.getBBox +// Function: svgedit.utilities.getBBox // Get the given/selected element's bounding box object, convert it to be more // usable when necessary // // Parameters: // elem - Optional DOM element to get the BBox for -svgedit.Utilities.getBBox = function(elem) { +svgedit.utilities.getBBox = function(elem) { var selected = elem || selectedElements[0]; if (elem.nodeType != 1) return null; var ret = null; @@ -429,9 +429,9 @@ svgedit.Utilities.getBBox = function(elem) { selected.textContent = 'a'; // Some character needed for the selector to use. ret = selected.getBBox(); selected.textContent = ''; - } else if(elname === 'path' && svgedit.BrowserSupport.isWebkit) { - ret = svgedit.Utilities.getPathBBox(selected); - } else if(elname === 'use' && !svgedit.BrowserSupport.isWebkit || elname === 'foreignObject') { + } else if(elname === 'path' && svgedit.browsersupport.isWebkit) { + ret = svgedit.utilities.getPathBBox(selected); + } else if(elname === 'use' && !svgedit.browsersupport.isWebkit || elname === 'foreignObject') { ret = selected.getBBox(); var bb = {}; bb.width = ret.width; @@ -456,14 +456,14 @@ svgedit.Utilities.getBBox = function(elem) { } } if(ret) { - ret = svgedit.Utilities.bboxToObj(ret); + ret = svgedit.utilities.bboxToObj(ret); } // get the bounding box from the DOM (which is in that element's coordinate system) return ret; }; -// Function: svgedit.Utilities.getRotationAngle +// Function: svgedit.utilities.getRotationAngle // Get the rotation angle of the given/selected DOM element // // Parameters: @@ -472,7 +472,7 @@ svgedit.Utilities.getBBox = function(elem) { // // Returns: // Float with the angle in degrees or radians -svgedit.Utilities.getRotationAngle = function(elem, to_rad) { +svgedit.utilities.getRotationAngle = function(elem, to_rad) { var selected = elem || selectedElements[0]; // find the rotation transform (if any) and set it var tlist = svgedit.transformlist.getTransformList(selected); diff --git a/editor/units.js b/editor/units.js new file mode 100644 index 00000000..174d99fe --- /dev/null +++ b/editor/units.js @@ -0,0 +1,74 @@ +/** + * Package: svgedit.units + * + * Licensed under the Apache License, Version 2 + * + * Copyright(c) 2010 Alexis Deveria + * Copyright(c) 2010 Jeff Schiller + */ + +// Dependencies: +// 1) jQuery + +(function() { + +if (!window.svgedit) { + window.svgedit = {}; +} + +if (!svgedit.units) { + svgedit.units = {}; +} + +var w_attrs = ['x', 'x1', 'cx', 'rx', 'width']; +var h_attrs = ['y', 'y1', 'cy', 'ry', 'height']; +var unit_attrs = $.merge(['r','radius'], w_attrs); + +var unitNumMap = { + '%': 2, + 'em': 3, + 'ex': 4, + 'px': 5, + 'cm': 6, + 'mm': 7, + 'in': 8, + 'pt': 9, + 'pc': 10 +}; + +$.merge(unit_attrs, h_attrs); + +/** + * Stores mapping of unit type to user coordinates. + */ +svgedit.units.typeMap = {px: 1}; + +/** + * Initializes this module. + */ +svgedit.units.init = function() { + var svgns = 'http://www.w3.org/2000/svg'; + + // Get correct em/ex values by creating a temporary SVG. + var svg = document.createElementNS(svgns, 'svg'); + document.body.appendChild(svg); + var rect = document.createElementNS(svgns,'rect'); + rect.setAttribute('width',"1em"); + rect.setAttribute('height',"1ex"); + rect.setAttribute('x',"1in"); + svg.appendChild(rect); + var bb = rect.getBBox(); + document.body.removeChild(svg); + + var inch = bb.x; + svgedit.units.typeMap['em'] = bb.width; + svgedit.units.typeMap['ex'] = bb.height; + svgedit.units.typeMap['in'] = inch; + svgedit.units.typeMap['cm'] = inch / 2.54; + svgedit.units.typeMap['mm'] = inch / 25.4; + svgedit.units.typeMap['pt'] = inch / 72; + svgedit.units.typeMap['pc'] = inch / 6; + svgedit.units.typeMap['%'] = 0; +}; + +})(); \ No newline at end of file