mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2025-11-15 01:01:43 +10:00
- 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:
@ -11,23 +11,28 @@ import { useResumeStore } from "@/client/stores/resume";
|
|||||||
|
|
||||||
import { SectionIcon } from "../shared/section-icon";
|
import { SectionIcon } from "../shared/section-icon";
|
||||||
|
|
||||||
|
const localFonts = ["Arial", "Cambria", "Garamond", "Times New Roman"];
|
||||||
|
|
||||||
const fontSuggestions = [
|
const fontSuggestions = [
|
||||||
"Open Sans",
|
...localFonts,
|
||||||
"Merriweather",
|
|
||||||
"Roboto Condensed",
|
|
||||||
"Playfair Display",
|
|
||||||
"Lato",
|
|
||||||
"Lora",
|
|
||||||
"PT Sans",
|
|
||||||
"PT Serif",
|
|
||||||
"IBM Plex Sans",
|
"IBM Plex Sans",
|
||||||
"IBM Plex Serif",
|
"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,
|
value: font.family,
|
||||||
label: font.family,
|
label: font.family,
|
||||||
}));
|
})) satisfies ComboboxOption[];
|
||||||
|
|
||||||
|
families.push(...localFonts.map((font) => ({ value: font, label: font })));
|
||||||
|
|
||||||
export const TypographySection = () => {
|
export const TypographySection = () => {
|
||||||
const [subsets, setSubsets] = useState<ComboboxOption[]>([]);
|
const [subsets, setSubsets] = useState<ComboboxOption[]>([]);
|
||||||
@ -52,10 +57,14 @@ export const TypographySection = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const subsets = fonts.find((font) => font.family === typography.font.family)?.subsets ?? [];
|
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 ?? [];
|
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]);
|
}, [typography.font.family]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -69,31 +78,33 @@ export const TypographySection = () => {
|
|||||||
|
|
||||||
<main className="grid gap-y-6">
|
<main className="grid gap-y-6">
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
{fontSuggestions.map((font) => (
|
{fontSuggestions
|
||||||
<Button
|
.sort((a, b) => a.localeCompare(b))
|
||||||
key={font}
|
.map((font) => (
|
||||||
variant="outline"
|
<Button
|
||||||
style={{ fontFamily: font }}
|
key={font}
|
||||||
disabled={typography.font.family === font}
|
variant="outline"
|
||||||
className={cn(
|
style={{ fontFamily: font }}
|
||||||
"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",
|
disabled={typography.font.family === font}
|
||||||
typography.font.family === font && "ring-1",
|
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",
|
||||||
onClick={() => {
|
typography.font.family === font && "ring-1",
|
||||||
setValue("metadata.typography.font.family", font);
|
)}
|
||||||
setValue("metadata.typography.font.subset", "latin");
|
onClick={() => {
|
||||||
setValue("metadata.typography.font.variants", ["regular"]);
|
setValue("metadata.typography.font.family", font);
|
||||||
}}
|
setValue("metadata.typography.font.subset", "latin");
|
||||||
>
|
setValue("metadata.typography.font.variants", ["regular"]);
|
||||||
{font}
|
}}
|
||||||
</Button>
|
>
|
||||||
))}
|
{font}
|
||||||
|
</Button>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-1.5">
|
<div className="space-y-1.5">
|
||||||
<Label>{t`Font Family`}</Label>
|
<Label>{t`Font Family`}</Label>
|
||||||
<Combobox
|
<Combobox
|
||||||
options={families}
|
options={families.sort((a, b) => a.label.localeCompare(b.label))}
|
||||||
value={typography.font.family}
|
value={typography.font.family}
|
||||||
searchPlaceholder={t`Search for a font family`}
|
searchPlaceholder={t`Search for a font family`}
|
||||||
onValueChange={(value) => {
|
onValueChange={(value) => {
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
import { HttpService } from "@nestjs/axios";
|
import { HttpService } from "@nestjs/axios";
|
||||||
import { Injectable, InternalServerErrorException, Logger } from "@nestjs/common";
|
import { Injectable, InternalServerErrorException, Logger } from "@nestjs/common";
|
||||||
import { ConfigService } from "@nestjs/config";
|
import { ConfigService } from "@nestjs/config";
|
||||||
import fontkit from "@pdf-lib/fontkit";
|
|
||||||
import { ResumeDto } from "@reactive-resume/dto";
|
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 retry from "async-retry";
|
||||||
import { PDFDocument } from "pdf-lib";
|
import { PDFDocument } from "pdf-lib";
|
||||||
import { connect } from "puppeteer";
|
import { connect } from "puppeteer";
|
||||||
@ -150,7 +149,7 @@ export class PrinterService {
|
|||||||
return temporaryHtml_;
|
return temporaryHtml_;
|
||||||
}, pageElement);
|
}, pageElement);
|
||||||
|
|
||||||
// Apply custom CSS if enabled
|
// Apply custom CSS, if enabled
|
||||||
const css = resume.data.metadata.css;
|
const css = resume.data.metadata.css;
|
||||||
|
|
||||||
if (css.visible) {
|
if (css.visible) {
|
||||||
@ -177,24 +176,6 @@ export class PrinterService {
|
|||||||
|
|
||||||
// Using 'pdf-lib', merge all the pages from their buffers into a single PDF
|
// Using 'pdf-lib', merge all the pages from their buffers into a single PDF
|
||||||
const pdf = await PDFDocument.create();
|
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) {
|
for (const element of pagesBuffer) {
|
||||||
const page = await PDFDocument.load(element);
|
const page = await PDFDocument.load(element);
|
||||||
|
|||||||
@ -145,7 +145,6 @@
|
|||||||
"@nestjs/swagger": "^7.4.2",
|
"@nestjs/swagger": "^7.4.2",
|
||||||
"@nestjs/terminus": "^10.3.0",
|
"@nestjs/terminus": "^10.3.0",
|
||||||
"@paralleldrive/cuid2": "^2.2.2",
|
"@paralleldrive/cuid2": "^2.2.2",
|
||||||
"@pdf-lib/fontkit": "^1.1.1",
|
|
||||||
"@phosphor-icons/react": "^2.1.7",
|
"@phosphor-icons/react": "^2.1.7",
|
||||||
"@prisma/client": "^5.22.0",
|
"@prisma/client": "^5.22.0",
|
||||||
"@radix-ui/react-accordion": "^1.2.2",
|
"@radix-ui/react-accordion": "^1.2.2",
|
||||||
|
|||||||
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
@ -74,9 +74,6 @@ importers:
|
|||||||
'@paralleldrive/cuid2':
|
'@paralleldrive/cuid2':
|
||||||
specifier: ^2.2.2
|
specifier: ^2.2.2
|
||||||
version: 2.2.2
|
version: 2.2.2
|
||||||
'@pdf-lib/fontkit':
|
|
||||||
specifier: ^1.1.1
|
|
||||||
version: 1.1.1
|
|
||||||
'@phosphor-icons/react':
|
'@phosphor-icons/react':
|
||||||
specifier: ^2.1.7
|
specifier: ^2.1.7
|
||||||
version: 2.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
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':
|
'@paralleldrive/cuid2@2.2.2':
|
||||||
resolution: {integrity: sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==}
|
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':
|
'@pdf-lib/standard-fonts@1.0.0':
|
||||||
resolution: {integrity: sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA==}
|
resolution: {integrity: sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA==}
|
||||||
|
|
||||||
@ -14607,10 +14601,6 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@noble/hashes': 1.3.3
|
'@noble/hashes': 1.3.3
|
||||||
|
|
||||||
'@pdf-lib/fontkit@1.1.1':
|
|
||||||
dependencies:
|
|
||||||
pako: 1.0.11
|
|
||||||
|
|
||||||
'@pdf-lib/standard-fonts@1.0.0':
|
'@pdf-lib/standard-fonts@1.0.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
pako: 1.0.11
|
pako: 1.0.11
|
||||||
|
|||||||
Reference in New Issue
Block a user