pdf-parser.js 4.7.0 → 4.8.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/README.md CHANGED
@@ -205,7 +205,27 @@ const image = decodeJpeg2000(jp2OrCodestreamBytes); // -> { width, height, bitDe
205
205
 
206
206
  Both accept a whole JP2 file or a bare codestream; `decodeJpeg2000` takes an optional `onWarning` for recoverable cases and throws `Jpeg2000UnsupportedError` for anything outside [JPEG 2000 scope](#jpeg-2000-scope). Inside a PDF none of this needs calling: `readPdf` decodes a `/JPXDecode` image XObject through the same path automatically.
207
207
 
208
- The generic byte- and image-container primitives (`crc32`, `deflate`/`inflate`/`inflateTolerant`, `ByteReader`/`ByteWriter`/`concatBytes`, `readJpegInfo`, `decodePng`/`encodePng`, `unfilterScanlines`/`filterScanlines`) are re-exported from [byte-codec](../byte-codec/README.md). The PDF-specific image codecs (`decodeCcittFax`, `decodeJbig2Embedded`, `decodeJpeg2000`/`readJpeg2000Metadata`/`parseJp2Container`) stay here.
208
+ Rendering a page, or one region of one, to pixels — for OCR, a vision model, or a thumbnail — through a rasteriser the caller supplies ([#1198](https://github.com/ExaDev/documents.js/issues/1198)):
209
+
210
+ ```ts
211
+ import { renderPdfPage } from "pdf-codec";
212
+ import { createCpuRasteriser } from "pdf-raster-cpu"; // the pure-software reference backend
213
+
214
+ const pngBytes = renderPdfPage(
215
+ pdfBytes,
216
+ 0,
217
+ { dpi: 200 },
218
+ createCpuRasteriser(),
219
+ );
220
+ ```
221
+
222
+ `renderPdfPage(pdfBytes, pageIndex, options, rasteriser)` walks the page's content through the same read machinery `readPdf` runs (the same interpreter, the same image recovery), transforms everything into a top-left-origin device space at the requested `scale` (or `dpi` — a PDF point is 1/72 inch, so `dpi: 144` is `scale: 2`), and drives the rasteriser with positioned draw operations: rectangle fills, filled/stroked vector paths (ellipses, arbitrary curves, and glyph outlines), and affine-placed images. It returns whatever the rasteriser's `finish()` produces — PNG bytes with the reference backend. The deliberate design point, from the issue's own clarification: **this package defines the `PageRasteriser` interface and takes an implementation; it does not pick a rasteriser or depend on any canvas API.** A runtime with no canvas at all (Cloudflare Workers has neither `canvas` nor `OffscreenCanvas`) and a runtime with a free hardware-accelerated one consume the same port, and the weight of a real raster backend lands only in the backend package a consumer installs — [`pdf-raster-cpu`](../pdf-raster-cpu/README.md) is this family's pure-software reference implementation, a browser consumer can wrap its own 2D canvas, and a Cloudflare consumer can drive Browser Rendering. No OCR, no vision, no network calls anywhere: the port hands a caller pixels and stops.
223
+
224
+ `options.clipPt` names the region to render, in the same point coordinates `LayoutFrame` (and `LayoutPage` items, and `document-outline.js`'s `segmentPdfRegions` region bounds) use — PDF user space relative to the visible region's lower-left corner, y increasing upward. A caller that located a figure via `segmentPdfRegions` passes `region.bounds` straight through as `clipPt` and gets exactly that figure's pixels, re-origined at the image's own top-left and scaled; `src/raster.test.ts` pins the coordinate agreement against `readPdf` itself (including a rotated, cropped page), so the clip contract is a tested fact rather than a hope. Text render order, fill rules, and optional-content visibility follow what a viewer displays: items in a layer the default configuration leaves `OFF` are not drawn.
225
+
226
+ **Text renders through the page's own embedded sfnt outlines, or not at all.** Each text run's embedded TrueType program (`/Type0` + `/Identity-H` + `/CIDFontType2`, the dominant mainstream shape, or a simple `/TrueType` font with a usable cmap) is opened with this package's own `glyf`/`cmap` readers and handed to the rasteriser as filled outline paths — a backend needs no font machinery of any kind. Faces that state no sfnt outlines are refused through named diagnostics (`raster/text-cff-outlines` for CFF programs, `raster/text-outlines-unavailable` for standard-14/unembedded fonts, Type 3 glyph procedures, and unreadable programs) rather than approximated with a substitute shape; the rest of the page still renders. Per-glyph placement follows the run's own text matrices, with one documented approximation: character-, word-, and horizontal-spacing state (`Tc`/`Tw`/`Tz`) is not modelled per glyph, and the residual is distributed uniformly across the run so its total extent always matches what the page draws.
227
+
228
+ The generic byte- and image-container primitives (`crc32`, `deflate`/`inflate`/`inflateTolerant`, `ByteWriter`/`concatBytes`, `readJpegInfo`, `decodePng`/`encodePng`, `unfilterScanlines`/`filterScanlines`) are re-exported from [byte-codec](../byte-codec/README.md). The PDF-specific image codecs (`decodeCcittFax`, `decodeJbig2Embedded`, `decodeJpeg2000`/`readJpeg2000Metadata`/`parseJp2Container`) stay here.
209
229
 
210
230
  Every module under `src/` is also deep-importable directly by its own subpath:
211
231
 
@@ -222,7 +242,7 @@ One subpath is a declared entry point in its own right: **`pdf-codec/read`** (an
222
242
  import { readPdf } from "pdf-codec/read";
223
243
  ```
224
244
 
225
- `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`).
245
+ `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`), standard-14 resolution/AFM metrics (`pdf-codec/fonts`, `pdf-codec/afm-widths`), and the rasterisation port (`pdf-codec/raster`, whose glyph machinery reads outlines out of the page's own embedded font programs rather than any vendored face).
226
246
 
227
247
  ## Architecture
228
248
 
@@ -235,13 +255,14 @@ The package is layered from generic primitives outward to the codec itself:
235
255
  - **`src/crypto/`** — MD5, SHA-256/384/512, RC4, and AES-CBC, hand-written with zero local imports, plus a thin `random.ts` wrapper around `globalThis.crypto.getRandomValues` for the writer's own salts/file keys/IVs. Not a preference: ISO 32000-1's key-derivation algorithms name MD5 and RC4 directly, neither offered by any portable platform crypto API, and `crypto.subtle` is asynchronous where this codec's read and write paths are both synchronous end to end — `getRandomValues` itself, unlike `crypto.subtle`, is synchronous and portable, so it is used directly rather than hand-written. Reaching for `node:crypto` would break the browser bundle. Each hash/cipher module cites its specification (RFC 1321, FIPS 180-4, FIPS 197) and is tested against published conformance vectors.
236
256
  - **The codec itself, importing only `layout`/`bytes`/`image`/`crypto`/`util` plus `document-schema.js`'s port types (no OOXML or ODF knowledge):**
237
257
  - **Write**: `objects.ts` (the `PdfObject` discriminated union), `afm-widths.ts`/`encoding.ts`/`winansi.ts`/`fonts.ts` (standard-14 metrics, WinAnsi encoding, family resolution), `font-registry.ts` (resolution port plus `resolveFaceWithRegistry`, the one step both measurer and writer resolve through so they can never disagree about which face a `LayoutFont` means), `font-face.ts` (`readFontFace`, reading a standalone font file's family/bold/italic triple off its `name`/`OS/2`/`head` tables), `measure.ts`/`text-layout.ts` (greedy line-wrapping against either standard-14 AFM widths plus per-family correction or a resolved face's own real `hmtx` advances — never both), `content-write.ts` (`LayoutItem[]` → content-stream operators, with text branching on standard-14 vs embedded face encoding, pair-kerning split into `TJ` arrays, stroke `style` becoming real dash/line-cap state, and `/P <</MCID n /OC R>> BDC`…`EMC` spans around items carrying a structure owner or an optional-content layer — the one marked-content spelling both read-side channels resolve through), `write.ts` (the full object graph, cross-reference table, trailer, and embedded font groups, plus the document-level round-trip surfaces: the `/Names /EmbeddedFiles` attachments tree and `/Outlines` bookmark tree, `/OCProperties` optional-content groups with each layer stated explicitly into the default configuration's `/ON` or `/OFF` list, the `/AcroForm` field tree with the merged-field/widget spelling (a single widget merges into its field dict; a multi-widget field's widgets are separate `/Subtype /Widget` kids, each also referenced from its page's `/Annots` — the same annotation object in both places, so a viewer reading only page-level annotations still renders every widget — and fully-qualified names decompose back into the `/T` chain), the `/StructTreeRoot` element tree with its `/ParentTree` number tree associating each marked item's MCID to its owning element, and the package-level residue rows restored inline onto the Catalog or trailer — the XMP packet as an uncompressed `/Metadata` stream, and any row whose serialisation references source-file objects skipped rather than emitted as a dangling reference).
238
- - **sfnt font tables**: `sfnt.ts` (bounds-checked table-directory reader), `cmap-table.ts` (character code → glyph ID, formats 0/4/6/12, exposed both as the best Unicode lookup and as every subtable individually, since a (3, 0) or (1, 0) subtable is keyed by a font's own codes rather than by code points), `hmtx-table.ts` (per-glyph advance widths), `font-tables.ts` (`head`/`maxp`/`OS/2`/`post`/`name`, including `post`'s own glyph names where a font still carries them), `glyf.ts` (`loca` offset index, per-glyph headers, composite component records, `glyphInkBounds`), `math-table.ts` (OpenType `MATH` constants/glyph-info/variants subtables). `ot-layout-common.ts` (Coverage/ClassDef, stored as sorted glyph ranges searched by bisection). `gpos-table.ts` reads `GPOS` for exactly one thing: pair-advance kerning through the `kern` feature, both PairPos formats and LookupType 9 Extension indirection — mark attachment, cursive joining, and contextual positioning have no consumer here. `gsub-table.ts` reads `GSUB` for the default-on feature set (`liga`/`rlig`/`calt`/`clig`) through Single, Ligature, Contextual, and Chaining Contextual substitutions (LookupTypes 1, 4, 5, 6, and the 7 Extension wrapper), with each lookup's `lookupFlag` skip semantics — ignore-base/ligature/marks, mark attachment classes, mark filtering sets — evaluated against `gdef-table.ts`'s reading of the font's `GDEF`; `smcp`/`dlig` stay opt-in through `GsubShaperOptions`, the switch a real shaper's caller flips. Every parser degrades to `undefined` on a missing/truncated table rather than throwing.
258
+ - **sfnt font tables**: `sfnt.ts` (bounds-checked table-directory reader), `cmap-table.ts` (character code → glyph ID, formats 0/4/6/12, exposed both as the best Unicode lookup and as every subtable individually, since a (3, 0) or (1, 0) subtable is keyed by a font's own codes rather than by code points), `hmtx-table.ts` (per-glyph advance widths), `font-tables.ts` (`head`/`maxp`/`OS/2`/`post`/`name`, including `post`'s own glyph names where a font still carries them), `glyf.ts` (`loca` offset index, per-glyph headers, composite component records, `glyphInkBounds`), `glyf-contours.ts` (the point arrays glyf.ts deliberately leaves undecoded: a glyph's on/off-curve contours, composites resolved, consumed by the raster port's outline rendering and differentially tested against the header-declared ink boxes), `math-table.ts` (OpenType `MATH` constants/glyph-info/variants subtables). `ot-layout-common.ts` (Coverage/ClassDef, stored as sorted glyph ranges searched by bisection). `gpos-table.ts` reads `GPOS` for exactly one thing: pair-advance kerning through the `kern` feature, both PairPos formats and LookupType 9 Extension indirection — mark attachment, cursive joining, and contextual positioning have no consumer here. `gsub-table.ts` reads `GSUB` for the default-on feature set (`liga`/`rlig`/`calt`/`clig`) through Single, Ligature, Contextual, and Chaining Contextual substitutions (LookupTypes 1, 4, 5, 6, and the 7 Extension wrapper), with each lookup's `lookupFlag` skip semantics — ignore-base/ligature/marks, mark attachment classes, mark filtering sets — evaluated against `gdef-table.ts`'s reading of the font's `GDEF`; `smcp`/`dlig` stay opt-in through `GsubShaperOptions`, the switch a real shaper's caller flips. Every parser degrades to `undefined` on a missing/truncated table rather than throwing.
239
259
  - **sfnt subsetting**: `sfnt-subset.ts` — a TrueType-outline glyph subsetter (Unicode code points → glyph IDs via `cmap`, transitive closure over `glyf` composite components, rebuilt sfnt carrying only used outlines). **Glyph IDs are preserved, never renumbered**, keeping composite component references valid and making CID == GID trivially true. Output rebuilds `head`/`hhea`/`maxp`/`loca`/`glyf`/`hmtx`, copies hinting programs verbatim, stubs `post`, omits `cmap`/`name`/`OS/2`/`GSUB`/`GPOS`/`kern` (none read through a `CIDFontType2` program per ISO 32000-1 9.9). Applies to `glyf`-flavoured fonts only; CFF returns `undefined`.
240
260
  - **Embedded math font**: `math-font.ts` (parses/caches the vendored STIX Two Math font, exposing size-specific `MathFontMetrics` and stretchy-glyph entry points), `math-stretch.ts` (OpenType MATH two-stage stretching: pick smallest pre-built variant reaching target, else assemble from repeated parts with seams overlapped), `math-font-write.ts` (builds the `/Type0`/`/CIDFontType0`/`/FontDescriptor`/`/FontFile3`/ToUnicode group), `math-content-write.ts` (`PositionedFormula[]` → content-stream bytes, Identity-H CIDs for text, `re`/`m`/`l` operators for rules, glyph-ID-addressed text objects for stretched constructions wrapped in `/ActualText`).
241
261
  - **Embedded text faces**: `embedded-font.ts` (parses one TrueType-outline face's metrics and `GPOS` pair kerning, and `encodeForShowEmbedded` — the single code path both measurement and text-showing go through so encoding and measuring cannot disagree). Every geometry field is converted into PDF's 1000-units-per-em glyph space. `embedded-font-write.ts` builds the `/Type0`/`/CIDFontType2`/`/FontDescriptor`/`/FontFile2`/ToUnicode group, with `/CIDToGIDMap /Identity` written explicitly and `/Length1` set to the **uncompressed** subset length. Its subset tag is a CRC32 over the face's PostScript name and glyph-ID list, so identical input yields byte-identical output.
242
262
  - **ToUnicode CMaps**: `tounicode.ts`, shared by both embedded-font writers — a character code → Unicode code point mapping written as a bfchar CMap (9.10.3), with supplementary-plane code points encoded as UTF-16BE surrogate pairs and entries emitted in blocks of at most 100.
243
263
  - **CFF reading**: `cff.ts` (shared `INDEX`/`DICT` container structures), `cff-bounds.ts` (a Type 2 charstring interpreter computing each glyph's tight ink bounding box by tracking the current point through every path operator and solving each cubic's real extrema from the roots of its derivative — a path walker, not a rasteriser; verified against the vendored STIX Two Math font's whole 5,543-glyph repertoire, matching fontTools' `BoundsPen` to within 0.01 design units). `cff-probe.ts` reads a bare CFF program's header/Name INDEX/Top DICT to detect the `ROS` operator defining a CID-keyed font — the guard a future source-embedded-font phase needs before it can trust CID == GID against an arbitrary caller-supplied font.
244
264
  - **Read**: `lexer.ts`/`parse.ts` (byte tokenizer and tokens → `PdfObject`), `filters.ts`/`predictors.ts` (Flate/LZW/ASCII85/ASCIIHex/RunLength/CCITTFax, TIFF/PNG predictors), `xref.ts`/`document.ts` (classic and cross-reference-stream resolution, object streams, `/Prev` chains, linear-scan recovery, the page tree with attribute inheritance), `encrypt.ts` (standard security handler: `/Encrypt` parsing, empty-user-password key derivation and `/U` verification, per-object keys, transparent string/stream decryption), `content-read.ts`/`interpret.ts` (content-stream tokenizer and graphics/text state machine, form-XObject recursion, general vector-path tracking), `cmap.ts`/`font-style.ts`/`font-read.ts` (`/ToUnicode` CMaps, font-dictionary resolution), `builtin-encoding.ts` (a font's own built-in encoding, read out of the embedded program itself — see [Text extraction and font encodings](#text-extraction-and-font-encodings)), `images-read.ts` (Image XObjects → PNG/JPEG bytes), `names.ts` (the document-level name-tree walker: one flattening pass for every `/Names` tenant), `navigation.ts` (named destinations from `/Dests` and `/Names` `/Dests`, reader-minted entries for direct destination arrays, and the `/Outlines` bookmark tree), `attachments.ts` (embedded files from the name tree, `/FileAttachment` filespecs, and `/AF`), `optional-content.ts` (`/OCProperties` groups and default-configuration visibility, plus the `/OC`-to-name resolution `interpret.ts` stamps onto span items), `annotations.ts` (sticky notes, FreeText, the `/QuadPoints` markup family, and residue for the opaque kinds), `form.ts` (the AcroForm field tree), `structure.ts` (the tagged-PDF `/StructTreeRoot` element tree with `/RoleMap` resolution and `/ClassMap` attribute merging, plus the `/ParentTree` walk that resolves each `(page, MCID)` pair to the owning element `read.ts` stamps onto an item), `xmp.ts` (a bounded Dublin Core extractor for the `/Metadata` packet), `pdf-text.ts` (PDF string/date scalar decoding), `read.ts` (`readPdf`, assembling all of the above into a `LayoutDocument`).
265
+ - **Raster**: `raster.ts` — the `PageRasteriser` port and `renderPdfPage` (#1198): re-walks one page through `interpretContentStream` (the same interpreter `readPdf` runs), recomputes the page's crop/rotation geometry (test-pinned to agree with `readPdf` bit for bit, since the `clipPt` contract rides on it), and drives a caller-supplied rasteriser with device-space draw ops — rect fills, filled/stroked vector paths, affine-placed images, and text as filled glyph-outline paths resolved from the page's own embedded sfnt programs (`glyf-contours.ts`'s decoded contours through the run's text matrices, per-glyph advances corrected against the run's exact end matrix). Optional-content layers the default configuration leaves OFF are not drawn; faces with no sfnt outlines are refused by name. No canvas dependency, no backend, no OCR/vision/network — the port is pure data plus callbacks, so `pdf-raster-cpu` (or a browser canvas wrapper) implements it elsewhere.
245
266
  - `codec.ts` — `pdfCodec`, a `z.codec()` pair over `readPdf`/`writePdf`, plus a standalone local copy of the `%PDF-` header check.
246
267
  - **`src/test-support/`** — hand-built PDF fixtures (`pdf.ts`) built by literal byte/string concatenation and deliberately importing NOTHING from this package's own writer (a fixture built by `writePdf` would let a writer bug hide from the corresponding reader test). `encrypted-pdfs.ts` applies the same principle: real PDFs encrypted by [qpdf](https://qpdf.sourceforge.io/), embedded as base64, so a bug in key derivation cannot cancel out between write and read halves. `fonts.ts` holds the real vendored Carlito and Caladea faces as raw sfnt bytes, and asserts values read out of the `.ttf` files by a standalone script with a bare `DataView`, not by this package's own parsers — external cross-checks rather than a parser's output compared against itself.
247
268
 
@@ -266,6 +287,7 @@ Dependency direction is strictly downward and checkable: `layout` imports only `
266
287
  - **`CCITTFaxDecode`, `JBIG2Decode` and `JPXDecode` images all decode for real** via hand-written decoders (`src/image/ccitt.ts` for ITU-T T.4/T.6 fax; `src/image/jbig2*.ts` for ITU-T T.88; `src/image/jpeg2000*.ts` for ISO/IEC 15444-1). JPEG images (`DCTDecode`) pass through losslessly in both directions. See [JBIG2 scope](#jbig2-scope) and [JPEG 2000 scope](#jpeg-2000-scope) for exactly what is and is not implemented.
267
288
  - **The write side re-encodes bilevel images as CCITT Group 4** (`src/image/ccitt-encode.ts`, a hand-written ITU-T T.6 encoder sharing the decoder's own code-table transcription): a grayscale image whose samples are all 0 or 255, with no soft mask, is written as `/CCITTFaxDecode` with `/K -1` whenever the G4 encoding comes out smaller than Flate over the same pixels — which for vertically coherent bilevel content (a scan's edges and text baselines) it does by an order of magnitude. Whichever encoding is smaller wins, deterministically, so decorrelated or repetitive bilevel content where Flate happens to win keeps Flate. **JBIG2 and JPEG 2000 re-encoding remain permanent boundaries, not gaps**: a hand-written JBIG2 encoder is research-grade symbol-dictionary design and a JPEG 2000 encoder is the full EBCOT/wavelet stack, and re-encoding lossy JPX back is not fidelity-preserving anyway. **What no longer follows from that boundary is generation loss on a pdf-to-pdf round trip**: `LayoutImageAsset.original` (the layout twin of `document-schema.js`'s `ContentImageOriginal`, landed through the #975-scorecard schema change it named) carries a source's own JBIG2/JPX compressed stream beside the decoded canonical, captured at read time together with the decoded `/JBIG2Globals` segments a symbol-dictionary stream needs, and the writer re-embeds those bytes verbatim under their own filter — the decoded canonical never reaches the file at all for such an image, a source soft mask still re-emits as a generated `/SMask`, and the round trip pays zero generation loss for exactly the two filters this package cannot re-encode.
268
289
  - **`interpret.ts` tracks general vector paths, not just axis-aligned `re` rectangles.** `m`/`l`/`c`/`v`/`y`/`h` (and `re` itself) accumulate real subpaths — CTM-transformed line/cubic segments, open or closed — and any paint operator emits an item built from them. A recovered path matching one of three characteristic shape patterns comes back as that shape's own kind, not a generic `LayoutPath`: an axis-aligned closed four-corner subpath is a `LayoutRect`; a closed subpath of four cubic segments meeting its bounding box at cardinal points with kappa-ratio control points is a `LayoutEllipse`; an open single-straight-segment stroke-only subpath is a `LayoutLine` (tolerance: `max(1e-3pt, 1e-4 × extent)`). **These are deliberate, bounded heuristics** — a false positive changes an item's kind, never its geometry, since every detected shape reproduces its source path's own points exactly. Off-axis rotations, non-quadrant curves, polygons, and multi-subpath figures stay a `LayoutPath`.
290
+ - **`renderPdfPage` renders vectors, images, and embedded-sfnt text; everything else it refuses by name.** Text whose font states no TrueType/glyf outlines (CFF programs, standard-14 faces with nothing embedded, Type 3 glyph procedures, Type0 fonts under a non-Identity-H encoding) draws nothing and reports `raster/text-cff-outlines` or `raster/text-outlines-unavailable` through the sink — a substitute shape would be a silent misrender, so the refusal is the honest behaviour and the rest of the page still renders. Image pixels are the rasteriser's own concern: the port hands through exactly what `images-read.ts` recovered (PNG for every decoded filter, JPEG bytes verbatim), so a canvas-owning backend draws DCTDecode scans natively while `pdf-raster-cpu` declines them by name (it has no JPEG decoder, and a scanned page's XObject remains extractable through `readPdf` for consumers that want the scan's own pixels). Per-glyph text placement distributes the interpreter's spacing state (`Tc`/`Tw`/`Tz`) uniformly across each run rather than modelling it per glyph, so a run's extent is exact while its internal glyph spacing under active spacing state is a bounded approximation.
269
291
  - **`writePdf`/`readPdf` round-trip a page's own `notes` field via a hidden `/Subtype /Text` annotation** with the `Hidden` flag set so it never renders or prints, distinguished from a genuine third-party sticky note by an internal author marker. This is a round-trip mechanism specific to this package's own writer/reader pair. `documents.js` uses this to carry pptx/odp speaker notes through PDF.
270
292
  - **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).
271
293
  - **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.
@@ -0,0 +1,122 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_sfnt = require("./sfnt.cjs");
3
+ //#region src/glyf-contours.ts
4
+ const FLAG_ON_CURVE = 1;
5
+ const FLAG_X_SHORT = 2;
6
+ const FLAG_Y_SHORT = 4;
7
+ const FLAG_REPEAT = 8;
8
+ const FLAG_X_SAME_OR_POSITIVE = 16;
9
+ const FLAG_Y_SAME_OR_POSITIVE = 32;
10
+ const MAX_COMPOSITE_DEPTH = 5;
11
+ function decodeSimpleContours(glyph) {
12
+ const numberOfContours = require_sfnt.i16(glyph, 0);
13
+ const endPtsOffset = 10;
14
+ if (!require_sfnt.hasBytes(glyph, endPtsOffset, numberOfContours * 2 + 2)) return;
15
+ const endPts = [];
16
+ for (let i = 0; i < numberOfContours; i++) endPts.push(require_sfnt.u16(glyph, endPtsOffset + i * 2));
17
+ const numPoints = endPts.length > 0 ? endPts[endPts.length - 1] + 1 : 0;
18
+ for (let i = 1; i < endPts.length; i++) if (endPts[i] <= endPts[i - 1]) return;
19
+ let offset = endPtsOffset + numberOfContours * 2;
20
+ const instructionLength = require_sfnt.u16(glyph, offset);
21
+ offset += 2 + instructionLength;
22
+ if (!require_sfnt.hasBytes(glyph, offset, numPoints)) return;
23
+ const flags = [];
24
+ while (flags.length < numPoints) {
25
+ const flag = require_sfnt.u8(glyph, offset);
26
+ flags.push(flag);
27
+ offset += 1;
28
+ if ((flag & FLAG_REPEAT) !== 0) {
29
+ if (!require_sfnt.hasBytes(glyph, offset, 1)) return;
30
+ const repeat = require_sfnt.u8(glyph, offset);
31
+ offset += 1;
32
+ if (flags.length + repeat > numPoints) return;
33
+ for (let r = 0; r < repeat; r++) flags.push(flag);
34
+ }
35
+ }
36
+ const xs = [];
37
+ let x = 0;
38
+ for (const flag of flags) {
39
+ if ((flag & FLAG_X_SHORT) !== 0) {
40
+ if (!require_sfnt.hasBytes(glyph, offset, 1)) return;
41
+ const magnitude = require_sfnt.u8(glyph, offset);
42
+ offset += 1;
43
+ x += (flag & FLAG_X_SAME_OR_POSITIVE) !== 0 ? magnitude : -magnitude;
44
+ } else if ((flag & FLAG_X_SAME_OR_POSITIVE) === 0) {
45
+ if (!require_sfnt.hasBytes(glyph, offset, 2)) return;
46
+ x += require_sfnt.i16(glyph, offset);
47
+ offset += 2;
48
+ }
49
+ xs.push(x);
50
+ }
51
+ const ys = [];
52
+ let y = 0;
53
+ for (const flag of flags) {
54
+ if ((flag & FLAG_Y_SHORT) !== 0) {
55
+ if (!require_sfnt.hasBytes(glyph, offset, 1)) return;
56
+ const magnitude = require_sfnt.u8(glyph, offset);
57
+ offset += 1;
58
+ y += (flag & FLAG_Y_SAME_OR_POSITIVE) !== 0 ? magnitude : -magnitude;
59
+ } else if ((flag & FLAG_Y_SAME_OR_POSITIVE) === 0) {
60
+ if (!require_sfnt.hasBytes(glyph, offset, 2)) return;
61
+ y += require_sfnt.i16(glyph, offset);
62
+ offset += 2;
63
+ }
64
+ ys.push(y);
65
+ }
66
+ const contours = [];
67
+ let pointIndex = 0;
68
+ for (const endPt of endPts) {
69
+ const points = [];
70
+ while (pointIndex <= endPt) {
71
+ const flag = flags[pointIndex];
72
+ points.push({
73
+ x: xs[pointIndex],
74
+ y: ys[pointIndex],
75
+ onCurve: (flag & FLAG_ON_CURVE) !== 0
76
+ });
77
+ pointIndex += 1;
78
+ }
79
+ contours.push(points);
80
+ }
81
+ return contours;
82
+ }
83
+ function placeComponentContours(contours, component) {
84
+ const [a, b, c, d] = component.transform ?? [
85
+ 1,
86
+ 0,
87
+ 0,
88
+ 1
89
+ ];
90
+ const scaledOffset = (component.flags & 2048) !== 0 && (component.flags & 4096) === 0;
91
+ const dx = scaledOffset ? a * component.argument1 + c * component.argument2 : component.argument1;
92
+ const dy = scaledOffset ? b * component.argument1 + d * component.argument2 : component.argument2;
93
+ return contours.map((points) => points.map((point) => ({
94
+ x: a * point.x + c * point.y + dx,
95
+ y: b * point.x + d * point.y + dy,
96
+ onCurve: point.onCurve
97
+ })));
98
+ }
99
+ function decodeGlyphOutline(glyf, glyphId) {
100
+ return decodeOutline(glyf, glyphId, 0);
101
+ }
102
+ function decodeOutline(glyf, glyphId, depth) {
103
+ const header = glyf.glyphHeader(glyphId);
104
+ if (header === void 0) return;
105
+ if (header.numberOfContours >= 0) {
106
+ const contours = decodeSimpleContours(glyf.glyphBytes(glyphId));
107
+ return contours === void 0 ? void 0 : { contours };
108
+ }
109
+ if (depth >= MAX_COMPOSITE_DEPTH) return;
110
+ const components = glyf.compositeComponents(glyphId);
111
+ if (components === void 0) return;
112
+ const contours = [];
113
+ for (const component of components) {
114
+ if (!component.argsAreXyValues) return;
115
+ const componentOutline = decodeOutline(glyf, component.glyphIndex, depth + 1);
116
+ if (componentOutline === void 0) return;
117
+ contours.push(...placeComponentContours(componentOutline.contours, component));
118
+ }
119
+ return { contours };
120
+ }
121
+ //#endregion
122
+ exports.decodeGlyphOutline = decodeGlyphOutline;
@@ -0,0 +1,13 @@
1
+ import { GlyfTable } from "./glyf.cjs";
2
+ //#region src/glyf-contours.d.ts
3
+ interface GlyphContourPoint {
4
+ readonly x: number;
5
+ readonly y: number;
6
+ readonly onCurve: boolean;
7
+ }
8
+ interface GlyphOutline {
9
+ readonly contours: readonly (readonly GlyphContourPoint[])[];
10
+ }
11
+ declare function decodeGlyphOutline(glyf: GlyfTable, glyphId: number): GlyphOutline | undefined;
12
+ //#endregion
13
+ export { GlyphContourPoint, GlyphOutline, decodeGlyphOutline };
@@ -0,0 +1,13 @@
1
+ import { GlyfTable } from "./glyf.js";
2
+ //#region src/glyf-contours.d.ts
3
+ interface GlyphContourPoint {
4
+ readonly x: number;
5
+ readonly y: number;
6
+ readonly onCurve: boolean;
7
+ }
8
+ interface GlyphOutline {
9
+ readonly contours: readonly (readonly GlyphContourPoint[])[];
10
+ }
11
+ declare function decodeGlyphOutline(glyf: GlyfTable, glyphId: number): GlyphOutline | undefined;
12
+ //#endregion
13
+ export { GlyphContourPoint, GlyphOutline, decodeGlyphOutline };
@@ -0,0 +1,121 @@
1
+ import { hasBytes, i16, u16, u8 } from "./sfnt.js";
2
+ //#region src/glyf-contours.ts
3
+ const FLAG_ON_CURVE = 1;
4
+ const FLAG_X_SHORT = 2;
5
+ const FLAG_Y_SHORT = 4;
6
+ const FLAG_REPEAT = 8;
7
+ const FLAG_X_SAME_OR_POSITIVE = 16;
8
+ const FLAG_Y_SAME_OR_POSITIVE = 32;
9
+ const MAX_COMPOSITE_DEPTH = 5;
10
+ function decodeSimpleContours(glyph) {
11
+ const numberOfContours = i16(glyph, 0);
12
+ const endPtsOffset = 10;
13
+ if (!hasBytes(glyph, endPtsOffset, numberOfContours * 2 + 2)) return;
14
+ const endPts = [];
15
+ for (let i = 0; i < numberOfContours; i++) endPts.push(u16(glyph, endPtsOffset + i * 2));
16
+ const numPoints = endPts.length > 0 ? endPts[endPts.length - 1] + 1 : 0;
17
+ for (let i = 1; i < endPts.length; i++) if (endPts[i] <= endPts[i - 1]) return;
18
+ let offset = endPtsOffset + numberOfContours * 2;
19
+ const instructionLength = u16(glyph, offset);
20
+ offset += 2 + instructionLength;
21
+ if (!hasBytes(glyph, offset, numPoints)) return;
22
+ const flags = [];
23
+ while (flags.length < numPoints) {
24
+ const flag = u8(glyph, offset);
25
+ flags.push(flag);
26
+ offset += 1;
27
+ if ((flag & FLAG_REPEAT) !== 0) {
28
+ if (!hasBytes(glyph, offset, 1)) return;
29
+ const repeat = u8(glyph, offset);
30
+ offset += 1;
31
+ if (flags.length + repeat > numPoints) return;
32
+ for (let r = 0; r < repeat; r++) flags.push(flag);
33
+ }
34
+ }
35
+ const xs = [];
36
+ let x = 0;
37
+ for (const flag of flags) {
38
+ if ((flag & FLAG_X_SHORT) !== 0) {
39
+ if (!hasBytes(glyph, offset, 1)) return;
40
+ const magnitude = u8(glyph, offset);
41
+ offset += 1;
42
+ x += (flag & FLAG_X_SAME_OR_POSITIVE) !== 0 ? magnitude : -magnitude;
43
+ } else if ((flag & FLAG_X_SAME_OR_POSITIVE) === 0) {
44
+ if (!hasBytes(glyph, offset, 2)) return;
45
+ x += i16(glyph, offset);
46
+ offset += 2;
47
+ }
48
+ xs.push(x);
49
+ }
50
+ const ys = [];
51
+ let y = 0;
52
+ for (const flag of flags) {
53
+ if ((flag & FLAG_Y_SHORT) !== 0) {
54
+ if (!hasBytes(glyph, offset, 1)) return;
55
+ const magnitude = u8(glyph, offset);
56
+ offset += 1;
57
+ y += (flag & FLAG_Y_SAME_OR_POSITIVE) !== 0 ? magnitude : -magnitude;
58
+ } else if ((flag & FLAG_Y_SAME_OR_POSITIVE) === 0) {
59
+ if (!hasBytes(glyph, offset, 2)) return;
60
+ y += i16(glyph, offset);
61
+ offset += 2;
62
+ }
63
+ ys.push(y);
64
+ }
65
+ const contours = [];
66
+ let pointIndex = 0;
67
+ for (const endPt of endPts) {
68
+ const points = [];
69
+ while (pointIndex <= endPt) {
70
+ const flag = flags[pointIndex];
71
+ points.push({
72
+ x: xs[pointIndex],
73
+ y: ys[pointIndex],
74
+ onCurve: (flag & FLAG_ON_CURVE) !== 0
75
+ });
76
+ pointIndex += 1;
77
+ }
78
+ contours.push(points);
79
+ }
80
+ return contours;
81
+ }
82
+ function placeComponentContours(contours, component) {
83
+ const [a, b, c, d] = component.transform ?? [
84
+ 1,
85
+ 0,
86
+ 0,
87
+ 1
88
+ ];
89
+ const scaledOffset = (component.flags & 2048) !== 0 && (component.flags & 4096) === 0;
90
+ const dx = scaledOffset ? a * component.argument1 + c * component.argument2 : component.argument1;
91
+ const dy = scaledOffset ? b * component.argument1 + d * component.argument2 : component.argument2;
92
+ return contours.map((points) => points.map((point) => ({
93
+ x: a * point.x + c * point.y + dx,
94
+ y: b * point.x + d * point.y + dy,
95
+ onCurve: point.onCurve
96
+ })));
97
+ }
98
+ function decodeGlyphOutline(glyf, glyphId) {
99
+ return decodeOutline(glyf, glyphId, 0);
100
+ }
101
+ function decodeOutline(glyf, glyphId, depth) {
102
+ const header = glyf.glyphHeader(glyphId);
103
+ if (header === void 0) return;
104
+ if (header.numberOfContours >= 0) {
105
+ const contours = decodeSimpleContours(glyf.glyphBytes(glyphId));
106
+ return contours === void 0 ? void 0 : { contours };
107
+ }
108
+ if (depth >= MAX_COMPOSITE_DEPTH) return;
109
+ const components = glyf.compositeComponents(glyphId);
110
+ if (components === void 0) return;
111
+ const contours = [];
112
+ for (const component of components) {
113
+ if (!component.argsAreXyValues) return;
114
+ const componentOutline = decodeOutline(glyf, component.glyphIndex, depth + 1);
115
+ if (componentOutline === void 0) return;
116
+ contours.push(...placeComponentContours(componentOutline.contours, component));
117
+ }
118
+ return { contours };
119
+ }
120
+ //#endregion
121
+ export { decodeGlyphOutline };
package/dist/index.cjs CHANGED
@@ -19,6 +19,7 @@ const require_measure = require("./measure.cjs");
19
19
  const require_write = require("./write.cjs");
20
20
  const require_codec = require("./codec.cjs");
21
21
  const require_font_face = require("./font-face.cjs");
22
+ const require_raster = require("./raster.cjs");
22
23
  exports.DEFAULT_VERTICAL_METRIC_POLICY = require_measure.DEFAULT_VERTICAL_METRIC_POLICY;
23
24
  exports.FontFaceParseError = require_font_face.FontFaceParseError;
24
25
  exports.Jbig2ParseError = require_image_jbig2_errors.Jbig2ParseError;
@@ -72,6 +73,7 @@ exports.pdfCodec = require_codec.pdfCodec;
72
73
  exports.readFontFace = require_font_face.readFontFace;
73
74
  exports.readJpeg2000Metadata = require_image_jpeg2000.readJpeg2000Metadata;
74
75
  exports.readPdf = require_read.readPdf;
76
+ exports.renderPdfPage = require_raster.renderPdfPage;
75
77
  exports.resolveFaceWithRegistry = require_font_registry.resolveFaceWithRegistry;
76
78
  exports.resolveStandardFont = require_fonts.resolveStandardFont;
77
79
  exports.scaleMathStretchConstruction = require_math_stretch.scaleMathStretchConstruction;
package/dist/index.d.cts CHANGED
@@ -23,6 +23,7 @@ import { a as MathGlyphPart, c as MathVariants, n as MathGlyphAssembly, o as Mat
23
23
  import { a as scaleMathStretchConstruction, i as assembleStretchyGlyph, n as MathStretchOptions, r as MathStretchPlacement, t as MathStretchConstruction } from "./math-stretch-C2JanDAz.cjs";
24
24
  import { LoadedMathFont, MathFont, MathFontDescriptorMetrics, loadMathFont } from "./math-font.cjs";
25
25
  import { DEFAULT_VERTICAL_METRIC_POLICY, FontMeasurerOptions, StandardFontMeasurerOptions, VerticalMetricPolicy, createFontMeasurer, createStandardFontMeasurer } from "./measure.cjs";
26
+ import { PageRasteriser, RasterDrawOp, RasterFillRectOp, RasterFillSpec, RasterImageOp, RasterMatrix, RasterPageGeometry, RasterPathOp, RasterPathSegment, RasterRegionPt, RasterStrokeSpec, RasterSubpath, RenderPdfPageOptions, renderPdfPage } from "./raster.cjs";
26
27
  import { FontRegistryOptions, FontSubstitution, MathAssembledGlyphs, MathBox, MathColor, MathFontMetrics, MathGlyphMetrics, MathGlyphPlacement, MathGlyphRun, MathLayoutItem, MathRule, MathStretchAxis, MathStretchGlyph, MathStretchResult, MathStroke, Point, PositionedFormula, ProvidedFont, StyledFragment, StyledRun, TextMeasurer, UnderlineMetrics, WrapOptions, WrappedLine } from "document-schema.js";
27
28
  export * from "byte-codec";
28
- export { type CcittFaxImage, type CcittFaxOptions, DEFAULT_VERTICAL_METRIC_POLICY, type EmbeddedFace, type EmbeddedFaceMetrics, type EmbeddedFaceSubstitution, type FontFace, FontFaceParseError, type FontMeasurerOptions, type FontMetrics, type FontRegistry, type FontRegistryOptions, type FontSubstitution, type GlyphInkBounds, type Jbig2DecodeOptions, type Jbig2Image, Jbig2ParseError, Jbig2UnsupportedError, type Jp2ChannelDefinition, type Jp2ColourSpace, type Jp2Container, type Jp2ImageHeader, type Jpeg2000ComponentMetadata, type Jpeg2000DecodeOptions, type Jpeg2000Image, type Jpeg2000Metadata, Jpeg2000ParseError, type Jpeg2000ProgressionOrder, type Jpeg2000QuantizationStyle, type Jpeg2000Transform, Jpeg2000UnsupportedError, LAYOUT_FORMAT_VERSION, LayoutAnnotation, LayoutAnnotationQuad, LayoutAnnotationQuadSchema, LayoutAnnotationSchema, LayoutAttachment, LayoutAttachmentSchema, LayoutDestination, LayoutDestinationSchema, LayoutDestinationTarget, LayoutDestinationTargetSchema, LayoutDocument, LayoutDocumentSchema, LayoutEllipse, LayoutEllipseSchema, LayoutFormField, LayoutFormFieldSchema, LayoutFormWidget, LayoutFormWidgetSchema, LayoutImage, LayoutImageAsset, LayoutImageAssetSchema, LayoutImageSchema, LayoutInternalLink, LayoutInternalLinkSchema, LayoutItem, LayoutItemSchema, LayoutLayer, LayoutLayerSchema, LayoutLine, LayoutLineSchema, LayoutLink, LayoutLinkSchema, LayoutOutlineItem, LayoutOutlineItemSchema, LayoutPage, LayoutPageSchema, LayoutPath, LayoutPathSchema, LayoutPathSegment, LayoutPathSegmentSchema, LayoutRect, LayoutRectSchema, LayoutStructureElement, LayoutStructureElementSchema, LayoutSubpath, LayoutSubpathSchema, LayoutText, LayoutTextSchema, type LoadedMathFont, type MathAssembledGlyphs, type MathBox, type MathColor, type MathFont, type MathFontDescriptorMetrics, type MathFontMetrics, type MathGlyphAssembly, type MathGlyphConstruction, type MathGlyphMetrics, type MathGlyphPart, type MathGlyphPlacement, type MathGlyphRun, type MathGlyphVariant, type MathLayoutItem, type MathRule, type MathStretchAxis, type MathStretchConstruction, type MathStretchGlyph, type MathStretchOptions, type MathStretchPlacement, type MathStretchResult, type MathStroke, type MathVariants, NOOP_DIAGNOSTIC_SINK, PdfBytesSchema, type PdfDiagnostic, type PdfDiagnosticSeverity, type PdfDiagnosticSink, PdfEncryptedError, PdfEncryptionError, type PdfEncryptionOptions, type PdfEncryptionPermissions, type PdfEncryptionScheme, PdfParseError, PdfPasswordRequiredError, type Point, type PositionedFormula, type ProvidedFont, type ReadPdfOptions, type ResolvedFace, type ResolvedFont, STANDARD_METRICS, type StandardFontMeasurerOptions, type StandardFontName, type StyledFragment, type StyledRun, type TextMeasurer, type UnderlineMetrics, type VerticalMetricPolicy, type WinAnsiSubstitution, type WrapOptions, type WrappedLine, type WritePdfOptions, assembleStretchyGlyph, createFontMeasurer, createFontRegistry, createStandardFontMeasurer, decodeCcittFax, decodeJbig2Embedded, decodeJpeg2000, filterScanlines, loadMathFont, looksLikeBareCodestream, parseJp2Container, pdfCodec, readFontFace, readJpeg2000Metadata, readPdf, resolveFaceWithRegistry, resolveStandardFont, scaleMathStretchConstruction, unfilterScanlines, writePdf };
29
+ export { type CcittFaxImage, type CcittFaxOptions, DEFAULT_VERTICAL_METRIC_POLICY, type EmbeddedFace, type EmbeddedFaceMetrics, type EmbeddedFaceSubstitution, type FontFace, FontFaceParseError, type FontMeasurerOptions, type FontMetrics, type FontRegistry, type FontRegistryOptions, type FontSubstitution, type GlyphInkBounds, type Jbig2DecodeOptions, type Jbig2Image, Jbig2ParseError, Jbig2UnsupportedError, type Jp2ChannelDefinition, type Jp2ColourSpace, type Jp2Container, type Jp2ImageHeader, type Jpeg2000ComponentMetadata, type Jpeg2000DecodeOptions, type Jpeg2000Image, type Jpeg2000Metadata, Jpeg2000ParseError, type Jpeg2000ProgressionOrder, type Jpeg2000QuantizationStyle, type Jpeg2000Transform, Jpeg2000UnsupportedError, LAYOUT_FORMAT_VERSION, LayoutAnnotation, LayoutAnnotationQuad, LayoutAnnotationQuadSchema, LayoutAnnotationSchema, LayoutAttachment, LayoutAttachmentSchema, LayoutDestination, LayoutDestinationSchema, LayoutDestinationTarget, LayoutDestinationTargetSchema, LayoutDocument, LayoutDocumentSchema, LayoutEllipse, LayoutEllipseSchema, LayoutFormField, LayoutFormFieldSchema, LayoutFormWidget, LayoutFormWidgetSchema, LayoutImage, LayoutImageAsset, LayoutImageAssetSchema, LayoutImageSchema, LayoutInternalLink, LayoutInternalLinkSchema, LayoutItem, LayoutItemSchema, LayoutLayer, LayoutLayerSchema, LayoutLine, LayoutLineSchema, LayoutLink, LayoutLinkSchema, LayoutOutlineItem, LayoutOutlineItemSchema, LayoutPage, LayoutPageSchema, LayoutPath, LayoutPathSchema, LayoutPathSegment, LayoutPathSegmentSchema, LayoutRect, LayoutRectSchema, LayoutStructureElement, LayoutStructureElementSchema, LayoutSubpath, LayoutSubpathSchema, LayoutText, LayoutTextSchema, type LoadedMathFont, type MathAssembledGlyphs, type MathBox, type MathColor, type MathFont, type MathFontDescriptorMetrics, type MathFontMetrics, type MathGlyphAssembly, type MathGlyphConstruction, type MathGlyphMetrics, type MathGlyphPart, type MathGlyphPlacement, type MathGlyphRun, type MathGlyphVariant, type MathLayoutItem, type MathRule, type MathStretchAxis, type MathStretchConstruction, type MathStretchGlyph, type MathStretchOptions, type MathStretchPlacement, type MathStretchResult, type MathStroke, type MathVariants, NOOP_DIAGNOSTIC_SINK, type PageRasteriser, PdfBytesSchema, type PdfDiagnostic, type PdfDiagnosticSeverity, type PdfDiagnosticSink, PdfEncryptedError, PdfEncryptionError, type PdfEncryptionOptions, type PdfEncryptionPermissions, type PdfEncryptionScheme, PdfParseError, PdfPasswordRequiredError, type Point, type PositionedFormula, type ProvidedFont, type RasterDrawOp, type RasterFillRectOp, type RasterFillSpec, type RasterImageOp, type RasterMatrix, type RasterPageGeometry, type RasterPathOp, type RasterPathSegment, type RasterRegionPt, type RasterStrokeSpec, type RasterSubpath, type ReadPdfOptions, type RenderPdfPageOptions, type ResolvedFace, type ResolvedFont, STANDARD_METRICS, type StandardFontMeasurerOptions, type StandardFontName, type StyledFragment, type StyledRun, type TextMeasurer, type UnderlineMetrics, type VerticalMetricPolicy, type WinAnsiSubstitution, type WrapOptions, type WrappedLine, type WritePdfOptions, assembleStretchyGlyph, createFontMeasurer, createFontRegistry, createStandardFontMeasurer, decodeCcittFax, decodeJbig2Embedded, decodeJpeg2000, filterScanlines, loadMathFont, looksLikeBareCodestream, parseJp2Container, pdfCodec, readFontFace, readJpeg2000Metadata, readPdf, renderPdfPage, resolveFaceWithRegistry, resolveStandardFont, scaleMathStretchConstruction, unfilterScanlines, writePdf };
package/dist/index.d.ts CHANGED
@@ -23,6 +23,7 @@ import { a as MathGlyphPart, c as MathVariants, n as MathGlyphAssembly, o as Mat
23
23
  import { a as scaleMathStretchConstruction, i as assembleStretchyGlyph, n as MathStretchOptions, r as MathStretchPlacement, t as MathStretchConstruction } from "./math-stretch-BbC2o4Br.js";
24
24
  import { LoadedMathFont, MathFont, MathFontDescriptorMetrics, loadMathFont } from "./math-font.js";
25
25
  import { DEFAULT_VERTICAL_METRIC_POLICY, FontMeasurerOptions, StandardFontMeasurerOptions, VerticalMetricPolicy, createFontMeasurer, createStandardFontMeasurer } from "./measure.js";
26
+ import { PageRasteriser, RasterDrawOp, RasterFillRectOp, RasterFillSpec, RasterImageOp, RasterMatrix, RasterPageGeometry, RasterPathOp, RasterPathSegment, RasterRegionPt, RasterStrokeSpec, RasterSubpath, RenderPdfPageOptions, renderPdfPage } from "./raster.js";
26
27
  import { FontRegistryOptions, FontSubstitution, MathAssembledGlyphs, MathBox, MathColor, MathFontMetrics, MathGlyphMetrics, MathGlyphPlacement, MathGlyphRun, MathLayoutItem, MathRule, MathStretchAxis, MathStretchGlyph, MathStretchResult, MathStroke, Point, PositionedFormula, ProvidedFont, StyledFragment, StyledRun, TextMeasurer, UnderlineMetrics, WrapOptions, WrappedLine } from "document-schema.js";
27
28
  export * from "byte-codec";
28
- export { type CcittFaxImage, type CcittFaxOptions, DEFAULT_VERTICAL_METRIC_POLICY, type EmbeddedFace, type EmbeddedFaceMetrics, type EmbeddedFaceSubstitution, type FontFace, FontFaceParseError, type FontMeasurerOptions, type FontMetrics, type FontRegistry, type FontRegistryOptions, type FontSubstitution, type GlyphInkBounds, type Jbig2DecodeOptions, type Jbig2Image, Jbig2ParseError, Jbig2UnsupportedError, type Jp2ChannelDefinition, type Jp2ColourSpace, type Jp2Container, type Jp2ImageHeader, type Jpeg2000ComponentMetadata, type Jpeg2000DecodeOptions, type Jpeg2000Image, type Jpeg2000Metadata, Jpeg2000ParseError, type Jpeg2000ProgressionOrder, type Jpeg2000QuantizationStyle, type Jpeg2000Transform, Jpeg2000UnsupportedError, LAYOUT_FORMAT_VERSION, LayoutAnnotation, LayoutAnnotationQuad, LayoutAnnotationQuadSchema, LayoutAnnotationSchema, LayoutAttachment, LayoutAttachmentSchema, LayoutDestination, LayoutDestinationSchema, LayoutDestinationTarget, LayoutDestinationTargetSchema, LayoutDocument, LayoutDocumentSchema, LayoutEllipse, LayoutEllipseSchema, LayoutFormField, LayoutFormFieldSchema, LayoutFormWidget, LayoutFormWidgetSchema, LayoutImage, LayoutImageAsset, LayoutImageAssetSchema, LayoutImageSchema, LayoutInternalLink, LayoutInternalLinkSchema, LayoutItem, LayoutItemSchema, LayoutLayer, LayoutLayerSchema, LayoutLine, LayoutLineSchema, LayoutLink, LayoutLinkSchema, LayoutOutlineItem, LayoutOutlineItemSchema, LayoutPage, LayoutPageSchema, LayoutPath, LayoutPathSchema, LayoutPathSegment, LayoutPathSegmentSchema, LayoutRect, LayoutRectSchema, LayoutStructureElement, LayoutStructureElementSchema, LayoutSubpath, LayoutSubpathSchema, LayoutText, LayoutTextSchema, type LoadedMathFont, type MathAssembledGlyphs, type MathBox, type MathColor, type MathFont, type MathFontDescriptorMetrics, type MathFontMetrics, type MathGlyphAssembly, type MathGlyphConstruction, type MathGlyphMetrics, type MathGlyphPart, type MathGlyphPlacement, type MathGlyphRun, type MathGlyphVariant, type MathLayoutItem, type MathRule, type MathStretchAxis, type MathStretchConstruction, type MathStretchGlyph, type MathStretchOptions, type MathStretchPlacement, type MathStretchResult, type MathStroke, type MathVariants, NOOP_DIAGNOSTIC_SINK, PdfBytesSchema, type PdfDiagnostic, type PdfDiagnosticSeverity, type PdfDiagnosticSink, PdfEncryptedError, PdfEncryptionError, type PdfEncryptionOptions, type PdfEncryptionPermissions, type PdfEncryptionScheme, PdfParseError, PdfPasswordRequiredError, type Point, type PositionedFormula, type ProvidedFont, type ReadPdfOptions, type ResolvedFace, type ResolvedFont, STANDARD_METRICS, type StandardFontMeasurerOptions, type StandardFontName, type StyledFragment, type StyledRun, type TextMeasurer, type UnderlineMetrics, type VerticalMetricPolicy, type WinAnsiSubstitution, type WrapOptions, type WrappedLine, type WritePdfOptions, assembleStretchyGlyph, createFontMeasurer, createFontRegistry, createStandardFontMeasurer, decodeCcittFax, decodeJbig2Embedded, decodeJpeg2000, filterScanlines, loadMathFont, looksLikeBareCodestream, parseJp2Container, pdfCodec, readFontFace, readJpeg2000Metadata, readPdf, resolveFaceWithRegistry, resolveStandardFont, scaleMathStretchConstruction, unfilterScanlines, writePdf };
29
+ export { type CcittFaxImage, type CcittFaxOptions, DEFAULT_VERTICAL_METRIC_POLICY, type EmbeddedFace, type EmbeddedFaceMetrics, type EmbeddedFaceSubstitution, type FontFace, FontFaceParseError, type FontMeasurerOptions, type FontMetrics, type FontRegistry, type FontRegistryOptions, type FontSubstitution, type GlyphInkBounds, type Jbig2DecodeOptions, type Jbig2Image, Jbig2ParseError, Jbig2UnsupportedError, type Jp2ChannelDefinition, type Jp2ColourSpace, type Jp2Container, type Jp2ImageHeader, type Jpeg2000ComponentMetadata, type Jpeg2000DecodeOptions, type Jpeg2000Image, type Jpeg2000Metadata, Jpeg2000ParseError, type Jpeg2000ProgressionOrder, type Jpeg2000QuantizationStyle, type Jpeg2000Transform, Jpeg2000UnsupportedError, LAYOUT_FORMAT_VERSION, LayoutAnnotation, LayoutAnnotationQuad, LayoutAnnotationQuadSchema, LayoutAnnotationSchema, LayoutAttachment, LayoutAttachmentSchema, LayoutDestination, LayoutDestinationSchema, LayoutDestinationTarget, LayoutDestinationTargetSchema, LayoutDocument, LayoutDocumentSchema, LayoutEllipse, LayoutEllipseSchema, LayoutFormField, LayoutFormFieldSchema, LayoutFormWidget, LayoutFormWidgetSchema, LayoutImage, LayoutImageAsset, LayoutImageAssetSchema, LayoutImageSchema, LayoutInternalLink, LayoutInternalLinkSchema, LayoutItem, LayoutItemSchema, LayoutLayer, LayoutLayerSchema, LayoutLine, LayoutLineSchema, LayoutLink, LayoutLinkSchema, LayoutOutlineItem, LayoutOutlineItemSchema, LayoutPage, LayoutPageSchema, LayoutPath, LayoutPathSchema, LayoutPathSegment, LayoutPathSegmentSchema, LayoutRect, LayoutRectSchema, LayoutStructureElement, LayoutStructureElementSchema, LayoutSubpath, LayoutSubpathSchema, LayoutText, LayoutTextSchema, type LoadedMathFont, type MathAssembledGlyphs, type MathBox, type MathColor, type MathFont, type MathFontDescriptorMetrics, type MathFontMetrics, type MathGlyphAssembly, type MathGlyphConstruction, type MathGlyphMetrics, type MathGlyphPart, type MathGlyphPlacement, type MathGlyphRun, type MathGlyphVariant, type MathLayoutItem, type MathRule, type MathStretchAxis, type MathStretchConstruction, type MathStretchGlyph, type MathStretchOptions, type MathStretchPlacement, type MathStretchResult, type MathStroke, type MathVariants, NOOP_DIAGNOSTIC_SINK, type PageRasteriser, PdfBytesSchema, type PdfDiagnostic, type PdfDiagnosticSeverity, type PdfDiagnosticSink, PdfEncryptedError, PdfEncryptionError, type PdfEncryptionOptions, type PdfEncryptionPermissions, type PdfEncryptionScheme, PdfParseError, PdfPasswordRequiredError, type Point, type PositionedFormula, type ProvidedFont, type RasterDrawOp, type RasterFillRectOp, type RasterFillSpec, type RasterImageOp, type RasterMatrix, type RasterPageGeometry, type RasterPathOp, type RasterPathSegment, type RasterRegionPt, type RasterStrokeSpec, type RasterSubpath, type ReadPdfOptions, type RenderPdfPageOptions, type ResolvedFace, type ResolvedFont, STANDARD_METRICS, type StandardFontMeasurerOptions, type StandardFontName, type StyledFragment, type StyledRun, type TextMeasurer, type UnderlineMetrics, type VerticalMetricPolicy, type WinAnsiSubstitution, type WrapOptions, type WrappedLine, type WritePdfOptions, assembleStretchyGlyph, createFontMeasurer, createFontRegistry, createStandardFontMeasurer, decodeCcittFax, decodeJbig2Embedded, decodeJpeg2000, filterScanlines, loadMathFont, looksLikeBareCodestream, parseJp2Container, pdfCodec, readFontFace, readJpeg2000Metadata, readPdf, renderPdfPage, resolveFaceWithRegistry, resolveStandardFont, scaleMathStretchConstruction, unfilterScanlines, writePdf };
package/dist/index.js CHANGED
@@ -18,5 +18,6 @@ import { DEFAULT_VERTICAL_METRIC_POLICY, createFontMeasurer, createStandardFontM
18
18
  import { writePdf } from "./write.js";
19
19
  import { PdfBytesSchema, pdfCodec } from "./codec.js";
20
20
  import { FontFaceParseError, readFontFace } from "./font-face.js";
21
+ import { renderPdfPage } from "./raster.js";
21
22
  export * from "byte-codec";
22
- export { DEFAULT_VERTICAL_METRIC_POLICY, FontFaceParseError, Jbig2ParseError, Jbig2UnsupportedError, Jpeg2000ParseError, Jpeg2000UnsupportedError, LAYOUT_FORMAT_VERSION, LayoutAnnotationQuadSchema, LayoutAnnotationSchema, LayoutAttachmentSchema, LayoutDestinationSchema, LayoutDestinationTargetSchema, LayoutDocumentSchema, LayoutEllipseSchema, LayoutFormFieldSchema, LayoutFormWidgetSchema, LayoutImageAssetSchema, LayoutImageSchema, LayoutInternalLinkSchema, LayoutItemSchema, LayoutLayerSchema, LayoutLineSchema, LayoutLinkSchema, LayoutOutlineItemSchema, LayoutPageSchema, LayoutPathSchema, LayoutPathSegmentSchema, LayoutRectSchema, LayoutStructureElementSchema, LayoutSubpathSchema, LayoutTextSchema, NOOP_DIAGNOSTIC_SINK, PdfBytesSchema, PdfEncryptedError, PdfEncryptionError, PdfParseError, PdfPasswordRequiredError, STANDARD_METRICS, assembleStretchyGlyph, createFontMeasurer, createFontRegistry, createStandardFontMeasurer, decodeCcittFax, decodeJbig2Embedded, decodeJpeg2000, filterScanlines, loadMathFont, looksLikeBareCodestream, parseJp2Container, pdfCodec, readFontFace, readJpeg2000Metadata, readPdf, resolveFaceWithRegistry, resolveStandardFont, scaleMathStretchConstruction, unfilterScanlines, writePdf };
23
+ export { DEFAULT_VERTICAL_METRIC_POLICY, FontFaceParseError, Jbig2ParseError, Jbig2UnsupportedError, Jpeg2000ParseError, Jpeg2000UnsupportedError, LAYOUT_FORMAT_VERSION, LayoutAnnotationQuadSchema, LayoutAnnotationSchema, LayoutAttachmentSchema, LayoutDestinationSchema, LayoutDestinationTargetSchema, LayoutDocumentSchema, LayoutEllipseSchema, LayoutFormFieldSchema, LayoutFormWidgetSchema, LayoutImageAssetSchema, LayoutImageSchema, LayoutInternalLinkSchema, LayoutItemSchema, LayoutLayerSchema, LayoutLineSchema, LayoutLinkSchema, LayoutOutlineItemSchema, LayoutPageSchema, LayoutPathSchema, LayoutPathSegmentSchema, LayoutRectSchema, LayoutStructureElementSchema, LayoutSubpathSchema, LayoutTextSchema, NOOP_DIAGNOSTIC_SINK, PdfBytesSchema, PdfEncryptedError, PdfEncryptionError, PdfParseError, PdfPasswordRequiredError, STANDARD_METRICS, assembleStretchyGlyph, createFontMeasurer, createFontRegistry, createStandardFontMeasurer, decodeCcittFax, decodeJbig2Embedded, decodeJpeg2000, filterScanlines, loadMathFont, looksLikeBareCodestream, parseJp2Container, pdfCodec, readFontFace, readJpeg2000Metadata, readPdf, renderPdfPage, resolveFaceWithRegistry, resolveStandardFont, scaleMathStretchConstruction, unfilterScanlines, writePdf };