Sync with SVG-edit
This commit is contained in:
parent
de3008d3e4
commit
bad5beec29
|
@ -127,7 +127,7 @@
|
|||
{"id": "tool_zoom", "title": "ज़ूम उपकरण"},
|
||||
{"id": "zoom", "title": "बदलें स्तर ज़ूम"},
|
||||
{"id": "zoomLabel", "textContent": "जूम:"},
|
||||
{"id": "sidepanel_handle", "textContent": "परतें", "title": "दायें/बाएं घसीट कर आकार बदलें"},
|
||||
{"id": "sidepanel_handle","textContent":"प र तें","title":"दायें/बाएं घसीट कर आकार बदलें"},
|
||||
{
|
||||
"js_strings": {
|
||||
"QerrorsRevertToSource": "आपके एस.वी.जी. स्रोत में त्रुटियों थी.\nक्या आप मूल एस.वी.जी स्रोत पर वापिस जाना चाहते हैं?",
|
||||
|
|
|
@ -87,12 +87,12 @@
|
|||
{"id":"tool_aligntop","title":"頂端對齊"},
|
||||
{"id":"tool_bold","title":"粗體"},
|
||||
{"id":"tool_circle","title":"圓"},
|
||||
{"id":"tool_clear","title":"清空圖像"},
|
||||
{"id":"tool_clear","textContent":"清空圖像"},
|
||||
{"id":"tool_clone","title":"複製"},
|
||||
{"id":"tool_clone_multi","title":"複製所選元素"},
|
||||
{"id":"tool_delete","title":"刪除"},
|
||||
{"id":"tool_delete_multi","title":"刪除所選元素"},
|
||||
{"id":"tool_docprops","title":"文件屬性"},
|
||||
{"id":"tool_docprops","textContent":"文件屬性"},
|
||||
{"id":"tool_docprops_cancel","textContent":"取消"},
|
||||
{"id":"tool_docprops_save","textContent":"保存"},
|
||||
{"id":"tool_ellipse","title":"橢圓"},
|
||||
|
@ -108,12 +108,12 @@
|
|||
{"id":"tool_node_clone","title":"增加節點"},
|
||||
{"id":"tool_node_delete","title":"刪除節點"},
|
||||
{"id":"tool_node_link","title":"將控制點連起來"},
|
||||
{"id":"tool_open","title":"打開圖像"},
|
||||
{"id":"tool_open","textContent":"打開圖像"},
|
||||
{"id":"tool_path","title":"路徑工具"},
|
||||
{"id":"tool_rect","title":"矩形"},
|
||||
{"id":"tool_redo","title":"復原"},
|
||||
{"id":"tool_reorient","title":"調整路徑"},
|
||||
{"id":"tool_save","title":"保存圖像"},
|
||||
{"id":"tool_save","textContent":"保存圖像"},
|
||||
{"id":"tool_select","title":"選擇工具"},
|
||||
{"id":"tool_source","title":"編輯SVG原始碼"},
|
||||
{"id":"tool_source_cancel","textContent":"取消"},
|
||||
|
@ -125,8 +125,6 @@
|
|||
{"id":"tool_ungroup","title":"取消群組"},
|
||||
{"id":"tool_wireframe","title":"框線模式(只瀏覽線條)"},
|
||||
{"id":"tool_zoom","title":"縮放工具"},
|
||||
{"id":"tools_ellipse_show","title":"橢圓/圓工具"},
|
||||
{"id":"tools_rect_show","title":"矩形/方形工具"},
|
||||
{"id":"zoom","title":"更改縮放級別"},
|
||||
{"id":"zoomLabel","textContent":"調整頁面大小:"},
|
||||
{"id":"sidepanel_handle","textContent":"圖層","title":"拖拉以改變側邊面板的大小"},
|
||||
|
|
|
@ -179,7 +179,6 @@ function svg_edit_setup() {
|
|||
// https://bugzilla.mozilla.org/show_bug.cgi?id=308590
|
||||
var saveHandler = function(window,svg) {
|
||||
window.opener.postMessage(svg, window.location.protocol + '//' + window.location.host);
|
||||
// window.open("data:image/svg+xml;base64," + Utils.encode64(svg));
|
||||
};
|
||||
|
||||
// called when we've selected a different element
|
||||
|
@ -383,12 +382,23 @@ function svg_edit_setup() {
|
|||
}
|
||||
|
||||
var extAdded = function(window, ext) {
|
||||
if("buttons" in ext) {
|
||||
|
||||
var cb_called = false;
|
||||
|
||||
var runCallback = function() {
|
||||
if(ext.callback && !cb_called) {
|
||||
cb_called = true;
|
||||
ext.callback();
|
||||
}
|
||||
}
|
||||
|
||||
if(ext.buttons) {
|
||||
var fallback_obj = {},
|
||||
placement_obj = {},
|
||||
svgicons = ext.svgicons;
|
||||
|
||||
var holders = {};
|
||||
|
||||
|
||||
// Add buttons given by extension
|
||||
$.each(ext.buttons, function(i, btn) {
|
||||
|
@ -515,10 +525,70 @@ function svg_edit_setup() {
|
|||
setIconSize('m');
|
||||
setIconSize(old);
|
||||
}
|
||||
runCallback();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
if(ext.context_tools) {
|
||||
$.each(ext.context_tools, function(i, tool) {
|
||||
// Add select tool
|
||||
var cont_id = tool.container_id?(' id="' + tool.container_id + '"'):"";
|
||||
|
||||
var panel = $('#' + tool.panel);
|
||||
|
||||
if(!panel.length) {
|
||||
panel = $('<div>', {id: tool.panel}).appendTo("#tools_top");
|
||||
}
|
||||
|
||||
// TODO: Allow support for other types, or adding to existing tool
|
||||
switch (tool.type) {
|
||||
case 'select':
|
||||
var html = '<label' + cont_id + '>'
|
||||
+ '<select id="' + tool.id + '">';
|
||||
$.each(tool.options, function(val, text) {
|
||||
var sel = (val == tool.defval) ? " selected":"";
|
||||
html += '<option value="'+val+'"' + sel + '>' + text + '</option>';
|
||||
});
|
||||
html += "</select></label>";
|
||||
// Creates the tool, hides & adds it, returns the select element
|
||||
var sel = $(html).appendTo(panel).find('select');
|
||||
|
||||
$.each(tool.events, function(evt, func) {
|
||||
$(sel).bind(evt, func);
|
||||
});
|
||||
break;
|
||||
|
||||
case 'input':
|
||||
var html = '<label' + cont_id + '">'
|
||||
+ '<span id="' + tool.id + '_label">'
|
||||
+ tool.label + ':</span>'
|
||||
+ '<input id="' + tool.id + '" title="' + tool.title
|
||||
+ '" size="' + (tool.size || "4") + '" value="' + (tool.defval || "") + '" type="text"/></label>'
|
||||
|
||||
// Creates the tool, hides & adds it, returns the select element
|
||||
|
||||
// Add to given tool.panel
|
||||
var inp = $(html).appendTo(panel).find('input');
|
||||
|
||||
if(tool.spindata) {
|
||||
inp.SpinButton(tool.spindata);
|
||||
}
|
||||
|
||||
if(tool.events) {
|
||||
$.each(tool.events, function(evt, func) {
|
||||
$(sel).bind(evt, func);
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
runCallback();
|
||||
};
|
||||
|
||||
var getPaint = function(color, opac) {
|
||||
|
@ -1865,7 +1935,7 @@ function svg_edit_setup() {
|
|||
var bNoFill = (svgCanvas.getFillColor() == 'none');
|
||||
var bNoStroke = (svgCanvas.getStrokeColor() == 'none');
|
||||
var buttonsNeedingStroke = [ '#tool_fhpath', '#tool_line' ];
|
||||
var buttonsNeedingFillAndStroke = [ '#tools_rect .tool_button', '#tools_ellipse .tool_button', '#tool_text' ];
|
||||
var buttonsNeedingFillAndStroke = [ '#tools_rect .tool_button', '#tools_ellipse .tool_button', '#tool_text', '#tool_path'];
|
||||
if (bNoStroke) {
|
||||
for (index in buttonsNeedingStroke) {
|
||||
var button = buttonsNeedingStroke[index];
|
||||
|
@ -2634,7 +2704,7 @@ function svg_edit_setup() {
|
|||
updateCanvas(true);
|
||||
});
|
||||
|
||||
// var revnums = "svg-editor.js ($Rev: 1342 $) ";
|
||||
// var revnums = "svg-editor.js ($Rev: 1347 $) ";
|
||||
// revnums += svgCanvas.getVersion();
|
||||
// $('#copyright')[0].setAttribute("title", revnums);
|
||||
return svgCanvas;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* svgcanvas.js
|
||||
*
|
||||
* Licensed under the Apache License, Version 2
|
||||
|
@ -984,27 +984,6 @@ function BatchCommand(text) {
|
|||
return result;
|
||||
}
|
||||
|
||||
this.addExtension = function(name, ext_func) {
|
||||
if(!(name in extensions)) {
|
||||
// Provide constants here (or should these be accessed through getSomething()?
|
||||
var ext = ext_func({
|
||||
content: svgcontent,
|
||||
root: svgroot,
|
||||
call: call,
|
||||
getNextId: getNextId,
|
||||
getElem: getElem,
|
||||
addSvgElementFromJson: addSvgElementFromJson,
|
||||
selectorManager: selectorManager,
|
||||
findDefs: findDefs,
|
||||
recalculateDimensions: recalculateDimensions
|
||||
});
|
||||
extensions[name] = ext;
|
||||
call("extension_added", ext);
|
||||
} else {
|
||||
console.log('Cannot add extension "' + name + '", an extension by that name already exists"');
|
||||
}
|
||||
};
|
||||
|
||||
// This method rounds the incoming value to the nearest value based on the current_zoom
|
||||
var round = function(val){
|
||||
return parseInt(val*current_zoom)/current_zoom;
|
||||
|
@ -2322,6 +2301,51 @@ function BatchCommand(text) {
|
|||
return (m.a == 1 && m.b == 0 && m.c == 0 && m.d == 1 && m.e == 0 && m.f == 0);
|
||||
}
|
||||
|
||||
// expects three points to be sent, each point must have an x,y field
|
||||
// returns an array of two points that are the smoothed
|
||||
this.smoothControlPoints = function(ct1, ct2, pt) {
|
||||
// each point must not be the origin
|
||||
var x1 = ct1.x - pt.x,
|
||||
y1 = ct1.y - pt.y,
|
||||
x2 = ct2.x - pt.x,
|
||||
y2 = ct2.y - pt.y;
|
||||
|
||||
if ( (x1 != 0 || y1 != 0) && (x2 != 0 || y2 != 0) ) {
|
||||
var anglea = Math.atan2(y1,x1),
|
||||
angleb = Math.atan2(y2,x2),
|
||||
r1 = Math.sqrt(x1*x1+y1*y1),
|
||||
r2 = Math.sqrt(x2*x2+y2*y2),
|
||||
nct1 = svgroot.createSVGPoint(),
|
||||
nct2 = svgroot.createSVGPoint();
|
||||
if (anglea < 0) { anglea += 2*Math.PI; }
|
||||
if (angleb < 0) { angleb += 2*Math.PI; }
|
||||
|
||||
var angleBetween = Math.abs(anglea - angleb),
|
||||
angleDiff = Math.abs(Math.PI - angleBetween)/2;
|
||||
|
||||
var new_anglea, new_angleb;
|
||||
if (anglea - angleb > 0) {
|
||||
new_anglea = angleBetween < Math.PI ? (anglea + angleDiff) : (anglea - angleDiff);
|
||||
new_angleb = angleBetween < Math.PI ? (angleb - angleDiff) : (angleb + angleDiff);
|
||||
}
|
||||
else {
|
||||
new_anglea = angleBetween < Math.PI ? (anglea - angleDiff) : (anglea + angleDiff);
|
||||
new_angleb = angleBetween < Math.PI ? (angleb + angleDiff) : (angleb - angleDiff);
|
||||
}
|
||||
|
||||
// rotate the points
|
||||
nct1.x = r1 * Math.cos(new_anglea) + pt.x;
|
||||
nct1.y = r1 * Math.sin(new_anglea) + pt.y;
|
||||
nct2.x = r2 * Math.cos(new_angleb) + pt.x;
|
||||
nct2.y = r2 * Math.sin(new_angleb) + pt.y;
|
||||
|
||||
return [nct1, nct2];
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
var smoothControlPoints = this.smoothControlPoints;
|
||||
|
||||
|
||||
// matrixMultiply() is provided because WebKit didn't implement multiply() correctly
|
||||
// on the SVGMatrix interface. See https://bugs.webkit.org/show_bug.cgi?id=16062
|
||||
// This function tries to return a SVGMatrix that is the multiplication m1*m2.
|
||||
|
@ -3521,6 +3545,18 @@ function BatchCommand(text) {
|
|||
var N = points.numberOfItems;
|
||||
if (N >= 4) {
|
||||
// loop through every 3 points and convert to a cubic bezier curve segment
|
||||
//
|
||||
// NOTE: this is cheating, it means that every 3 points has the potential to
|
||||
// be a corner instead of treating each point in an equal manner. In general,
|
||||
// this technique does not look that good.
|
||||
//
|
||||
// I am open to better ideas!
|
||||
//
|
||||
// Reading:
|
||||
// - http://www.efg2.com/Lab/Graphics/Jean-YvesQueinecBezierCurves.htm
|
||||
// - http://www.codeproject.com/KB/graphics/BezierSpline.aspx?msg=2956963
|
||||
// - http://www.ian-ko.com/ET_GeoWizards/UserGuide/smooth.htm
|
||||
// - http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/Bezier/bezier-der.html
|
||||
var curpos = points.getItem(0), prevCtlPt = null;
|
||||
var d = [];
|
||||
d.push(["M",curpos.x,",",curpos.y," C"].join(""));
|
||||
|
@ -3532,7 +3568,14 @@ function BatchCommand(text) {
|
|||
// if the previous segment had a control point, we want to smooth out
|
||||
// the control points on both sides
|
||||
if (prevCtlPt) {
|
||||
// TODO: fancy processing here :)
|
||||
var newpts = smoothControlPoints( prevCtlPt, ct1, curpos );
|
||||
if (newpts && newpts.length == 2) {
|
||||
var prevArr = d[d.length-1].split(',');
|
||||
prevArr[2] = newpts[0].x;
|
||||
prevArr[3] = newpts[0].y;
|
||||
d[d.length-1] = prevArr.join(',');
|
||||
ct1 = newpts[1];
|
||||
}
|
||||
}
|
||||
|
||||
d.push([ct1.x,ct1.y,ct2.x,ct2.y,end.x,end.y].join(','));
|
||||
|
@ -6549,6 +6592,9 @@ function BatchCommand(text) {
|
|||
// selector if the element is in that array
|
||||
if ($.inArray(elem, selectedElements) != -1) {
|
||||
setTimeout(function() {
|
||||
// Due to element replacement, this element may no longer
|
||||
// be part of the DOM
|
||||
if(!elem.parentNode) return;
|
||||
selectorManager.requestSelector(elem).resize();
|
||||
},0);
|
||||
}
|
||||
|
@ -7391,7 +7437,7 @@ function BatchCommand(text) {
|
|||
// Function: getVersion
|
||||
// Returns a string which describes the revision number of SvgCanvas.
|
||||
this.getVersion = function() {
|
||||
return "svgcanvas.js ($Rev: 1341 $)";
|
||||
return "svgcanvas.js ($Rev: 1349 $)";
|
||||
};
|
||||
|
||||
this.setUiStrings = function(strs) {
|
||||
|
@ -7426,6 +7472,78 @@ function BatchCommand(text) {
|
|||
// return svgdoc.getElementById(id);
|
||||
}
|
||||
|
||||
// Being able to access private methods publicly seems wrong somehow,
|
||||
// but currently appears to be the best way to allow testing and provide
|
||||
// access to them to plugins.
|
||||
this.getPrivateMethods = function() {
|
||||
return {
|
||||
addCommandToHistory: addCommandToHistory,
|
||||
addGradient: addGradient,
|
||||
addSvgElementFromJson: addSvgElementFromJson,
|
||||
assignAttributes: assignAttributes,
|
||||
BatchCommand: BatchCommand,
|
||||
call: call,
|
||||
ChangeElementCommand: ChangeElementCommand,
|
||||
cleanupElement: cleanupElement,
|
||||
copyElem: copyElem,
|
||||
ffClone: ffClone,
|
||||
findDefs: findDefs,
|
||||
findDuplicateGradient: findDuplicateGradient,
|
||||
fromXml: fromXml,
|
||||
getElem: getElem,
|
||||
getId: getId,
|
||||
getIntersectionList: getIntersectionList,
|
||||
getNextId: getNextId,
|
||||
getPathBBox: getPathBBox,
|
||||
getUrlFromAttr: getUrlFromAttr,
|
||||
hasMatrixTransform: hasMatrixTransform,
|
||||
identifyLayers: identifyLayers,
|
||||
InsertElementCommand: InsertElementCommand,
|
||||
isIdentity: isIdentity,
|
||||
logMatrix: logMatrix,
|
||||
matrixMultiply: matrixMultiply,
|
||||
MoveElementCommand: MoveElementCommand,
|
||||
preventClickDefault: preventClickDefault,
|
||||
recalculateAllSelectedDimensions: recalculateAllSelectedDimensions,
|
||||
recalculateDimensions: recalculateDimensions,
|
||||
remapElement: remapElement,
|
||||
RemoveElementCommand: RemoveElementCommand,
|
||||
removeUnusedGrads: removeUnusedGrads,
|
||||
resetUndoStack: resetUndoStack,
|
||||
round: round,
|
||||
runExtensions: runExtensions,
|
||||
sanitizeSvg: sanitizeSvg,
|
||||
Selector: Selector,
|
||||
SelectorManager: SelectorManager,
|
||||
shortFloat: shortFloat,
|
||||
svgCanvasToString: svgCanvasToString,
|
||||
SVGEditTransformList: SVGEditTransformList,
|
||||
svgToString: svgToString,
|
||||
toString: toString,
|
||||
toXml: toXml,
|
||||
transformBox: transformBox,
|
||||
transformListToTransform: transformListToTransform,
|
||||
transformPoint: transformPoint,
|
||||
transformToObj: transformToObj,
|
||||
walkTree: walkTree
|
||||
}
|
||||
}
|
||||
|
||||
this.addExtension = function(name, ext_func) {
|
||||
if(!(name in extensions)) {
|
||||
// Provide private vars/funcs here. Is there a better way to do this?
|
||||
var ext = ext_func($.extend(canvas.getPrivateMethods(), {
|
||||
svgroot: svgroot,
|
||||
svgcontent: svgcontent,
|
||||
selectorManager: selectorManager
|
||||
}));
|
||||
extensions[name] = ext;
|
||||
call("extension_added", ext);
|
||||
} else {
|
||||
console.log('Cannot add extension "' + name + '", an extension by that name already exists"');
|
||||
}
|
||||
};
|
||||
|
||||
// Test support for features/bugs
|
||||
(function() {
|
||||
// segList functions (for FF1.5 and 2.0)
|
||||
|
|
|
@ -9,8 +9,7 @@
|
|||
|
||||
$(function() {
|
||||
svgCanvas.addExtension("Arrows", function(S) {
|
||||
var svgcontent = S.content,
|
||||
getElem = S.getElem,
|
||||
var svgcontent = S.svgcontent,
|
||||
addElem = S.addSvgElementFromJson,
|
||||
selElems;
|
||||
|
||||
|
@ -64,7 +63,7 @@ $(function() {
|
|||
|
||||
function addMarker(id, type) {
|
||||
// TODO: Make marker (or use?) per arrow type, since refX can be different
|
||||
var marker = getElem(id);
|
||||
var marker = S.getElem(id);
|
||||
|
||||
var pathdata = {
|
||||
se_arrow_fw: {d:"m0,0l10,5l-10,5l5,-5l-5,-5z", refx:8},
|
||||
|
@ -104,7 +103,8 @@ $(function() {
|
|||
marker.setAttribute('refX', data.refx);
|
||||
}
|
||||
|
||||
function setArrow(type) {
|
||||
function setArrow() {
|
||||
var type = this.value;
|
||||
resetMarker();
|
||||
|
||||
if(type == "none") {
|
||||
|
@ -114,7 +114,6 @@ $(function() {
|
|||
var fw_id = "se_arrow_fw";
|
||||
var bk_id = "se_arrow_bk";
|
||||
|
||||
|
||||
// Set marker on element
|
||||
var id = fw_id;
|
||||
if(type == "mid_bk") {
|
||||
|
@ -134,24 +133,29 @@ $(function() {
|
|||
S.call("changed", selElems);
|
||||
}
|
||||
|
||||
// Init code
|
||||
(function() {
|
||||
var conn_tools = $('<div id="arrow_panel">\
|
||||
<label><select id="arrow_list">\
|
||||
<option value="none">No arrow</option>\
|
||||
<option value="end">----></option>\
|
||||
<option value="start"><----</option>\
|
||||
<option value="both"><---></option>\
|
||||
<option value="mid">-->--</option>\
|
||||
<option value="mid_bk">--<--</option>\
|
||||
</select></label></div>"').hide().appendTo("#tools_top");
|
||||
$('#arrow_list').change(function() {
|
||||
setArrow(this.value);
|
||||
});
|
||||
}());
|
||||
|
||||
return {
|
||||
name: "Arrows",
|
||||
context_tools: [{
|
||||
type: "select",
|
||||
panel: "arrow_panel",
|
||||
title: "Select arrow type",
|
||||
id: "arrow_list",
|
||||
options: {
|
||||
none: "No arrow",
|
||||
end: "---->",
|
||||
start: "<----",
|
||||
both: "<--->",
|
||||
mid: "-->--",
|
||||
mid_bk: "--<--"
|
||||
},
|
||||
defval: "none",
|
||||
events: {
|
||||
change: setArrow
|
||||
}
|
||||
}],
|
||||
callback: function() {
|
||||
$('#arrow_panel').hide();
|
||||
},
|
||||
addLangData: function(lang) {
|
||||
return {
|
||||
data: lang_list[lang]
|
||||
|
@ -180,4 +184,4 @@ $(function() {
|
|||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
|
||||
$(function() {
|
||||
svgCanvas.addExtension("Connector", function(S) {
|
||||
var svgcontent = S.content,
|
||||
svgroot = S.root,
|
||||
var svgcontent = S.svgcontent,
|
||||
svgroot = S.svgroot,
|
||||
getNextId = S.getNextId,
|
||||
getElem = S.getElem,
|
||||
addElem = S.addSvgElementFromJson,
|
||||
|
@ -104,14 +104,29 @@ $(function() {
|
|||
svgCanvas.removeFromSelection($(conn_sel).toArray());
|
||||
}
|
||||
|
||||
// Loop through selected elements
|
||||
while(i--) {
|
||||
var elem = all_els[i];
|
||||
if(!elem) continue;
|
||||
|
||||
// Element was deleted, so delete connector
|
||||
var was_deleted = !elem.parentNode;
|
||||
|
||||
// Skip connector
|
||||
if($(elem).data('c_start')) continue;
|
||||
|
||||
// Loop through connectors to see if one is connected to the element
|
||||
connectors.each(function() {
|
||||
var start = $(this).data("c_start");
|
||||
var end = $(this).data("c_end");
|
||||
|
||||
// Connector found for this element
|
||||
if(start == elem.id || end == elem.id) {
|
||||
|
||||
if(was_deleted) {
|
||||
$(this).remove();
|
||||
return;
|
||||
}
|
||||
var bb = svgCanvas.getStrokedBBox([elem]);
|
||||
connections.push({
|
||||
elem: elem,
|
||||
|
@ -138,8 +153,8 @@ $(function() {
|
|||
var line = conn.connector;
|
||||
var elem = conn.elem;
|
||||
|
||||
var pre = conn.is_start?'start':'end';
|
||||
var sw = line.getAttribute('stroke-width');
|
||||
var pre = conn.is_start?'start':'end';
|
||||
|
||||
// Update bbox for this element
|
||||
var bb = svgCanvas.getStrokedBBox([elem]);
|
||||
|
@ -458,6 +473,7 @@ $(function() {
|
|||
se_ns = svgCanvas.getEditorNS(true);
|
||||
cur_line.setAttributeNS(se_ns, "se:connector", conn_str);
|
||||
cur_line.setAttribute('class', conn_sel.substr(1));
|
||||
cur_line.setAttribute('opacity', 1);
|
||||
svgCanvas.addToSelection([cur_line]);
|
||||
svgCanvas.moveToBottomSelectedElement();
|
||||
selManager.requestSelector(cur_line).showGrips(false);
|
||||
|
@ -507,11 +523,40 @@ $(function() {
|
|||
elem.getAttribute("marker-end")
|
||||
)) {
|
||||
var start = elem.getAttribute("marker-start");
|
||||
var mid = elem.getAttribute("marker-mid");
|
||||
var end = elem.getAttribute("marker-end");
|
||||
cur_line = elem;
|
||||
$(elem)
|
||||
.data("start_off", !!start)
|
||||
.data("end_off", !!end);
|
||||
|
||||
if(elem.tagName == "line" && mid) {
|
||||
// Convert to polyline to accept mid-arrow
|
||||
|
||||
var x1 = elem.getAttribute('x1')-0;
|
||||
var x2 = elem.getAttribute('x2')-0;
|
||||
var y1 = elem.getAttribute('y1')-0;
|
||||
var y2 = elem.getAttribute('y2')-0;
|
||||
var id = elem.id;
|
||||
|
||||
var mid_pt = (' '+((x1+x2)/2)+','+((y1+y2)/2) + ' ');
|
||||
var pline = addElem({
|
||||
"element": "polyline",
|
||||
"attr": {
|
||||
"points": (x1+','+y1+ mid_pt +x2+','+y2),
|
||||
"stroke": elem.getAttribute('stroke'),
|
||||
"stroke-width": elem.getAttribute('stroke-width'),
|
||||
"marker-mid": mid,
|
||||
"fill": "none",
|
||||
"opacity": elem.getAttribute('opacity') || 1
|
||||
}
|
||||
});
|
||||
$(elem).after(pline).remove();
|
||||
svgCanvas.clearSelection();
|
||||
pline.id = id;
|
||||
svgCanvas.addToSelection([pline]);
|
||||
}
|
||||
|
||||
}
|
||||
updateConnectors();
|
||||
},
|
||||
|
|
52
public/svg-edit/extras/tojson.py
Normal file
52
public/svg-edit/extras/tojson.py
Normal file
|
@ -0,0 +1,52 @@
|
|||
import sys, json, codecs
|
||||
infile = codecs.open(sys.argv[1], "r", "utf-8")
|
||||
outfile = codecs.open(sys.argv[1][:-3], "w", "utf-8")
|
||||
indata = infile.readlines()
|
||||
look = False
|
||||
out = "[\n"
|
||||
js = []
|
||||
jss = ""
|
||||
|
||||
def readfrompos(pos):
|
||||
global out
|
||||
global js
|
||||
|
||||
if (indata[pos].startswith("#, -x-svg-edit-title")) or (indata[pos].startswith("#, -x-svg-edit-textContent")):
|
||||
out += '{'
|
||||
out += '"id": '
|
||||
out += " ".join(indata[pos+1].split()[1:]) + ", "
|
||||
out += '"' + line[15:].strip() + '": '
|
||||
out += " ".join(indata[pos+2].split()[1:])
|
||||
out += '}'
|
||||
elif (indata[pos].startswith("#, -x-svg-edit-both")):
|
||||
out += '{'
|
||||
out += '"id": '
|
||||
out += " ".join(indata[pos+1].split()[1:]) + ", "
|
||||
out += '"textContent": '
|
||||
out += '"' + " ".join(indata[pos+2].split()[1:]).split('|')[1] + ', '
|
||||
out += '"title": '
|
||||
out += " ".join(indata[pos+2].split()[1:]).split('|')[0] + '"'
|
||||
out += '}'
|
||||
elif (indata[pos].startswith("#, -x-svg-edit-js_strings")):
|
||||
js.append((" ".join(indata[pos+1].split()[1:]), " ".join(indata[pos+2].split()[1:])))
|
||||
|
||||
for pos, line in enumerate(indata):
|
||||
if (not look) and (line.startswith('# ---')):
|
||||
look = True
|
||||
marker = pos
|
||||
elif (look) and (line.startswith('#, -x-svg-edit')):
|
||||
readfrompos(pos)
|
||||
|
||||
js.sort()
|
||||
|
||||
for j in js:
|
||||
jss += " %s: %s,\n" % (j[0], j[1])
|
||||
|
||||
out += '{\n "js_strings": {\n'
|
||||
out += str(jss)
|
||||
out += ' "": ""\n }'
|
||||
out += "\n}"
|
||||
out += "\n]"
|
||||
out = out.replace('}{', '},\n{')
|
||||
|
||||
outfile.write(out)
|
39
public/svg-edit/extras/topo.py
Normal file
39
public/svg-edit/extras/topo.py
Normal file
|
@ -0,0 +1,39 @@
|
|||
import sys, json, codecs
|
||||
infile = json.load(codecs.open(sys.argv[1], "r", "utf-8"))
|
||||
outfile = codecs.open(sys.argv[1] + ".po", "w", "utf-8")
|
||||
out = []
|
||||
|
||||
out.append("""# LANGUAGE FILE FOR SVG-EDIT, AUTOGENERATED BY TOPO.PY
|
||||
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Content-Type: text/plain; charset=utf-8\\n"
|
||||
"Content-Transfer-Encoding: 8bit\\n"
|
||||
|
||||
# ---
|
||||
|
||||
""")
|
||||
|
||||
def printstr(flag, i, s):
|
||||
out.append('\n')
|
||||
if flag == '-x-svg-edit-both':
|
||||
out.append("# Enter the title first, then the contents, seperated by a pipe char (|)\n")
|
||||
out.append("#, " + flag + '\n')
|
||||
out.append("msgid \"" + i + "\"" + '\n')
|
||||
out.append("msgstr \"" + s.replace('\n', '\\n') + "\"" + '\n')
|
||||
|
||||
for line in infile:
|
||||
if line.has_key('title') and line.has_key('textContent'):
|
||||
printstr('-x-svg-edit-both', line['id'], "|".join(((line['title'], line['textContent']))))
|
||||
elif line.has_key('title'):
|
||||
printstr('-x-svg-edit-title', line['id'], line['title'])
|
||||
elif line.has_key('textContent'):
|
||||
printstr('-x-svg-edit-textContent', line['id'], line['textContent'])
|
||||
elif line.has_key('js_strings'):
|
||||
for i, s in line['js_strings'].items():
|
||||
printstr('-x-svg-edit-js_strings', i, s)
|
||||
else:
|
||||
pass # The line wasn't really a string
|
||||
|
||||
outfile.writelines(out)
|
||||
outfile.close()
|
Loading…
Reference in a new issue