Some additional JSLint; update jsPDF and SVG plugin; handle canvg for image export within svgcanvas and provide new "datauri" to "exported" event.
git-svn-id: http://svg-edit.googlecode.com/svn/trunk@2875 eee81c28-f429-11dd-99c0-75d572ba1dddmaster
parent
c9544ce5bf
commit
6f7651299c
|
@ -2,6 +2,8 @@
|
||||||
/*jslint vars: true */
|
/*jslint vars: true */
|
||||||
var initEmbed;
|
var initEmbed;
|
||||||
|
|
||||||
|
// Todo: Get rid of frame.contentWindow dependencies so can be more easily adjusted to work cross-domain
|
||||||
|
|
||||||
$(function () {'use strict';
|
$(function () {'use strict';
|
||||||
|
|
||||||
var svgCanvas = null;
|
var svgCanvas = null;
|
||||||
|
@ -35,6 +37,7 @@ $(function () {'use strict';
|
||||||
|
|
||||||
function exportPNG() {
|
function exportPNG() {
|
||||||
var str = frame.contentWindow.svgEditor.uiStrings.notification.loadingImage;
|
var str = frame.contentWindow.svgEditor.uiStrings.notification.loadingImage;
|
||||||
|
|
||||||
var exportWindow = window.open(
|
var exportWindow = window.open(
|
||||||
'data:text/html;charset=utf-8,' + encodeURIComponent('<title>' + str + '</title><h1>' + str + '</h1>'),
|
'data:text/html;charset=utf-8,' + encodeURIComponent('<title>' + str + '</title><h1>' + str + '</h1>'),
|
||||||
'svg-edit-exportWindow'
|
'svg-edit-exportWindow'
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,72 +1,77 @@
|
||||||
|
/*globals RGBColor, DOMParser, jsPDF*/
|
||||||
|
/*jslint eqeq:true, vars:true*/
|
||||||
/*
|
/*
|
||||||
* svgToPdf.js
|
* svgToPdf.js
|
||||||
*
|
*
|
||||||
* Copyright 2012 Florian Hülsmann <fh@cbix.de>
|
* Copyright 2012-2014 Florian Hülsmann <fh@cbix.de>
|
||||||
* Updated in 2013 by Datascope Analytics <info@datascopeanalytics.com>
|
* Copyright 2014 Ben Gribaudo <www.bengribaudo.com>
|
||||||
|
*
|
||||||
* This script is free software: you can redistribute it and/or modify
|
* This script is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This script is distributed in the hope that it will be useful,
|
* This script is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Lesser General Public License for more details.
|
* GNU Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
* along with this file. If not, see <http://www.gnu.org/licenses/>.
|
* along with this file. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
(function(jsPDFAPI, undef) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
// These are all of the currently supported attributes of the svg elements
|
|
||||||
// that we are converting to PDF. The path is empty and taken care of in a
|
|
||||||
// different way below.
|
|
||||||
var pdfSvgAttr = {
|
var pdfSvgAttr = {
|
||||||
// allowed attributes. all others are removed from the preview.
|
// allowed attributes. all others are removed from the preview.
|
||||||
g: ['stroke', 'fill', 'stroke-width'],
|
g: ['stroke', 'fill', 'stroke-width'],
|
||||||
line: ['x1', 'y1', 'x2', 'y2', 'stroke', 'stroke-width', 'fill'],
|
line: ['x1', 'y1', 'x2', 'y2', 'stroke', 'stroke-width'],
|
||||||
rect: ['x', 'y', 'width', 'height', 'stroke', 'fill', 'stroke-width'],
|
rect: ['x', 'y', 'width', 'height', 'stroke', 'fill', 'stroke-width'],
|
||||||
ellipse: ['cx', 'cy', 'rx', 'ry', 'stroke', 'fill', 'stroke-width'],
|
ellipse: ['cx', 'cy', 'rx', 'ry', 'stroke', 'fill', 'stroke-width'],
|
||||||
circle: ['cx', 'cy', 'r', 'stroke', 'fill', 'stroke-width'],
|
circle: ['cx', 'cy', 'r', 'stroke', 'fill', 'stroke-width'],
|
||||||
text: ['x', 'y', 'font-size', 'font-family', 'text-anchor', 'font-weight', 'font-style', 'fill'],
|
text: ['x', 'y', 'font-size', 'font-family', 'text-anchor', 'font-weight', 'font-style', 'fill']
|
||||||
path: []
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var attributeIsNotEmpty = function (node, attr) {
|
||||||
|
var attVal = attr ? node.getAttribute(attr) : node;
|
||||||
|
return attVal !== '' && attVal !== null;
|
||||||
|
};
|
||||||
|
|
||||||
|
var nodeIs = function (node, possible) {
|
||||||
|
return possible.indexOf(node.tagName.toLowerCase()) > -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
var removeAttributes = function(node, attributes) {
|
||||||
|
var toRemove = [];
|
||||||
|
[].forEach.call(node.attributes, function(a) {
|
||||||
|
if (attributeIsNotEmpty(a) && attributes.indexOf(a.name.toLowerCase()) == -1) {
|
||||||
|
toRemove.push(a.name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
toRemove.forEach(function(a) {
|
||||||
|
node.removeAttribute(a.name);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
var svgElementToPdf = function(element, pdf, options) {
|
var svgElementToPdf = function(element, pdf, options) {
|
||||||
// pdf is a jsPDF object
|
// pdf is a jsPDF object
|
||||||
var remove = (typeof(options.removeInvalid) == 'undefined' ? remove = false : options.removeInvalid);
|
//console.log("options =", options);
|
||||||
var k = (typeof(options.removeInvalid) == 'undefined' ? 1.0 : options.scale);
|
var remove = (options.removeInvalid == undef ? false : options.removeInvalid);
|
||||||
|
var k = (options.scale == undef ? 1.0 : options.scale);
|
||||||
var x_offset = (typeof(options.x_offset) == 'undefined' ? 0 : options.x_offset);
|
|
||||||
var y_offset = (typeof(options.y_offset) == 'undefined' ? 0 : options.y_offset);
|
|
||||||
var ego_or_link = (typeof(options.ego_or_link) == 'undefined' ? false : options.ego_or_link);
|
|
||||||
var colorMode = null;
|
var colorMode = null;
|
||||||
$(element).children().each(function(i, node) {
|
[].forEach.call(element.children, function(node) {
|
||||||
var n = $(node);
|
//console.log("passing: ", node);
|
||||||
if (n.is("g")) {
|
|
||||||
if (n.attr('transform') != null) {
|
|
||||||
var matrix = n.attr('transform').replace(/,/g, ' ').replace('matrix(', '').replace(')', ' cm');
|
|
||||||
pdf.internal.write('q');
|
|
||||||
pdf.internal.write(matrix);
|
|
||||||
svgElementToPdf(n, pdf, options);
|
|
||||||
pdf.internal.write('Q');
|
|
||||||
} else {
|
|
||||||
svgElementToPdf(n, pdf, options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var hasFillColor = false;
|
var hasFillColor = false;
|
||||||
var hasStrokeColor = false;
|
var hasStrokeColor = false;
|
||||||
if (n.is('g,line,rect,ellipse,circle,text,path')) {
|
var fillRGB;
|
||||||
|
if(nodeIs(node, ['g', 'line', 'rect', 'ellipse', 'circle', 'text'])) {
|
||||||
var fillColor = n.attr('fill');
|
var fillColor = node.getAttribute('fill');
|
||||||
if (fillColor != null) {
|
if(attributeIsNotEmpty(fillColor)) {
|
||||||
var fillRGB = new RGBColor(fillColor);
|
fillRGB = new RGBColor(fillColor);
|
||||||
|
if(fillRGB.ok) {
|
||||||
if (fillRGB.ok) {
|
|
||||||
//console.log("fillRGB is okay");
|
|
||||||
hasFillColor = true;
|
hasFillColor = true;
|
||||||
colorMode = 'F';
|
colorMode = 'F';
|
||||||
} else {
|
} else {
|
||||||
|
@ -74,596 +79,149 @@ var svgElementToPdf = function(element, pdf, options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(nodeIs(node, ['g', 'line', 'rect', 'ellipse', 'circle'])) {
|
||||||
if (hasFillColor) {
|
if(hasFillColor) {
|
||||||
|
pdf.setFillColor(fillRGB.r, fillRGB.g, fillRGB.b);
|
||||||
pdf.setFillColor(fillRGB.r, fillRGB.g, fillRGB.b);
|
}
|
||||||
}
|
if(attributeIsNotEmpty(node, 'stroke-width')) {
|
||||||
|
pdf.setLineWidth(k * parseInt(node.getAttribute('stroke-width'), 10));
|
||||||
var strokeColor = n.attr('stroke');
|
}
|
||||||
if (strokeColor != null && strokeColor !== 'none') {
|
var strokeColor = node.getAttribute('stroke');
|
||||||
|
if(attributeIsNotEmpty(strokeColor)) {
|
||||||
var strokeRGB = new RGBColor(strokeColor);
|
var strokeRGB = new RGBColor(strokeColor);
|
||||||
if (strokeRGB.ok) {
|
if(strokeRGB.ok) {
|
||||||
hasStrokeColor = true;
|
hasStrokeColor = true;
|
||||||
|
pdf.setDrawColor(strokeRGB.r, strokeRGB.g, strokeRGB.b);
|
||||||
pdf.setDrawColor(strokeRGB.r, strokeRGB.g, strokeRGB.b);
|
if(colorMode == 'F') {
|
||||||
if (colorMode == 'F') {
|
colorMode = 'FD';
|
||||||
colorMode = 'FD';
|
} else {
|
||||||
|
colorMode = null;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
colorMode = null;
|
||||||
colorMode = "S";
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
|
|
||||||
colorMode = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (n.get(0).tagName.toLowerCase()) {
|
switch(node.tagName.toLowerCase()) {
|
||||||
|
case 'svg':
|
||||||
|
case 'a':
|
||||||
|
case 'g':
|
||||||
|
svgElementToPdf(node, pdf, options);
|
||||||
|
removeAttributes(node, pdfSvgAttr.g);
|
||||||
|
break;
|
||||||
case 'line':
|
case 'line':
|
||||||
pdf.line(
|
pdf.line(
|
||||||
k * parseInt(n.attr('x1')),
|
k*parseInt(node.getAttribute('x1'), 10),
|
||||||
k * parseInt(n.attr('y1')),
|
k*parseInt(node.getAttribute('y1'), 10),
|
||||||
k * parseInt(n.attr('x2')),
|
k*parseInt(node.getAttribute('x2'), 10),
|
||||||
k * parseInt(n.attr('y2')));
|
k*parseInt(node.getAttribute('y2'), 10)
|
||||||
|
);
|
||||||
// $.each(node.attributes, function(i, a) {
|
removeAttributes(node, pdfSvgAttr.line);
|
||||||
// if(a != null && pdfSvgAttr.line.indexOf(a.name.toLowerCase()) == -1) {
|
|
||||||
// node.removeAttribute(a.name);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
break;
|
break;
|
||||||
case 'rect':
|
case 'rect':
|
||||||
//console.log("in rectangle");
|
|
||||||
pdf.rect(
|
pdf.rect(
|
||||||
k * (parseInt(n.attr('x')) + x_offset),
|
k*parseInt(node.getAttribute('x'), 10),
|
||||||
k * (parseInt(n.attr('y')) + y_offset),
|
k*parseInt(node.getAttribute('y'), 10),
|
||||||
k * parseInt(n.attr('width')),
|
k*parseInt(node.getAttribute('width'), 10),
|
||||||
k * parseInt(n.attr('height')),
|
k*parseInt(node.getAttribute('height'), 10),
|
||||||
colorMode);
|
colorMode
|
||||||
// $.each(node.attributes, function(i, a) {
|
);
|
||||||
// if(a != null && pdfSvgAttr.rect.indexOf(a.name.toLowerCase()) == -1) {
|
removeAttributes(node, pdfSvgAttr.rect);
|
||||||
// node.removeAttribute(a.name);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
break;
|
break;
|
||||||
case 'ellipse':
|
case 'ellipse':
|
||||||
pdf.ellipse(
|
pdf.ellipse(
|
||||||
k * parseInt(n.attr('cx')),
|
k*parseInt(node.getAttribute('cx'), 10),
|
||||||
k * parseInt(n.attr('cy')),
|
k*parseInt(node.getAttribute('cy'), 10),
|
||||||
k * parseInt(n.attr('rx')),
|
k*parseInt(node.getAttribute('rx'), 10),
|
||||||
k * parseInt(n.attr('ry')),
|
k*parseInt(node.getAttribute('ry'), 10),
|
||||||
colorMode);
|
colorMode
|
||||||
// $.each(node.attributes, function(i, a) {
|
);
|
||||||
// if(a != null && pdfSvgAttr.ellipse.indexOf(a.name.toLowerCase()) == -1) {
|
removeAttributes(node, pdfSvgAttr.ellipse);
|
||||||
// node.removeAttribute(a.name);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
break;
|
break;
|
||||||
case 'circle':
|
case 'circle':
|
||||||
pdf.circle(
|
pdf.circle(
|
||||||
k * (parseInt(n.attr('cx')) + x_offset),
|
k*parseInt(node.getAttribute('cx'), 10),
|
||||||
k * (parseInt(n.attr('cy')) + y_offset),
|
k*parseInt(node.getAttribute('cy'), 10),
|
||||||
k * parseInt(n.attr('r')),
|
k*parseInt(node.getAttribute('r'), 10),
|
||||||
colorMode);
|
colorMode
|
||||||
// $.each(node.attributes, function(i, a) {
|
);
|
||||||
// if(a != null && pdfSvgAttr.circle.indexOf(a.name.toLowerCase()) == -1) {
|
removeAttributes(node, pdfSvgAttr.circle);
|
||||||
// node.removeAttribute(a.name);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
break;
|
break;
|
||||||
case 'text':
|
case 'text':
|
||||||
var fontFamily = 'helvetica';
|
if(node.hasAttribute('font-family')) {
|
||||||
if (node.hasAttribute('font-family')) {
|
switch((node.getAttribute('font-family') || '').toLowerCase()) {
|
||||||
|
case 'serif': pdf.setFont('times'); break;
|
||||||
switch (n.attr('font-family').toLowerCase().split(',')[0]) {
|
case 'monospace': pdf.setFont('courier'); break;
|
||||||
case 'times':
|
|
||||||
var fontFamily = 'times';
|
|
||||||
pdf.setFont('times');
|
|
||||||
break;
|
|
||||||
case 'courier':
|
|
||||||
var fontFamily = 'courier';
|
|
||||||
pdf.setFont('courier');
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
node.setAttribute('font-family', 'sans-serif');
|
||||||
pdf.setFont('helvetica');
|
pdf.setFont('helvetica');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(hasFillColor) {
|
||||||
// If no font family, we set the font to the times by default
|
pdf.setTextColor(fillRGB.r, fillRGB.g, fillRGB.b);
|
||||||
else {
|
|
||||||
pdf.setFont('helvetica');
|
|
||||||
}
|
}
|
||||||
|
var fontType = "";
|
||||||
// if (colorMode !== "FD" || colorMode !== 'F') {
|
if(node.hasAttribute('font-weight')) {
|
||||||
// console.log("I'm setting text color");
|
if(node.getAttribute('font-weight') == "bold") {
|
||||||
// pdf.setTextColor(fillRGB.r, fillRGB.g, fillRGB.b);
|
|
||||||
// }
|
|
||||||
|
|
||||||
var fontType = "normal";
|
|
||||||
if (node.hasAttribute('font-weight')) {
|
|
||||||
if (n.attr('font-weight') == "bold") {
|
|
||||||
fontType = "bold";
|
fontType = "bold";
|
||||||
} else {
|
} else {
|
||||||
node.removeAttribute('font-weight');
|
node.removeAttribute('font-weight');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(node.hasAttribute('font-style')) {
|
||||||
if (node.hasAttribute('font-style')) {
|
if(node.getAttribute('font-style') == "italic") {
|
||||||
if (n.attr('font-style') == "italic") {
|
|
||||||
fontType += "italic";
|
fontType += "italic";
|
||||||
} else {
|
} else {
|
||||||
node.removeAttribute('font-style');
|
node.removeAttribute('font-style');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pdf.setFontType(fontType);
|
pdf.setFontType(fontType);
|
||||||
var pdfFontSize = 9;
|
var pdfFontSize = 16;
|
||||||
if (node.hasAttribute('font-size')) {
|
if(node.hasAttribute('font-size')) {
|
||||||
pdfFontSize = parseInt(n.attr('font-size'));
|
pdfFontSize = parseInt(node.getAttribute('font-size'), 10);
|
||||||
}
|
}
|
||||||
|
var box = node.getBBox();
|
||||||
var fontMetrics = pdf.internal.getFont(fontFamily, fontType)
|
|
||||||
.metadata.Unicode;
|
|
||||||
|
|
||||||
var text_value = n.text();
|
|
||||||
var name_length = pdf.getStringUnitWidth(
|
|
||||||
text_value,
|
|
||||||
fontMetrics) * pdfFontSize;
|
|
||||||
|
|
||||||
|
|
||||||
//FIXME: use more accurate positioning!!
|
//FIXME: use more accurate positioning!!
|
||||||
var label_offset = 0;
|
var x, y, xOffset = 0;
|
||||||
var x = parseInt(n.attr('x')) + x_offset - label_offset;
|
if(node.hasAttribute('text-anchor')) {
|
||||||
var y = parseInt(n.attr('y')) + y_offset;
|
switch(node.getAttribute('text-anchor')) {
|
||||||
|
case 'end': xOffset = box.width; break;
|
||||||
|
case 'middle': xOffset = box.width / 2; break;
|
||||||
|
case 'start': break;
|
||||||
if (node.hasAttribute('text-anchor')) {
|
case 'default': node.setAttribute('text-anchor', 'start'); break;
|
||||||
switch (n.attr('text-anchor')) {
|
|
||||||
case 'end':
|
|
||||||
break;
|
|
||||||
case 'middle':
|
|
||||||
label_offset = name_length / 2;
|
|
||||||
break;
|
|
||||||
case 'start':
|
|
||||||
label_offset = 0;
|
|
||||||
break;
|
|
||||||
case 'default':
|
|
||||||
label_offset = 0;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
x = parseInt(n.attr('x')) + x_offset - label_offset;
|
x = parseInt(node.getAttribute('x'), 10) - xOffset;
|
||||||
y = parseInt(n.attr('y')) + y_offset;
|
y = parseInt(node.getAttribute('y'), 10);
|
||||||
}
|
}
|
||||||
|
//console.log("fontSize:", pdfFontSize, "text:", node.textContent);
|
||||||
|
|
||||||
|
|
||||||
pdf.setFontSize(pdfFontSize).text(
|
pdf.setFontSize(pdfFontSize).text(
|
||||||
k * x,
|
k * x,
|
||||||
k * y,
|
k * y,
|
||||||
text_value);
|
node.textContent
|
||||||
// $.each(node.attributes, function(i, a) {
|
);
|
||||||
// if(a != null && pdfSvgAttr.text.indexOf(a.name.toLowerCase()) == -1) {
|
removeAttributes(node, pdfSvgAttr.text);
|
||||||
// node.removeAttribute(a.name);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
break;
|
break;
|
||||||
case 'path':
|
//TODO: image
|
||||||
// //console.log("node is: ",node.attributes)
|
|
||||||
// $.each(node.attributes, function(i, a) {
|
|
||||||
// //console.log(pdfSvgAttr.path.indexOf(a.name.toLowerCase()));
|
|
||||||
// });
|
|
||||||
|
|
||||||
var updated_path = n.attr('d');
|
|
||||||
// Separate the svg 'd' string to a list of letter
|
|
||||||
// and number elements. Iterate on this list.
|
|
||||||
// console.log('path before',path);
|
|
||||||
svg_regex = /(m|l|h|v|c|s|a|z)/gi;
|
|
||||||
// console.log('TESTING REGULAR
|
|
||||||
// EXPRESSION',svg_regex.test('m')); The crazy ie9 case
|
|
||||||
// where they take our path and make some crazy scientific
|
|
||||||
// notation
|
|
||||||
updated_path = updated_path.replace(/(e)?-/g, function($0, $1) {
|
|
||||||
return $1 ? $0 : ' -';
|
|
||||||
})
|
|
||||||
// .replace(/-/g, ' -')
|
|
||||||
.replace(svg_regex, ' $1 ')
|
|
||||||
.replace(/,+/g, ' ')
|
|
||||||
.replace(/^\s+|\s+$/g, '')
|
|
||||||
.split(/[\s]+/);
|
|
||||||
|
|
||||||
var svg_element = null;
|
|
||||||
var i = 0;
|
|
||||||
|
|
||||||
// mx and my will define the starting points from each m/M case
|
|
||||||
var mx = null;
|
|
||||||
var my = null;
|
|
||||||
// x and y will redefine the starting points
|
|
||||||
var x = null;
|
|
||||||
var y = null;
|
|
||||||
|
|
||||||
// big list contains the large list of lists to pass to
|
|
||||||
// jspdf to render the appropriate path
|
|
||||||
var big_list = [];
|
|
||||||
|
|
||||||
// for S/s shorthand bezier calculations of 2nd control pts
|
|
||||||
var previous_element = {
|
|
||||||
element: null,
|
|
||||||
prev_numbers: [],
|
|
||||||
point: []
|
|
||||||
};
|
|
||||||
var m_flag = 0;
|
|
||||||
// Go through our list until we are done with the updated_path
|
|
||||||
while (i < updated_path.length) {
|
|
||||||
|
|
||||||
// Numbers will hold the list of numbers for the
|
|
||||||
// appropriate updated_path
|
|
||||||
var numbers = [];
|
|
||||||
|
|
||||||
// svg_element is a letter corresponding to the type
|
|
||||||
// of updated_path to draw
|
|
||||||
var sci_regex = /[+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?/;
|
|
||||||
var svg_element = updated_path[i];
|
|
||||||
if (sci_regex.test(svg_element)) {
|
|
||||||
svg_element = String(Number(svg_element));
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
//if svg_element is s/S, need to find 1st control pts
|
|
||||||
if (/s/i.test(svg_element)) {
|
|
||||||
previous_element.point = find_s_points(svg_element,
|
|
||||||
previous_element);
|
|
||||||
}
|
|
||||||
|
|
||||||
// for some reason z followed by another letter
|
|
||||||
// i.e. 'z m' skips that 2nd letter, so added if
|
|
||||||
// statement to get around that.
|
|
||||||
if (/z/i.test(svg_element) == false) {
|
|
||||||
|
|
||||||
// Parse through the updated_path until we find the next
|
|
||||||
// letter or we are at the end of the updated_path
|
|
||||||
while ((svg_regex.test(updated_path[i]) == false) && (i != updated_path.length)) {
|
|
||||||
numbers.push(k * parseFloat(updated_path[i]));
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
switch (svg_element) {
|
|
||||||
case 'm':
|
|
||||||
//paths and subpaths must always start with m/M.
|
|
||||||
//thus we call pdf.lines
|
|
||||||
if (big_list.length != 0) {
|
|
||||||
pdf.lines(big_list, mx, my, [1, 1], null);
|
|
||||||
}
|
|
||||||
big_list = [];
|
|
||||||
|
|
||||||
// check if this is 1st command in the path
|
|
||||||
if (previous_element.element == null) {
|
|
||||||
x = numbers[0];
|
|
||||||
mx = numbers[0];
|
|
||||||
y = numbers[1];
|
|
||||||
my = numbers[1];
|
|
||||||
} else {
|
|
||||||
x += numbers[0];
|
|
||||||
mx += numbers[0];
|
|
||||||
y += numbers[1];
|
|
||||||
my += numbers[1];
|
|
||||||
}
|
|
||||||
if (numbers.length != 2) {
|
|
||||||
var lines_numbers = numbers.slice(2, numbers.length);
|
|
||||||
|
|
||||||
var new_numbers = change_numbers(lines_numbers,
|
|
||||||
x, y, true);
|
|
||||||
_.each(new_numbers, function(num) {
|
|
||||||
big_list.push(num);
|
|
||||||
});
|
|
||||||
// pdf.lines(new_numbers,x,y,[1,1],null);
|
|
||||||
x += sums(new_numbers, true);
|
|
||||||
y += sums(new_numbers, false);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'M':
|
|
||||||
if (big_list.length != 0) {
|
|
||||||
pdf.lines(big_list, mx, my, [1, 1], null);
|
|
||||||
}
|
|
||||||
big_list = [];
|
|
||||||
|
|
||||||
x = numbers[0];
|
|
||||||
mx = numbers[0] + x_offset;
|
|
||||||
y = numbers[1];
|
|
||||||
my = numbers[1] + y_offset;
|
|
||||||
|
|
||||||
if (numbers.length != 2) {
|
|
||||||
x = numbers[0];
|
|
||||||
y = numbers[1];
|
|
||||||
var lines_numbers = numbers.slice(2, numbers.length);
|
|
||||||
var new_numbers = change_numbers(lines_numbers,
|
|
||||||
x, y, false);
|
|
||||||
pdf.lines(new_numbers, x, y, [1, 1], null);
|
|
||||||
x += new_numbers[new_numbers.length - 1][0];
|
|
||||||
y += new_numbers[new_numbers.length - 1][1];
|
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
var new_numbers = change_numbers(numbers, x, y, true);
|
|
||||||
_.each(new_numbers, function(num) {
|
|
||||||
big_list.push(num);
|
|
||||||
});
|
|
||||||
// pdf.lines(new_numbers,x,y,[1,1],null);
|
|
||||||
x += sums(new_numbers, true);
|
|
||||||
y += sums(new_numbers, false);
|
|
||||||
break;
|
|
||||||
case 'L':
|
|
||||||
var new_numbers = change_numbers(numbers, x, y, false);
|
|
||||||
_.each(new_numbers, function(num) {
|
|
||||||
big_list.push(num);
|
|
||||||
});
|
|
||||||
//pdf.lines(new_numbers,x,y,[1,1],null);
|
|
||||||
x += new_numbers[new_numbers.length - 1][0];
|
|
||||||
y += new_numbers[new_numbers.length - 1][1];
|
|
||||||
break;
|
|
||||||
case 'h':
|
|
||||||
// x does not change. Only y changes
|
|
||||||
var sum = _.reduce(numbers,
|
|
||||||
|
|
||||||
function(memo, num) {
|
|
||||||
return memo + num;
|
|
||||||
}, 0);
|
|
||||||
var new_numbers = [
|
|
||||||
[sum, 0]
|
|
||||||
];
|
|
||||||
_.each(new_numbers, function(num) {
|
|
||||||
big_list.push(num);
|
|
||||||
});
|
|
||||||
// pdf.lines([[sum,0]],x,y,[1,1],null);
|
|
||||||
x += sum;
|
|
||||||
break;
|
|
||||||
case 'H':
|
|
||||||
big_list.push([numbers[numbers.length - 1] - x, 0]);
|
|
||||||
// pdf.lines([[numbers[numbers.length-1]-x,0]],
|
|
||||||
// x,y,[1,1],null);
|
|
||||||
x = numbers[numbers.length - 1];
|
|
||||||
break;
|
|
||||||
case 'v':
|
|
||||||
var sum = _.reduce(numbers,
|
|
||||||
|
|
||||||
function(memo, num) {
|
|
||||||
return memo + num;
|
|
||||||
}, 0);
|
|
||||||
var new_numbers = [
|
|
||||||
[0, sum]
|
|
||||||
];
|
|
||||||
_.each(new_numbers, function(num) {
|
|
||||||
big_list.push(num);
|
|
||||||
});
|
|
||||||
// pdf.lines([[0,sum]],x,y,[1,1],null);
|
|
||||||
y += sum;
|
|
||||||
break;
|
|
||||||
case 'V':
|
|
||||||
big_list.push([0, numbers[numbers.length - 1] - y]);
|
|
||||||
// pdf.lines([[0,numbers[numbers.length-1]-y]],
|
|
||||||
// x,y,[1,1],null);
|
|
||||||
y = numbers[numbers.length - 1];
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
var new_numbers = bezier_numbers(numbers, x, y, true);
|
|
||||||
_.each(new_numbers, function(num) {
|
|
||||||
big_list.push(num);
|
|
||||||
});
|
|
||||||
// pdf.lines(new_numbers,x,y,[1,1],null);
|
|
||||||
x += sums(new_numbers, true);
|
|
||||||
y += sums(new_numbers, false);
|
|
||||||
break;
|
|
||||||
case 'C':
|
|
||||||
var new_numbers = bezier_numbers(numbers, x, y, false);
|
|
||||||
_.each(new_numbers, function(num) {
|
|
||||||
big_list.push(num);
|
|
||||||
});
|
|
||||||
// pdf.lines(new_numbers,x,y,[1,1],null);
|
|
||||||
x = numbers[numbers.length - 2];
|
|
||||||
y = numbers[numbers.length - 1];
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
var new_numbers = s_bezier_numbers(numbers, x, y,
|
|
||||||
true, previous_element);
|
|
||||||
_.each(new_numbers, function(num) {
|
|
||||||
big_list.push(num);
|
|
||||||
});
|
|
||||||
// pdf.lines(new_numbers,x,y,[1,1],null);
|
|
||||||
x += sums(new_numbers, true);
|
|
||||||
y += sums(new_numbers, false);
|
|
||||||
break;
|
|
||||||
case 'S':
|
|
||||||
var new_numbers = s_bezier_numbers(numbers, x, y, false,
|
|
||||||
previous_element);
|
|
||||||
_.each(new_numbers, function(num) {
|
|
||||||
big_list.push(num);
|
|
||||||
});
|
|
||||||
// pdf.lines(new_numbers,x,y,[1,1],null);
|
|
||||||
x = numbers[numbers.length - 2];
|
|
||||||
y = numbers[numbers.length - 1];
|
|
||||||
break;
|
|
||||||
case 'A':
|
|
||||||
// for now a hack.treat this as a line
|
|
||||||
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 'z':
|
|
||||||
big_list.push([mx - x, my - y]);
|
|
||||||
x = mx;
|
|
||||||
y = my;
|
|
||||||
// pdf.lines([[mx-x,my-y]],x,y,[1,1],null);
|
|
||||||
break;
|
|
||||||
case 'Z':
|
|
||||||
big_list.push([mx - x, my - y]);
|
|
||||||
x = mx;
|
|
||||||
y = my;
|
|
||||||
// pdf.lines([[mx-x,my-y]],x,y,[1,1],null);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
console.log('Sorry, the', svg_element, 'svg command is not yet available.');
|
|
||||||
}
|
|
||||||
previous_element.element = svg_element;
|
|
||||||
previous_element.prev_numbers = numbers;
|
|
||||||
}
|
|
||||||
pdf.lines(big_list, mx, my, [1, 1], colorMode);
|
|
||||||
var numbs = null;
|
|
||||||
break;
|
|
||||||
//TODO: image
|
|
||||||
default:
|
default:
|
||||||
//console.log("cannot identify: ", node);
|
|
||||||
if (remove) {
|
if (remove) {
|
||||||
//console.log("can't translate to pdf:", node);
|
console.log("can't translate to pdf:", node);
|
||||||
n.remove();
|
node.parentNode.removeChild(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return pdf;
|
return pdf;
|
||||||
}
|
};
|
||||||
|
|
||||||
function sums(ListOfLists, is_x) {
|
jsPDFAPI.addSVG = function(element, x, y, options) {
|
||||||
if (is_x) {
|
|
||||||
var sum = _.reduce(ListOfLists,
|
|
||||||
|
|
||||||
function(memo, num) {
|
options = (options === undef ? {} : options);
|
||||||
return memo + num[num.length - 2];
|
options.x_offset = x;
|
||||||
}, 0);
|
options.y_offset = y;
|
||||||
} else {
|
|
||||||
var sum = _.reduce(ListOfLists,
|
|
||||||
|
|
||||||
function(memo, num) {
|
if (typeof element === 'string') {
|
||||||
return memo + num[num.length - 1];
|
element = new DOMParser().parseFromString(element, 'text/xml').documentElement;
|
||||||
}, 0);
|
|
||||||
}
|
}
|
||||||
return sum;
|
svgElementToPdf(element, this, options);
|
||||||
}
|
return this;
|
||||||
|
};
|
||||||
function change_numbers(numbers, x, y, relative) {
|
}(jsPDF.API));
|
||||||
var i = 0;
|
|
||||||
var prev_x = x;
|
|
||||||
var prev_y = y;
|
|
||||||
var new_numbers = [];
|
|
||||||
while (i < numbers.length) {
|
|
||||||
if (relative) {
|
|
||||||
x = numbers[i];
|
|
||||||
y = numbers[i + 1];
|
|
||||||
} else {
|
|
||||||
x = numbers[i] - prev_x;
|
|
||||||
y = numbers[i + 1] - prev_y;
|
|
||||||
}
|
|
||||||
prev_x = numbers[i];
|
|
||||||
prev_y = numbers[i + 1];
|
|
||||||
new_numbers.push([x, y]);
|
|
||||||
i += 2;
|
|
||||||
}
|
|
||||||
return new_numbers;
|
|
||||||
}
|
|
||||||
|
|
||||||
function bezier_numbers(numbers, x, y, relative) {
|
|
||||||
// the bezier numbers are ALL relative to the
|
|
||||||
// previous case line's (x,y), not all relative to
|
|
||||||
// each other.
|
|
||||||
var i = 0;
|
|
||||||
var prev_x = x;
|
|
||||||
var prev_y = y;
|
|
||||||
var new_numbers = [];
|
|
||||||
while (i < numbers.length) {
|
|
||||||
if (relative) {
|
|
||||||
var numbers_to_push = numbers.slice(i, i + 6);
|
|
||||||
} else {
|
|
||||||
var numbers_to_push = [];
|
|
||||||
for (var k = i; k < i + 6; k = k + 2) {
|
|
||||||
numbers_to_push.push(
|
|
||||||
numbers[k] - prev_x,
|
|
||||||
numbers[k + 1] - prev_y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
prev_x = numbers[i + 4];
|
|
||||||
prev_y = numbers[i + 5];
|
|
||||||
new_numbers.push(numbers_to_push);
|
|
||||||
i += 6;
|
|
||||||
}
|
|
||||||
return new_numbers;
|
|
||||||
}
|
|
||||||
|
|
||||||
function s_bezier_numbers(numbers, x, y, relative,
|
|
||||||
previous_element) {
|
|
||||||
var i = 0;
|
|
||||||
var prev_x = x;
|
|
||||||
var prev_y = y;
|
|
||||||
var new_numbers = [];
|
|
||||||
while (i < numbers.length) {
|
|
||||||
var numbers_to_push = [];
|
|
||||||
//need to check if relative for the 4 s/S numbers
|
|
||||||
if (relative) {
|
|
||||||
//find that 1st control point
|
|
||||||
if (i < 4 && (previous_element.element == 'c' || previous_element.element == 's')) {
|
|
||||||
// case 1: there was a prev c/C/s/S
|
|
||||||
// outside this numbers segment
|
|
||||||
numbers_to_push.push(previous_element.point[0],
|
|
||||||
previous_element.point[1]);
|
|
||||||
} else if (i >= 4) {
|
|
||||||
//case 1: there was a prev s/S
|
|
||||||
//within this numbers segment
|
|
||||||
numbers_to_push.push(numbers[i - 2] - numbers[i - 4],
|
|
||||||
numbers[i - 1] - numbers[i - 3]);
|
|
||||||
} else {
|
|
||||||
// case 2: no prev c/C/s/S, therefore
|
|
||||||
// 1st control pt = current pt.
|
|
||||||
numbers_to_push.push(prev_x, prev_y);
|
|
||||||
}
|
|
||||||
//then add the rest of the s numbers
|
|
||||||
for (var k = i; k < i + 4; k++) {
|
|
||||||
numbers_to_push.push(numbers[k]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//find that 1st control point
|
|
||||||
if (i < 4 && (previous_element.element == 'C' || previous_element.element == 'S')) {
|
|
||||||
// case 1: there was a prev c/C/s/S
|
|
||||||
// outside this numbers segment
|
|
||||||
numbers_to_push.push(previous_element.point[0] - prev_x,
|
|
||||||
previous_element.point[1] - prev_y);
|
|
||||||
} else if (i >= 4) {
|
|
||||||
//case 1: there was a prev s/S
|
|
||||||
//within this numbers segment
|
|
||||||
numbers_to_push.push(numbers[i - 2] + numbers[i - 2] - numbers[i - 4],
|
|
||||||
numbers[i - 1] + numbers[i - 1] - numbers[i - 3]);
|
|
||||||
} else {
|
|
||||||
// case 2: no prev c/C/s/S, therefore
|
|
||||||
// 1st control pt = current pt.
|
|
||||||
numbers_to_push.push(prev_x, prev_y);
|
|
||||||
}
|
|
||||||
//then add the rest of the s numbers
|
|
||||||
for (var k = i; k < i + 4; k = k + 2) {
|
|
||||||
numbers_to_push.push(numbers[k] - prev_x);
|
|
||||||
numbers_to_push.push(numbers[k + 1] - prev_y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
prev_x = numbers[i + 2];
|
|
||||||
prev_y = numbers[i + 3];
|
|
||||||
|
|
||||||
new_numbers.push(numbers_to_push);
|
|
||||||
i += 4;
|
|
||||||
}
|
|
||||||
return new_numbers;
|
|
||||||
}
|
|
||||||
|
|
||||||
function find_s_points(svg_element, previous_element) {
|
|
||||||
if (/(s|c)/.test(previous_element.element)) {
|
|
||||||
numbs = previous_element.prev_numbers;
|
|
||||||
previous_element.point = [numbs[numbs.length - 2] - numbs[numbs.length - 4],
|
|
||||||
numbs[numbs.length - 1] - numbs[numbs.length - 3]];
|
|
||||||
} else if (/(S|C)/.test(previous_element.element)) {
|
|
||||||
numbs = previous_element.prev_numbers;
|
|
||||||
previous_element.point = [2 * numbs[numbs.length - 2] - numbs[numbs.length - 4],
|
|
||||||
2 * numbs[numbs.length - 1] - numbs[numbs.length - 3]];
|
|
||||||
}
|
|
||||||
return previous_element.point
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*globals svgEditor:true, globalStorage, widget, svgedit, canvg, svgElementToPdf, jQuery, $, DOMParser, FileReader */
|
/*globals svgEditor:true, globalStorage, widget, svgedit, canvg, jQuery, $, DOMParser, FileReader */
|
||||||
/*jslint vars: true, eqeq: true, todo: true, forin: true, continue: true, regexp: true */
|
/*jslint vars: true, eqeq: true, todo: true, forin: true, continue: true, regexp: true */
|
||||||
/*
|
/*
|
||||||
* svg-editor.js
|
* svg-editor.js
|
||||||
|
@ -409,11 +409,11 @@ TODOS
|
||||||
}
|
}
|
||||||
if (opts.exportImage) {
|
if (opts.exportImage) {
|
||||||
customExportImage = opts.exportImage;
|
customExportImage = opts.exportImage;
|
||||||
svgCanvas.bind('exported', Utils.buildCanvgCallback(customExportImage));
|
svgCanvas.bind('exported', customExportImage); // canvg and our RGBColor will be available to the method
|
||||||
}
|
}
|
||||||
if (opts.exportPDF) {
|
if (opts.exportPDF) {
|
||||||
customExportPDF = opts.exportPDF;
|
customExportPDF = opts.exportPDF;
|
||||||
svgCanvas.bind('exportedPDF', Utils.buildJSPDFCallback(customExportPDF));
|
svgCanvas.bind('exportedPDF', customExportPDF); // jsPDF and our RGBColor will be available to the method
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -1071,39 +1071,28 @@ TODOS
|
||||||
|
|
||||||
var exportHandler = function(win, data) {
|
var exportHandler = function(win, data) {
|
||||||
var issues = data.issues,
|
var issues = data.issues,
|
||||||
type = data.type || 'PNG',
|
|
||||||
exportWindowName = data.exportWindowName;
|
exportWindowName = data.exportWindowName;
|
||||||
|
|
||||||
if (exportWindowName) {
|
if (exportWindowName) {
|
||||||
exportWindow = window.open('', exportWindowName); // A hack to get the window via JSON-able name without opening a new one
|
exportWindow = window.open('', exportWindowName); // A hack to get the window via JSON-able name without opening a new one
|
||||||
}
|
}
|
||||||
if (!$('#export_canvas').length) {
|
|
||||||
$('<canvas>', {id: 'export_canvas'}).hide().appendTo('body');
|
|
||||||
}
|
|
||||||
var c = $('#export_canvas')[0];
|
|
||||||
c.width = svgCanvas.contentW;
|
|
||||||
c.height = svgCanvas.contentH;
|
|
||||||
|
|
||||||
canvg(c, data.svg, {renderCallback: function() {
|
exportWindow.location.href = data.datauri;
|
||||||
var dataURLType = (type === 'ICO' ? 'BMP' : type).toLowerCase();
|
var done = $.pref('export_notice_done');
|
||||||
var datauri = data.quality ? c.toDataURL('image/' + dataURLType, data.quality) : c.toDataURL('image/' + dataURLType);
|
if (done !== 'all') {
|
||||||
exportWindow.location.href = datauri;
|
var note = uiStrings.notification.saveFromBrowser.replace('%s', data.type);
|
||||||
var done = $.pref('export_notice_done');
|
|
||||||
if (done !== 'all') {
|
|
||||||
var note = uiStrings.notification.saveFromBrowser.replace('%s', type);
|
|
||||||
|
|
||||||
// Check if there's issues
|
// Check if there's issues
|
||||||
if (issues.length) {
|
if (issues.length) {
|
||||||
var pre = '\n \u2022 ';
|
var pre = '\n \u2022 ';
|
||||||
note += ('\n\n' + uiStrings.notification.noteTheseIssues + pre + issues.join(pre));
|
note += ('\n\n' + uiStrings.notification.noteTheseIssues + pre + issues.join(pre));
|
||||||
}
|
|
||||||
|
|
||||||
// Note that this will also prevent the notice even though new issues may appear later.
|
|
||||||
// May want to find a way to deal with that without annoying the user
|
|
||||||
$.pref('export_notice_done', 'all');
|
|
||||||
exportWindow.alert(note);
|
|
||||||
}
|
}
|
||||||
}});
|
|
||||||
|
// Note that this will also prevent the notice even though new issues may appear later.
|
||||||
|
// May want to find a way to deal with that without annoying the user
|
||||||
|
$.pref('export_notice_done', 'all');
|
||||||
|
exportWindow.alert(note);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var operaRepaint = function() {
|
var operaRepaint = function() {
|
||||||
|
@ -2843,7 +2832,7 @@ TODOS
|
||||||
svgCanvas.bind('transition', elementTransition);
|
svgCanvas.bind('transition', elementTransition);
|
||||||
svgCanvas.bind('changed', elementChanged);
|
svgCanvas.bind('changed', elementChanged);
|
||||||
svgCanvas.bind('saved', saveHandler);
|
svgCanvas.bind('saved', saveHandler);
|
||||||
svgCanvas.bind('exported', Utils.buildCanvgCallback(exportHandler));
|
svgCanvas.bind('exported', exportHandler);
|
||||||
svgCanvas.bind('exportedPDF', function (win, data) {
|
svgCanvas.bind('exportedPDF', function (win, data) {
|
||||||
var exportWindowName = data.exportWindowName;
|
var exportWindowName = data.exportWindowName;
|
||||||
if (exportWindowName) {
|
if (exportWindowName) {
|
||||||
|
|
|
@ -291,6 +291,7 @@ var InsertElementCommand = svgedit.history.InsertElementCommand;
|
||||||
var RemoveElementCommand = svgedit.history.RemoveElementCommand;
|
var RemoveElementCommand = svgedit.history.RemoveElementCommand;
|
||||||
var ChangeElementCommand = svgedit.history.ChangeElementCommand;
|
var ChangeElementCommand = svgedit.history.ChangeElementCommand;
|
||||||
var BatchCommand = svgedit.history.BatchCommand;
|
var BatchCommand = svgedit.history.BatchCommand;
|
||||||
|
var call;
|
||||||
// Implement the svgedit.history.HistoryEventHandler interface.
|
// Implement the svgedit.history.HistoryEventHandler interface.
|
||||||
canvas.undoMgr = new svgedit.history.UndoManager({
|
canvas.undoMgr = new svgedit.history.UndoManager({
|
||||||
handleHistoryEvent: function(eventType, cmd) {
|
handleHistoryEvent: function(eventType, cmd) {
|
||||||
|
@ -395,7 +396,7 @@ $(opac_ani).attr({
|
||||||
|
|
||||||
var restoreRefElems = function(elem) {
|
var restoreRefElems = function(elem) {
|
||||||
// Look for missing reference elements, restore any found
|
// Look for missing reference elements, restore any found
|
||||||
var o, i,
|
var o, i, l,
|
||||||
attrs = $(elem).attr(ref_attrs);
|
attrs = $(elem).attr(ref_attrs);
|
||||||
for (o in attrs) {
|
for (o in attrs) {
|
||||||
var val = attrs[o];
|
var val = attrs[o];
|
||||||
|
@ -850,7 +851,7 @@ var copyElem = function(el) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Set scope for these functions
|
// Set scope for these functions
|
||||||
var getId, getNextId, call;
|
var getId, getNextId;
|
||||||
var textActions, pathActions;
|
var textActions, pathActions;
|
||||||
|
|
||||||
(function(c) {
|
(function(c) {
|
||||||
|
@ -1146,8 +1147,9 @@ var removeFromSelection = this.removeFromSelection = function(elemsToRemove) {
|
||||||
// find every element and remove it from our array copy
|
// find every element and remove it from our array copy
|
||||||
var i,
|
var i,
|
||||||
j = 0,
|
j = 0,
|
||||||
newSelectedItems = new Array(selectedElements.length),
|
newSelectedItems = [],
|
||||||
len = selectedElements.length;
|
len = selectedElements.length;
|
||||||
|
newSelectedItems.length = len;
|
||||||
for (i = 0; i < len; ++i) {
|
for (i = 0; i < len; ++i) {
|
||||||
var elem = selectedElements[i];
|
var elem = selectedElements[i];
|
||||||
if (elem) {
|
if (elem) {
|
||||||
|
@ -2852,7 +2854,8 @@ textActions = canvas.textActions = (function() {
|
||||||
|
|
||||||
matrix = xform ? svgedit.math.getMatrix(curtext) : null;
|
matrix = xform ? svgedit.math.getMatrix(curtext) : null;
|
||||||
|
|
||||||
chardata = new Array(len);
|
chardata = [];
|
||||||
|
chardata.length = len;
|
||||||
textinput.focus();
|
textinput.focus();
|
||||||
|
|
||||||
$(curtext).unbind('dblclick', selectWord).dblclick(selectWord);
|
$(curtext).unbind('dblclick', selectWord).dblclick(selectWord);
|
||||||
|
@ -2931,7 +2934,8 @@ pathActions = canvas.pathActions = function() {
|
||||||
}
|
}
|
||||||
this.selected_pts.sort();
|
this.selected_pts.sort();
|
||||||
i = this.selected_pts.length;
|
i = this.selected_pts.length;
|
||||||
var grips = new Array(i);
|
var grips = [];
|
||||||
|
grips.length = i;
|
||||||
// Loop through points to be selected and highlight each
|
// Loop through points to be selected and highlight each
|
||||||
while (i--) {
|
while (i--) {
|
||||||
var pt = this.selected_pts[i];
|
var pt = this.selected_pts[i];
|
||||||
|
@ -4364,7 +4368,23 @@ this.rasterExport = function(imgType, quality, exportWindowName) {
|
||||||
var mimeType = 'image/' + imgType.toLowerCase();
|
var mimeType = 'image/' + imgType.toLowerCase();
|
||||||
var issues = getIssues();
|
var issues = getIssues();
|
||||||
var str = this.svgCanvasToString();
|
var str = this.svgCanvasToString();
|
||||||
call('exported', {svg: str, issues: issues, type: imgType, mimeType: mimeType, quality: quality, exportWindowName: exportWindowName});
|
|
||||||
|
svgedit.utilities.buildCanvgCallback(function () {
|
||||||
|
var type = imgType || 'PNG';
|
||||||
|
if (!$('#export_canvas').length) {
|
||||||
|
$('<canvas>', {id: 'export_canvas'}).hide().appendTo('body');
|
||||||
|
}
|
||||||
|
var c = $('#export_canvas')[0];
|
||||||
|
c.width = svgCanvas.contentW;
|
||||||
|
c.height = svgCanvas.contentH;
|
||||||
|
|
||||||
|
canvg(c, str, {renderCallback: function() {
|
||||||
|
var dataURLType = (type === 'ICO' ? 'BMP' : type).toLowerCase();
|
||||||
|
var datauri = quality ? c.toDataURL('image/' + dataURLType, quality) : c.toDataURL('image/' + dataURLType);
|
||||||
|
|
||||||
|
call('exported', {datauri: datauri, svg: str, issues: issues, type: imgType, mimeType: mimeType, quality: quality, exportWindowName: exportWindowName});
|
||||||
|
}});
|
||||||
|
})();
|
||||||
};
|
};
|
||||||
|
|
||||||
this.exportPDF = function (exportWindowName, outputType) {
|
this.exportPDF = function (exportWindowName, outputType) {
|
||||||
|
@ -4389,7 +4409,7 @@ this.exportPDF = function (exportWindowName, outputType) {
|
||||||
});
|
});
|
||||||
var issues = getIssues();
|
var issues = getIssues();
|
||||||
var str = that.svgCanvasToString();
|
var str = that.svgCanvasToString();
|
||||||
svgElementToPdf(str, doc, {});
|
doc.addSVG(str, 0, 0);
|
||||||
|
|
||||||
// doc.output('save'); // Works to open in a new
|
// doc.output('save'); // Works to open in a new
|
||||||
// window; todo: configure this and other export
|
// window; todo: configure this and other export
|
||||||
|
|
Loading…
Reference in New Issue