schoero / swissqrbill

Swiss QR Bill generation in Node.js and browsers
MIT License
155 stars 29 forks source link

fix: bold font in azure static web apps #439

Open Marco-Selenati opened 2 months ago

Marco-Selenati commented 2 months ago

Hello

I had problems when deploying to Azure static web apps. It couldn't find the font files. I need to pass them in as a Blob so that they are found. This works in pdfkit but this library assumes that the font will be a string.

I changed it to accept two fonts one normal and one bold this should make my use case work.

Thanks for the great library

schoero commented 2 months ago

Thank you for the PR.

I can see some problems with the current state of this PR:

I have already started working on fixing these issues as I was reviewing, so you don't need to be concerned about it.

I will get back to this in the next days.

schoero commented 2 months ago

I tried to create the test cases for the Blob fonts and read the PDFKit documentation again.

Does it not work for you to register the fonts as described in the documentation?

You could register the font using the Blob and reference it later by the name:

pdf.registerFont("Liberation-Sans", LiberationSansBlob);
pdf.registerFont("Liberation-Sans-Bold", LiberationSansBoldBlob);
const qrBill = new SwissQRBill(data, { fontName: "Liberation-Sans" });

If you already pass the Blob, there should be no way for PDFKit to not find the fonts.

Marco-Selenati commented 2 months ago

Thank you for your help

I tried that before making a commit, but sadly, it gave me an error message saying it could not write to a folder named /data/.

It might be related to this issue https://github.com/foliojs/pdfkit/issues/1516 But i don't think so because the logs say:

at GET4 (/home/site/wwwroot/sk_render/index.js:348936:40) {
    errno: -2,
    syscall: 'open',
    code: 'ENOENT',
path: '/home/site/wwwroot/sk_render/data/Helvetica.afm'
}

The path seems valid to me but i don't think it should even touch the file system if possible. This error only happens when i call pdf.registerFont. So i wrote the commit that i can pass the buffer so that i can avoid this call.

This also only happens in Azure Static Web Apps on my machine it works perfectly with pdf.registerFont or the commit I wrote. Azure Static Web Apps also might have a read only file system for the uploaded code? That would probably be the reason for why the write fails but i cant find anything in the Microsoft docs.

Maybe I could start a PR on the pdfkit repo so that pdf.registerFont would not try to write to the file system? I'm not sure if that would make sense.

Marco-Selenati commented 2 months ago

I Have found a workaround for the issue I created a seperate common js vite build with polyfills for fs stream and zlib.

So no "type": "module" in the package.json. And the vite.config.js looks like this:

import { defineConfig } from 'vite';
import arraybuffer from 'vite-plugin-arraybuffer';
import dts from 'vite-plugin-dts';
import { nodePolyfills } from 'vite-plugin-node-polyfills';

export default defineConfig({
    build: {
        target: 'node18',
        lib: {
            entry: './src/index.ts',
            formats: ['es']
        },
        rollupOptions: {
            external: []
        },
        outDir: 'build'
    },
    plugins: [
        nodePolyfills({
            include: ['fs', 'stream', 'zlib']
        }),
        arraybuffer(),
        dts({ rollupTypes: true })
    ],
    optimizeDeps: {
        include: []
    }
});

Then i can use it the way you suggested:

import helveticaBold from './fonts/Helvetica-Bold.ttf?arraybuffer';
import helvetica from './fonts/Helvetica.ttf?arraybuffer';

pdf.registerFont('Helvetica', helvetica);
pdf.registerFont('Helvetica-Bold', helveticaBold);

const qrBill = new SwissQRBill(data, {
    fontName: 'Helvetica'
});

qrBill.attachTo(pdf);

The downside is that the bundle is over 2 MiB but it works