pdf-codec 3.4.4 → 3.5.1

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.
Files changed (82) hide show
  1. package/README.md +47 -26
  2. package/dist/{afm-widths-Dxucrg7D.js → afm-widths-BLl6ORCt.js} +2 -2
  3. package/dist/{afm-widths-BoeTOK2r.cjs → afm-widths-Cj9d3GVK.cjs} +2 -2
  4. package/dist/{afm-widths-DyDq56Ph.d.cts → afm-widths-CneRyu5l.d.cts} +1 -1
  5. package/dist/{afm-widths-DyDq56Ph.d.ts → afm-widths-CneRyu5l.d.ts} +1 -1
  6. package/dist/afm-widths.cjs +1 -1
  7. package/dist/afm-widths.d.cts +1 -1
  8. package/dist/afm-widths.d.ts +1 -1
  9. package/dist/afm-widths.js +1 -1
  10. package/dist/content-read.d.cts +2 -2
  11. package/dist/content-read.d.ts +2 -2
  12. package/dist/content-write.cjs +1 -1
  13. package/dist/content-write.d.cts +3 -3
  14. package/dist/content-write.d.ts +3 -3
  15. package/dist/content-write.js +1 -1
  16. package/dist/diagnostics.d.cts +1 -1
  17. package/dist/diagnostics.d.ts +1 -1
  18. package/dist/encoding.cjs +1 -1
  19. package/dist/encoding.js +1 -1
  20. package/dist/encrypt.d.cts +1 -1
  21. package/dist/encrypt.d.ts +1 -1
  22. package/dist/filters.cjs +14 -10
  23. package/dist/filters.js +14 -10
  24. package/dist/font-read.cjs +1 -1
  25. package/dist/font-read.js +1 -1
  26. package/dist/font-registry.d.cts +3 -3
  27. package/dist/font-registry.d.ts +3 -3
  28. package/dist/font-substitutes.d.cts +1 -1
  29. package/dist/font-substitutes.d.ts +1 -1
  30. package/dist/fonts.d.cts +2 -2
  31. package/dist/fonts.d.ts +2 -2
  32. package/dist/image/jbig2-bitmap.d.cts +1 -1
  33. package/dist/image/jbig2-bitmap.d.ts +1 -1
  34. package/dist/image/jbig2.cjs +3 -1
  35. package/dist/image/jbig2.js +3 -1
  36. package/dist/image/jp2-boxes.d.cts +1 -1
  37. package/dist/image/jp2-boxes.d.ts +1 -1
  38. package/dist/image/jpeg2000-codestream.d.cts +3 -3
  39. package/dist/image/jpeg2000-codestream.d.ts +3 -3
  40. package/dist/image/jpeg2000-t1.d.cts +1 -1
  41. package/dist/image/jpeg2000-t1.d.ts +1 -1
  42. package/dist/image/png-encode.d.cts +1 -1
  43. package/dist/image/png-encode.d.ts +1 -1
  44. package/dist/image/png-filter.d.cts +1 -1
  45. package/dist/image/png-filter.d.ts +1 -1
  46. package/dist/images-read.cjs +7 -5
  47. package/dist/images-read.d.cts +1 -1
  48. package/dist/images-read.d.ts +1 -1
  49. package/dist/images-read.js +7 -5
  50. package/dist/index.cjs +1 -1
  51. package/dist/index.d.cts +2 -2
  52. package/dist/index.d.ts +2 -2
  53. package/dist/index.js +1 -1
  54. package/dist/interpret.d.cts +10 -10
  55. package/dist/interpret.d.ts +10 -10
  56. package/dist/layout.d.cts +1 -1
  57. package/dist/layout.d.ts +1 -1
  58. package/dist/lexer.d.cts +9 -9
  59. package/dist/lexer.d.ts +9 -9
  60. package/dist/math-font.d.cts +1 -1
  61. package/dist/math-font.d.ts +1 -1
  62. package/dist/{math-stretch-a_rHNRvc.d.ts → math-stretch-BbC2o4Br.d.ts} +1 -1
  63. package/dist/{math-stretch-E26z6byT.d.cts → math-stretch-C2JanDAz.d.cts} +1 -1
  64. package/dist/math-stretch.d.cts +1 -1
  65. package/dist/math-stretch.d.ts +1 -1
  66. package/dist/measure.cjs +1 -1
  67. package/dist/measure.d.cts +1 -1
  68. package/dist/measure.d.ts +1 -1
  69. package/dist/measure.js +1 -1
  70. package/dist/objects.d.cts +12 -12
  71. package/dist/objects.d.ts +12 -12
  72. package/dist/util/base64.cjs +4 -4
  73. package/dist/util/base64.js +4 -4
  74. package/dist/winansi.cjs +1 -1
  75. package/dist/winansi.d.cts +1 -1
  76. package/dist/winansi.d.ts +1 -1
  77. package/dist/winansi.js +1 -1
  78. package/dist/write.cjs +1 -1
  79. package/dist/write.js +1 -1
  80. package/dist/xref.d.cts +2 -2
  81. package/dist/xref.d.ts +2 -2
  82. package/package.json +3 -11
