-
Notifications
You must be signed in to change notification settings - Fork 184
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
Pdf non généré si caractères spéciaux dans le nom #35
Comments
Bonjour, |
J'ai utilisé le caractère č. Oui, ce n'est pas le caractère français. Potentiellement d'autre caractères peuvent poser le même problème. Mais aucun erreur n'a été affiché pour indiquer que c'est le caractère qui n'est pas permis. Je pense qu'afficher le message erreur serait suffisant pour ce type d'erreur car les gens ne peuvent pas deviner d'où viens erreur et pour quoi le pdf ne se génère pas. |
C'est la même chose pour lettre "Ś" dans lieu de naissance. |
Hello @philippeBron! It looks like you are using the standard Helvetica font to draw text: deplacement-covid-19/src/certificate.js Line 113 in 61b778a
The standard fonts only support characters in the WinAnsi character set. This restriction is an unfortunate artifact of the PDF spec and its age. There are 14 standard fonts (of which Helvetica is one). Here's a document that demonstrates all 14 fonts and their supported character sets:
import { PDFDocument } from 'pdf-lib';
(async () => {
const pdfDoc = await PDFDocument.create();
const font = await pdfDoc.embedFont(StandardFonts.Helvetica);
const characterSet = font.getCharacterSet();
console.log('Total supported characters:', characterSet.length);
console.log('Supports è?', characterSet.includes('è'.codePointAt(0)));
console.log('Supports ç?', characterSet.includes('ç'.codePointAt(0)));
console.log('Supports č?', characterSet.includes('č'.codePointAt(0)));
console.log('Supports Ś?', characterSet.includes('Ś'.codePointAt(0)));
})();
// Output:
// Total supported characters: 218
// Supports è? true
// Supports ç? true
// Supports č? false
// Supports Ś? false However, you can still produce PDFs with characters outside the WinAnsi character set. You just need to use an embedded font that supports them. The Ubuntu font, for example. Here's what happens to our above example if we embed the Ubuntu font instead of Helvetica: import fontkit from '@pdf-lib/fontkit';
import { PDFDocument } from 'pdf-lib';
(async () => {
const ubuntuFontBytes = await fetch(
'https://pdf-lib.js.org/assets/ubuntu/Ubuntu-R.ttf',
).then((res) => res.arrayBuffer());
const pdfDoc = await PDFDocument.create();
pdfDoc.registerFontkit(fontkit);
const font = await pdfDoc.embedFont(ubuntuFontBytes);
const characterSet = font.getCharacterSet();
console.log('Total supported characters:', characterSet.length);
console.log('Supports è?', characterSet.includes('è'.codePointAt(0)));
console.log('Supports ç?', characterSet.includes('ç'.codePointAt(0)));
console.log('Supports č?', characterSet.includes('č'.codePointAt(0)));
console.log('Supports Ś?', characterSet.includes('Ś'.codePointAt(0)));
})();
// Output:
// Total supported characters: 1195
// Supports è? true
// Supports ç? true
// Supports č? true
// Supports Ś? true Note that the Ubuntu font supports 1195 characters, significantly more than the 218 supported by the standard Helvetica font. And you can see that Finally, I should mention that since custom fonts are embedded in the PDF file you produce, the resulting file size is necessarily increased. This probably isn't a big deal since many custom fonts are pretty small. But if you only use a few of the characters in the font, you can reduce the file size by subsetting the font (with the import fontkit from '@pdf-lib/fontkit';
import { PDFDocument } from 'pdf-lib';
(async () => {
const ubuntuFontBytes = await fetch(
'https://pdf-lib.js.org/assets/ubuntu/Ubuntu-R.ttf',
).then((res) => res.arrayBuffer());
/***** Without Subsetting *****/
const pdfDoc1 = await PDFDocument.create();
pdfDoc1.registerFontkit(fontkit);
const font1 = await pdfDoc1.embedFont(ubuntuFontBytes);
const page1 = pdfDoc1.addPage([500, 500]);
page1.setFont(font1);
page1.drawText('Testing č Ś', { x: 50, y: 150 });
const pdfBytes1 = await pdfDoc1.save();
console.log('File size in bytes without subsetting:', pdfBytes1.length);
/***** With Subsetting *****/
const pdfDoc2 = await PDFDocument.create();
pdfDoc2.registerFontkit(fontkit);
const font2 = await pdfDoc2.embedFont(ubuntuFontBytes, { subset: true });
const page2 = pdfDoc2.addPage([500, 500]);
page2.setFont(font2);
page2.drawText('Testing č Ś', { x: 50, y: 150 });
const pdfBytes2 = await pdfDoc2.save();
console.log('File size in bytes with subsetting:', pdfBytes2.length);
})();
// Output:
// File size in bytes without subsetting: 181211
// File size in bytes with subsetting: 5566 |
@Hopding you have found the solution. May be you can do pull request of your solution.. |
@philippeBron Comme l'a fait remarquer @Hopding, le problème est lié à la police utilisée (Helvetica des StandardFonts de pdf-lib) qui ne supporte qu'un nombre limité de caractères (ceux de la table Windows-1252). J'ai implémenté le code proposé par @Hopding, cela corrige effectivement le problème. Comme le fait remarquer @marek-vanco, le plus "gênant" (même si ce service est très pratique et que je suis - nous sommes des milliers - à vous remercier de l'avoir mis à disposition de tous), c'est que l'erreur soit silencieuse pour l'utilisateur / trice car un nombre non-négligeable de nos citoyens possèdent un "č" ou encore un "Ś" dans leur nom de famille ou encore leur lieu de naissance. Il pourrait exister 2 approches :
P.S : Ci-dessous, le diff de certificate.js au cas où il pourrait être utile. |
Le PDF n'est pas généré si les caractères spéciaux sont utilisés dans le nom. Aucun message erreur n indique la cause de non génération... Le bouton fait rien du tout. En remplaçant des caractères avec ASCII < 128 la génération fonctionne. Mais ce n'est pas évident de trouver la cause pour une personne moins alaise avec le PC.
The text was updated successfully, but these errors were encountered: