Skip to content

Commit

Permalink
Merge pull request #2797 from asturur/svg-text-f
Browse files Browse the repository at this point in the history
Add font faces to svg
  • Loading branch information
kangax committed Feb 18, 2016
2 parents 2473589 + eb71b76 commit 3adaec2
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 13 deletions.
2 changes: 1 addition & 1 deletion HEADER.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ fabric.SHARED_ATTRIBUTES = [
*/
fabric.DPI = 96;
fabric.reNum = '(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)';

fabric.fontPaths = { };

/**
* Device Pixel Ratio
Expand Down
8 changes: 4 additions & 4 deletions src/mixins/itext.svg_export.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,12 @@
_createTextCharBg: function(styleDecl, lineLeftOffset, lineTopOffset, heightOfLine, charWidth, charOffset) {
return [
//jscs:disable validateIndentation
'<rect fill="', styleDecl.textBackgroundColor,
'\t\t<rect fill="', styleDecl.textBackgroundColor,
'" x="', toFixed(lineLeftOffset + charOffset, NUM_FRACTION_DIGITS),
'" y="', toFixed(lineTopOffset - this.height/2, NUM_FRACTION_DIGITS),
'" width="', toFixed(charWidth, NUM_FRACTION_DIGITS),
'" height="', toFixed(heightOfLine / this.lineHeight, NUM_FRACTION_DIGITS),
'"></rect>'
'"></rect>\n'
//jscs:enable validateIndentation
].join('');
},
Expand All @@ -95,7 +95,7 @@

return [
//jscs:disable validateIndentation
'<tspan x="', toFixed(lineLeftOffset + charOffset, NUM_FRACTION_DIGITS), '" y="',
'\t\t\t<tspan x="', toFixed(lineLeftOffset + charOffset, NUM_FRACTION_DIGITS), '" y="',
toFixed(lineTopOffset - this.height/2, NUM_FRACTION_DIGITS), '" ',
(styleDecl.fontFamily ? 'font-family="' + styleDecl.fontFamily.replace(/"/g, '\'') + '" ': ''),
(styleDecl.fontSize ? 'font-size="' + styleDecl.fontSize + '" ': ''),
Expand All @@ -104,7 +104,7 @@
(styleDecl.textDecoration ? 'text-decoration="' + styleDecl.textDecoration + '" ': ''),
'style="', fillStyles, '">',
fabric.util.string.escapeXml(_char),
'</tspan>'
'</tspan>\n'
//jscs:enable validateIndentation
].join('');
}
Expand Down
39 changes: 31 additions & 8 deletions src/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -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('');
}
Expand All @@ -1049,7 +1072,7 @@
markup = [
//jscs:disable validateIndentation
'\t<style type="text/css">',
'<![CDATA[',
'<![CDATA[\n',
markup,
']]>',
'</style>\n'
Expand Down
24 changes: 24 additions & 0 deletions test/unit/itext.js
Original file line number Diff line number Diff line change
Expand Up @@ -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<g transform=\"translate(124.88 52.93)\">\n\t\t<text font-family=\"Times New Roman\" font-size=\"40\" font-weight=\"normal\" style=\"stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;\" ><tspan x=\"-124.384765625\" y=\"-17.232\" style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #112233; fill-rule: ; opacity: 1;\">t</tspan><tspan x=\"-113.271484375\" y=\"-17.232\" style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: ; opacity: 1;\">e</tspan><tspan x=\"-95.517578125\" y=\"-17.232\" style=\"stroke: #223344; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: ; opacity: 1;\">s</tspan><tspan x=\"-79.951171875\" y=\"-17.232\" style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: ; opacity: 1;\">t</tspan><tspan x=\"-68.837890625\" y=\"-17.232\" style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: ; opacity: 1;\"> </tspan><tspan x=\"-58.837890625\" y=\"-17.232\" style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: ; opacity: 1;\">f</tspan><tspan x=\"-45.517578125\" y=\"-17.232\" style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: ; opacity: 1;\">o</tspan><tspan x=\"-25.517578125\" y=\"-17.232\" style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: ; opacity: 1;\">o</tspan><tspan x=\"-5.517578125\" y=\"-17.232\" style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: ; opacity: 1;\"> </tspan><tspan x=\"4.482421875\" y=\"-17.232\" style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: ; opacity: 1;\">b</tspan><tspan x=\"24.482421875\" y=\"-17.232\" style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: ; opacity: 1;\">a</tspan><tspan x=\"42.236328125\" y=\"-17.232\" style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: ; opacity: 1;\">r</tspan><tspan x=\"55.556640625\" y=\"-17.232\" style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: ; opacity: 1;\">-</tspan><tspan x=\"68.876953125\" y=\"-17.232\" style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: ; opacity: 1;\">b</tspan><tspan x=\"88.876953125\" y=\"-17.232\" style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: ; opacity: 1;\">a</tspan><tspan x=\"106.630859375\" y=\"-17.232\" style=\"stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: ; opacity: 1;\">z</tspan><tspan x=\"-124.38\" y=\"35.2\" fill=\"rgb(0,0,0)\">qux</tspan></text>\n\t</g>\n');
}
});

})();

0 comments on commit 3adaec2

Please sign in to comment.