postext-pdf 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +67 -0
- package/dist/__bench__/render.bench.test.d.ts +2 -0
- package/dist/__bench__/render.bench.test.d.ts.map +1 -0
- package/dist/__bench__/render.bench.test.js +86 -0
- package/dist/__bench__/render.bench.test.js.map +1 -0
- package/dist/__tests__/accessibility.test.d.ts +2 -0
- package/dist/__tests__/accessibility.test.d.ts.map +1 -0
- package/dist/__tests__/accessibility.test.js +364 -0
- package/dist/__tests__/accessibility.test.js.map +1 -0
- package/dist/__tests__/contentsLinks.test.d.ts +2 -0
- package/dist/__tests__/contentsLinks.test.d.ts.map +1 -0
- package/dist/__tests__/contentsLinks.test.js +131 -0
- package/dist/__tests__/contentsLinks.test.js.map +1 -0
- package/dist/__tests__/fontCache.test.d.ts +2 -0
- package/dist/__tests__/fontCache.test.d.ts.map +1 -0
- package/dist/__tests__/fontCache.test.js +42 -0
- package/dist/__tests__/fontCache.test.js.map +1 -0
- package/dist/__tests__/headerFooter.test.d.ts +2 -0
- package/dist/__tests__/headerFooter.test.d.ts.map +1 -0
- package/dist/__tests__/headerFooter.test.js +68 -0
- package/dist/__tests__/headerFooter.test.js.map +1 -0
- package/dist/__tests__/rotatedTable.test.d.ts +2 -0
- package/dist/__tests__/rotatedTable.test.d.ts.map +1 -0
- package/dist/__tests__/rotatedTable.test.js +112 -0
- package/dist/__tests__/rotatedTable.test.js.map +1 -0
- package/dist/__tests__/svgVector.test.d.ts +2 -0
- package/dist/__tests__/svgVector.test.d.ts.map +1 -0
- package/dist/__tests__/svgVector.test.js +322 -0
- package/dist/__tests__/svgVector.test.js.map +1 -0
- package/dist/__tests__/toUnicode.test.d.ts +2 -0
- package/dist/__tests__/toUnicode.test.d.ts.map +1 -0
- package/dist/__tests__/toUnicode.test.js +57 -0
- package/dist/__tests__/toUnicode.test.js.map +1 -0
- package/dist/colors.d.ts +23 -0
- package/dist/colors.d.ts.map +1 -0
- package/dist/colors.js +47 -0
- package/dist/colors.js.map +1 -0
- package/dist/fontCache.d.ts +41 -0
- package/dist/fontCache.d.ts.map +1 -0
- package/dist/fontCache.js +154 -0
- package/dist/fontCache.js.map +1 -0
- package/dist/fontString.d.ts +14 -0
- package/dist/fontString.d.ts.map +1 -0
- package/dist/fontString.js +43 -0
- package/dist/fontString.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/pdf-backend/blockRender.d.ts +15 -0
- package/dist/pdf-backend/blockRender.d.ts.map +1 -0
- package/dist/pdf-backend/blockRender.js +244 -0
- package/dist/pdf-backend/blockRender.js.map +1 -0
- package/dist/pdf-backend/fontHelpers.d.ts +6 -0
- package/dist/pdf-backend/fontHelpers.d.ts.map +1 -0
- package/dist/pdf-backend/fontHelpers.js +81 -0
- package/dist/pdf-backend/fontHelpers.js.map +1 -0
- package/dist/pdf-backend/headerFooter.d.ts +15 -0
- package/dist/pdf-backend/headerFooter.d.ts.map +1 -0
- package/dist/pdf-backend/headerFooter.js +145 -0
- package/dist/pdf-backend/headerFooter.js.map +1 -0
- package/dist/pdf-backend/index.d.ts +47 -0
- package/dist/pdf-backend/index.d.ts.map +1 -0
- package/dist/pdf-backend/index.js +227 -0
- package/dist/pdf-backend/index.js.map +1 -0
- package/dist/pdf-backend/links.d.ts +44 -0
- package/dist/pdf-backend/links.d.ts.map +1 -0
- package/dist/pdf-backend/links.js +110 -0
- package/dist/pdf-backend/links.js.map +1 -0
- package/dist/pdf-backend/outlines.d.ts +8 -0
- package/dist/pdf-backend/outlines.d.ts.map +1 -0
- package/dist/pdf-backend/outlines.js +145 -0
- package/dist/pdf-backend/outlines.js.map +1 -0
- package/dist/pdf-backend/pageDecorations.d.ts +13 -0
- package/dist/pdf-backend/pageDecorations.d.ts.map +1 -0
- package/dist/pdf-backend/pageDecorations.js +88 -0
- package/dist/pdf-backend/pageDecorations.js.map +1 -0
- package/dist/pdf-backend/pageLabels.d.ts +8 -0
- package/dist/pdf-backend/pageLabels.d.ts.map +1 -0
- package/dist/pdf-backend/pageLabels.js +61 -0
- package/dist/pdf-backend/pageLabels.js.map +1 -0
- package/dist/pdf-backend/primitives.d.ts +46 -0
- package/dist/pdf-backend/primitives.d.ts.map +1 -0
- package/dist/pdf-backend/primitives.js +162 -0
- package/dist/pdf-backend/primitives.js.map +1 -0
- package/dist/pdf-backend/renderResourceBlock.d.ts +87 -0
- package/dist/pdf-backend/renderResourceBlock.d.ts.map +1 -0
- package/dist/pdf-backend/renderResourceBlock.js +753 -0
- package/dist/pdf-backend/renderResourceBlock.js.map +1 -0
- package/dist/pdf-backend/structureFlow.d.ts +55 -0
- package/dist/pdf-backend/structureFlow.d.ts.map +1 -0
- package/dist/pdf-backend/structureFlow.js +180 -0
- package/dist/pdf-backend/structureFlow.js.map +1 -0
- package/dist/pdf-backend/svgVector.d.ts +144 -0
- package/dist/pdf-backend/svgVector.d.ts.map +1 -0
- package/dist/pdf-backend/svgVector.js +1455 -0
- package/dist/pdf-backend/svgVector.js.map +1 -0
- package/dist/pdf-backend/tagging.d.ts +136 -0
- package/dist/pdf-backend/tagging.d.ts.map +1 -0
- package/dist/pdf-backend/tagging.js +296 -0
- package/dist/pdf-backend/tagging.js.map +1 -0
- package/dist/woff2.d.ts +11 -0
- package/dist/woff2.d.ts.map +1 -0
- package/dist/woff2.js +47 -0
- package/dist/woff2.js.map +1 -0
- package/dist/worker/client.d.ts +30 -0
- package/dist/worker/client.d.ts.map +1 -0
- package/dist/worker/client.js +112 -0
- package/dist/worker/client.js.map +1 -0
- package/dist/worker/pdf.worker.d.ts +2 -0
- package/dist/worker/pdf.worker.d.ts.map +1 -0
- package/dist/worker/pdf.worker.js +67 -0
- package/dist/worker/pdf.worker.js.map +1 -0
- package/dist/worker/protocol.d.ts +49 -0
- package/dist/worker/protocol.d.ts.map +1 -0
- package/dist/worker/protocol.js +2 -0
- package/dist/worker/protocol.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { fontKey, parseFontString } from './fontString';
|
|
2
|
+
/** True when `bytes` starts with the `OTTO` magic identifying a CFF-flavored
|
|
3
|
+
* OpenType font — the ones pdf-lib cannot subset reliably, so they embed
|
|
4
|
+
* whole (see `preloadFontStrings`). */
|
|
5
|
+
function isCffOpenType(bytes) {
|
|
6
|
+
return (bytes.length >= 4 &&
|
|
7
|
+
bytes[0] === 0x4f && // O
|
|
8
|
+
bytes[1] === 0x54 && // T
|
|
9
|
+
bytes[2] === 0x54 && // T
|
|
10
|
+
bytes[3] === 0x4f // O
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
/** pdf-lib builds a CID font's `W` (advance widths) array from the glyphs
|
|
14
|
+
* reachable through the cmap, so a face embedded whole leaves every
|
|
15
|
+
* GSUB-only glyph — the fi/fl ligatures, contextual alternates — at the
|
|
16
|
+
* default 1000-unit advance, and viewers draw "refl eja" with a gap after
|
|
17
|
+
* the ligature (or the next glyph overlapping it). Replace the width
|
|
18
|
+
* computation with one that covers every glyph in the face. */
|
|
19
|
+
export function coverAllGlyphWidths(font) {
|
|
20
|
+
const embedder = font.embedder;
|
|
21
|
+
const face = embedder.font;
|
|
22
|
+
const toPdfUnits = 1000 / face.unitsPerEm;
|
|
23
|
+
embedder.computeWidths = () => {
|
|
24
|
+
const widths = [];
|
|
25
|
+
for (let gid = 0; gid < face.numGlyphs; gid++) {
|
|
26
|
+
widths.push(face.getGlyph(gid).advanceWidth * toPdfUnits);
|
|
27
|
+
}
|
|
28
|
+
return [0, widths];
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/** UTF-16BE hex of a code point sequence, for a CMap `bfchar` destination. */
|
|
32
|
+
function utf16Hex(codePoints) {
|
|
33
|
+
let out = '';
|
|
34
|
+
for (const cp of codePoints) {
|
|
35
|
+
if (cp > 0xffff) {
|
|
36
|
+
const v = cp - 0x10000;
|
|
37
|
+
out += (0xd800 + (v >> 10)).toString(16).padStart(4, '0') + (0xdc00 + (v & 0x3ff)).toString(16).padStart(4, '0');
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
out += cp.toString(16).padStart(4, '0');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
/** A ToUnicode CMap (Identity-H codes = glyph ids) for the given glyphs. */
|
|
46
|
+
export function toUnicodeCmap(glyphs) {
|
|
47
|
+
const entries = glyphs
|
|
48
|
+
.filter((g) => g.codePoints.length > 0)
|
|
49
|
+
.sort((a, b) => a.id - b.id)
|
|
50
|
+
.map((g) => `<${g.id.toString(16).padStart(4, '0')}> <${utf16Hex(g.codePoints)}>`);
|
|
51
|
+
let blocks = '';
|
|
52
|
+
for (let i = 0; i < entries.length; i += 100) {
|
|
53
|
+
const chunk = entries.slice(i, i + 100);
|
|
54
|
+
blocks += `${chunk.length} beginbfchar\n${chunk.join('\n')}\nendbfchar\n`;
|
|
55
|
+
}
|
|
56
|
+
return ('/CIDInit /ProcSet findresource begin\n12 dict begin\nbegincmap\n' +
|
|
57
|
+
'/CIDSystemInfo <<\n /Registry (Adobe)\n /Ordering (UCS)\n /Supplement 0\n>> def\n' +
|
|
58
|
+
'/CMapName /Adobe-Identity-UCS def\n/CMapType 2 def\n' +
|
|
59
|
+
'1 begincodespacerange\n<0000><ffff>\nendcodespacerange\n' +
|
|
60
|
+
blocks +
|
|
61
|
+
'endcmap\nCMapName currentdict /CMap defineresource pop\nend\nend\n');
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* A fully embedded face gets a ToUnicode map covering only the glyphs its
|
|
65
|
+
* cmap reaches, so a ligature the shaper substitutes (`fi`, `fl`, `ffi`)
|
|
66
|
+
* has no Unicode value: text extraction drops the letters and PDF/UA
|
|
67
|
+
* validators reject the font (ISO 14289-1 §7.21.7). Record every glyph the
|
|
68
|
+
* layout engine produces for the text actually set — its `codePoints` are
|
|
69
|
+
* the characters it stands for, ligatures included — and write the map
|
|
70
|
+
* from the cmap glyphs plus those.
|
|
71
|
+
*/
|
|
72
|
+
export function coverAllGlyphUnicode(font) {
|
|
73
|
+
const embedder = font.embedder;
|
|
74
|
+
const face = embedder.font;
|
|
75
|
+
const shaped = new Map();
|
|
76
|
+
const layout = face.layout.bind(face);
|
|
77
|
+
face.layout = (text, features) => {
|
|
78
|
+
const run = layout(text, features);
|
|
79
|
+
for (const g of run.glyphs) {
|
|
80
|
+
if (g.codePoints.length > 0 && !shaped.has(g.id))
|
|
81
|
+
shaped.set(g.id, g.codePoints);
|
|
82
|
+
}
|
|
83
|
+
return run;
|
|
84
|
+
};
|
|
85
|
+
embedder.embedUnicodeCmap = (context) => {
|
|
86
|
+
const glyphs = [...embedder.glyphCache.access()];
|
|
87
|
+
const known = new Set(glyphs.map((g) => g.id));
|
|
88
|
+
for (const [id, codePoints] of shaped)
|
|
89
|
+
if (!known.has(id))
|
|
90
|
+
glyphs.push({ id, codePoints });
|
|
91
|
+
return context.register(context.flateStream(toUnicodeCmap(glyphs)));
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Per-document mapping from `family|weight|style` to an embedded pdf-lib
|
|
96
|
+
* font. Entries are populated up-front by `preload()` so that block-level
|
|
97
|
+
* rendering (`get()`) is a sync lookup. A fontString that fails to parse or
|
|
98
|
+
* to load is mapped to `null` and reported back via `missing()`.
|
|
99
|
+
*/
|
|
100
|
+
export class FontCache {
|
|
101
|
+
pdfDoc;
|
|
102
|
+
provider;
|
|
103
|
+
map = new Map();
|
|
104
|
+
failed = new Set();
|
|
105
|
+
constructor(pdfDoc, provider) {
|
|
106
|
+
this.pdfDoc = pdfDoc;
|
|
107
|
+
this.provider = provider;
|
|
108
|
+
}
|
|
109
|
+
async preloadFontStrings(fontStrings) {
|
|
110
|
+
const jobs = new Map();
|
|
111
|
+
for (const fs of fontStrings) {
|
|
112
|
+
if (!fs)
|
|
113
|
+
continue;
|
|
114
|
+
const parsed = parseFontString(fs);
|
|
115
|
+
if (!parsed)
|
|
116
|
+
continue;
|
|
117
|
+
const key = fontKey(parsed.family, parsed.weight, parsed.style);
|
|
118
|
+
if (this.map.has(key) || jobs.has(key))
|
|
119
|
+
continue;
|
|
120
|
+
jobs.set(key, { family: parsed.family, weight: parsed.weight, style: parsed.style });
|
|
121
|
+
}
|
|
122
|
+
await Promise.all(Array.from(jobs.entries()).map(async ([key, spec]) => {
|
|
123
|
+
try {
|
|
124
|
+
const bytes = await this.provider(spec.family, spec.weight, spec.style);
|
|
125
|
+
// pdf-lib's CFF subsetter emits a font stream some viewers cannot
|
|
126
|
+
// parse (macOS Preview draws the text in a fallback face), so CFF
|
|
127
|
+
// OpenType (.otf, signature `OTTO`) embeds whole — larger PDF, but
|
|
128
|
+
// every viewer reads it. TrueType fonts subset normally.
|
|
129
|
+
const subset = !isCffOpenType(bytes);
|
|
130
|
+
const font = await this.pdfDoc.embedFont(bytes, { subset });
|
|
131
|
+
if (!subset) {
|
|
132
|
+
coverAllGlyphWidths(font);
|
|
133
|
+
coverAllGlyphUnicode(font);
|
|
134
|
+
}
|
|
135
|
+
this.map.set(key, font);
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
this.failed.add(`${spec.family} ${spec.weight}${spec.style === 'italic' ? ' italic' : ''}`);
|
|
139
|
+
this.map.set(key, null);
|
|
140
|
+
}
|
|
141
|
+
}));
|
|
142
|
+
}
|
|
143
|
+
get(fontString) {
|
|
144
|
+
const parsed = parseFontString(fontString);
|
|
145
|
+
if (!parsed)
|
|
146
|
+
return null;
|
|
147
|
+
const key = fontKey(parsed.family, parsed.weight, parsed.style);
|
|
148
|
+
return this.map.get(key) ?? null;
|
|
149
|
+
}
|
|
150
|
+
missing() {
|
|
151
|
+
return [...this.failed];
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=fontCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fontCache.js","sourceRoot":"","sources":["../src/fontCache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface ParsedFontString {
|
|
2
|
+
family: string;
|
|
3
|
+
weight: number;
|
|
4
|
+
style: 'normal' | 'italic';
|
|
5
|
+
sizePx: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Parse a CSS-canvas font shorthand of the form produced by `buildFontString()`
|
|
9
|
+
* in the `postext` package (e.g. `italic 700 16px "EB Garamond"`). The regex
|
|
10
|
+
* mirrors `html-backend.ts` so exactly the same shapes are accepted.
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseFontString(fs: string): ParsedFontString | null;
|
|
13
|
+
export declare function fontKey(family: string, weight: number, style: 'normal' | 'italic'): string;
|
|
14
|
+
//# sourceMappingURL=fontString.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fontString.d.ts","sourceRoot":"","sources":["../src/fontString.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAMnE;AAwBD,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAE1F"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse a CSS-canvas font shorthand of the form produced by `buildFontString()`
|
|
3
|
+
* in the `postext` package (e.g. `italic 700 16px "EB Garamond"`). The regex
|
|
4
|
+
* mirrors `html-backend.ts` so exactly the same shapes are accepted.
|
|
5
|
+
*/
|
|
6
|
+
export function parseFontString(fs) {
|
|
7
|
+
const cached = parsedFontStrings.get(fs);
|
|
8
|
+
if (cached !== undefined)
|
|
9
|
+
return cached;
|
|
10
|
+
const parsed = parseFontStringUncached(fs);
|
|
11
|
+
parsedFontStrings.set(fs, parsed);
|
|
12
|
+
return parsed;
|
|
13
|
+
}
|
|
14
|
+
// Memoized: parsing runs per rendered text segment but a document only uses
|
|
15
|
+
// a handful of distinct font strings. Results are treated as read-only.
|
|
16
|
+
const parsedFontStrings = new Map();
|
|
17
|
+
function parseFontStringUncached(fs) {
|
|
18
|
+
const m = fs.match(/^(.*?)(\d+(?:\.\d+)?)px\s+(.+)$/);
|
|
19
|
+
if (!m)
|
|
20
|
+
return null;
|
|
21
|
+
const prefix = (m[1] ?? '').trim();
|
|
22
|
+
const sizePx = parseFloat(m[2]);
|
|
23
|
+
const family = (m[3] ?? '').trim().replace(/^['"]|['"]$/g, '');
|
|
24
|
+
let style = 'normal';
|
|
25
|
+
let weight = 400;
|
|
26
|
+
for (const token of prefix.split(/\s+/).filter(Boolean)) {
|
|
27
|
+
if (token === 'italic' || token === 'oblique')
|
|
28
|
+
style = 'italic';
|
|
29
|
+
else if (token === 'bold')
|
|
30
|
+
weight = 700;
|
|
31
|
+
else if (token === 'normal')
|
|
32
|
+
continue;
|
|
33
|
+
else if (/^\d+$/.test(token))
|
|
34
|
+
weight = parseInt(token, 10);
|
|
35
|
+
}
|
|
36
|
+
if (!Number.isFinite(sizePx) || !family)
|
|
37
|
+
return null;
|
|
38
|
+
return { family, weight, style, sizePx };
|
|
39
|
+
}
|
|
40
|
+
export function fontKey(family, weight, style) {
|
|
41
|
+
return `${family}|${weight}|${style}`;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=fontString.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fontString.js","sourceRoot":"","sources":["../src/fontString.ts"],"names":[],"mappings":"AAOA;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,EAAU;IACxC,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACzC,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IACxC,MAAM,MAAM,GAAG,uBAAuB,CAAC,EAAE,CAAC,CAAC;IAC3C,iBAAiB,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IAClC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,4EAA4E;AAC5E,wEAAwE;AACxE,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAmC,CAAC;AAErE,SAAS,uBAAuB,CAAC,EAAU;IACzC,MAAM,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACtD,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACnC,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IAC/D,IAAI,KAAK,GAAwB,QAAQ,CAAC;IAC1C,IAAI,MAAM,GAAG,GAAG,CAAC;IACjB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACxD,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,SAAS;YAAE,KAAK,GAAG,QAAQ,CAAC;aAC3D,IAAI,KAAK,KAAK,MAAM;YAAE,MAAM,GAAG,GAAG,CAAC;aACnC,IAAI,KAAK,KAAK,QAAQ;YAAE,SAAS;aACjC,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;YAAE,MAAM,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACrD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,MAAc,EAAE,MAAc,EAAE,KAA0B;IAChF,OAAO,GAAG,MAAM,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;AACxC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { renderToPdf } from './pdf-backend';
|
|
2
|
+
export type { RenderToPdfOptions, RenderProgress, PdfFontProvider, ResourceBytesProvider } from './pdf-backend';
|
|
3
|
+
export { decompressWoff2 } from './woff2';
|
|
4
|
+
export { svgToVectorDrawing, type VectorDrawing } from './pdf-backend/svgVector';
|
|
5
|
+
export { sniffBytes, rasterizeSvgWithDom, type SvgRasterizer } from './pdf-backend/renderResourceBlock';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAChH,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACjF,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,KAAK,aAAa,EAAE,MAAM,mCAAmC,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { renderToPdf } from './pdf-backend';
|
|
2
|
+
export { decompressWoff2 } from './woff2';
|
|
3
|
+
export { svgToVectorDrawing } from './pdf-backend/svgVector';
|
|
4
|
+
export { sniffBytes, rasterizeSvgWithDom } from './pdf-backend/renderResourceBlock';
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAsB,MAAM,yBAAyB,CAAC;AACjF,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAsB,MAAM,mCAAmC,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { VDTBlock } from 'postext';
|
|
2
|
+
import { FontCache } from '../fontCache';
|
|
3
|
+
import { type PageCtx } from './primitives';
|
|
4
|
+
import { type ResourceImageMap } from './renderResourceBlock';
|
|
5
|
+
import { LinkRegistry } from './links';
|
|
6
|
+
import type { StructureFlow } from './structureFlow';
|
|
7
|
+
/** Per-document context for resource rendering, threaded through `renderBlock`. */
|
|
8
|
+
export interface ResourceRenderContext {
|
|
9
|
+
images: ResourceImageMap;
|
|
10
|
+
linkRegistry: LinkRegistry;
|
|
11
|
+
/** Structure mapping of an accessible (tagged) render; absent otherwise. */
|
|
12
|
+
structure?: StructureFlow;
|
|
13
|
+
}
|
|
14
|
+
export declare function renderBlock(ctx: PageCtx, block: VDTBlock, columnWidth: number, columnX: number, fontCache: FontCache, resourceCtx?: ResourceRenderContext): void;
|
|
15
|
+
//# sourceMappingURL=blockRender.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blockRender.d.ts","sourceRoot":"","sources":["../../src/pdf-backend/blockRender.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAuC,MAAM,SAAS,CAAC;AAE7E,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,KAAK,OAAO,EAAsD,MAAM,cAAc,CAAC;AAGhG,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,mFAAmF;AACnF,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,gBAAgB,CAAC;IACzB,YAAY,EAAE,YAAY,CAAC;IAC3B,4EAA4E;IAC5E,SAAS,CAAC,EAAE,aAAa,CAAC;CAC3B;AAmPD,wBAAgB,WAAW,CACzB,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,QAAQ,EACf,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,SAAS,EACpB,WAAW,CAAC,EAAE,qBAAqB,GAClC,IAAI,CA0DN"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { setCharacterSpacing } from 'pdf-lib';
|
|
2
|
+
import { parseFontString } from '../fontString';
|
|
3
|
+
import { drawLinePx, drawSwatchPx, drawTextPx, colorFromHex } from './primitives';
|
|
4
|
+
import { pickSegmentColor, pickSegmentFont } from './fontHelpers';
|
|
5
|
+
import { renderHeaderFooterSlot } from './headerFooter';
|
|
6
|
+
import { renderResourceBlock, } from './renderResourceBlock';
|
|
7
|
+
import { tagArtifact, tagContent } from './tagging';
|
|
8
|
+
function renderMathRender(ctx, render, topLeftXPx, topLeftYPx, fallbackColor) {
|
|
9
|
+
if (!render.paths.length || render.viewBox.width <= 0 || render.viewBox.height <= 0)
|
|
10
|
+
return;
|
|
11
|
+
const { scale: pxToPt, pageHeightPt } = ctx;
|
|
12
|
+
const pxPerVb = render.widthPx / render.viewBox.width;
|
|
13
|
+
const S = pxPerVb * pxToPt;
|
|
14
|
+
const x = topLeftXPx * pxToPt - render.viewBox.minX * S;
|
|
15
|
+
const y = pageHeightPt - topLeftYPx * pxToPt + render.viewBox.minY * S;
|
|
16
|
+
for (const path of render.paths) {
|
|
17
|
+
const color = path.fill === 'currentColor' ? fallbackColor : colorFromHex(path.fill, ctx.colorSpace);
|
|
18
|
+
ctx.page.drawSvgPath(path.d, { x, y, scale: S, color });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function renderMathSegment(ctx, seg, xPx, baselinePx, fallbackColor) {
|
|
22
|
+
if (!seg.mathRender)
|
|
23
|
+
return;
|
|
24
|
+
renderMathRender(ctx, seg.mathRender, xPx, baselinePx - seg.mathRender.ascentPx, fallbackColor);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Paint a line's segments left to right starting at `startX`. When
|
|
28
|
+
* `justifiedSpaceWidth` is set, spaces advance by it instead of their
|
|
29
|
+
* measured width. `:ref` segments record a link annotation rectangle so the
|
|
30
|
+
* reference is clickable in the final PDF.
|
|
31
|
+
*
|
|
32
|
+
* In a tagged render (`elem` set) the text joins `elem`, each inline formula
|
|
33
|
+
* gets its own `Formula` element (alt text = its TeX) and each ref a `Link`
|
|
34
|
+
* element; word spaces are painted as real space glyphs so text extraction
|
|
35
|
+
* never has to infer them from the gaps of a justified line.
|
|
36
|
+
*/
|
|
37
|
+
function renderSegments(ctx, segments, startX, baseline, line, block, blockFont, blockSize, blockColor, fontCache, linkRegistry, elem, justifiedSpaceWidth) {
|
|
38
|
+
let x = startX;
|
|
39
|
+
for (const seg of segments) {
|
|
40
|
+
if (seg.kind === 'space') {
|
|
41
|
+
if (ctx.tags && seg.text) {
|
|
42
|
+
tagContent(ctx, elem);
|
|
43
|
+
drawTextPx(ctx, seg.text, x, baseline, blockFont, blockSize, blockColor);
|
|
44
|
+
}
|
|
45
|
+
x += justifiedSpaceWidth ?? seg.width;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (seg.kind === 'math') {
|
|
49
|
+
if (elem) {
|
|
50
|
+
const formula = elem.type === 'Formula' ? elem : elem.child('Formula', { alt: seg.mathRender?.tex ?? '' });
|
|
51
|
+
tagContent(ctx, formula);
|
|
52
|
+
}
|
|
53
|
+
renderMathSegment(ctx, seg, x, baseline, blockColor);
|
|
54
|
+
x += seg.width;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (seg.kind === 'swatch') {
|
|
58
|
+
tagContent(ctx, elem);
|
|
59
|
+
drawSwatchPx(ctx, x, baseline, seg.width, seg.swatch?.color, blockColor);
|
|
60
|
+
x += seg.width;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
const fontStr = seg.fontString ?? pickSegmentFont(!!seg.bold, !!seg.italic, block);
|
|
64
|
+
const font = fontCache.get(fontStr) ?? blockFont;
|
|
65
|
+
const size = parseFontString(fontStr)?.sizePx ?? blockSize;
|
|
66
|
+
const colorHex = seg.color
|
|
67
|
+
?? (seg.refResourceId !== undefined && block.refColor
|
|
68
|
+
? block.refColor
|
|
69
|
+
: pickSegmentColor(!!seg.bold, !!seg.italic, block));
|
|
70
|
+
const color = colorHex === block.color ? blockColor : colorFromHex(colorHex, ctx.colorSpace);
|
|
71
|
+
const link = seg.refResourceId !== undefined && elem ? elem.child('Link') : undefined;
|
|
72
|
+
tagContent(ctx, link ?? elem);
|
|
73
|
+
drawTextPx(ctx, seg.text, x, baseline + (seg.baselineShift ?? 0), font, size, color);
|
|
74
|
+
if (seg.refResourceId !== undefined && linkRegistry) {
|
|
75
|
+
const { scale, pageHeightPt } = ctx;
|
|
76
|
+
const x1 = x * scale;
|
|
77
|
+
const x2 = (x + seg.width) * scale;
|
|
78
|
+
const y2 = pageHeightPt - line.bbox.y * scale;
|
|
79
|
+
const y1 = pageHeightPt - (line.bbox.y + line.bbox.height) * scale;
|
|
80
|
+
linkRegistry.addLink(ctx.page, [x1, y1, x2, y2], seg.refResourceId, link ? { elem: link, contents: seg.text } : undefined);
|
|
81
|
+
}
|
|
82
|
+
x += seg.width;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/** Column-balancing tracking: the block was measured with extra advance
|
|
86
|
+
* after every glyph, so paint it with the matching character spacing
|
|
87
|
+
* (`Tc`, in points at the page scale) and reset it afterwards. */
|
|
88
|
+
function renderLine(ctx, line, block, columnWidth, columnX, fontCache, linkRegistry, elem) {
|
|
89
|
+
const tracked = block.letterSpacing !== undefined && block.letterSpacing > 0;
|
|
90
|
+
if (tracked)
|
|
91
|
+
ctx.page.pushOperators(setCharacterSpacing(block.letterSpacing * ctx.scale));
|
|
92
|
+
renderLineText(ctx, line, block, columnWidth, columnX, fontCache, linkRegistry, elem);
|
|
93
|
+
if (tracked)
|
|
94
|
+
ctx.page.pushOperators(setCharacterSpacing(0));
|
|
95
|
+
}
|
|
96
|
+
function renderLineText(ctx, line, block, columnWidth, columnX, fontCache, linkRegistry, elem) {
|
|
97
|
+
const blockFont = fontCache.get(block.fontString);
|
|
98
|
+
if (!blockFont)
|
|
99
|
+
return;
|
|
100
|
+
const blockSize = parseFontString(block.fontString)?.sizePx ?? 0;
|
|
101
|
+
const blockColor = colorFromHex(block.color, ctx.colorSpace);
|
|
102
|
+
const lineIndent = line.bbox.x - columnX;
|
|
103
|
+
const effectiveWidth = columnWidth - lineIndent;
|
|
104
|
+
const segments = line.segments;
|
|
105
|
+
// Last lines render ragged at natural width — except when overfull:
|
|
106
|
+
// Knuth-Plass may accept a final line wider than the measure on the
|
|
107
|
+
// assumption that its inter-word glue shrinks (TeX glue-setting semantics),
|
|
108
|
+
// so honor that by compressing the spaces to fit the measure exactly.
|
|
109
|
+
if (block.textAlign === 'justify' && segments && segments.length > 0) {
|
|
110
|
+
let wordWidth = 0;
|
|
111
|
+
let naturalWidth = 0;
|
|
112
|
+
let spaceCount = 0;
|
|
113
|
+
for (const seg of segments) {
|
|
114
|
+
if (seg.kind === 'space')
|
|
115
|
+
spaceCount++;
|
|
116
|
+
else
|
|
117
|
+
wordWidth += seg.width;
|
|
118
|
+
naturalWidth += seg.width;
|
|
119
|
+
}
|
|
120
|
+
if (spaceCount > 0 && ((!line.isLastLine && !line.ragged) || naturalWidth > effectiveWidth)) {
|
|
121
|
+
const justifiedSpaceWidth = (effectiveWidth - wordWidth) / spaceCount;
|
|
122
|
+
renderSegments(ctx, segments, line.bbox.x, line.baseline, line, block, blockFont, blockSize, blockColor, fontCache, linkRegistry, elem, justifiedSpaceWidth);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if ((block.textAlign === 'center' || block.textAlign === 'right') && segments) {
|
|
127
|
+
let contentWidth = 0;
|
|
128
|
+
for (const seg of segments)
|
|
129
|
+
contentWidth += seg.width;
|
|
130
|
+
const slack = Math.max(0, effectiveWidth - contentWidth);
|
|
131
|
+
const startX = line.bbox.x + (block.textAlign === 'center' ? slack / 2 : slack);
|
|
132
|
+
renderSegments(ctx, segments, startX, line.baseline, line, block, blockFont, blockSize, blockColor, fontCache, linkRegistry, elem);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
// Ragged (left-aligned) rendering — also used for last lines of justified
|
|
136
|
+
// blocks. Segments are needed when any of them styles differently from the
|
|
137
|
+
// block (bold/italic/math/ref/own font or colour); otherwise one drawTextPx
|
|
138
|
+
// paints the line.
|
|
139
|
+
if (segments && segments.some((s) => s.bold || s.italic || s.kind === 'math' || s.kind === 'swatch' || s.refResourceId !== undefined || s.fontString !== undefined || s.color !== undefined || s.baselineShift !== undefined)) {
|
|
140
|
+
renderSegments(ctx, segments, line.bbox.x, line.baseline, line, block, blockFont, blockSize, blockColor, fontCache, linkRegistry, elem);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
tagContent(ctx, elem);
|
|
144
|
+
const plainX = block.textAlign === 'right' ? line.bbox.x + Math.max(0, effectiveWidth - line.bbox.width) : line.bbox.x;
|
|
145
|
+
drawTextPx(ctx, line.text, plainX, line.baseline, blockFont, blockSize, blockColor);
|
|
146
|
+
}
|
|
147
|
+
function renderBullet(ctx, block, fontCache, elem) {
|
|
148
|
+
if (!block.bulletText ||
|
|
149
|
+
!block.bulletFontString ||
|
|
150
|
+
block.bulletOffsetX === undefined) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
const firstLine = block.lines[0];
|
|
154
|
+
if (!firstLine)
|
|
155
|
+
return;
|
|
156
|
+
const font = fontCache.get(block.bulletFontString);
|
|
157
|
+
if (!font)
|
|
158
|
+
return;
|
|
159
|
+
const size = parseFontString(block.bulletFontString)?.sizePx ?? 0;
|
|
160
|
+
const colorHex = block.bulletColor ?? block.color;
|
|
161
|
+
const color = colorFromHex(colorHex, ctx.colorSpace);
|
|
162
|
+
// Canvas uses `textBaseline='middle'` at bulletY; pdf-lib draws from the
|
|
163
|
+
// alphabetic baseline. Shift the baseline down by ~0.3em so the em-square
|
|
164
|
+
// midline aligns at bulletY, matching canvas placement within hinting tolerance.
|
|
165
|
+
const midY = block.bulletY ?? firstLine.baseline;
|
|
166
|
+
const baselinePx = midY + size * 0.3;
|
|
167
|
+
tagContent(ctx, elem);
|
|
168
|
+
drawTextPx(ctx, block.bulletText, block.bulletOffsetX, baselinePx, font, size, color);
|
|
169
|
+
// Ordered-list separator styled apart from the number (own font/colour).
|
|
170
|
+
if (block.separatorText && block.separatorX !== undefined) {
|
|
171
|
+
const sepFontString = block.separatorFontString ?? block.bulletFontString;
|
|
172
|
+
const sepFont = fontCache.get(sepFontString);
|
|
173
|
+
if (!sepFont)
|
|
174
|
+
return;
|
|
175
|
+
const sepSize = parseFontString(sepFontString)?.sizePx ?? size;
|
|
176
|
+
const sepColor = colorFromHex(block.separatorColor ?? colorHex, ctx.colorSpace);
|
|
177
|
+
drawTextPx(ctx, block.separatorText, block.separatorX, midY + sepSize * 0.3, sepFont, sepSize, sepColor);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
function renderStrikethrough(ctx, block) {
|
|
181
|
+
if (!block.strikethroughText)
|
|
182
|
+
return;
|
|
183
|
+
tagArtifact(ctx, { type: 'Layout' });
|
|
184
|
+
const color = colorFromHex(block.color, ctx.colorSpace);
|
|
185
|
+
const thickness = Math.max(1, block.lines[0]?.bbox.height ? block.lines[0].bbox.height * 0.05 : 1);
|
|
186
|
+
for (const line of block.lines) {
|
|
187
|
+
const y = line.baseline - line.bbox.height * 0.28;
|
|
188
|
+
drawLinePx(ctx, line.bbox.x, y, line.bbox.x + line.bbox.width, y, color, thickness);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/** Annotation rectangle of a block's box, in PDF points. */
|
|
192
|
+
function rectOfBlock(ctx, block) {
|
|
193
|
+
const { scale, pageHeightPt } = ctx;
|
|
194
|
+
const { x, y, width, height } = block.bbox;
|
|
195
|
+
return [x * scale, pageHeightPt - (y + height) * scale, (x + width) * scale, pageHeightPt - y * scale];
|
|
196
|
+
}
|
|
197
|
+
export function renderBlock(ctx, block, columnWidth, columnX, fontCache, resourceCtx) {
|
|
198
|
+
if (block.hidden)
|
|
199
|
+
return;
|
|
200
|
+
const structure = resourceCtx?.structure;
|
|
201
|
+
const linkRegistry = resourceCtx?.linkRegistry;
|
|
202
|
+
// A row of the contents links to the page it lists: the whole row is
|
|
203
|
+
// the annotation, its text the `Link` element in a tagged render.
|
|
204
|
+
const targetPage = block.tocEntry?.pageIndex ?? block.tocPart?.pageIndex;
|
|
205
|
+
if (block.designOverlay) {
|
|
206
|
+
// A heading's advanced design or a callout frame: the overlay's text is
|
|
207
|
+
// the heading / the callout title, its boxes and icons are decoration.
|
|
208
|
+
let link;
|
|
209
|
+
const textElem = structure
|
|
210
|
+
? () => link ?? (targetPage !== undefined ? (link = structure.blockElem(block).child('Link')) : structure.blockElem(block))
|
|
211
|
+
: undefined;
|
|
212
|
+
renderHeaderFooterSlot(ctx, block.designOverlay, fontCache, resourceCtx?.images, textElem ? { text: textElem, artifact: { type: 'Layout' } } : undefined);
|
|
213
|
+
if (targetPage !== undefined && linkRegistry) {
|
|
214
|
+
const contents = block.tocPart ? `${block.tocPart.number} ${block.tocPart.title}`.trim() : block.lines.map((l) => l.text).join(' ');
|
|
215
|
+
linkRegistry.addPageLink(ctx.page, rectOfBlock(ctx, block), targetPage, link ? { elem: link, contents } : undefined);
|
|
216
|
+
}
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
if (block.type === 'resource') {
|
|
220
|
+
renderResourceBlock(ctx, block, fontCache, resourceCtx?.images ?? new Map(), resourceCtx?.linkRegistry, structure);
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
const blockElem = structure && (block.lines.length > 0 || block.bulletText) ? structure.blockElem(block) : undefined;
|
|
224
|
+
const link = targetPage !== undefined && blockElem ? blockElem.child('Link') : undefined;
|
|
225
|
+
const elem = link ?? blockElem;
|
|
226
|
+
if (block.type === 'listItem') {
|
|
227
|
+
renderBullet(ctx, block, fontCache, structure?.bulletElem(block) ?? elem);
|
|
228
|
+
}
|
|
229
|
+
// Justify against the block's own measure (see the canvas backend): blocks
|
|
230
|
+
// inside callouts are narrower than their column.
|
|
231
|
+
void columnWidth;
|
|
232
|
+
void columnX;
|
|
233
|
+
for (const line of block.lines) {
|
|
234
|
+
renderLine(ctx, line, block, block.bbox.width, block.bbox.x, fontCache, linkRegistry, elem);
|
|
235
|
+
}
|
|
236
|
+
if (targetPage !== undefined && linkRegistry) {
|
|
237
|
+
const contents = block.lines.map((l) => l.text).join(' ');
|
|
238
|
+
linkRegistry.addPageLink(ctx.page, rectOfBlock(ctx, block), targetPage, link ? { elem: link, contents } : undefined);
|
|
239
|
+
}
|
|
240
|
+
if (block.strikethroughText) {
|
|
241
|
+
renderStrikethrough(ctx, block);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=blockRender.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blockRender.js","sourceRoot":"","sources":["../../src/pdf-backend/blockRender.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { VDTDocument, VDTBlock } from 'postext';
|
|
2
|
+
/** Collect every fontString referenced anywhere in the VDT. */
|
|
3
|
+
export declare function collectFontStrings(doc: VDTDocument): string[];
|
|
4
|
+
export declare function pickSegmentFont(bold: boolean, italic: boolean, block: VDTBlock): string;
|
|
5
|
+
export declare function pickSegmentColor(bold: boolean, italic: boolean, block: VDTBlock): string;
|
|
6
|
+
//# sourceMappingURL=fontHelpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fontHelpers.d.ts","sourceRoot":"","sources":["../../src/pdf-backend/fontHelpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAErD,+DAA+D;AAC/D,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,EAAE,CAoD7D;AAED,wBAAgB,eAAe,CAC7B,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,OAAO,EACf,KAAK,EAAE,QAAQ,GACd,MAAM,CAKR;AAED,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,OAAO,EACf,KAAK,EAAE,QAAQ,GACd,MAAM,CAIR"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/** Collect every fontString referenced anywhere in the VDT. */
|
|
2
|
+
export function collectFontStrings(doc) {
|
|
3
|
+
const out = new Set();
|
|
4
|
+
// Floated resources live on their page's float band, not in doc.blocks.
|
|
5
|
+
const blocks = [...doc.blocks];
|
|
6
|
+
for (const page of doc.pages) {
|
|
7
|
+
if (page.floats)
|
|
8
|
+
blocks.push(...page.floats);
|
|
9
|
+
}
|
|
10
|
+
for (const block of blocks) {
|
|
11
|
+
// Design overlays (advanced heading designs, callout titles/icons).
|
|
12
|
+
if (block.designOverlay) {
|
|
13
|
+
for (const b of block.designOverlay.blocks) {
|
|
14
|
+
if (b.kind === 'text')
|
|
15
|
+
out.add(b.fontString);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
if (block.fontString)
|
|
19
|
+
out.add(block.fontString);
|
|
20
|
+
if (block.boldFontString)
|
|
21
|
+
out.add(block.boldFontString);
|
|
22
|
+
if (block.italicFontString)
|
|
23
|
+
out.add(block.italicFontString);
|
|
24
|
+
if (block.boldItalicFontString)
|
|
25
|
+
out.add(block.boldItalicFontString);
|
|
26
|
+
if (block.bulletFontString)
|
|
27
|
+
out.add(block.bulletFontString);
|
|
28
|
+
if (block.separatorFontString)
|
|
29
|
+
out.add(block.separatorFontString);
|
|
30
|
+
// Resource caption + table cell fonts (issue #49).
|
|
31
|
+
const rb = block.resourceBlock;
|
|
32
|
+
if (rb) {
|
|
33
|
+
out.add(rb.captionFontString);
|
|
34
|
+
out.add(rb.captionBoldFontString);
|
|
35
|
+
out.add(rb.captionItalicFontString);
|
|
36
|
+
out.add(rb.captionBoldItalicFontString);
|
|
37
|
+
out.add(rb.noteFontString);
|
|
38
|
+
out.add(rb.noteBoldFontString);
|
|
39
|
+
out.add(rb.noteItalicFontString);
|
|
40
|
+
out.add(rb.noteBoldItalicFontString);
|
|
41
|
+
if (rb.table) {
|
|
42
|
+
out.add(rb.table.fontString);
|
|
43
|
+
out.add(rb.table.boldFontString);
|
|
44
|
+
out.add(rb.table.italicFontString);
|
|
45
|
+
out.add(rb.table.boldItalicFontString);
|
|
46
|
+
out.add(rb.table.headerFontString);
|
|
47
|
+
out.add(rb.table.headerBoldFontString);
|
|
48
|
+
out.add(rb.table.headerItalicFontString);
|
|
49
|
+
out.add(rb.table.headerBoldItalicFontString);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
for (const page of doc.pages) {
|
|
54
|
+
for (const slot of [page.header, page.footer, page.openerBand]) {
|
|
55
|
+
if (!slot)
|
|
56
|
+
continue;
|
|
57
|
+
for (const b of slot.blocks) {
|
|
58
|
+
if (b.kind === 'text')
|
|
59
|
+
out.add(b.fontString);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return [...out];
|
|
64
|
+
}
|
|
65
|
+
export function pickSegmentFont(bold, italic, block) {
|
|
66
|
+
if (bold && italic && block.boldItalicFontString)
|
|
67
|
+
return block.boldItalicFontString;
|
|
68
|
+
if (bold && block.boldFontString)
|
|
69
|
+
return block.boldFontString;
|
|
70
|
+
if (italic && block.italicFontString)
|
|
71
|
+
return block.italicFontString;
|
|
72
|
+
return block.fontString;
|
|
73
|
+
}
|
|
74
|
+
export function pickSegmentColor(bold, italic, block) {
|
|
75
|
+
if (bold && block.boldColor)
|
|
76
|
+
return block.boldColor;
|
|
77
|
+
if (italic && block.italicColor)
|
|
78
|
+
return block.italicColor;
|
|
79
|
+
return block.color;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=fontHelpers.js.map
|