fix: use noto sans for text insertion on pdfs

Use Noto Sans to gracefully handle inserting custom text
on PDF's. Previously we were using Helvetica which is a
standard PDF font but that would fail for any character
that couldn't be encoded in WinANSI.

Noto Sans was chosen as it has support for a large number
of languages and glyphs with challenges now being adding
support for CJK glyphs.
This commit is contained in:
Mythie
2024-05-23 13:07:37 +10:00
parent 4c0b772fc9
commit d58a88196a
7 changed files with 19 additions and 3 deletions

View File

@ -18,6 +18,10 @@ const FONT_CAVEAT_BYTES = fs.readFileSync(
path.join(__dirname, '../../packages/assets/fonts/caveat.ttf'), path.join(__dirname, '../../packages/assets/fonts/caveat.ttf'),
); );
const FONT_NOTO_SANS_BYTES = fs.readFileSync(
path.join(__dirname, '../../packages/assets/fonts/noto-sans.ttf'),
);
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
const config = { const config = {
experimental: { experimental: {
@ -38,6 +42,7 @@ const config = {
env: { env: {
NEXT_PUBLIC_PROJECT: 'marketing', NEXT_PUBLIC_PROJECT: 'marketing',
FONT_CAVEAT_URI: `data:font/ttf;base64,${FONT_CAVEAT_BYTES.toString('base64')}`, FONT_CAVEAT_URI: `data:font/ttf;base64,${FONT_CAVEAT_BYTES.toString('base64')}`,
FONT_NOTO_SANS_URI: `data:font/ttf;base64,${FONT_NOTO_SANS_BYTES.toString('base64')}`,
}, },
modularizeImports: { modularizeImports: {
'lucide-react': { 'lucide-react': {

View File

@ -18,6 +18,10 @@ const FONT_CAVEAT_BYTES = fs.readFileSync(
path.join(__dirname, '../../packages/assets/fonts/caveat.ttf'), path.join(__dirname, '../../packages/assets/fonts/caveat.ttf'),
); );
const FONT_NOTO_SANS_BYTES = fs.readFileSync(
path.join(__dirname, '../../packages/assets/fonts/noto-sans.ttf'),
);
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
const config = { const config = {
output: process.env.DOCKER_OUTPUT ? 'standalone' : undefined, output: process.env.DOCKER_OUTPUT ? 'standalone' : undefined,
@ -42,6 +46,7 @@ const config = {
APP_VERSION: version, APP_VERSION: version,
NEXT_PUBLIC_PROJECT: 'web', NEXT_PUBLIC_PROJECT: 'web',
FONT_CAVEAT_URI: `data:font/ttf;base64,${FONT_CAVEAT_BYTES.toString('base64')}`, FONT_CAVEAT_URI: `data:font/ttf;base64,${FONT_CAVEAT_BYTES.toString('base64')}`,
FONT_NOTO_SANS_URI: `data:font/ttf;base64,${FONT_NOTO_SANS_BYTES.toString('base64')}`,
}, },
modularizeImports: { modularizeImports: {
'lucide-react': { 'lucide-react': {

Binary file not shown.

View File

@ -1,6 +1,6 @@
import { APP_BASE_URL } from './app'; import { APP_BASE_URL } from './app';
export const DEFAULT_STANDARD_FONT_SIZE = 15; export const DEFAULT_STANDARD_FONT_SIZE = 12;
export const DEFAULT_HANDWRITING_FONT_SIZE = 50; export const DEFAULT_HANDWRITING_FONT_SIZE = 50;
export const MIN_STANDARD_FONT_SIZE = 8; export const MIN_STANDARD_FONT_SIZE = 8;

View File

@ -1,6 +1,6 @@
// https://github.com/Hopding/pdf-lib/issues/20#issuecomment-412852821 // https://github.com/Hopding/pdf-lib/issues/20#issuecomment-412852821
import fontkit from '@pdf-lib/fontkit'; import fontkit from '@pdf-lib/fontkit';
import { PDFDocument, StandardFonts } from 'pdf-lib'; import { PDFDocument } from 'pdf-lib';
import { import {
DEFAULT_HANDWRITING_FONT_SIZE, DEFAULT_HANDWRITING_FONT_SIZE,
@ -17,6 +17,10 @@ export const insertFieldInPDF = async (pdf: PDFDocument, field: FieldWithSignatu
res.arrayBuffer(), res.arrayBuffer(),
); );
const fontUbuntu = await fetch(process.env.FONT_NOTO_SANS_URI).then(async (res) =>
res.arrayBuffer(),
);
const isSignatureField = isSignatureFieldType(field.type); const isSignatureField = isSignatureFieldType(field.type);
pdf.registerFontkit(fontkit); pdf.registerFontkit(fontkit);
@ -41,7 +45,7 @@ export const insertFieldInPDF = async (pdf: PDFDocument, field: FieldWithSignatu
const fieldX = pageWidth * (Number(field.positionX) / 100); const fieldX = pageWidth * (Number(field.positionX) / 100);
const fieldY = pageHeight * (Number(field.positionY) / 100); const fieldY = pageHeight * (Number(field.positionY) / 100);
const font = await pdf.embedFont(isSignatureField ? fontCaveat : StandardFonts.Helvetica); const font = await pdf.embedFont(isSignatureField ? fontCaveat : fontUbuntu);
if (field.type === FieldType.SIGNATURE || field.type === FieldType.FREE_SIGNATURE) { if (field.type === FieldType.SIGNATURE || field.type === FieldType.FREE_SIGNATURE) {
await pdf.embedFont(fontCaveat); await pdf.embedFont(fontCaveat);

View File

@ -73,6 +73,7 @@ declare namespace NodeJS {
DEPLOYMENT_TARGET?: 'webapp' | 'marketing'; DEPLOYMENT_TARGET?: 'webapp' | 'marketing';
FONT_CAVEAT_URI: string; FONT_CAVEAT_URI: string;
FONT_NOTO_SANS_URI: string;
POSTGRES_URL?: string; POSTGRES_URL?: string;
DATABASE_URL?: string; DATABASE_URL?: string;

View File

@ -112,6 +112,7 @@
"NODE_ENV", "NODE_ENV",
"DEPLOYMENT_TARGET", "DEPLOYMENT_TARGET",
"FONT_CAVEAT_URI", "FONT_CAVEAT_URI",
"FONT_NOTO_SANS_URI",
"POSTGRES_URL", "POSTGRES_URL",
"DATABASE_URL", "DATABASE_URL",
"DATABASE_URL_UNPOOLED", "DATABASE_URL_UNPOOLED",