package/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  This is a genuinely large undertaking with an honest trade-off spelled out in [Fidelity](#fidelity): this is not, and does not attempt to be, as robust against adversarial or badly malformed real-world PDFs as a library with 15+ years of hardening. What it buys instead is a dependency-free, fully auditable PDF implementation with no supply-chain surface beyond `document-schema.js`, `fflate`, and `zod`.
10
10
 
11
- `documents.js` uses this package to convert docx/pptx/odt/odp/ods/odg to and from PDF, and to render MathML formulas (typeset by its own `src/mathml/` engine) through the embedded math font this package parses and writes. That MathML *layout* engine deliberately stays in `documents.js` — see [Architecture](#architecture) for exactly where the boundary sits and why a real `MathBox` value crosses it with zero cast or wrapper.
11
+ `documents.js` uses this package to convert docx/pptx/odt/odp/ods/odg to and from PDF, and to render MathML formulas (typeset by its own `src/mathml/` engine) through the embedded math font this package parses and writes. That MathML _layout_ engine deliberately stays in `documents.js` — see [Architecture](#architecture) for exactly where the boundary sits and why a real `MathBox` value crosses it with zero cast or wrapper.
12
12
 
13
13
  ```mermaid
14
14
  graph TD
@@ -73,7 +73,7 @@ npm install pdf-codec
73
73
  Reading and writing PDF bytes:
74
74
 
75
75
  ```ts
76
- import { readPdf, writePdf } from 'pdf-codec';
76
+ import { readPdf, writePdf } from "pdf-codec";
77
77
 
78
78
  const layout = readPdf(pdfBytes); // -> LayoutDocument: pages of positioned text/image/rect/line/ellipse/path/link items
79
79
  const bytes = writePdf(layout);
@@ -81,7 +81,7 @@ const bytes = writePdf(layout);
81
81
 
82
82
  `LayoutDocument` and its whole item family — every item/page/image-asset type and schema, plus `LAYOUT_FORMAT_VERSION` — are this package's own exports, ported from `document-schema.js` (which dropped them) so a codec's native model lives in the codec, the same family pattern as `ooxml.js`'s `Package`/`XmlElement` and `markdown-codec`'s AST. `readPdf`/`writePdf` keep their signatures; callers see the same names from a new home. `documents.js` re-exports the family onward from its own barrel — those re-exports now source from `pdf-codec` rather than `document-schema.js`, same names, new source.
83
83
 
84
- There is deliberately **no `DocumentTree`-returning read or `DocumentTree`-accepting write here**, and `readPdf`/`writePdf` are this package's primary API precisely because of that. Only `markdown-codec`'s own read entry point returns `document-schema.js`'s flat `ContentDocument` directly — `ooxml.js`'s `readDocx`/`readPptx` return `DocxDocument`/`PptxDocument` and `odf.js`'s `readOdt`/`readOds` return `OdtDocument`/`OdsDocument`, each codec's own native model, with only `ooxml.js`'s separate `readXlsxContent` producing a `ContentDocument` outright. What lets `documents.js` offer one tree-native entry point uniformly across those formats (`decompose`/`assembleTree` outward, `flattenTree` back) is its own `readXContent` wrapper layer (`readDocxContent`, `readOdtContent`, and siblings), projecting each codec's native model into the flat `ContentDocument` — a step the codecs themselves don't take. PDF has no such wrapper to project through: `readPdf` yields *layout* cheaply, because positioned glyphs and paths are all the format actually states, and semantic content only through a separate, expensive, lossy reconstruction pass that infers paragraphs, headings, tables, and shapes back out of geometry. That inference is semantic policy rather than codec business, so it lives in `documents.js` — a caller wanting a PDF as a `DocumentTree` passes `onDocument` to a named conversion function or to `convertDocument` itself and reads the tree off that callback (`convertDocument` on its own returns only bytes), or uses `createLocalDocumentConverter()`'s `DocumentConverter` port, whose `ConversionResult.package` is populated by wiring that same callback internally. The write direction is asymmetric for a different reason than it might look: turning a `DocumentTree` into PDF bytes is not itself a layout pass — `documents.js`'s `layoutDocumentFromPackage` is a mechanical inverse that walks the positions a *prior* layout pass already stamped onto the package's own content nodes as `frames`, and it only works at all when those frames exist (a bridge conversion's own dump, e.g. `odt-to-docx`, carries no `pages` and cannot reach PDF this way). The actual font-measuring, line-breaking engine runs earlier, wherever the package first passed through an X-to-PDF or PDF-to-X conversion — both the frame-stamping and the frame-walking are `documents.js`'s. Keeping both edges out of this package is still what makes the item layer an honest record of what a file says, separate from what any consumer thinks it means.
84
+ There is deliberately **no `DocumentTree`-returning read or `DocumentTree`-accepting write here**, and `readPdf`/`writePdf` are this package's primary API precisely because of that. Only `markdown-codec`'s own read entry point returns `document-schema.js`'s flat `ContentDocument` directly — `ooxml.js`'s `readDocx`/`readPptx` return `DocxDocument`/`PptxDocument` and `odf.js`'s `readOdt`/`readOds` return `OdtDocument`/`OdsDocument`, each codec's own native model, with only `ooxml.js`'s separate `readXlsxContent` producing a `ContentDocument` outright. What lets `documents.js` offer one tree-native entry point uniformly across those formats (`decompose`/`assembleTree` outward, `flattenTree` back) is its own `readXContent` wrapper layer (`readDocxContent`, `readOdtContent`, and siblings), projecting each codec's native model into the flat `ContentDocument` — a step the codecs themselves don't take. PDF has no such wrapper to project through: `readPdf` yields _layout_ cheaply, because positioned glyphs and paths are all the format actually states, and semantic content only through a separate, expensive, lossy reconstruction pass that infers paragraphs, headings, tables, and shapes back out of geometry. That inference is semantic policy rather than codec business, so it lives in `documents.js` — a caller wanting a PDF as a `DocumentTree` passes `onDocument` to a named conversion function or to `convertDocument` itself and reads the tree off that callback (`convertDocument` on its own returns only bytes), or uses `createLocalDocumentConverter()`'s `DocumentConverter` port, whose `ConversionResult.package` is populated by wiring that same callback internally. The write direction is asymmetric for a different reason than it might look: turning a `DocumentTree` into PDF bytes is not itself a layout pass — `documents.js`'s `layoutDocumentFromPackage` is a mechanical inverse that walks the positions a _prior_ layout pass already stamped onto the package's own content nodes as `frames`, and it only works at all when those frames exist (a bridge conversion's own dump, e.g. `odt-to-docx`, carries no `pages` and cannot reach PDF this way). The actual font-measuring, line-breaking engine runs earlier, wherever the package first passed through an X-to-PDF or PDF-to-X conversion — both the frame-stamping and the frame-walking are `documents.js`'s. Keeping both edges out of this package is still what makes the item layer an honest record of what a file says, separate from what any consumer thinks it means.
85
85
 
86
86
  An encrypted PDF that opens without a password decrypts transparently — no extra option, no password parameter; one that genuinely needs a user password throws `PdfPasswordRequiredError`. See [Gotchas](#gotchas-and-quirks) for exactly which encryption is supported.
87
87
 
@@ -94,8 +94,8 @@ Both accept an optional `signal` (`AbortSignal`); `readPdf` additionally takes a
94
94
  The same round trip is also available as a schema-validated [`z.codec()`](https://zod.dev) pair:
95
95
 
96
96
  ```ts
97
- import { z } from 'zod';
98
- import { pdfCodec } from 'pdf-codec';
97
+ import { z } from "zod";
98
+ import { pdfCodec } from "pdf-codec";
99
99
 
100
100
  const layout = z.decode(pdfCodec, pdfBytes); // throws a ZodError if pdfBytes has no %PDF- header
101
101
  const pdfBytes2 = z.encode(pdfCodec, layout);
@@ -106,13 +106,19 @@ This is the no-extra-options form only — `readPdf`/`writePdf` remain the entry
106
106
  Embedding a real math formula: `writePdf`'s own `formulas` option takes an array of `PositionedFormula` — an already-laid-out `MathBox` (positioned glyph runs, fraction/radical rules, radical hook strokes) placed at a page position. This package supplies the font — `loadMathFont()` parses and caches the vendored STIX Two Math font once per process — but it does not lay MathML out itself; that is a separate concern this package deliberately doesn't own (see [Architecture](#architecture)).
107
107
 
108
108
  ```ts
109
- import { loadMathFont, writePdf } from 'pdf-codec';
110
- import { layoutFormula } from 'documents.js'; // or any other producer of a structurally-compatible MathBox
109
+ import { loadMathFont, writePdf } from "pdf-codec";
110
+ import { layoutFormula } from "documents.js"; // or any other producer of a structurally-compatible MathBox
111
111
 
112
112
  const { metricsAt } = loadMathFont();
113
- const { box } = layoutFormula(mathml, { metrics: metricsAt(12), sizePt: 12, color: { r: 0, g: 0, b: 0 } });
114
-
115
- const pdfBytes = writePdf(doc, { formulas: [{ pageIndex: 0, xPt: 50, yPt: 700, box }] });
113
+ const { box } = layoutFormula(mathml, {
114
+ metrics: metricsAt(12),
115
+ sizePt: 12,
116
+ color: { r: 0, g: 0, b: 0 },
117
+ });
118
+
119
+ const pdfBytes = writePdf(doc, {
120
+ formulas: [{ pageIndex: 0, xPt: 50, yPt: 700, box }],
121
+ });
116
122
  ```
117
123
 
118
124
  Because `MathBox` and its own constituent types (`MathGlyphRun`/`MathRule`/`MathStroke`/`MathAssembledGlyphs`/`MathColor`) are plain, structurally-typed data — not a class, not branded — any producer whose output matches the shape works here with no cast, no wrapper, and no transformation.
@@ -120,10 +126,10 @@ Because `MathBox` and its own constituent types (`MathGlyphRun`/`MathRule`/`Math
120
126
  Sizing a stretchy glyph — a parenthesis tall enough to wrap a big fraction, a radical sign sized to its radicand, an over-brace as wide as the content under it — is the OpenType `MATH` table's `MathVariants` job, and `loadMathFont()` exposes it directly:
121
127
 
122
128
  ```ts
123
- import { loadMathFont } from 'pdf-codec';
129
+ import { loadMathFont } from "pdf-codec";
124
130
 
125
131
  const { stretchGlyph } = loadMathFont();
126
- const paren = stretchGlyph(0x28, 'vertical', 40, 12); // a '(' stretched to 40pt, set at 12pt
132
+ const paren = stretchGlyph(0x28, "vertical", 40, 12); // a '(' stretched to 40pt, set at 12pt
127
133
  // paren.kind -> 'assembly' (no single pre-built variant reaches 40pt)
128
134
  // paren.size -> the extent actually achieved, >= 40 whenever the font can reach it
129
135
  // paren.placements -> [{ glyphId, offset, advance }, ...], bottom to top, seams already overlapped
@@ -140,7 +146,7 @@ Building a layout engine on top of this codec (this is what `documents.js`'s own
140
146
  Embedding real fonts instead of substituting standard-14 faces, via a `FontRegistry` (see `src/font-registry.ts` for the source-document → caller-supplied → vendored-substitute → standard-14 resolution order). Pass the same registry to both the measurer and `writePdf` so what was measured and what gets drawn come from one font:
141
147
 
142
148
  ```ts
143
- import { createFontMeasurer, createFontRegistry, writePdf } from 'pdf-codec';
149
+ import { createFontMeasurer, createFontRegistry, writePdf } from "pdf-codec";
144
150
 
145
151
  // With no `fonts`/`sourceFonts` of its own, the registry still maps Calibri onto the vendored,
146
152
  // metric-compatible Carlito face this package embeds (and Cambria onto Caladea).
@@ -148,7 +154,10 @@ const fonts = createFontRegistry();
148
154
 
149
155
  const measurer = createFontMeasurer(fonts);
150
156
  // ... wrap text + build a LayoutDocument using the measurer (documents.js owns wrapRunsToWidth) ...
151
- const pdfBytes = writePdf(doc, { fonts, onMissingGlyph: (m) => console.warn('no glyph for', m.from) });
157
+ const pdfBytes = writePdf(doc, {
158
+ fonts,
159
+ onMissingGlyph: (m) => console.warn("no glyph for", m.from),
160
+ });
152
161
  ```
153
162
 
154
163
  Every text run whose family resolves to a real face is subsetted to the glyphs the document actually uses and embedded as its own `/Type0` + `/CIDFontType2` + `/FontFile2` group. **Omit `fonts` and nothing changes at all** — output is byte-identical to a build with no embedded-font support (asserted against golden digests in `src/write-embedded-font.test.ts`).
@@ -156,10 +165,15 @@ Every text run whose family resolves to a real face is subsetted to the glyphs t
156
165
  Inspecting a standalone font file before handing it to a `FontRegistry` as a `ProvidedFont`: `readFontFace` reads family/bold/italic straight off the font's own `name`/`OS/2`/`head` tables — exactly the triple `ProvidedFont` needs:
157
166
 
158
167
  ```ts
159
- import { createFontRegistry, readFontFace } from 'pdf-codec';
160
-
161
- const { family, bold, italic } = readFontFace(brandSansTtfBytes, 'BrandSans-Bold.ttf'); // throws FontFaceParseError, naming the source, for a .ttc/.woff file or one with no family name
162
- const fonts = createFontRegistry({ fonts: [{ family, bold, italic, bytes: brandSansTtfBytes }] });
168
+ import { createFontRegistry, readFontFace } from "pdf-codec";
169
+
170
+ const { family, bold, italic } = readFontFace(
171
+ brandSansTtfBytes,
172
+ "BrandSans-Bold.ttf",
173
+ ); // throws FontFaceParseError, naming the source, for a .ttc/.woff file or one with no family name
174
+ const fonts = createFontRegistry({
175
+ fonts: [{ family, bold, italic, bytes: brandSansTtfBytes }],
176
+ });
163
177
  ```
164
178
 
165
179
  `createFontMeasurer`'s second argument carries `verticalMetrics`, a `VerticalMetricPolicy` of `'hhea'` (default) / `'os2Typo'` / `'os2Win'`, deciding which of the three competing ascent/descent/line-gap sets an sfnt declares should drive line height for an embedded face.
@@ -167,11 +181,18 @@ const fonts = createFontRegistry({ fonts: [{ family, bold, italic, bytes: brandS
167
181
  Reading a JPEG 2000 image directly, either as pixels or as metadata alone:
168
182
 
169
183
  ```ts
170
- import { decodeJpeg2000, readJpeg2000Metadata } from 'pdf-codec';
184
+ import { decodeJpeg2000, readJpeg2000Metadata } from "pdf-codec";
171
185
 
172
186
  // Works on any conforming codestream -- including one whose pixels this decoder refuses, which is what `decodable`/`undecodableReason` are for.
173
187
  const metadata = readJpeg2000Metadata(jp2OrCodestreamBytes);
174
- console.log(metadata.width, metadata.height, metadata.transform, metadata.layers, metadata.decodable, metadata.undecodableReason);
188
+ console.log(
189
+ metadata.width,
190
+ metadata.height,
191
+ metadata.transform,
192
+ metadata.layers,
193
+ metadata.decodable,
194
+ metadata.undecodableReason,
195
+ );
175
196
 
176
197
  const image = decodeJpeg2000(jp2OrCodestreamBytes); // -> { width, height, bitDepth, components: Int32Array[] }, one plane per component
177
198
  ```
@@ -183,8 +204,8 @@ The generic byte- and image-container primitives (`crc32`, `deflate`/`inflate`/`
183
204
  Every module under `src/` is also deep-importable directly by its own subpath:
184
205
 
185
206
  ```ts
186
- import { crc32 } from 'pdf-codec/bytes/crc32';
187
- import { readJpegInfo } from 'pdf-codec/image/jpeg-info';
207
+ import { crc32 } from "pdf-codec/bytes/crc32";
208
+ import { readJpegInfo } from "pdf-codec/image/jpeg-info";
188
209
  ```
189
210
 
190
211
  This works via package.json's `"./*"` wildcard export, resolving any `pdf-codec/<path>` subpath to the correspondingly-named file under `dist/` — both ESM `import` and CJS `require` resolve the same way.
@@ -192,7 +213,7 @@ This works via package.json's `"./*"` wildcard export, resolving any `pdf-codec/
192
213
  One subpath is a declared entry point in its own right: **`pdf-codec/read`** (an explicit `exports` entry onto `src/read.ts`, the read pipeline's own module). A consumer that only ever reads PDFs and imports the root barrel statically reaches `write.ts`'s module-scope imports — `math-font.ts` (the vendored STIX Two Math font) and `font-registry.ts` (the four Carlito/Caladea faces), together ~2.9 MB of font binaries it can never execute, which on Cloudflare Workers' free plan (3 MB gzipped for an entire Worker) is most of the budget. The read entry's module graph provably excludes them:
193
214
 
194
215
  ```ts
195
- import { readPdf } from 'pdf-codec/read';
216
+ import { readPdf } from "pdf-codec/read";
196
217
  ```
197
218
 
198
219
  `src/read-graph.test.ts` walks the entry's static import graph and fails the build if `write.ts`, `math-font.ts`, `font-registry.ts`, or any asset module becomes reachable (type-only imports are exempt — they erase at compile time — so a read-side module can keep typing against the root barrel's types while its runtime graph stays narrow). The entry carries `readPdf` and the read pipeline's own helpers (`normalizeRotation`, `pageRotationTransform`); the other read-adjacent surfaces it does not itself own stay deep-importable through the wildcard and are asset-free the same way — the diagnostics vocabulary (`pdf-codec/diagnostics`), the `LayoutDocument` item family (`pdf-codec/layout`), PDF string/date scalar decoding (`pdf-codec/pdf-text`), and standard-14 resolution/AFM metrics (`pdf-codec/fonts`, `pdf-codec/afm-widths`).
@@ -241,7 +262,7 @@ Dependency direction is strictly downward and checkable: `layout` imports only `
241
262
  - **STIX Two Math is a CFF-flavoured OpenType font, not TrueType/glyf** — the **entire** `CFF ` table is embedded verbatim as a single `/FontFile3` `/Subtype /CIDFontType0C` stream (a real, correct, working embedded font, just not glyph-subsetted). Everything else genuinely IS built from a targeted parse of only what's used: `cmap` resolves exactly the Unicode code points a document's formulas reference, and the emitted `/W` widths array covers only drawn glyph IDs. A CID-keyed composite font built this way needs no `/CIDToGIDMap` — per ISO 32000-1 9.7.4.2, a `/CIDFontType0` whose `/FontFile3` is a non-CID-keyed CFF program is read with CID directly indexing `CharStrings` by glyph order (CID == GID).
242
263
  - **The OpenType `MATH` table's `MathVariants` is parsed, stretchy-glyph assembly implemented, and the result genuinely drawable** via `MathAssembledGlyphs` (glyph-ID-addressed placements, since most construction glyphs have no Unicode code point — they draw directly because CID == GID here). An unencoded glyph gets no ToUnicode entry; the construction is wrapped in an `/ActualText` span carrying the operator's own text so it still extracts as `(`. `MathConstants` and `MathGlyphInfo` (italics correction, top-accent attachment) are parsed in full.
243
264
  - **What this package draws for a stretchy glyph is decided entirely by its caller.** Which operators a document actually stretches is a layout-engine decision — `documents.js`'s own `src/mathml/layout.ts` currently stretches vertical fences in an `mrow` and nothing else.
244
- - **Real per-glyph ink bounds are measured from the outline (`inkAscentPt`/`inkDescentPt`), computed by walking each glyph's Type 2 charstring.** `ascentPerEm`/`descentPerEm` remain alongside them as the uniform face-wide figure, still the right measure for anything sized against the font rather than particular characters, and the fallback for a glyph with no outline to measure. An ink box is genuinely tight, which for a math font is often *larger* than the nominal metrics (over a tenth of STIX Two Math's repertoire draws above its nominal ascent). `inkDescentPt` is negative where the glyph's lowest ink sits above the baseline.
265
+ - **Real per-glyph ink bounds are measured from the outline (`inkAscentPt`/`inkDescentPt`), computed by walking each glyph's Type 2 charstring.** `ascentPerEm`/`descentPerEm` remain alongside them as the uniform face-wide figure, still the right measure for anything sized against the font rather than particular characters, and the fallback for a glyph with no outline to measure. An ink box is genuinely tight, which for a math font is often _larger_ than the nominal metrics (over a tenth of STIX Two Math's repertoire draws above its nominal ascent). `inkDescentPt` is negative where the glyph's lowest ink sits above the baseline.
245
266
  - **A `LayoutLine`/`LayoutPath` `style` of `dashed`/`dotted` becomes a real dash-array (`d`) operator scaled to the stroke's own width; `double` becomes two genuinely separate offset strokes.** Dash lengths are stroke-width multiples so a hairline and a thick rule both read as recognisably dashed: `dashed` emits `[3w 3w] 0 d`, `dotted` emits `[0 2w] 0 d` with a `1 J` round cap (the zero on-length under a round cap paints a filled circle — exactly a dot; under PDF's default butt cap it paints nothing). Both are reset immediately after the paint operator (`[] 0 d`, `0 J`) since the graphics state persists for the whole content stream. `double` has no PDF operator and is drawn as geometry: width `w` splits into three equal bands, each rule `w/3` wide with centreline `w/3` offset, outer edges matching the single stroke's. Nothing on the read side recovers a stroke style — a dashed line read back comes back solid.
246
267
  - **An embedded `CIDFontType2` program needs no `cmap` table of its own**, and `sfnt-subset.ts`'s output doesn't carry one — character code → CID goes through the `Type0` font's `/Encoding` (Identity-H, so CID == character code), and CID → GID through `/CIDToGIDMap /Identity` (matching the GID-preserving design). Both happen inside the PDF's object graph, before the embedded font program is consulted (ISO 32000-1 9.7.4.2).
247
268
  - **`GPOS` pair kerning is read and applied for an embedded face; no other OpenType layout feature is.** `GSUB` (ligatures, contextual alternates, small caps) is never applied — a face's `fi` ligature is drawn as two separate glyphs. The legacy `kern` table is not read either (neither Carlito nor Caladea ships one). A kerned run is shown with `TJ`, and the sign of a `TJ` number is the opposite of the adjustment it expresses (ISO 32000-1 9.4.3: a positive number moves the next glyph closer). A run with no kerning pairs stays as one unsplit hex string with `Tj`.
@@ -259,7 +280,7 @@ Dependency direction is strictly downward and checkable: `layout` imports only `
259
280
 
260
281
  **Verification.** `src/test-support/jbig2.ts` holds real streams from three independent producers: jbig2enc (the encoder behind essentially every JBIG2-in-PDF in the wild), libtiff (MMR payloads), and a hand-written T.88 Annex E arithmetic encoder for templates jbig2enc will not emit. Every stream — hand-encoded ones included — is decoded by jbig2dec (Ghostscript's independent implementation) before being written out, and the bitmap recorded as each fixture's expected output is jbig2dec's, not this package's. The symbol-mode fixtures exist in six variants with only `REFCORNER`/`TRANSPOSED` bits rewritten, turning jbig2dec's output into a real differential test of the placement rules jbig2enc never exercises.
261
282
 
262
- A differential test pins the *set* of template positions and offsets but not their *order* — a context index is only a label for a neighbourhood pattern, so any consistent permutation cancels between encoder and decoder. TPGRON is refused rather than shipped unverified: jbig2enc's refinement support is disabled upstream, so the only available stream is one this package encoded itself, which cannot pin the pseudo-context constant even in principle (brute-forcing all 1024 candidates confirmed different unrelated bands of constants pass depending on the test image).
283
+ A differential test pins the _set_ of template positions and offsets but not their _order_ — a context index is only a label for a neighbourhood pattern, so any consistent permutation cancels between encoder and decoder. TPGRON is refused rather than shipped unverified: jbig2enc's refinement support is disabled upstream, so the only available stream is one this package encoded itself, which cannot pin the pseudo-context constant even in principle (brute-forcing all 1024 candidates confirmed different unrelated bands of constants pass depending on the test image).
263
284
 
264
285
  ## JPEG 2000 scope
265
286
 
@@ -281,7 +302,7 @@ A differential test pins the *set* of template positions and offsets but not the
281
302
 
282
303
  **The one exception is math-formula rendering (`WritePdfOptions.formulas`): this genuinely embeds a real, hand-parsed font.** Real box-model glyph runs through the embedded STIX Two Math font with genuine per-glyph metrics and font-wide layout constants parsed directly from the `MATH` table. Stretchy constructions are real: a `MathVariants` variant or assembly resolved, measured against actual outlines, and drawn by glyph ID.
283
304
 
284
- **`readPdf(writePdf(doc))` is not guaranteed to reproduce `doc` exactly, and `writePdf(readPdf(bytes))` is not guaranteed to reproduce `bytes` exactly.** A PDF page is fundamentally positioned drawing operators, not a structured document — a shape drawn any way other than the recognised characteristic patterns, or rotated off-axis, collapses to a generic `LayoutPath`. This is a deliberate, permanent contrast with format-preserving codecs like `ooxml.js`'s `packageCodec`. `pdfCodec` shares `z.codec()`'s *mechanism* (schema-validated both ways) but not that *guarantee*.
305
+ **`readPdf(writePdf(doc))` is not guaranteed to reproduce `doc` exactly, and `writePdf(readPdf(bytes))` is not guaranteed to reproduce `bytes` exactly.** A PDF page is fundamentally positioned drawing operators, not a structured document — a shape drawn any way other than the recognised characteristic patterns, or rotated off-axis, collapses to a generic `LayoutPath`. This is a deliberate, permanent contrast with format-preserving codecs like `ooxml.js`'s `packageCodec`. `pdfCodec` shares `z.codec()`'s _mechanism_ (schema-validated both ways) but not that _guarantee_.
285
306
 
286
307
  **Optional real-world corpus.** `test/corpus/` (gitignored) holds a `pnpm test:corpus` vitest project for manual conformance checking against real PDFs — Word/PowerPoint/Chrome/LibreOffice exports. Not part of `pnpm test` and does not gate CI; drop files in locally before a significant parser change.
287
308
 
@@ -557,7 +557,7 @@ function parseWidths(source) {
557
557
  return map;
558
558
  }
559
559
  const STANDARD_METRICS = {
560
- "Helvetica": {
560
+ Helvetica: {
561
561
  ascender: 718,
562
562
  descender: -207,
563
563
  capHeight: 718,
@@ -693,7 +693,7 @@ const STANDARD_METRICS = {
693
693
  lineHeightEm: 1.15,
694
694
  widths: parseWidths("space 250 exclam 389 quotedbl 555 numbersign 500 dollar 500 percent 833 ampersand 778 quoteright 333 parenleft 333 parenright 333 asterisk 500 plus 570 comma 250 hyphen 333 period 250 slash 278 zero 500 one 500 two 500 three 500 four 500 five 500 six 500 seven 500 eight 500 nine 500 colon 333 semicolon 333 less 570 equal 570 greater 570 question 500 at 832 A 667 B 667 C 667 D 722 E 667 F 667 G 722 H 778 I 389 J 500 K 667 L 611 M 889 N 722 O 722 P 611 Q 722 R 667 S 556 T 611 U 722 V 667 W 889 X 667 Y 611 Z 611 bracketleft 333 backslash 278 bracketright 333 asciicircum 570 underscore 500 quoteleft 333 a 500 b 500 c 444 d 500 e 444 f 333 g 500 h 556 i 278 j 278 k 500 l 278 m 778 n 556 o 500 p 500 q 500 r 389 s 389 t 278 u 556 v 444 w 667 x 500 y 444 z 389 braceleft 348 bar 220 braceright 348 asciitilde 570 exclamdown 389 cent 500 sterling 500 fraction 167 yen 500 florin 500 section 500 currency 500 quotesingle 278 quotedblleft 500 guillemotleft 500 guilsinglleft 333 guilsinglright 333 fi 556 fl 556 endash 500 dagger 500 daggerdbl 500 periodcentered 250 paragraph 500 bullet 350 quotesinglbase 333 quotedblbase 500 quotedblright 500 guillemotright 500 ellipsis 1000 perthousand 1000 questiondown 500 grave 333 acute 333 circumflex 333 tilde 333 macron 333 breve 333 dotaccent 333 dieresis 333 ring 333 cedilla 333 hungarumlaut 333 ogonek 333 caron 333 emdash 1000 AE 944 ordfeminine 266 Lslash 611 Oslash 722 OE 944 ordmasculine 300 ae 722 dotlessi 278 lslash 278 oslash 500 oe 722 germandbls 500 Idieresis 389 eacute 444 abreve 500 uhungarumlaut 556 ecaron 444 Ydieresis 611 divide 570 Yacute 611 Acircumflex 667 aacute 500 Ucircumflex 722 yacute 444 scommaaccent 389 ecircumflex 444 Uring 722 Udieresis 722 aogonek 500 Uacute 722 uogonek 556 Edieresis 667 Dcroat 722 commaaccent 250 copyright 747 Emacron 667 ccaron 444 aring 500 Ncommaaccent 722 lacute 278 agrave 500 Tcommaaccent 611 Cacute 667 atilde 500 Edotaccent 667 scaron 389 scedilla 389 iacute 278 lozenge 494 Rcaron 667 Gcommaaccent 722 ucircumflex 556 acircumflex 500 Amacron 667 rcaron 389 ccedilla 444 Zdotaccent 611 Thorn 611 Omacron 722 Racute 667 Sacute 556 dcaron 608 Umacron 722 uring 556 threesuperior 300 Ograve 722 Agrave 667 Abreve 667 multiply 570 uacute 556 Tcaron 611 partialdiff 494 ydieresis 444 Nacute 722 icircumflex 278 Ecircumflex 667 adieresis 500 edieresis 444 cacute 444 nacute 556 umacron 556 Ncaron 722 Iacute 389 plusminus 570 brokenbar 220 registered 747 Gbreve 722 Idotaccent 389 summation 600 Egrave 667 racute 389 omacron 500 Zacute 611 Zcaron 611 greaterequal 549 Eth 722 Ccedilla 667 lcommaaccent 278 tcaron 366 eogonek 444 Uogonek 722 Aacute 667 Adieresis 667 egrave 444 zacute 389 iogonek 278 Oacute 722 oacute 500 amacron 500 sacute 389 idieresis 278 Ocircumflex 722 Ugrave 722 Delta 612 thorn 500 twosuperior 300 Odieresis 722 mu 576 igrave 278 ohungarumlaut 500 Eogonek 667 dcroat 500 threequarters 750 Scedilla 556 lcaron 382 Kcommaaccent 667 Lacute 611 trademark 1000 edotaccent 444 Igrave 389 Imacron 389 Lcaron 611 onehalf 750 lessequal 549 ocircumflex 500 ntilde 556 Uhungarumlaut 722 Eacute 667 emacron 444 gbreve 500 onequarter 750 Scaron 556 Scommaaccent 556 Ohungarumlaut 722 degree 400 ograve 500 Ccaron 667 ugrave 556 radical 549 Dcaron 722 rcommaaccent 389 Ntilde 722 otilde 500 Rcommaaccent 667 Lcommaaccent 611 Atilde 667 Aogonek 667 Aring 667 Otilde 722 zdotaccent 389 Ecaron 667 Iogonek 389 kcommaaccent 500 minus 606 Icircumflex 389 ncaron 556 tcommaaccent 278 logicalnot 606 odieresis 500 udieresis 556 notequal 549 gcommaaccent 500 eth 500 zcaron 389 ncommaaccent 556 onesuperior 300 imacron 278 Euro 500")
695
695
  },
696
- "Courier": {
696
+ Courier: {
697
697
  ascender: 629,
698
698
  descender: -157,
699
699
  capHeight: 562,
@@ -557,7 +557,7 @@ function parseWidths(source) {
557
557
  return map;
558
558
  }
559
559
  const STANDARD_METRICS = {
560
- "Helvetica": {
560
+ Helvetica: {
561
561
  ascender: 718,
562
562
  descender: -207,
563
563
  capHeight: 718,
@@ -693,7 +693,7 @@ const STANDARD_METRICS = {
693
693
  lineHeightEm: 1.15,
694
694
  widths: parseWidths("space 250 exclam 389 quotedbl 555 numbersign 500 dollar 500 percent 833 ampersand 778 quoteright 333 parenleft 333 parenright 333 asterisk 500 plus 570 comma 250 hyphen 333 period 250 slash 278 zero 500 one 500 two 500 three 500 four 500 five 500 six 500 seven 500 eight 500 nine 500 colon 333 semicolon 333 less 570 equal 570 greater 570 question 500 at 832 A 667 B 667 C 667 D 722 E 667 F 667 G 722 H 778 I 389 J 500 K 667 L 611 M 889 N 722 O 722 P 611 Q 722 R 667 S 556 T 611 U 722 V 667 W 889 X 667 Y 611 Z 611 bracketleft 333 backslash 278 bracketright 333 asciicircum 570 underscore 500 quoteleft 333 a 500 b 500 c 444 d 500 e 444 f 333 g 500 h 556 i 278 j 278 k 500 l 278 m 778 n 556 o 500 p 500 q 500 r 389 s 389 t 278 u 556 v 444 w 667 x 500 y 444 z 389 braceleft 348 bar 220 braceright 348 asciitilde 570 exclamdown 389 cent 500 sterling 500 fraction 167 yen 500 florin 500 section 500 currency 500 quotesingle 278 quotedblleft 500 guillemotleft 500 guilsinglleft 333 guilsinglright 333 fi 556 fl 556 endash 500 dagger 500 daggerdbl 500 periodcentered 250 paragraph 500 bullet 350 quotesinglbase 333 quotedblbase 500 quotedblright 500 guillemotright 500 ellipsis 1000 perthousand 1000 questiondown 500 grave 333 acute 333 circumflex 333 tilde 333 macron 333 breve 333 dotaccent 333 dieresis 333 ring 333 cedilla 333 hungarumlaut 333 ogonek 333 caron 333 emdash 1000 AE 944 ordfeminine 266 Lslash 611 Oslash 722 OE 944 ordmasculine 300 ae 722 dotlessi 278 lslash 278 oslash 500 oe 722 germandbls 500 Idieresis 389 eacute 444 abreve 500 uhungarumlaut 556 ecaron 444 Ydieresis 611 divide 570 Yacute 611 Acircumflex 667 aacute 500 Ucircumflex 722 yacute 444 scommaaccent 389 ecircumflex 444 Uring 722 Udieresis 722 aogonek 500 Uacute 722 uogonek 556 Edieresis 667 Dcroat 722 commaaccent 250 copyright 747 Emacron 667 ccaron 444 aring 500 Ncommaaccent 722 lacute 278 agrave 500 Tcommaaccent 611 Cacute 667 atilde 500 Edotaccent 667 scaron 389 scedilla 389 iacute 278 lozenge 494 Rcaron 667 Gcommaaccent 722 ucircumflex 556 acircumflex 500 Amacron 667 rcaron 389 ccedilla 444 Zdotaccent 611 Thorn 611 Omacron 722 Racute 667 Sacute 556 dcaron 608 Umacron 722 uring 556 threesuperior 300 Ograve 722 Agrave 667 Abreve 667 multiply 570 uacute 556 Tcaron 611 partialdiff 494 ydieresis 444 Nacute 722 icircumflex 278 Ecircumflex 667 adieresis 500 edieresis 444 cacute 444 nacute 556 umacron 556 Ncaron 722 Iacute 389 plusminus 570 brokenbar 220 registered 747 Gbreve 722 Idotaccent 389 summation 600 Egrave 667 racute 389 omacron 500 Zacute 611 Zcaron 611 greaterequal 549 Eth 722 Ccedilla 667 lcommaaccent 278 tcaron 366 eogonek 444 Uogonek 722 Aacute 667 Adieresis 667 egrave 444 zacute 389 iogonek 278 Oacute 722 oacute 500 amacron 500 sacute 389 idieresis 278 Ocircumflex 722 Ugrave 722 Delta 612 thorn 500 twosuperior 300 Odieresis 722 mu 576 igrave 278 ohungarumlaut 500 Eogonek 667 dcroat 500 threequarters 750 Scedilla 556 lcaron 382 Kcommaaccent 667 Lacute 611 trademark 1000 edotaccent 444 Igrave 389 Imacron 389 Lcaron 611 onehalf 750 lessequal 549 ocircumflex 500 ntilde 556 Uhungarumlaut 722 Eacute 667 emacron 444 gbreve 500 onequarter 750 Scaron 556 Scommaaccent 556 Ohungarumlaut 722 degree 400 ograve 500 Ccaron 667 ugrave 556 radical 549 Dcaron 722 rcommaaccent 389 Ntilde 722 otilde 500 Rcommaaccent 667 Lcommaaccent 611 Atilde 667 Aogonek 667 Aring 667 Otilde 722 zdotaccent 389 Ecaron 667 Iogonek 389 kcommaaccent 500 minus 606 Icircumflex 389 ncaron 556 tcommaaccent 278 logicalnot 606 odieresis 500 udieresis 556 notequal 549 gcommaaccent 500 eth 500 zcaron 389 ncommaaccent 556 onesuperior 300 imacron 278 Euro 500")
695
695
  },
696
- "Courier": {
696
+ Courier: {
697
697
  ascender: 629,
698
698
  descender: -157,
699
699
  capHeight: 562,
@@ -1,5 +1,5 @@
1
1
  //#region src/afm-widths.d.ts
2
- type StandardFontName = 'Helvetica' | 'Helvetica-Bold' | 'Helvetica-Oblique' | 'Helvetica-BoldOblique' | 'Times-Roman' | 'Times-Bold' | 'Times-Italic' | 'Times-BoldItalic' | 'Courier' | 'Courier-Bold' | 'Courier-Oblique' | 'Courier-BoldOblique';
2
+ type StandardFontName = "Helvetica" | "Helvetica-Bold" | "Helvetica-Oblique" | "Helvetica-BoldOblique" | "Times-Roman" | "Times-Bold" | "Times-Italic" | "Times-BoldItalic" | "Courier" | "Courier-Bold" | "Courier-Oblique" | "Courier-BoldOblique";
3
3
  interface FontMetrics {
4
4
  readonly ascender: number;
5
5
  readonly descender: number;
@@ -1,5 +1,5 @@
1
1
  //#region src/afm-widths.d.ts
2
- type StandardFontName = 'Helvetica' | 'Helvetica-Bold' | 'Helvetica-Oblique' | 'Helvetica-BoldOblique' | 'Times-Roman' | 'Times-Bold' | 'Times-Italic' | 'Times-BoldItalic' | 'Courier' | 'Courier-Bold' | 'Courier-Oblique' | 'Courier-BoldOblique';
2
+ type StandardFontName = "Helvetica" | "Helvetica-Bold" | "Helvetica-Oblique" | "Helvetica-BoldOblique" | "Times-Roman" | "Times-Bold" | "Times-Italic" | "Times-BoldItalic" | "Courier" | "Courier-Bold" | "Courier-Oblique" | "Courier-BoldOblique";
3
3
  interface FontMetrics {
4
4
  readonly ascender: number;
5
5
  readonly descender: number;
@@ -1,4 +1,4 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_afm_widths = require("./afm-widths-BoeTOK2r.cjs");
2
+ const require_afm_widths = require("./afm-widths-Cj9d3GVK.cjs");
3
3
  exports.STANDARD_METRICS = require_afm_widths.STANDARD_METRICS;
4
4
  exports.widthOfCode = require_afm_widths.widthOfCode;
@@ -1,2 +1,2 @@
1
- import { i as widthOfCode, n as STANDARD_METRICS, r as StandardFontName, t as FontMetrics } from "./afm-widths-DyDq56Ph.cjs";
1
+ import { i as widthOfCode, n as STANDARD_METRICS, r as StandardFontName, t as FontMetrics } from "./afm-widths-CneRyu5l.cjs";
2
2
  export { FontMetrics, STANDARD_METRICS, StandardFontName, widthOfCode };
@@ -1,2 +1,2 @@
1
- import { i as widthOfCode, n as STANDARD_METRICS, r as StandardFontName, t as FontMetrics } from "./afm-widths-DyDq56Ph.js";
1
+ import { i as widthOfCode, n as STANDARD_METRICS, r as StandardFontName, t as FontMetrics } from "./afm-widths-CneRyu5l.js";
2
2
  export { FontMetrics, STANDARD_METRICS, StandardFontName, widthOfCode };
@@ -1,2 +1,2 @@
1
- import { n as widthOfCode, t as STANDARD_METRICS } from "./afm-widths-Dxucrg7D.js";
1
+ import { n as widthOfCode, t as STANDARD_METRICS } from "./afm-widths-BLl6ORCt.js";
2
2
  export { STANDARD_METRICS, widthOfCode };
@@ -10,10 +10,10 @@ interface InlineImage {
10
10
  readonly data: Uint8Array<ArrayBuffer>;
11
11
  }
12
12
  type ContentToken = {
13
- readonly kind: 'operation';
13
+ readonly kind: "operation";
14
14
  readonly operation: ContentOperation;
15
15
  } | {
16
- readonly kind: 'inlineImage';
16
+ readonly kind: "inlineImage";
17
17
  readonly image: InlineImage;
18
18
  };
19
19
  declare function readContentStream(bytes: Uint8Array<ArrayBuffer>, sink: PdfDiagnosticSink): ContentToken[];
@@ -10,10 +10,10 @@ interface InlineImage {
10
10
  readonly data: Uint8Array<ArrayBuffer>;
11
11
  }
12
12
  type ContentToken = {
13
- readonly kind: 'operation';
13
+ readonly kind: "operation";
14
14
  readonly operation: ContentOperation;
15
15
  } | {
16
- readonly kind: 'inlineImage';
16
+ readonly kind: "inlineImage";
17
17
  readonly image: InlineImage;
18
18
  };
19
19
  declare function readContentStream(bytes: Uint8Array<ArrayBuffer>, sink: PdfDiagnosticSink): ContentToken[];
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_afm_widths = require("./afm-widths-BoeTOK2r.cjs");
2
+ const require_afm_widths = require("./afm-widths-Cj9d3GVK.cjs");
3
3
  const require_objects = require("./objects.cjs");
4
4
  const require_bytes_writer = require("./bytes/writer.cjs");
5
5
  const require_serialize = require("./serialize.cjs");
@@ -1,15 +1,15 @@
1
- import { r as StandardFontName } from "./afm-widths-DyDq56Ph.cjs";
1
+ import { r as StandardFontName } from "./afm-widths-CneRyu5l.cjs";
2
2
  import { LayoutItem } from "./layout.cjs";
3
3
  import { r as EmbeddedFaceSubstitution, t as EmbeddedFace } from "./embedded-font-BU6Jgcof.cjs";
4
4
  import { WinAnsiSubstitution } from "./winansi.cjs";
5
5
  import { LayoutFont, TextMeasurer } from "document-schema.js";
6
6
  //#region src/content-write.d.ts
7
7
  type ResolvedFontResource = {
8
- readonly kind: 'standard';
8
+ readonly kind: "standard";
9
9
  readonly resourceName: string;
10
10
  readonly standardName: StandardFontName;
11
11
  } | {
12
- readonly kind: 'embedded';
12
+ readonly kind: "embedded";
13
13
  readonly resourceName: string;
14
14
  readonly face: EmbeddedFace;
15
15
  };
@@ -1,15 +1,15 @@
1
- import { r as StandardFontName } from "./afm-widths-DyDq56Ph.js";
1
+ import { r as StandardFontName } from "./afm-widths-CneRyu5l.js";
2
2
  import { LayoutItem } from "./layout.js";
3
3
  import { r as EmbeddedFaceSubstitution, t as EmbeddedFace } from "./embedded-font-fREdbxnr.js";
4
4
  import { WinAnsiSubstitution } from "./winansi.js";
5
5
  import { LayoutFont, TextMeasurer } from "document-schema.js";
6
6
  //#region src/content-write.d.ts
7
7
  type ResolvedFontResource = {
8
- readonly kind: 'standard';
8
+ readonly kind: "standard";
9
9
  readonly resourceName: string;
10
10
  readonly standardName: StandardFontName;
11
11
  } | {
12
- readonly kind: 'embedded';
12
+ readonly kind: "embedded";
13
13
  readonly resourceName: string;
14
14
  readonly face: EmbeddedFace;
15
15
  };
@@ -1,4 +1,4 @@
1
- import { o as encodeForShow } from "./afm-widths-Dxucrg7D.js";
1
+ import { o as encodeForShow } from "./afm-widths-BLl6ORCt.js";
2
2
  import { pdfArray, pdfHexString, pdfNum } from "./objects.js";
3
3
  import { ByteWriter } from "./bytes/writer.js";
4
4
  import { formatNumber, writeObject } from "./serialize.js";
@@ -1,5 +1,5 @@
1
1
  //#region src/diagnostics.d.ts
2
- type PdfDiagnosticSeverity = 'info' | 'warning';
2
+ type PdfDiagnosticSeverity = "info" | "warning";
3
3
  interface PdfDiagnostic {
4
4
  readonly code: string;
5
5
  readonly severity: PdfDiagnosticSeverity;
@@ -1,5 +1,5 @@
1
1
  //#region src/diagnostics.d.ts
2
- type PdfDiagnosticSeverity = 'info' | 'warning';
2
+ type PdfDiagnosticSeverity = "info" | "warning";
3
3
  interface PdfDiagnostic {
4
4
  readonly code: string;
5
5
  readonly severity: PdfDiagnosticSeverity;
package/dist/encoding.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_afm_widths = require("./afm-widths-BoeTOK2r.cjs");
2
+ const require_afm_widths = require("./afm-widths-Cj9d3GVK.cjs");
3
3
  exports.WINANSI_GLYPH_NAMES = require_afm_widths.WINANSI_GLYPH_NAMES;
4
4
  exports.glyphNameToUnicode = require_afm_widths.glyphNameToUnicode;
5
5
  exports.winAnsiGlyphName = require_afm_widths.winAnsiGlyphName;
package/dist/encoding.js CHANGED
@@ -1,2 +1,2 @@
1
- import { a as winAnsiGlyphName, i as glyphNameToUnicode, r as WINANSI_GLYPH_NAMES } from "./afm-widths-Dxucrg7D.js";
1
+ import { a as winAnsiGlyphName, i as glyphNameToUnicode, r as WINANSI_GLYPH_NAMES } from "./afm-widths-BLl6ORCt.js";
2
2
  export { WINANSI_GLYPH_NAMES, glyphNameToUnicode, winAnsiGlyphName };
@@ -1,7 +1,7 @@
1
1
  import { PdfDiagnosticSink } from "./diagnostics.cjs";
2
2
  import { PdfDict } from "./objects.cjs";
3
3
  //#region src/encrypt.d.ts
4
- type CipherMethod = 'identity' | 'rc4' | 'aes';
4
+ type CipherMethod = "identity" | "rc4" | "aes";
5
5
  interface PdfDecryptor {
6
6
  decryptString(bytes: Uint8Array<ArrayBuffer>, num: number, gen: number): Uint8Array<ArrayBuffer>;
7
7
  decryptStream(bytes: Uint8Array<ArrayBuffer>, dict: PdfDict, num: number, gen: number): Uint8Array<ArrayBuffer>;
package/dist/encrypt.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { PdfDiagnosticSink } from "./diagnostics.js";
2
2
  import { PdfDict } from "./objects.js";
3
3
  //#region src/encrypt.d.ts
4
- type CipherMethod = 'identity' | 'rc4' | 'aes';
4
+ type CipherMethod = "identity" | "rc4" | "aes";
5
5
  interface PdfDecryptor {
6
6
  decryptString(bytes: Uint8Array<ArrayBuffer>, num: number, gen: number): Uint8Array<ArrayBuffer>;
7
7
  decryptStream(bytes: Uint8Array<ArrayBuffer>, dict: PdfDict, num: number, gen: number): Uint8Array<ArrayBuffer>;
package/dist/filters.cjs CHANGED
@@ -62,11 +62,13 @@ function ccittFaxDecode(data, parm, dict, sink) {
62
62
  rows,
63
63
  blackIs1: require_objects.asBool(parmGet("BlackIs1")),
64
64
  encodedByteAlign: require_objects.asBool(parmGet("EncodedByteAlign")),
65
- onWarning: (message) => sink({
66
- code: "pdf/ccitt-fax-degraded",
67
- severity: "warning",
68
- message
69
- })
65
+ onWarning: (message) => {
66
+ sink({
67
+ code: "pdf/ccitt-fax-degraded",
68
+ severity: "warning",
69
+ message
70
+ });
71
+ }
70
72
  }).bytes;
71
73
  }
72
74
  function jbig2Decode(data, parm, dict, sink, resolve) {
@@ -84,11 +86,13 @@ function jbig2Decode(data, parm, dict, sink, resolve) {
84
86
  globals,
85
87
  width: require_objects.asNumber(require_objects.dictGet(dict, "Width") ?? require_objects.dictGet(dict, "W")),
86
88
  height: require_objects.asNumber(require_objects.dictGet(dict, "Height") ?? require_objects.dictGet(dict, "H")),
87
- onWarning: (message) => sink({
88
- code: "pdf/jbig2-degraded",
89
- severity: "warning",
90
- message
91
- })
89
+ onWarning: (message) => {
90
+ sink({
91
+ code: "pdf/jbig2-degraded",
92
+ severity: "warning",
93
+ message
94
+ });
95
+ }
92
96
  });
93
97
  return Uint8Array.from(image.bytes, (byte) => byte ^ 255);
94
98
  } catch (error) {
package/dist/filters.js CHANGED
@@ -61,11 +61,13 @@ function ccittFaxDecode(data, parm, dict, sink) {
61
61
  rows,
62
62
  blackIs1: asBool(parmGet("BlackIs1")),
63
63
  encodedByteAlign: asBool(parmGet("EncodedByteAlign")),
64
- onWarning: (message) => sink({
65
- code: "pdf/ccitt-fax-degraded",
66
- severity: "warning",
67
- message
68
- })
64
+ onWarning: (message) => {
65
+ sink({
66
+ code: "pdf/ccitt-fax-degraded",
67
+ severity: "warning",
68
+ message
69
+ });
70
+ }
69
71
  }).bytes;
70
72
  }
71
73
  function jbig2Decode(data, parm, dict, sink, resolve) {
@@ -83,11 +85,13 @@ function jbig2Decode(data, parm, dict, sink, resolve) {
83
85
  globals,
84
86
  width: asNumber(dictGet(dict, "Width") ?? dictGet(dict, "W")),
85
87
  height: asNumber(dictGet(dict, "Height") ?? dictGet(dict, "H")),
86
- onWarning: (message) => sink({
87
- code: "pdf/jbig2-degraded",
88
- severity: "warning",
89
- message
90
- })
88
+ onWarning: (message) => {
89
+ sink({
90
+ code: "pdf/jbig2-degraded",
91
+ severity: "warning",
92
+ message
93
+ });
94
+ }
91
95
  });
92
96
  return Uint8Array.from(image.bytes, (byte) => byte ^ 255);
93
97
  } catch (error) {
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_afm_widths = require("./afm-widths-BoeTOK2r.cjs");
2
+ const require_afm_widths = require("./afm-widths-Cj9d3GVK.cjs");
3
3
  const require_objects = require("./objects.cjs");
4
4
  const require_filters = require("./filters.cjs");
5
5
  const require_cmap = require("./cmap.cjs");
package/dist/font-read.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as winAnsiGlyphName, i as glyphNameToUnicode, n as widthOfCode } from "./afm-widths-Dxucrg7D.js";
1
+ import { a as winAnsiGlyphName, i as glyphNameToUnicode, n as widthOfCode } from "./afm-widths-BLl6ORCt.js";
2
2
  import { asArray, asName, asNumber, dictGet } from "./objects.js";
3
3
  import { decodeStream } from "./filters.js";
4
4
  import { parseToUnicodeCMap } from "./cmap.js";
@@ -1,12 +1,12 @@
1
- import { r as StandardFontName } from "./afm-widths-DyDq56Ph.cjs";
1
+ import { r as StandardFontName } from "./afm-widths-CneRyu5l.cjs";
2
2
  import { t as EmbeddedFace } from "./embedded-font-BU6Jgcof.cjs";
3
3
  import { FontRegistryOptions, LayoutFont } from "document-schema.js";
4
4
  //#region src/font-registry.d.ts
5
5
  type ResolvedFace = {
6
- readonly kind: 'embedded';
6
+ readonly kind: "embedded";
7
7
  readonly face: EmbeddedFace;
8
8
  } | {
9
- readonly kind: 'standard';
9
+ readonly kind: "standard";
10
10
  readonly standardName: StandardFontName;
11
11
  readonly matched: boolean;
12
12
  };
@@ -1,12 +1,12 @@
1
- import { r as StandardFontName } from "./afm-widths-DyDq56Ph.js";
1
+ import { r as StandardFontName } from "./afm-widths-CneRyu5l.js";
2
2
  import { t as EmbeddedFace } from "./embedded-font-fREdbxnr.js";
3
3
  import { FontRegistryOptions, LayoutFont } from "document-schema.js";
4
4
  //#region src/font-registry.d.ts
5
5
  type ResolvedFace = {
6
- readonly kind: 'embedded';
6
+ readonly kind: "embedded";
7
7
  readonly face: EmbeddedFace;
8
8
  } | {
9
- readonly kind: 'standard';
9
+ readonly kind: "standard";
10
10
  readonly standardName: StandardFontName;
11
11
  readonly matched: boolean;
12
12
  };
@@ -1,5 +1,5 @@
1
1
  //#region src/font-substitutes.d.ts
2
- type VendoredFamily = 'carlito' | 'caladea';
2
+ type VendoredFamily = "carlito" | "caladea";
3
3
  declare function resolveVendoredSubstituteFamily(rawFamily: string): VendoredFamily | undefined;
4
4
  //#endregion
5
5
  export { VendoredFamily, resolveVendoredSubstituteFamily };
@@ -1,5 +1,5 @@
1
1
  //#region src/font-substitutes.d.ts
2
- type VendoredFamily = 'carlito' | 'caladea';
2
+ type VendoredFamily = "carlito" | "caladea";
3
3
  declare function resolveVendoredSubstituteFamily(rawFamily: string): VendoredFamily | undefined;
4
4
  //#endregion
5
5
  export { VendoredFamily, resolveVendoredSubstituteFamily };
package/dist/fonts.d.cts CHANGED
@@ -1,6 +1,6 @@
1
- import { r as StandardFontName } from "./afm-widths-DyDq56Ph.cjs";
1
+ import { r as StandardFontName } from "./afm-widths-CneRyu5l.cjs";
2
2
  //#region src/fonts.d.ts
3
- type StandardFamily = 'helvetica' | 'times' | 'courier';
3
+ type StandardFamily = "helvetica" | "times" | "courier";
4
4
  declare function normalizeFamilyName(raw: string): string;
5
5
  interface FontFamilyResolution {
6
6
  readonly family: StandardFamily;
package/dist/fonts.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { r as StandardFontName } from "./afm-widths-DyDq56Ph.js";
1
+ import { r as StandardFontName } from "./afm-widths-CneRyu5l.js";
2
2
  //#region src/fonts.d.ts
3
- type StandardFamily = 'helvetica' | 'times' | 'courier';
3
+ type StandardFamily = "helvetica" | "times" | "courier";
4
4
  declare function normalizeFamilyName(raw: string): string;
5
5
  interface FontFamilyResolution {
6
6
  readonly family: StandardFamily;
@@ -11,7 +11,7 @@ declare class Jbig2BitmapTooLargeError extends Jbig2ParseError {
11
11
  }
12
12
  declare function createBitmap(width: number, height: number, fill?: number): Jbig2Bitmap;
13
13
  declare function getPixel(bitmap: Jbig2Bitmap, x: number, y: number): number;
14
- type Jbig2CombinationOperator = 'or' | 'and' | 'xor' | 'xnor' | 'replace';
14
+ type Jbig2CombinationOperator = "or" | "and" | "xor" | "xnor" | "replace";
15
15
  declare function combinationOperatorFromCode(code: number): Jbig2CombinationOperator | undefined;
16
16
  declare function combineBitmap(destination: Jbig2Bitmap, source: Jbig2Bitmap, x: number, y: number, operator: Jbig2CombinationOperator): void;
17
17
  declare function packBitmapRows(bitmap: Jbig2Bitmap, width: number, height: number): Uint8Array<ArrayBuffer>;