-
Notifications
You must be signed in to change notification settings - Fork 104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The exported PDF is not rendering custom fonts on some of the PDF text objects. #255
Comments
Please reduce your SVG to just the text where the fonts are not applied. |
so I checked how we could implement the underlining and the line-through text decoration properties on the pdf, and we need to draw a line with the same color as the tspan style declaration but in order to do that, we need to get the text object width and height to add this to the x and y props and then draw from there, so I if you can guide me on how to get these props (style declaration, text rendered height and width) after we set the text and were specifically we need to set it on svg2pdf I will gladly do the work and testing needed @HackbrettXXX |
Thank you for reducing the SVG. Regarding the underline and strike-through: a PR would be very much appreciated. The best location to put the code is probably somewhere in textchunk: https://github.com/yWorks/svg2pdf.js/blob/master/src/textchunk.ts#L72. The text position and width is already known there. One issue you might run into is that every tspan might get its own line and we might need to consolidate the lines for inline tspans. |
I checked the possible font issues and they seems to be related to the font weight declaration, in the svg these are custom fonts that are added as 'normal' font weights, so there's no match on both the use and font declaration, I will start working on the changes required to add the underlining. |
I'm having a related problem, I'm also using fabric.js and I need to generate a PDF from the SVG generated by canvas, the SVG is being generated and displayed correctly, I use some custom fonts, I managed to add the custom fonts and it's working If the text element has a tspan inside, but when I use a standard PDF font like Helvetica and Courier it doesn't work svg<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="637" height="1012" viewBox="301.5 50 637 1012" xml:space="preserve">
<desc>Created with Fabric.js 5.3.0</desc>
<defs>
</defs>
<g transform="matrix(1 0 0 1 620.5 556.5)" id="stage">
<rect style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,255,255); fill-rule: nonzero; opacity: 1;" x="-318.5" y="-506" rx="0" ry="0" width="637" height="1012"/>
</g>
<g transform="matrix(4.41 0 0 4.41 512.63 234.05)" style="" id="itext-001c8nc3i">
<text xml:space="preserve" font-family="Helvetica" font-size="20" font-style="normal" font-weight="normal" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(254,0,0); fill-rule: nonzero; opacity: 1; white-space: pre;"><tspan x="-41.13" y="6.28">Helvetica</tspan></text>
</g>
<g transform="matrix(4.29 0 0 4.29 443.87 125.01)" style="" id="itext-001th0bi9">
<text xml:space="preserve" font-family="Calibri" font-size="20" font-style="normal" font-weight="normal" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1; white-space: pre;"><tspan x="-25.75" y="6.28">Calibri</tspan></text>
</g>
<g transform="matrix(4.34 0 0 4.34 730.56 125)" style="" id="itext-001s4e88y">
<text xml:space="preserve" font-family="Roboto" font-size="20" font-style="normal" font-weight="normal" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,216,0); fill-rule: nonzero; opacity: 1; white-space: pre;"><tspan x="-32.05" y="6.28">Roboto</tspan></text>
</g>
<g transform="matrix(3.43 0 0 3.43 533.1 334.93)" style="" id="itext-001od0816">
<text xml:space="preserve" font-family="Gotham Condensed" font-size="20" font-style="normal" font-weight="normal" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,188); fill-rule: nonzero; opacity: 1; white-space: pre;"><tspan x="-56.73" y="6.28">Gotham Condensed</tspan></text>
</g>
<g transform="matrix(4.18 0 0 4.18 596.4 444.54)" style="" id="itext-000kx8wdn">
<text xml:space="preserve" font-family="Brush Script MT" font-size="20" font-style="normal" font-weight="normal" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(250,116,0); fill-rule: nonzero; opacity: 1; white-space: pre;"><tspan x="-59.88" y="6.28">Brush Script MT</tspan></text>
</g>
<g transform="matrix(3.66 0 0 3.66 817.59 236.17)" style="" id="itext-000eqyaha">
<text xml:space="preserve" font-family="Courier" font-size="20" font-style="normal" font-weight="normal" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(207,0,254); fill-rule: nonzero; opacity: 1; white-space: pre;"><tspan x="-30" y="6.28">Texto</tspan></text>
</g>
</svg>
<script src="assets/js/chart.js"></script>
<script src="assets/js/fabric/5.3.0/fabric.js"></script>
<script src="assets/js/jspdf/2.5.1/jspdf.umd.min.js"></script>
<script src="assets/js/svg2pdf.js/2.2.3/svg2pdf.umd.min.js"></script>
<script>
const { jsPDF } = window.jspdf
async function svgToPdf(svgElement, x, y, width, height, fileName) {
await loadFont('assets/fonts/calibri/calibri.ttf', 'Calibri', 'normal', 'normal', '400');
await loadFont('assets/fonts/roboto/roboto_regular.ttf', 'Roboto', 'normal', '400');
await loadFont('assets/fonts/gotham/gotham_condensed_medium.ttf', 'Gotham Condensed', 'normal', '400');
await loadFont('assets/fonts/brush_script/brush_script_mt.ttf', 'Brush Script MT', 'normal', '400');
await loadFont('assets/fonts/arial/arial.ttf', 'Arial', 'normal', '400');
await loadFont('assets/fonts/arial/arial_black.ttf', 'Arial Black', 'normal', '400');
//orientation, unit, format
const doc = new jsPDF('p', 'mm', [width, height]);
await doc
.svg(svgElement, {
x: x,
y: y,
width: width,
height: height
});
doc.setFont('Helvetica', 'normal');
doc.text("Texto Helvetica", 100, 100);
// save the created pdf
doc.save(fileName)
}
// [src] file 'calibri-normal.ttf', [name] 'calibri', [style] 'normal'
async function loadFont(src, name, style, weight) {
const dataBase64 = await urlContentToDataUri(src);
const filename = src.split('\\').pop().split('/').pop();
console.log(filename);
console.log(name);
var callAddFont = function () {
this.addFileToVFS(filename, dataBase64);
this.addFont(filename, name, style, weight);
};
jsPDF.API.events.push(['addFonts', callAddFont]);
}
function urlContentToDataUri(url) {
return fetch(url)
.then(response => response.blob())
.then(blob => new Promise(callback => {
const reader = new FileReader();
reader.onload = function () { callback(this.result.substr(this.result.indexOf(',') + 1)) };
reader.readAsDataURL(blob);
}));
}
</script> |
I will add my findings here, you must add all the fonts used on the canvas to the PDF to be safe, even the safe fonts |
Describe the bug
I'm using this library and fabricJS to make and exportable version of the canvas and have a pdf from there, I was able to add custom fonts and the source of the pdf generator is a svg export, but some of the pdf objects (once is generated) have missing font declarations, and i used some text styling to and it doesn't appear to be applied (underlining and striking) too.
P.S: the PDF file size is exponentially bigger than the SVG representation, any hints about this.
What version are you using (exact version of svg2pdf.js and jspdf)?
svg2pdf.js -> 2.2.1
jspdf-> 2.5.1
To Reproduce
//add jspdf font files as follow, the font is an object holding all the font information
//some of the code is removed but all should work
const [fontName] = font.file_name.split('.');
const fontFetchResponse = await Axios.get(font.file_url, { responseType: 'arraybuffer' });
pdf.addFileToVFS(font.file_name, Buffer.from(fontFetchResponse.data, 'binary').toString('base64'));
pdf.addFont(font.file_name, fontName, 'normal');
pdf.setFont(fontName);
//then
const pdf = new jsPDF({ unit: 'in', putOnlyUsedFonts: true });
const imageInformation = canvas.toSVG({ suppressPreamble: true });
//add a page
pdf.addPage([pageWidth, pageHeight], orientation);
//adding the svg to pdf
await pdf.svg(imageInformation, { x: 0, y: 0, width: pageWidth, height: pageHeight });
Expected behavior
have the pdf objects with their respective font declaration, and styling
Desktop (please complete the following information):
Additional context
Added fonts, svg file and exported PDF on this file
export_svg.zip
The text was updated successfully, but these errors were encountered: