mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-06-22 04:11:55 +10:00
dd7623f11e
* fix(pdf): align textkit line-box and font metrics to browser behaviour CJK characters in resumes with a tightened typography line-height (< ~1.4) had their descenders clipped by the next line. Latin glyphs in the same resume rendered fine. Fixes the visual regression vs the v5.0.x Puppeteer-based renderer reported in issue #2986 and follow-ups. The clipping is caused by two independent gaps in @react-pdf/textkit relative to standard CSS line-box rules: 1. `height(run)` short-circuits to the user-supplied lineHeight and ignores the run's intrinsic ascent + descent. CSS line-boxes are spec'd as `max(line-height, content-area)` — when CJK glyphs are present the content-area is taller than a tightened lineHeight, so the box must grow. textkit didn't, so the baseline (computed from the real, larger CJK ascent) sat below the box and the descender bled into the next line. 2. `ascent / descent / lineGap` are read directly from fontkit's hhea defaults. For Source Han Sans/Serif (the CJK fallbacks registered in #3013) hhea is intentionally inflated for legacy Windows GDI compatibility (1.45 em vs 1.0 em), so even a fixed line-box would have been excessively tall. Browsers (and the v5.0.x Puppeteer renderer) read OS/2 sTypoAscender/Descender/LineGap instead, which are the values the type designers intend for modern shaping. Both are upstream behaviours of `@react-pdf/textkit`, but waiting for an upstream release would leave existing users with broken CJK output. The fix is shipped as a pnpm patch (~30 LOC): - `resolveTypoMetrics(font)`: prefer OS/2 typo metrics, fall back to hhea when an OS/2 table is absent (e.g. the StandardFont stand-ins for Helvetica/Courier/Times). Used by ascent/descent/lineGap so all height-related calculations stay consistent. - `height(run)`: `Math.max(lineHeight || 0, intrinsic)` instead of the original short-circuit, matching CSS line-box rules. The patch is self-contained: existing Latin-only resumes are unaffected (IBM Plex Serif's typo metrics equal hhea; Roboto's typo is slightly smaller, but only changes the rendered line-box for users who set lineHeight below ~1.17, which already used to clip ascenders under v5.1.x and now lays out as it would in a browser). Tooling notes: - `Dockerfile.dev` copies `patches/` before `pnpm install` so the dev image build no longer fails on `--frozen-lockfile`. The production `Dockerfile` already gets it for free via `turbo prune --docker` (the patch reference in package.json marks the directory as part of the pruned slice). - The patch will become a no-op once an equivalent fix lands upstream in @react-pdf/textkit; the entry can then be removed from `pnpm.patchedDependencies` and the file deleted. * fix(deps): regenerate lockfile and move patchedDependencies for pnpm 11 The previous commit's lockfile was authored by pnpm 8 (lockfileVersion 6.0) and kept patchedDependencies under package.json#pnpm. The repository now declares packageManager: pnpm@11.1.2, which: - writes lockfileVersion 9.0 and rejects v6 with ERR_PNPM_LOCKFILE_BREAKING_CHANGE on --frozen-lockfile (CI failure observed in autofix.ci); - reads pnpm settings from pnpm-workspace.yaml, silently ignoring the package.json#pnpm field — so the textkit patch was no longer applied. Regenerate pnpm-lock.yaml with pnpm 11.1.2 and move patchedDependencies to pnpm-workspace.yaml so the patch is applied and CI passes. * chore: update dependencies --------- Co-authored-by: Amruth Pillai <im.amruth@gmail.com>
29 lines
968 B
JSON
29 lines
968 B
JSON
{
|
|
"name": "@reactive-resume/env",
|
|
"version": "0.0.0",
|
|
"type": "module",
|
|
"private": true,
|
|
"exports": {
|
|
"./server": "./src/server.ts"
|
|
},
|
|
"scripts": {
|
|
"typecheck": "tsgo --noEmit",
|
|
"test": "vitest run --passWithNoTests",
|
|
"test:coverage": "vitest run --coverage --passWithNoTests",
|
|
"test:ci": "vitest run --coverage --reporter=default --reporter=github-actions --reporter=json --reporter=junit --outputFile.json=reports/vitest-results.json --outputFile.junit=reports/vitest-junit.xml --passWithNoTests",
|
|
"test:agent": "vitest run --reporter=agent --reporter=json --outputFile.json=reports/vitest-results.json --passWithNoTests"
|
|
},
|
|
"dependencies": {
|
|
"@reactive-resume/utils": "workspace:*",
|
|
"@t3-oss/env-core": "^0.13.11",
|
|
"dotenv": "^17.4.2",
|
|
"zod": "^4.4.3"
|
|
},
|
|
"devDependencies": {
|
|
"@reactive-resume/config": "workspace:*",
|
|
"@types/node": "^25.8.0",
|
|
"@typescript/native-preview": "7.0.0-dev.20260517.1",
|
|
"typescript": "^6.0.3"
|
|
}
|
|
}
|