- include more local fonts, such as Times New Roman and Arial (fixes #2170)

- remove embedding fonts to PDF as it wasn't doing anything
This commit is contained in:
Amruth Pillai
2025-01-25 00:47:39 +01:00
parent c7ae0e94d7
commit 9406d78653
4 changed files with 45 additions and 64 deletions

View File

@ -11,23 +11,28 @@ import { useResumeStore } from "@/client/stores/resume";
import { SectionIcon } from "../shared/section-icon";
const localFonts = ["Arial", "Cambria", "Garamond", "Times New Roman"];
const fontSuggestions = [
"Open Sans",
"Merriweather",
"Roboto Condensed",
"Playfair Display",
"Lato",
"Lora",
"PT Sans",
"PT Serif",
...localFonts,
"IBM Plex Sans",
"IBM Plex Serif",
"Lato",
"Lora",
"Merriweather",
"Open Sans",
"Playfair Display",
"PT Sans",
"PT Serif",
"Roboto Condensed",
];
const families: ComboboxOption[] = fonts.map((font) => ({
const families = fonts.map((font) => ({
value: font.family,
label: font.family,
}));
})) satisfies ComboboxOption[];
families.push(...localFonts.map((font) => ({ value: font, label: font })));
export const TypographySection = () => {
const [subsets, setSubsets] = useState<ComboboxOption[]>([]);
@ -52,10 +57,14 @@ export const TypographySection = () => {
useEffect(() => {
const subsets = fonts.find((font) => font.family === typography.font.family)?.subsets ?? [];
setSubsets(subsets.map((subset) => ({ value: subset, label: subset })));
if (subsets.length > 0) {
setSubsets(subsets.map((subset) => ({ value: subset, label: subset })));
}
const variants = fonts.find((font) => font.family === typography.font.family)?.variants ?? [];
setVariants(variants.map((variant) => ({ value: variant, label: variant })));
if (variants.length > 0) {
setVariants(variants.map((variant) => ({ value: variant, label: variant })));
}
}, [typography.font.family]);
return (
@ -69,31 +78,33 @@ export const TypographySection = () => {
<main className="grid gap-y-6">
<div className="grid grid-cols-2 gap-4">
{fontSuggestions.map((font) => (
<Button
key={font}
variant="outline"
style={{ fontFamily: font }}
disabled={typography.font.family === font}
className={cn(
"flex h-12 items-center justify-center overflow-hidden rounded border text-center text-xs ring-primary transition-colors hover:bg-secondary-accent focus:outline-none focus:ring-1 disabled:opacity-100 lg:text-sm",
typography.font.family === font && "ring-1",
)}
onClick={() => {
setValue("metadata.typography.font.family", font);
setValue("metadata.typography.font.subset", "latin");
setValue("metadata.typography.font.variants", ["regular"]);
}}
>
{font}
</Button>
))}
{fontSuggestions
.sort((a, b) => a.localeCompare(b))
.map((font) => (
<Button
key={font}
variant="outline"
style={{ fontFamily: font }}
disabled={typography.font.family === font}
className={cn(
"flex h-12 items-center justify-center overflow-hidden rounded border text-center text-xs ring-primary transition-colors hover:bg-secondary-accent focus:outline-none focus:ring-1 disabled:opacity-100 lg:text-sm",
typography.font.family === font && "ring-1",
)}
onClick={() => {
setValue("metadata.typography.font.family", font);
setValue("metadata.typography.font.subset", "latin");
setValue("metadata.typography.font.variants", ["regular"]);
}}
>
{font}
</Button>
))}
</div>
<div className="space-y-1.5">
<Label>{t`Font Family`}</Label>
<Combobox
options={families}
options={families.sort((a, b) => a.label.localeCompare(b.label))}
value={typography.font.family}
searchPlaceholder={t`Search for a font family`}
onValueChange={(value) => {

View File

@ -1,9 +1,8 @@
import { HttpService } from "@nestjs/axios";
import { Injectable, InternalServerErrorException, Logger } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import fontkit from "@pdf-lib/fontkit";
import { ResumeDto } from "@reactive-resume/dto";
import { ErrorMessage, getFontUrls } from "@reactive-resume/utils";
import { ErrorMessage } from "@reactive-resume/utils";
import retry from "async-retry";
import { PDFDocument } from "pdf-lib";
import { connect } from "puppeteer";
@ -150,7 +149,7 @@ export class PrinterService {
return temporaryHtml_;
}, pageElement);
// Apply custom CSS if enabled
// Apply custom CSS, if enabled
const css = resume.data.metadata.css;
if (css.visible) {
@ -177,24 +176,6 @@ export class PrinterService {
// Using 'pdf-lib', merge all the pages from their buffers into a single PDF
const pdf = await PDFDocument.create();
pdf.registerFontkit(fontkit);
// Get information about fonts used in the resume from the metadata
const fontData = resume.data.metadata.typography.font;
const fontUrls = getFontUrls(fontData.family, fontData.variants);
// Load all the fonts from the URLs using HttpService
const responses = await Promise.all(
fontUrls.map((url) =>
this.httpService.axiosRef.get(url, {
responseType: "arraybuffer",
}),
),
);
const fontsBuffer = responses.map((response) => response.data as ArrayBuffer);
// Embed all the fonts in the PDF
await Promise.all(fontsBuffer.map((buffer) => pdf.embedFont(buffer)));
for (const element of pagesBuffer) {
const page = await PDFDocument.load(element);

View File

@ -145,7 +145,6 @@
"@nestjs/swagger": "^7.4.2",
"@nestjs/terminus": "^10.3.0",
"@paralleldrive/cuid2": "^2.2.2",
"@pdf-lib/fontkit": "^1.1.1",
"@phosphor-icons/react": "^2.1.7",
"@prisma/client": "^5.22.0",
"@radix-ui/react-accordion": "^1.2.2",

10
pnpm-lock.yaml generated
View File

@ -74,9 +74,6 @@ importers:
'@paralleldrive/cuid2':
specifier: ^2.2.2
version: 2.2.2
'@pdf-lib/fontkit':
specifier: ^1.1.1
version: 1.1.1
'@phosphor-icons/react':
specifier: ^2.1.7
version: 2.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@ -2976,9 +2973,6 @@ packages:
'@paralleldrive/cuid2@2.2.2':
resolution: {integrity: sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==}
'@pdf-lib/fontkit@1.1.1':
resolution: {integrity: sha512-KjMd7grNapIWS/Dm0gvfHEilSyAmeLvrEGVcqLGi0VYebuqqzTbgF29efCx7tvx+IEbG3zQciRSWl3GkUSvjZg==}
'@pdf-lib/standard-fonts@1.0.0':
resolution: {integrity: sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA==}
@ -14607,10 +14601,6 @@ snapshots:
dependencies:
'@noble/hashes': 1.3.3
'@pdf-lib/fontkit@1.1.1':
dependencies:
pako: 1.0.11
'@pdf-lib/standard-fonts@1.0.0':
dependencies:
pako: 1.0.11