diff --git a/HEADER.js b/HEADER.js index 7731cf18893..53a8a1226e1 100644 --- a/HEADER.js +++ b/HEADER.js @@ -58,7 +58,7 @@ fabric.SHARED_ATTRIBUTES = [ */ fabric.DPI = 96; fabric.reNum = '(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)'; - +fabric.fontPaths = { }; /** * Device Pixel Ratio diff --git a/src/mixins/itext.svg_export.js b/src/mixins/itext.svg_export.js index 87fdc6be4c6..f23c22da87e 100644 --- a/src/mixins/itext.svg_export.js +++ b/src/mixins/itext.svg_export.js @@ -70,12 +70,12 @@ _createTextCharBg: function(styleDecl, lineLeftOffset, lineTopOffset, heightOfLine, charWidth, charOffset) { return [ //jscs:disable validateIndentation - '' + '">\n' //jscs:enable validateIndentation ].join(''); }, @@ -95,7 +95,7 @@ return [ //jscs:disable validateIndentation - '', fabric.util.string.escapeXml(_char), - '' + '\n' //jscs:enable validateIndentation ].join(''); } diff --git a/src/parser.js b/src/parser.js index 723dba58bdc..9aecddeb253 100644 --- a/src/parser.js +++ b/src/parser.js @@ -1023,24 +1023,47 @@ }, /** - * Creates markup containing SVG font faces + * Creates markup containing SVG font faces, + * font URLs for font faces must be collected by developers + * and are not extracted from the DOM by fabricjs * @param {Array} objects Array of fabric objects * @return {String} */ createSVGFontFacesMarkup: function(objects) { - var markup = ''; + var markup = '', fontList = { }, obj, fontFamily, + style, row, rowIndex, char, charIndex, + fontPaths = fabric.fontPaths; for (var i = 0, len = objects.length; i < len; i++) { - if (objects[i].type !== 'text' || !objects[i].path) { + obj = objects[i]; + fontFamily = obj.fontFamily; + if (obj.type.indexOf('text') === -1 || fontList[fontFamily] || !fontPaths[fontFamily]) { continue; } + fontList[fontFamily] = true; + if (!obj.styles) { + continue; + } + style = obj.styles; + for (rowIndex in style) { + char = style[rowIndex]; + for (charIndex in row) { + char = row[charIndex]; + fontFamily = char.fontFamily; + if (!fontList[fontFamily] && fontPaths[fontFamily]) { + fontList[fontFamily] = true; + } + } + } + } + for (var j in fontList) { markup += [ //jscs:disable validateIndentation - '@font-face {', - 'font-family: ', objects[i].fontFamily, '; ', - 'src: url(\'', objects[i].path, '\')', - '}\n' + '\t\t@font-face {\n', + '\t\t\tfont-family: \'', j, '\';\n', + '\t\t\tsrc: url(\'', fontPaths[j], '\');\n', + '\t\t}\n' //jscs:enable validateIndentation ].join(''); } @@ -1049,7 +1072,7 @@ markup = [ //jscs:disable validateIndentation '\t\n' diff --git a/test/unit/itext.js b/test/unit/itext.js index 087225387df..adeaa0d86ad 100644 --- a/test/unit/itext.js +++ b/test/unit/itext.js @@ -588,4 +588,28 @@ // TODO: more SVG tests here? }); + test('toSVGWithFonts', function() { + var iText = new fabric.IText('test foo bar-baz\nqux', { + styles: { + 0: { + 0: { fill: '#112233' }, + 2: { stroke: '#223344', fontFamily: 'Engagement' }, + 3: { backgroundColor: '#00FF00' } + } + }, + fontFamily: 'Plaster' + }); + fabric.fontPaths = { + Engagement: 'path-to-engagement-font-file', + Plaster: 'path-to-plaster-font-file', + }; + canvas.add(iText); + equal(typeof iText.toSVG, 'function'); + + // because translate values differ + if (!fabric.isLikelyNode) { + equal(canvas.toSVG(), '\t\n\t\ttest foo bar-bazqux\n\t\n'); + } + }); + })();