diff --git a/public/svg-edit/editor/svg-editor.css b/public/svg-edit/editor/svg-editor.css
index a792239c..de7ad15f 100644
--- a/public/svg-edit/editor/svg-editor.css
+++ b/public/svg-edit/editor/svg-editor.css
@@ -1020,7 +1020,8 @@ span.zoom_tool {
margin-left: 30px;
}
-#svg_docprops #svg_docprops_container {
+#svg_docprops #svg_docprops_container,
+#svg_prefs #svg_prefs_container {
position: absolute;
top: 50px;
padding: 10px;
@@ -1042,40 +1043,45 @@ span.zoom_tool {
max-width: 14em;
}
-#tool_docprops_back {
+#tool_docprops_back,
+#tool_prefs_back {
margin-left: 1em;
overflow: auto;
}
#svg_docprops_container #svg_docprops_docprops,
-#svg_docprops_container #svg_docprops_prefs {
+#svg_prefs #svg_docprops_prefs {
float: left;
width: 221px;
margin: 5px .7em;
overflow: hidden;
}
-#svg_docprops_container #svg_docprops_prefs {
+#svg_prefs_container fieldset + fieldset {
float: right;
}
-#svg_docprops legend {
+#svg_docprops legend,
+#svg_prefs legend {
max-width: 195px;
}
-#svg_docprops_docprops > legend, #svg_docprops_prefs > legend {
+#svg_docprops_docprops > legend,
+#svg_prefs_container > fieldset > legend {
font-weight: bold;
font-size: 1.1em;
}
-#svg_docprops_container fieldset {
+#svg_docprops_container fieldset,
+#svg_prefs fieldset {
padding: 5px;
margin: 5px;
border: 1px solid #DDD;
}
-#svg_docprops_container label {
+#svg_docprops_container label,
+#svg_prefs_container label {
display: block;
margin: .5em;
}
@@ -1105,7 +1111,7 @@ span.zoom_tool {
padding-left: 20px;
}
-#svg_docprops_container div.color_block {
+#svg_prefs_container div.color_block {
float: left;
margin: 2px;
padding: 20px;
@@ -1123,12 +1129,14 @@ span.zoom_tool {
text-align: left;
}
-#svg_docprops button {
+#svg_docprops button,
+#svg_prefs button {
margin-top: 0;
margin-bottom: 5px;
}
-#svg_docprops {
+#svg_docprops,
+#svg_prefs {
display: none;
}
@@ -1140,7 +1148,8 @@ span.zoom_tool {
margin-left: 0;
}
-#svg_docprops #svg_docprops_overlay {
+#svg_docprops #svg_docprops_overlay,
+#svg_prefs #svg_prefs_overlay {
position: absolute;
top: 0px;
right: 0px;
@@ -1151,6 +1160,10 @@ span.zoom_tool {
z-index: 20000;
}
+#tool_prefs_option {
+ float: right;
+}
+
.toolbar_button button {
border:1px solid #dedede;
line-height:130%;
diff --git a/public/svg-edit/editor/svg-editor.html b/public/svg-edit/editor/svg-editor.html
index 6b51c267..d193edeb 100644
--- a/public/svg-edit/editor/svg-editor.html
+++ b/public/svg-edit/editor/svg-editor.html
@@ -137,13 +137,18 @@ script type="text/javascript" src="locale/locale.min.js">
Document Properties [P]
-
+
+
+
+
+
+
+
+
+
-
+
diff --git a/public/svg-edit/editor/svg-editor.js b/public/svg-edit/editor/svg-editor.js
index 894fd89f..c0575f14 100644
--- a/public/svg-edit/editor/svg-editor.js
+++ b/public/svg-edit/editor/svg-editor.js
@@ -51,6 +51,7 @@
wireframe: false,
colorPickerCSS: null,
gridSnapping: false,
+ baseUnit: 'px',
snappingStep: 10,
showRulers: true
},
@@ -252,7 +253,7 @@
$.svgIcons(curConfig.imgPath + 'svg_edit_icons.svg', {
w:24, h:24,
id_match: false,
- no_img: (!!window.opera), // Opera gives odd behavior w/images
+ no_img: !isWebkit, // Opera & Firefox 4 gives odd behavior w/images
fallback_path: curConfig.imgPath,
fallback:{
'new_image':'clear.png',
@@ -375,8 +376,8 @@
'#layer_moreopts':'context_menu',
'#layerlist td.layervis':'eye',
- '#tool_source_save,#tool_docprops_save':'ok',
- '#tool_source_cancel,#tool_docprops_cancel':'cancel',
+ '#tool_source_save,#tool_docprops_save,#tool_prefs_save':'ok',
+ '#tool_source_cancel,#tool_docprops_cancel,#tool_prefs_cancel':'cancel',
'#rwidthLabel, #iwidthLabel':'width',
'#rheightLabel, #iheightLabel':'height',
@@ -457,10 +458,10 @@
"#ffaaaa", "#ffd4aa", "#ffffaa", "#d4ffaa",
"#aaffaa", "#aaffd4", "#aaffff", "#aad4ff",
"#aaaaff", "#d4aaff", "#ffaaff", "#ffaad4",
- ];
-
- isMac = (navigator.platform.indexOf("Mac") >= 0);
- modKey = (isMac ? "meta+" : "ctrl+"); // ⌘
+ ],
+ isMac = (navigator.platform.indexOf("Mac") >= 0),
+ isWebkit = (navigator.userAgent.indexOf("AppleWebKit") >= 0),
+ modKey = (isMac ? "meta+" : "ctrl+"), // ⌘
path = svgCanvas.pathActions,
undoMgr = svgCanvas.undoMgr,
Utils = svgCanvas.Utils,
@@ -559,6 +560,7 @@
var multiselected = false;
var editingsource = false;
var docprops = false;
+ var preferences = false;
var cur_context = '';
var orig_title = $('title:first').text();
@@ -1789,6 +1791,13 @@
this.value = selectedElement.getAttribute(attr);
return false;
}
+
+ // Convert unitless value to one with given unit
+ if(curConfig.baseUnit !== 'px' && !isNaN(val) ) {
+ val += curConfig.baseUnit;
+ this.value = val;
+ }
+
// if the user is changing the id, then de-select the element first
// change the ID, then re-select it with the new ID
if (attr == "id") {
@@ -2578,7 +2587,7 @@
$('#svg_source_textarea').focus();
};
- $('#svg_docprops_container').draggable({cancel:'button,fieldset'});
+ $('#svg_docprops_container, #svg_prefs_container').draggable({cancel:'button,fieldset'});
var showDocProperties = function(){
if (docprops) return;
@@ -2593,6 +2602,15 @@
$('#canvas_height').val(res.h);
$('#canvas_title').val(svgCanvas.getDocumentTitle());
+ $('#svg_docprops').fadeIn();
+ };
+
+
+ var showPreferences = function(){
+ if (preferences) return;
+ preferences = true;
+ $('#main_menu').hide();
+
// Update background color with current one
var blocks = $('#bg_blocks div');
var cur_bg = 'cur_background';
@@ -2616,8 +2634,8 @@
$('#grid_snapping_on').removeAttr('checked');
}
- $('#svg_docprops').fadeIn();
- };
+ $('#svg_prefs').fadeIn();
+ };
var properlySourceSizeTextArea = function(){
// TODO: remove magic numbers here and get values from CSS
@@ -2690,7 +2708,11 @@
// set image save option
curPrefs.img_save = $('#image_save_opts :checked').val();
$.pref('img_save',curPrefs.img_save);
-
+ updateCanvas();
+ hideDocProperties();
+ };
+
+ var savePreferences = function() {
// set background
var color = $('#bg_blocks div.cur_background').css('background-color') || '#FFF';
setBackground(color, $('#canvas_bg_url').val());
@@ -2711,12 +2733,13 @@
$('#rulers').toggle(curConfig.showRulers);
if(curConfig.showRulers) updateRulers();
+ curConfig.baseUnit = $('#base_unit').val();
svgCanvas.setConfig(curConfig);
updateCanvas();
- hideDocProperties();
- };
+ hidePreferences();
+ }
function setBackground(color, url) {
// if(color == curPrefs.bkgd_color && url == curPrefs.bkgd_url) return;
@@ -3008,7 +3031,7 @@
var cancelOverlays = function() {
$('#dialog_box').hide();
- if (!editingsource && !docprops) {
+ if (!editingsource && !docprops && !preferences) {
if(cur_context) {
svgCanvas.leaveContext();
}
@@ -3027,6 +3050,8 @@
}
else if (docprops) {
hideDocProperties();
+ } else if (preferences) {
+ hidePreferences();
}
};
@@ -3044,6 +3069,11 @@
$('#image_save_opts input').val([curPrefs.img_save]);
docprops = false;
};
+
+ var hidePreferences = function(){
+ $('#svg_prefs').hide();
+ preferences = false;
+ };
var win_wh = {width:$(window).width(), height:$(window).height()};
@@ -3697,10 +3727,12 @@
{sel:'#tool_import', fn: clickImport, evt: 'mouseup'},
{sel:'#tool_source', fn: showSourceEditor, evt: 'click', key: ['U', true]},
{sel:'#tool_wireframe', fn: clickWireframe, evt: 'click', key: ['F', true]},
- {sel:'#tool_source_cancel,#svg_source_overlay,#tool_docprops_cancel', fn: cancelOverlays, evt: 'click', key: ['esc', false, false], hidekey: true},
+ {sel:'#tool_source_cancel,#svg_source_overlay,#tool_docprops_cancel,#tool_prefs_cancel', fn: cancelOverlays, evt: 'click', key: ['esc', false, false], hidekey: true},
{sel:'#tool_source_save', fn: saveSourceEditor, evt: 'click'},
{sel:'#tool_docprops_save', fn: saveDocProperties, evt: 'click'},
{sel:'#tool_docprops', fn: showDocProperties, evt: 'mouseup', key: ['P', true]},
+ {sel:'#tool_prefs_save', fn: savePreferences, evt: 'click'},
+ {sel:'#tool_prefs_option', fn: function() {showPreferences();return false}, evt: 'mouseup', key: ['I', true]},
{sel:'#tool_delete,#tool_delete_multi', fn: deleteSelected, evt: 'click', key: ['del/backspace', true]},
{sel:'#tool_reorient', fn: reorientPath, evt: 'click'},
{sel:'#tool_node_link', fn: linkControlPoints, evt: 'click'},
@@ -3911,6 +3943,10 @@
if(curConfig.gridSnapping) {
$('#grid_snapping_on')[0].checked = true;
}
+
+ if(curConfig.baseUnit) {
+ $('#base_unit').val(curConfig.baseUnit);
+ }
if(curConfig.snappingStep) {
$('#grid_snapping_step').val(curConfig.snappingStep);
@@ -4158,6 +4194,9 @@
var c_elem = svgCanvas.getContentElem();
+ var units = svgCanvas.getUnits();
+ var unit = units[curConfig.baseUnit]; // 1 = 1px
+
for(var d = 0; d < 2; d++) {
var is_x = (d === 0);
var dim = is_x ? 'x' : 'y';
@@ -4170,11 +4209,10 @@
var len = hcanv[lentype] = scanvas[lentype]();
var ctx = hcanv.getContext("2d");
- var unit = 1; // 1 = 1px
+ var u_multi = unit * zoom;
// Calculate the main number interval
- var raw_m = 50 / zoom;
-
+ var raw_m = 50 / u_multi;
var multi = 1;
for(var i = 0; i < r_intervals.length; i++) {
var num = r_intervals[i];
@@ -4184,11 +4222,11 @@
}
}
- var big_int = unit * multi * zoom;
-
+ var big_int = multi * u_multi;
+
ctx.font = "9px sans-serif";
- var ruler_d = ((content_d / zoom) % multi) * zoom;
+ var ruler_d = ((content_d / u_multi) % multi) * u_multi;
for (; ruler_d < len; ruler_d += big_int) {
var real_d = Math.round((ruler_d) - content_d );
@@ -4202,7 +4240,14 @@
ctx.lineTo(0, cur_d);
}
- var label = Math.round(real_d / zoom);
+
+ var num = real_d / u_multi;
+ if(multi >= 1) {
+ label = Math.round(num);
+ } else {
+ var decs = (multi+'').split('.')[1].length;
+ label = num.toFixed(decs)-0;
+ }
// Do anything special for negative numbers?
// var is_neg = label < 0;
@@ -4245,7 +4290,7 @@
updateCanvas(true);
// });
- // var revnums = "svg-editor.js ($Rev: 1774 $) ";
+ // var revnums = "svg-editor.js ($Rev: 1778 $) ";
// revnums += svgCanvas.getVersion();
// $('#copyright')[0].setAttribute("title", revnums);
diff --git a/public/svg-edit/editor/svgcanvas.js b/public/svg-edit/editor/svgcanvas.js
index 423d7bf1..46880a58 100644
--- a/public/svg-edit/editor/svgcanvas.js
+++ b/public/svg-edit/editor/svgcanvas.js
@@ -1,4 +1,4 @@
-/*
+/*
* svgcanvas.js
*
* Licensed under the Apache License, Version 2
@@ -447,8 +447,8 @@ var canvas = this,
htmlns = "http://www.w3.org/1999/xhtml",
mathns = "http://www.w3.org/1998/Math/MathML",
- // Map of units, those set to 0 are updated later based on calculations
- unit_types = {'em':0,'ex':0,'px':1,'cm':35.43307,'mm':3.543307,'in':90,'pt':1.25,'pc':15,'%':0},
+ // Map of units, updated later based on px conversion.
+ unit_types = {px: 1},
//nonce to uniquify id's
nonce = Math.floor(Math.random()*100001),
@@ -538,7 +538,7 @@ $(opac_ani).attr({
// Group: Unit conversion functions
// Set the scope for these functions
-var convertToNum, convertToUnit, setUnitAttr;
+var convertToNum, convertToUnit, setUnitAttr, unitConvertAttrs;
(function() {
var w_attrs = ['x', 'x1', 'cx', 'rx', 'width'];
@@ -590,7 +590,7 @@ var convertToNum, convertToUnit, setUnitAttr;
// New value is a number, so check currently used unit
var old_val = elem.getAttribute(attr);
- if(old_val !== null && isNaN(old_val)) {
+ if(old_val !== null && (isNaN(old_val) || curConfig.baseUnit !== 'px')) {
// Old value was a number, so get unit, then convert
var unit;
if(old_val.substr(-1) === '%') {
@@ -604,9 +604,12 @@ var convertToNum, convertToUnit, setUnitAttr;
} else {
return val / Math.sqrt((res.w*res.w) + (res.h*res.h))/Math.sqrt(2);
}
-
} else {
- unit = old_val.substr(-2);
+ if(curConfig.baseUnit !== 'px') {
+ unit = curConfig.baseUnit;
+ } else {
+ unit = old_val.substr(-2);
+ }
val = val / unit_types[unit];
}
@@ -656,6 +659,56 @@ var convertToNum, convertToUnit, setUnitAttr;
return valid;
}
+ // Function: getUnits
+ // Returns the unit object with values for each unit
+ canvas.getUnits = function() {
+ return unit_types;
+ }
+
+ // Function: unitConvertAttrs
+ // Converts all applicable attributes to the given baseUnit
+ unitConvertAttrs = canvas.unitConvertAttrs = function(element) {
+ var elName = element.tagName;
+ var unit = curConfig.baseUnit;
+ var attrs;
+ switch (elName)
+ {
+ case "line":
+ attrs = ['x1', 'x2', 'y1', 'y2'];
+ break;
+ case "circle":
+ attrs = ['cx', 'cy', 'r'];
+ break;
+ case "ellipse":
+ attrs = ['cx', 'cy', 'rx', 'ry'];
+ break;
+ case "foreignObject":
+ case "rect":
+ case "image":
+ case "use":
+ attrs = ['x', 'y', 'width', 'height'];
+ break;
+ case "text":
+ attrs = ['x', 'y'];
+ break;
+ }
+ if(!attrs) return;
+ var len = attrs.length
+ for(var i = 0; i < len; i++) {
+ var attr = attrs[i];
+ var cur = element.getAttribute(attr);
+ if(cur) {
+ if(!isNaN(cur)) {
+ element.setAttribute(attr, (cur / unit_types[unit]) + unit);
+ } else {
+ // Convert existing?
+ }
+ }
+ }
+
+
+ }
+
})();
@@ -2046,6 +2099,8 @@ var shortFloat = function(val) {
return Number(Number(val).toFixed(digits));
} else if($.isArray(val)) {
return shortFloat(val[0]) + ',' + shortFloat(val[1]);
+ } else {
+ return parseFloat(val).toFixed(digits) - 0;
}
}
@@ -5107,7 +5162,8 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
var real_x = x;
var real_y = y;
-
+
+ var useUnit = (curConfig.baseUnit !== 'px');
started = false;
switch (current_mode)
@@ -5342,6 +5398,8 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
} else if (element != null) {
canvas.addedNew = true;
+ if(useUnit) unitConvertAttrs(element);
+
var ani_dur = .2, c_ani;
if(opac_ani.beginElement && element.getAttribute('opacity') != cur_shape.opacity) {
c_ani = $(opac_ani).clone().attr({
@@ -7800,6 +7858,9 @@ var svgCanvasToString = this.svgCanvasToString = function() {
// String with the given element as an SVG tag
var svgToString = this.svgToString = function(elem, indent) {
var out = new Array(), toXml = Utils.toXml;
+
+ var unit = curConfig.baseUnit
+ var unit_re = new RegExp('^-?[\\d\\.]+' + unit + '$');
if (elem) {
cleanupElement(elem);
@@ -7810,7 +7871,7 @@ var svgToString = this.svgToString = function(elem, indent) {
for (var i=0; i
=0; i--) {
attr = attrs.item(i);
var attrVal = toXml(attr.nodeValue);
//remove bogus attributes added by Gecko
- if (['-moz-math-font-style', '_moz-math-font-style'].indexOf(attr.localName) >= 0) continue;
+ if (moz_attrs.indexOf(attr.localName) >= 0) continue;
if (attrVal != "") {
if(attrVal.indexOf('pointer-events') === 0) continue;
if(attr.localName === "class" && attrVal.indexOf('se_') === 0) continue;
@@ -7862,6 +7924,8 @@ var svgToString = this.svgToString = function(elem, indent) {
if(attr.localName === 'd') attrVal = pathActions.convertPath(elem, true);
if(!isNaN(attrVal)) {
attrVal = shortFloat(attrVal);
+ } else if(unit_re.test(attrVal)) {
+ attrVal = shortFloat(attrVal) + unit;
}
// Embed images when saving
@@ -8060,6 +8124,9 @@ this.randomizeIds = function() {
// g - The parent element of the tree to give unique IDs
var uniquifyElems = this.uniquifyElems = function(g) {
var ids = {};
+ var ref_attrs = ["clip-path", "fill", "filter", "marker-end", "marker-mid", "marker-start", "mask", "stroke"];
+ var ref_elems = ["filter", "linearGradient", "pattern", "radialGradient", "textPath", "use"];
+
walkTree(g, function(n) {
// if it's an element node
if (n.nodeType == 1) {
@@ -8075,7 +8142,7 @@ var uniquifyElems = this.uniquifyElems = function(g) {
// now search for all attributes on this element that might refer
// to other elements
- $.each(["clip-path", "fill", "filter", "marker-end", "marker-mid", "marker-start", "mask", "stroke"],function(i,attr) {
+ $.each(ref_attrs,function(i,attr) {
var attrnode = n.getAttributeNode(attr);
if (attrnode) {
// the incoming file has been sanitized, so we should be able to safely just strip off the leading #
@@ -8094,9 +8161,7 @@ var uniquifyElems = this.uniquifyElems = function(g) {
// check xlink:href now
var href = getHref(n);
// TODO: what if an or element refers to an element internally?
- if(href &&
- ["filter", "linearGradient", "pattern",
- "radialGradient", "textPath", "use"].indexOf(n.nodeName) >= 0)
+ if(href && ref_elems.indexOf(n.nodeName) >= 0)
{
var refid = href.substr(1);
if (!(refid in ids)) {
@@ -9188,7 +9253,7 @@ this.getZoom = function(){return current_zoom;};
// Function: getVersion
// Returns a string which describes the revision number of SvgCanvas.
this.getVersion = function() {
- return "svgcanvas.js ($Rev: 1775 $)";
+ return "svgcanvas.js ($Rev: 1777 $)";
};
// Function: setUiStrings
@@ -10355,6 +10420,9 @@ var changeSelectedAttributeNoUndo = function(attr, newValue, elems) {
}
var elems = elems || selectedElements;
var i = elems.length;
+ var no_xy_elems = ['g', 'polyline', 'path'];
+ var good_g_attrs = ['transform', 'opacity', 'filter'];
+
while (i--) {
var elem = elems[i];
if (elem == null) continue;
@@ -10365,19 +10433,19 @@ var changeSelectedAttributeNoUndo = function(attr, newValue, elems) {
}
// Set x,y vals on elements that don't have them
- if((attr == 'x' || attr == 'y') && ['g', 'polyline', 'path'].indexOf(elem.tagName) >= 0) {
+ if((attr === 'x' || attr === 'y') && no_xy_elems.indexOf(elem.tagName) >= 0) {
var bbox = getStrokedBBox([elem]);
- var diff_x = attr == 'x' ? newValue - bbox.x : 0;
- var diff_y = attr == 'y' ? newValue - bbox.y : 0;
+ var diff_x = attr === 'x' ? newValue - bbox.x : 0;
+ var diff_y = attr === 'y' ? newValue - bbox.y : 0;
canvas.moveSelectedElements(diff_x*current_zoom, diff_y*current_zoom, true);
continue;
}
- // only allow the transform/opacity attribute to change on elements, slightly hacky
- if (elem.tagName == "g" && ['transform', 'opacity', 'filter'].indexOf(attr) >= 0);
- var oldval = attr == "#text" ? elem.textContent : elem.getAttribute(attr);
+ // only allow the transform/opacity/filter attribute to change on elements, slightly hacky
+ if (elem.tagName === "g" && good_g_attrs.indexOf(attr) >= 0);
+ var oldval = attr === "#text" ? elem.textContent : elem.getAttribute(attr);
if (oldval == null) oldval = "";
- if (oldval != String(newValue)) {
+ if (oldval !== String(newValue)) {
if (attr == "#text") {
var old_w = getBBox(elem).width;
elem.textContent = newValue;
@@ -11332,10 +11400,18 @@ function disableAdvancedTextEdit() {
var rect = document.createElementNS(svgns,'rect');
rect.setAttribute('width',"1em");
rect.setAttribute('height',"1ex");
+ rect.setAttribute('x',"1in");
svgcontent.appendChild(rect);
var bb = rect.getBBox();
unit_types.em = bb.width;
unit_types.ex = bb.height;
+ var inch = bb.x;
+ unit_types['in'] = inch;
+ unit_types.cm = inch / 2.54;
+ unit_types.mm = inch / 25.4;
+ unit_types.pt = inch / 72;
+ unit_types.pc = inch / 6;
+ unit_types['%'] = 0;
svgcontent.removeChild(rect);
}());