Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 35 additions & 18 deletions apps/web/src/components/project-controls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ import { useRef, useState } from 'react'
import { Download, Upload } from 'lucide-react'

import { Button } from '@/components/ui/button'
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from '@/components/ui/tooltip'
import { downloadProject, importProject } from '@/lib/project'
import { usePhotoStore } from '@/stores/photo-store'
import { settingsSnapshot, useSettingsStore } from '@/stores/settings-store'
Expand Down Expand Up @@ -53,24 +58,36 @@ export function ProjectControls() {
event.target.value = ''
}}
/>
<Button
variant="outline"
size="sm"
disabled={busy}
onClick={() => inputRef.current?.click()}
>
<Upload className="size-3.5" />
Open
</Button>
<Button
variant="outline"
size="sm"
disabled={busy || photos.length === 0}
onClick={() => void handleSave()}
>
<Download className="size-3.5" />
Save
</Button>
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="outline"
size="icon"
className="size-8"
aria-label="Open project"
disabled={busy}
onClick={() => inputRef.current?.click()}
>
<Upload className="size-4" />
</Button>
</TooltipTrigger>
<TooltipContent>Open project</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="outline"
size="icon"
className="size-8"
aria-label="Save project"
disabled={busy || photos.length === 0}
onClick={() => void handleSave()}
>
<Download className="size-4" />
</Button>
</TooltipTrigger>
<TooltipContent>Save project</TooltipContent>
</Tooltip>
</div>
{error && <span className="text-destructive text-xs">{error}</span>}
</div>
Expand Down
9 changes: 5 additions & 4 deletions apps/web/src/lib/pdf-fonts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import patrickHandUrl from '@/fonts/PatrickHand-Regular.ttf?url'
import shadowsUrl from '@/fonts/ShadowsIntoLight-Regular.ttf?url'

// Static TTFs for the handwriting caption fonts, so the exported PDF matches the
// on-screen preview. Only fonts that render faithfully in pdf-lib (which has no
// GPOS kerning) are offered — Caveat, a connected script, was dropped for this
// reason (see #23).
// on-screen preview. We embed the FULL font (no subsetting): pdf-lib's subsetter
// drops glyphs for some of these — Kalam came out as scattered half-words — and
// the size cost is trivial next to the 300-DPI photos. Connected scripts that
// rely on GPOS kerning pdf-lib lacks (e.g. Caveat) are still excluded (see #23).
const PDF_FONT_URLS: Record<string, string> = {
'indie-flower': indieFlowerUrl,
'patrick-hand': patrickHandUrl,
Expand Down Expand Up @@ -40,7 +41,7 @@ export async function embedCaptionFont(
if (!url) return null
try {
doc.registerFontkit(fontkit)
return await doc.embedFont(await fontBytes(url), { subset: true })
return await doc.embedFont(await fontBytes(url), { subset: false })
} catch {
return null
}
Expand Down
6 changes: 6 additions & 0 deletions apps/web/src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
--foreground: oklch(0.145 0 0);
--card: oklch(1 0 0);
--card-foreground: oklch(0.145 0 0);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.145 0 0);
--primary: oklch(0.205 0 0);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0);
Expand All @@ -30,6 +32,8 @@
--foreground: oklch(0.985 0 0);
--card: oklch(0.205 0 0);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.205 0 0);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.985 0 0);
--primary-foreground: oklch(0.205 0 0);
--secondary: oklch(0.269 0 0);
Expand All @@ -53,6 +57,8 @@
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
Expand Down
Loading