pdf-codec 5.6.1 → 5.7.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.
- package/README.md +3 -3
- package/dist/index.cjs +3 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -3
- package/dist/{interpret-2_N_lh0h.cjs → interpret-BkDxq0QA.cjs} +40 -65
- package/dist/{interpret-BeMKZGBm.js → interpret-BtzX-LWm.js} +33 -58
- package/dist/interpret-colors.cjs +1 -1
- package/dist/interpret-colors.js +1 -1
- package/dist/interpret-state.cjs +66 -0
- package/dist/interpret-state.d.cts +51 -0
- package/dist/interpret-state.d.ts +51 -0
- package/dist/interpret-state.js +59 -0
- package/dist/interpret.cjs +1 -1
- package/dist/interpret.js +1 -1
- package/dist/{raster-CIc6ot36.js → raster-DCDcD7no.js} +1 -1
- package/dist/{raster-B8i3Tgjj.cjs → raster-De_zVqCu.cjs} +1 -1
- package/dist/raster-text.cjs +1 -1
- package/dist/raster-text.js +1 -1
- package/dist/raster.cjs +1 -1
- package/dist/raster.js +1 -1
- package/dist/read.cjs +1 -1
- package/dist/read.js +1 -1
- package/dist/text-group.cjs +75 -2
- package/dist/text-group.d.cts +24 -1
- package/dist/text-group.d.ts +24 -1
- package/dist/text-group.js +74 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -283,7 +283,7 @@ The package is layered from generic primitives outward to the codec itself:
|
|
|
283
283
|
- **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.
|
|
284
284
|
- **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.
|
|
285
285
|
- **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.
|
|
286
|
-
- **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`).
|
|
286
|
+
- **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`/`interpret-state.ts` (content-stream tokenizer and graphics/text state machine, with the state records and the per-glyph displacement arithmetic in the last, 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`).
|
|
287
287
|
- **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.
|
|
288
288
|
- `codec.ts` — `pdfCodec`, a `z.codec()` pair over `readPdf`/`writePdf`, plus a standalone local copy of the `%PDF-` header check.
|
|
289
289
|
- **`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.
|
|
@@ -334,7 +334,7 @@ Reading a program's built-in encoding is what stops a symbol-encoded subset —
|
|
|
334
334
|
|
|
335
335
|
## Grouping text runs into lines and words
|
|
336
336
|
|
|
337
|
-
`readPdf` reports one positioned run per text-showing operator, and a PDF says nothing about lines or words: a line of prose can arrive as one run, as one run per word, or as one run per glyph, entirely at the producer's discretion. `groupPdfTextRuns` turns those runs back into lines of words, and `pdf-codec/text-group` serves it without the write half or the vendored fonts, alongside `pdf-codec/read`.
|
|
337
|
+
`readPdf` reports one positioned run per text-showing operator, split wherever the operator itself opens a gap at least a word space wide between two of its glyphs (a `TJ` adjustment, a character spacing `Tc`, or the two summed, since a producer can set one against the other), and a PDF says nothing about lines or words: a line of prose can arrive as one run, as one run per word, or as one run per glyph, entirely at the producer's discretion. `groupPdfTextRuns` turns those runs back into lines of words, and `pdf-codec/text-group` serves it without the write half or the vendored fonts, alongside `pdf-codec/read`.
|
|
338
338
|
|
|
339
339
|
```ts
|
|
340
340
|
import { readPdf } from "pdf-codec/read";
|
|
@@ -353,7 +353,7 @@ Two runs are on one line when their baselines sit within a fraction of an em of
|
|
|
353
353
|
|
|
354
354
|
A run whose `widthPt` is absent states no advance, so where it ends is unknown and the gap after it is underivable. `runGapPt` reports `undefined` for that, and an undefined gap is **no evidence of a space**. Reading it as zero puts the previous run's end at its own start, turns its whole advance into an apparent gap, and produces "Com plete ly".
|
|
355
355
|
|
|
356
|
-
Gaps that are derivable become a word space at an eighth of an em (the narrowest genuine one: the standard fourteen faces set their space glyph at 250/1000 em, and justified setting compresses to no less than half of that) and a column boundary past a full em (wider than the em space, the widest single space character there is), so a table's row reads as `"North\t4.2m\t11%"` rather than as one sentence. `runsShareBaseline` and `runGapPt` are exported on their own for a consumer with its own pipeline around them, and every threshold is overridable.
|
|
356
|
+
Gaps that are derivable become a word space at an eighth of an em (the narrowest genuine one: the standard fourteen faces set their space glyph at 250/1000 em, and justified setting compresses to no less than half of that) and a column boundary past a full em (wider than the em space, the widest single space character there is), so a table's row reads as `"North\t4.2m\t11%"` rather than as one sentence. `runsShareBaseline` and `runGapPt` are exported on their own for a consumer with its own pipeline around them, and every threshold is overridable. `scriptPositionOf(base, candidate)` says whether a run is a superscript or subscript of the run it touches: set at no more than three quarters of its size, with its baseline moved by more than a twentieth and at most half of its em (fonts declare script sizes about 0.65 em and offsets between 0.07 and 0.48 em), and no further than a word space from it along the baseline. A script raised past the same-baseline tolerance would otherwise be clustered as a line of its own, so `groupPdfTextRuns` returns it to its base's line, and `attachScriptRuns` does the same for a consumer that clusters lines itself. A line's text joins a script to its base like any touching run (`280m2`); `scriptPositionOf` on a word's `runs` is what tells a reader to raise or lower it.
|
|
357
357
|
|
|
358
358
|
Limits, each inherent to what a PDF states rather than to the implementation: grouping is by baseline alone with no page segmentation, so on a multi-column page whose columns sit at different vertical offsets a line of one can fall within tolerance of a line of the next and the two are reported as one line with a column boundary between them, which is the cut a caller needs (`document-outline.js`'s `segmentPdfRegions` finds the gutter first if you want them genuinely apart); text comes out in visual order, so a right-to-left script needs the Unicode Bidi Algorithm applied to the result; a vertically set run groups into a column instead of a line, reported with a `rotationDeg` of 270 and its own `writingMode`, with columns ordered right to left; and a word hyphenated across a line end stays split, hyphen intact, because rejoining it is a paragraph-level judgement this package leaves to its consumers.
|
|
359
359
|
|
package/dist/index.cjs
CHANGED
|
@@ -21,7 +21,7 @@ const require_write_skipped_surfaces = require("./write-skipped-surfaces.cjs");
|
|
|
21
21
|
const require_write = require("./write.cjs");
|
|
22
22
|
const require_codec = require("./codec.cjs");
|
|
23
23
|
const require_font_face = require("./font-face.cjs");
|
|
24
|
-
const require_raster = require("./raster-
|
|
24
|
+
const require_raster = require("./raster-De_zVqCu.cjs");
|
|
25
25
|
exports.DEFAULT_BASELINE_TOLERANCE_EM = require_text_group.DEFAULT_BASELINE_TOLERANCE_EM;
|
|
26
26
|
exports.DEFAULT_COLUMN_GAP_EM = require_text_group.DEFAULT_COLUMN_GAP_EM;
|
|
27
27
|
exports.DEFAULT_VERTICAL_METRIC_POLICY = require_measure.DEFAULT_VERTICAL_METRIC_POLICY;
|
|
@@ -68,6 +68,7 @@ exports.PdfPasswordRequiredError = require_diagnostics.PdfPasswordRequiredError;
|
|
|
68
68
|
exports.PdfSkippedSurfacesError = require_write_skipped_surfaces.PdfSkippedSurfacesError;
|
|
69
69
|
exports.STANDARD_METRICS = require_afm_widths.STANDARD_METRICS;
|
|
70
70
|
exports.assembleStretchyGlyph = require_math_stretch.assembleStretchyGlyph;
|
|
71
|
+
exports.attachScriptRuns = require_text_group.attachScriptRuns;
|
|
71
72
|
exports.createFontMeasurer = require_measure.createFontMeasurer;
|
|
72
73
|
exports.createFontRegistry = require_font_registry.createFontRegistry;
|
|
73
74
|
exports.createStandardFontMeasurer = require_measure.createStandardFontMeasurer;
|
|
@@ -89,6 +90,7 @@ exports.resolveStandardFont = require_fonts.resolveStandardFont;
|
|
|
89
90
|
exports.runGapPt = require_text_group.runGapPt;
|
|
90
91
|
exports.runsShareBaseline = require_text_group.runsShareBaseline;
|
|
91
92
|
exports.scaleMathStretchConstruction = require_math_stretch.scaleMathStretchConstruction;
|
|
93
|
+
exports.scriptPositionOf = require_text_group.scriptPositionOf;
|
|
92
94
|
exports.sourcePageIndex = require_layout.sourcePageIndex;
|
|
93
95
|
exports.unfilterScanlines = require_image_png_filter.unfilterScanlines;
|
|
94
96
|
exports.writePdf = require_write.writePdf;
|
package/dist/index.d.cts
CHANGED
|
@@ -24,8 +24,8 @@ import { a as MathGlyphPart, c as MathVariants, n as MathGlyphAssembly, o as Mat
|
|
|
24
24
|
import { a as scaleMathStretchConstruction, i as assembleStretchyGlyph, n as MathStretchOptions, r as MathStretchPlacement, t as MathStretchConstruction } from "./math-stretch-C2JanDAz.cjs";
|
|
25
25
|
import { LoadedMathFont, MathFont, MathFontDescriptorMetrics, loadMathFont } from "./math-font.cjs";
|
|
26
26
|
import { DEFAULT_VERTICAL_METRIC_POLICY, FontMeasurerOptions, StandardFontMeasurerOptions, VerticalMetricPolicy, createFontMeasurer, createStandardFontMeasurer } from "./measure.cjs";
|
|
27
|
-
import { DEFAULT_BASELINE_TOLERANCE_EM, DEFAULT_COLUMN_GAP_EM, DEFAULT_WORD_GAP_EM, PdfTextBox, PdfTextGroupingOptions, PdfTextLine, PdfTextRunGeometry, PdfTextWord, PdfWordSeparator, groupPdfTextRuns, runGapPt, runsShareBaseline } from "./text-group.cjs";
|
|
27
|
+
import { DEFAULT_BASELINE_TOLERANCE_EM, DEFAULT_COLUMN_GAP_EM, DEFAULT_WORD_GAP_EM, PdfLineWithScripts, PdfScriptPosition, PdfTextBox, PdfTextGroupingOptions, PdfTextLine, PdfTextRunGeometry, PdfTextWord, PdfWordSeparator, attachScriptRuns, groupPdfTextRuns, runGapPt, runsShareBaseline, scriptPositionOf } from "./text-group.cjs";
|
|
28
28
|
import { PageRasteriser, RasterDrawOp, RasterFillRectOp, RasterFillSpec, RasterImageOp, RasterMatrix, RasterPageGeometry, RasterPathOp, RasterPathSegment, RasterRegionPt, RasterStrokeSpec, RasterSubpath, RenderPdfPageOptions, renderPdfPage } from "./raster.cjs";
|
|
29
29
|
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";
|
|
30
30
|
export * from "byte-codec";
|
|
31
|
-
export { type CcittFaxImage, type CcittFaxOptions, DEFAULT_BASELINE_TOLERANCE_EM, DEFAULT_COLUMN_GAP_EM, DEFAULT_VERTICAL_METRIC_POLICY, DEFAULT_WORD_GAP_EM, 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, LayoutDocumentSurface, LayoutDocumentSurfaceSchema, 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, PdfPageSelectionError, PdfParseError, PdfPartialDocumentError, PdfPasswordRequiredError, PdfSkippedSurfacesError, type PdfTextBox, type PdfTextGroupingOptions, type PdfTextLine, type PdfTextRunGeometry, type PdfTextWord, type PdfWordSeparator, 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 ReadPdfSurfaces, 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, groupPdfTextRuns, loadMathFont, looksLikeBareCodestream, parseJp2Container, pdfCodec, readFontFace, readJpeg2000Metadata, readPdf, renderPdfPage, resolveFaceWithRegistry, resolveStandardFont, runGapPt, runsShareBaseline, scaleMathStretchConstruction, sourcePageIndex, unfilterScanlines, writePdf };
|
|
31
|
+
export { type CcittFaxImage, type CcittFaxOptions, DEFAULT_BASELINE_TOLERANCE_EM, DEFAULT_COLUMN_GAP_EM, DEFAULT_VERTICAL_METRIC_POLICY, DEFAULT_WORD_GAP_EM, 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, LayoutDocumentSurface, LayoutDocumentSurfaceSchema, 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, type PdfLineWithScripts, PdfPageSelectionError, PdfParseError, PdfPartialDocumentError, PdfPasswordRequiredError, type PdfScriptPosition, PdfSkippedSurfacesError, type PdfTextBox, type PdfTextGroupingOptions, type PdfTextLine, type PdfTextRunGeometry, type PdfTextWord, type PdfWordSeparator, 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 ReadPdfSurfaces, 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, attachScriptRuns, createFontMeasurer, createFontRegistry, createStandardFontMeasurer, decodeCcittFax, decodeJbig2Embedded, decodeJpeg2000, filterScanlines, groupPdfTextRuns, loadMathFont, looksLikeBareCodestream, parseJp2Container, pdfCodec, readFontFace, readJpeg2000Metadata, readPdf, renderPdfPage, resolveFaceWithRegistry, resolveStandardFont, runGapPt, runsShareBaseline, scaleMathStretchConstruction, scriptPositionOf, sourcePageIndex, unfilterScanlines, writePdf };
|
package/dist/index.d.ts
CHANGED
|
@@ -24,8 +24,8 @@ import { a as MathGlyphPart, c as MathVariants, n as MathGlyphAssembly, o as Mat
|
|
|
24
24
|
import { a as scaleMathStretchConstruction, i as assembleStretchyGlyph, n as MathStretchOptions, r as MathStretchPlacement, t as MathStretchConstruction } from "./math-stretch-BbC2o4Br.js";
|
|
25
25
|
import { LoadedMathFont, MathFont, MathFontDescriptorMetrics, loadMathFont } from "./math-font.js";
|
|
26
26
|
import { DEFAULT_VERTICAL_METRIC_POLICY, FontMeasurerOptions, StandardFontMeasurerOptions, VerticalMetricPolicy, createFontMeasurer, createStandardFontMeasurer } from "./measure.js";
|
|
27
|
-
import { DEFAULT_BASELINE_TOLERANCE_EM, DEFAULT_COLUMN_GAP_EM, DEFAULT_WORD_GAP_EM, PdfTextBox, PdfTextGroupingOptions, PdfTextLine, PdfTextRunGeometry, PdfTextWord, PdfWordSeparator, groupPdfTextRuns, runGapPt, runsShareBaseline } from "./text-group.js";
|
|
27
|
+
import { DEFAULT_BASELINE_TOLERANCE_EM, DEFAULT_COLUMN_GAP_EM, DEFAULT_WORD_GAP_EM, PdfLineWithScripts, PdfScriptPosition, PdfTextBox, PdfTextGroupingOptions, PdfTextLine, PdfTextRunGeometry, PdfTextWord, PdfWordSeparator, attachScriptRuns, groupPdfTextRuns, runGapPt, runsShareBaseline, scriptPositionOf } from "./text-group.js";
|
|
28
28
|
import { PageRasteriser, RasterDrawOp, RasterFillRectOp, RasterFillSpec, RasterImageOp, RasterMatrix, RasterPageGeometry, RasterPathOp, RasterPathSegment, RasterRegionPt, RasterStrokeSpec, RasterSubpath, RenderPdfPageOptions, renderPdfPage } from "./raster.js";
|
|
29
29
|
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";
|
|
30
30
|
export * from "byte-codec";
|
|
31
|
-
export { type CcittFaxImage, type CcittFaxOptions, DEFAULT_BASELINE_TOLERANCE_EM, DEFAULT_COLUMN_GAP_EM, DEFAULT_VERTICAL_METRIC_POLICY, DEFAULT_WORD_GAP_EM, 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, LayoutDocumentSurface, LayoutDocumentSurfaceSchema, 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, PdfPageSelectionError, PdfParseError, PdfPartialDocumentError, PdfPasswordRequiredError, PdfSkippedSurfacesError, type PdfTextBox, type PdfTextGroupingOptions, type PdfTextLine, type PdfTextRunGeometry, type PdfTextWord, type PdfWordSeparator, 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 ReadPdfSurfaces, 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, groupPdfTextRuns, loadMathFont, looksLikeBareCodestream, parseJp2Container, pdfCodec, readFontFace, readJpeg2000Metadata, readPdf, renderPdfPage, resolveFaceWithRegistry, resolveStandardFont, runGapPt, runsShareBaseline, scaleMathStretchConstruction, sourcePageIndex, unfilterScanlines, writePdf };
|
|
31
|
+
export { type CcittFaxImage, type CcittFaxOptions, DEFAULT_BASELINE_TOLERANCE_EM, DEFAULT_COLUMN_GAP_EM, DEFAULT_VERTICAL_METRIC_POLICY, DEFAULT_WORD_GAP_EM, 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, LayoutDocumentSurface, LayoutDocumentSurfaceSchema, 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, type PdfLineWithScripts, PdfPageSelectionError, PdfParseError, PdfPartialDocumentError, PdfPasswordRequiredError, type PdfScriptPosition, PdfSkippedSurfacesError, type PdfTextBox, type PdfTextGroupingOptions, type PdfTextLine, type PdfTextRunGeometry, type PdfTextWord, type PdfWordSeparator, 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 ReadPdfSurfaces, 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, attachScriptRuns, createFontMeasurer, createFontRegistry, createStandardFontMeasurer, decodeCcittFax, decodeJbig2Embedded, decodeJpeg2000, filterScanlines, groupPdfTextRuns, loadMathFont, looksLikeBareCodestream, parseJp2Container, pdfCodec, readFontFace, readJpeg2000Metadata, readPdf, renderPdfPage, resolveFaceWithRegistry, resolveStandardFont, runGapPt, runsShareBaseline, scaleMathStretchConstruction, scriptPositionOf, sourcePageIndex, unfilterScanlines, writePdf };
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import { decodeJpeg2000, readJpeg2000Metadata } from "./image/jpeg2000.js";
|
|
|
9
9
|
import { LAYOUT_FORMAT_VERSION, LayoutAnnotationQuadSchema, LayoutAnnotationSchema, LayoutAttachmentSchema, LayoutDestinationSchema, LayoutDestinationTargetSchema, LayoutDocumentSchema, LayoutDocumentSurfaceSchema, LayoutEllipseSchema, LayoutFormFieldSchema, LayoutFormWidgetSchema, LayoutImageAssetSchema, LayoutImageSchema, LayoutInternalLinkSchema, LayoutItemSchema, LayoutLayerSchema, LayoutLineSchema, LayoutLinkSchema, LayoutOutlineItemSchema, LayoutPageSchema, LayoutPathSchema, LayoutPathSegmentSchema, LayoutRectSchema, LayoutStructureElementSchema, LayoutSubpathSchema, LayoutTextSchema, sourcePageIndex } from "./layout.js";
|
|
10
10
|
import { NOOP_DIAGNOSTIC_SINK, PdfEncryptedError, PdfPageSelectionError, PdfParseError, PdfPasswordRequiredError } from "./diagnostics.js";
|
|
11
11
|
import { resolveStandardFont } from "./fonts.js";
|
|
12
|
-
import { DEFAULT_BASELINE_TOLERANCE_EM, DEFAULT_COLUMN_GAP_EM, DEFAULT_WORD_GAP_EM, groupPdfTextRuns, runGapPt, runsShareBaseline } from "./text-group.js";
|
|
12
|
+
import { DEFAULT_BASELINE_TOLERANCE_EM, DEFAULT_COLUMN_GAP_EM, DEFAULT_WORD_GAP_EM, attachScriptRuns, groupPdfTextRuns, runGapPt, runsShareBaseline, scriptPositionOf } from "./text-group.js";
|
|
13
13
|
import { readPdf } from "./read.js";
|
|
14
14
|
import { PdfEncryptionError } from "./encrypt-write.js";
|
|
15
15
|
import { assembleStretchyGlyph, scaleMathStretchConstruction } from "./math-stretch.js";
|
|
@@ -20,6 +20,6 @@ import { PdfSkippedSurfacesError } from "./write-skipped-surfaces.js";
|
|
|
20
20
|
import { PdfPartialDocumentError, writePdf } from "./write.js";
|
|
21
21
|
import { PdfBytesSchema, pdfCodec } from "./codec.js";
|
|
22
22
|
import { FontFaceParseError, readFontFace } from "./font-face.js";
|
|
23
|
-
import { r as renderPdfPage } from "./raster-
|
|
23
|
+
import { r as renderPdfPage } from "./raster-DCDcD7no.js";
|
|
24
24
|
export * from "byte-codec";
|
|
25
|
-
export { DEFAULT_BASELINE_TOLERANCE_EM, DEFAULT_COLUMN_GAP_EM, DEFAULT_VERTICAL_METRIC_POLICY, DEFAULT_WORD_GAP_EM, FontFaceParseError, Jbig2ParseError, Jbig2UnsupportedError, Jpeg2000ParseError, Jpeg2000UnsupportedError, LAYOUT_FORMAT_VERSION, LayoutAnnotationQuadSchema, LayoutAnnotationSchema, LayoutAttachmentSchema, LayoutDestinationSchema, LayoutDestinationTargetSchema, LayoutDocumentSchema, LayoutDocumentSurfaceSchema, LayoutEllipseSchema, LayoutFormFieldSchema, LayoutFormWidgetSchema, LayoutImageAssetSchema, LayoutImageSchema, LayoutInternalLinkSchema, LayoutItemSchema, LayoutLayerSchema, LayoutLineSchema, LayoutLinkSchema, LayoutOutlineItemSchema, LayoutPageSchema, LayoutPathSchema, LayoutPathSegmentSchema, LayoutRectSchema, LayoutStructureElementSchema, LayoutSubpathSchema, LayoutTextSchema, NOOP_DIAGNOSTIC_SINK, PdfBytesSchema, PdfEncryptedError, PdfEncryptionError, PdfPageSelectionError, PdfParseError, PdfPartialDocumentError, PdfPasswordRequiredError, PdfSkippedSurfacesError, STANDARD_METRICS, assembleStretchyGlyph, createFontMeasurer, createFontRegistry, createStandardFontMeasurer, decodeCcittFax, decodeJbig2Embedded, decodeJpeg2000, filterScanlines, groupPdfTextRuns, loadMathFont, looksLikeBareCodestream, parseJp2Container, pdfCodec, readFontFace, readJpeg2000Metadata, readPdf, renderPdfPage, resolveFaceWithRegistry, resolveStandardFont, runGapPt, runsShareBaseline, scaleMathStretchConstruction, sourcePageIndex, unfilterScanlines, writePdf };
|
|
25
|
+
export { DEFAULT_BASELINE_TOLERANCE_EM, DEFAULT_COLUMN_GAP_EM, DEFAULT_VERTICAL_METRIC_POLICY, DEFAULT_WORD_GAP_EM, FontFaceParseError, Jbig2ParseError, Jbig2UnsupportedError, Jpeg2000ParseError, Jpeg2000UnsupportedError, LAYOUT_FORMAT_VERSION, LayoutAnnotationQuadSchema, LayoutAnnotationSchema, LayoutAttachmentSchema, LayoutDestinationSchema, LayoutDestinationTargetSchema, LayoutDocumentSchema, LayoutDocumentSurfaceSchema, LayoutEllipseSchema, LayoutFormFieldSchema, LayoutFormWidgetSchema, LayoutImageAssetSchema, LayoutImageSchema, LayoutInternalLinkSchema, LayoutItemSchema, LayoutLayerSchema, LayoutLineSchema, LayoutLinkSchema, LayoutOutlineItemSchema, LayoutPageSchema, LayoutPathSchema, LayoutPathSegmentSchema, LayoutRectSchema, LayoutStructureElementSchema, LayoutSubpathSchema, LayoutTextSchema, NOOP_DIAGNOSTIC_SINK, PdfBytesSchema, PdfEncryptedError, PdfEncryptionError, PdfPageSelectionError, PdfParseError, PdfPartialDocumentError, PdfPasswordRequiredError, PdfSkippedSurfacesError, STANDARD_METRICS, assembleStretchyGlyph, attachScriptRuns, createFontMeasurer, createFontRegistry, createStandardFontMeasurer, decodeCcittFax, decodeJbig2Embedded, decodeJpeg2000, filterScanlines, groupPdfTextRuns, loadMathFont, looksLikeBareCodestream, parseJp2Container, pdfCodec, readFontFace, readJpeg2000Metadata, readPdf, renderPdfPage, resolveFaceWithRegistry, resolveStandardFont, runGapPt, runsShareBaseline, scaleMathStretchConstruction, scriptPositionOf, sourcePageIndex, unfilterScanlines, writePdf };
|
|
@@ -2,7 +2,8 @@ const require_objects = require("./objects.cjs");
|
|
|
2
2
|
const require_matrix = require("./matrix.cjs");
|
|
3
3
|
const require_filters = require("./filters.cjs");
|
|
4
4
|
const require_content_read = require("./content-read.cjs");
|
|
5
|
-
require("./text-group.cjs");
|
|
5
|
+
const require_text_group = require("./text-group.cjs");
|
|
6
|
+
const require_interpret_state = require("./interpret-state.cjs");
|
|
6
7
|
const require_interpret_shapes = require("./interpret-shapes.cjs");
|
|
7
8
|
const require_interpret_marked = require("./interpret-marked.cjs");
|
|
8
9
|
let document_schema_js = require("document-schema.js");
|
|
@@ -44,38 +45,7 @@ function genericColor(operands) {
|
|
|
44
45
|
//#endregion
|
|
45
46
|
//#region src/interpret.ts
|
|
46
47
|
const MAX_FORM_XOBJECT_DEPTH = 12;
|
|
47
|
-
const FALLBACK_GLYPH_WIDTH_PER_1000 = 500;
|
|
48
|
-
const GLYPH_SPACE_PER_TEXT_SPACE_UNIT = 1e3;
|
|
49
|
-
const ASCII_SPACE = 32;
|
|
50
48
|
const DEFAULT_LINE_WIDTH_PT = 1;
|
|
51
|
-
function initialTextParameters() {
|
|
52
|
-
return {
|
|
53
|
-
fontResourceName: void 0,
|
|
54
|
-
fontSizePt: 0,
|
|
55
|
-
charSpace: 0,
|
|
56
|
-
wordSpace: 0,
|
|
57
|
-
horizScale: 1,
|
|
58
|
-
leading: 0,
|
|
59
|
-
rise: 0
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
function defaultTextObjectState() {
|
|
63
|
-
return {
|
|
64
|
-
tm: require_matrix.IDENTITY_MATRIX,
|
|
65
|
-
tlm: require_matrix.IDENTITY_MATRIX
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
function computeTrm(gs, text) {
|
|
69
|
-
const fontMatrix = [
|
|
70
|
-
gs.fontSizePt * gs.horizScale,
|
|
71
|
-
0,
|
|
72
|
-
0,
|
|
73
|
-
gs.fontSizePt,
|
|
74
|
-
0,
|
|
75
|
-
gs.rise
|
|
76
|
-
];
|
|
77
|
-
return require_matrix.multiplyMatrices(require_matrix.multiplyMatrices(fontMatrix, text.tm), gs.ctm);
|
|
78
|
-
}
|
|
79
49
|
function numAt(operands, index) {
|
|
80
50
|
return require_objects.asNumber(operands[index]) ?? 0;
|
|
81
51
|
}
|
|
@@ -104,7 +74,7 @@ function interpretContentStream(bytes, resources, context) {
|
|
|
104
74
|
strokeColor: document_schema_js.COLOR_BLACK,
|
|
105
75
|
lineWidth: DEFAULT_LINE_WIDTH_PT,
|
|
106
76
|
dashArray: [],
|
|
107
|
-
...initialTextParameters()
|
|
77
|
+
...require_interpret_state.initialTextParameters()
|
|
108
78
|
}, context, 0, new require_interpret_shapes.MarkedContentStack());
|
|
109
79
|
}
|
|
110
80
|
function lastPointOf(subpath) {
|
|
@@ -122,7 +92,7 @@ function runContentStream(bytes, resources, initialState, context, depth, marked
|
|
|
122
92
|
const operations = require_content_read.readContentStream(bytes, context.sink);
|
|
123
93
|
const gsStack = [];
|
|
124
94
|
let gs = initialState;
|
|
125
|
-
let text = defaultTextObjectState();
|
|
95
|
+
let text = require_interpret_state.defaultTextObjectState();
|
|
126
96
|
let pathSubpaths = [];
|
|
127
97
|
let currentSubpath;
|
|
128
98
|
const inScope = (key) => markedContent.inScope(key);
|
|
@@ -236,25 +206,16 @@ function runContentStream(bytes, resources, initialState, context, depth, marked
|
|
|
236
206
|
}
|
|
237
207
|
resetPath();
|
|
238
208
|
};
|
|
239
|
-
const
|
|
240
|
-
const
|
|
241
|
-
if (
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
});
|
|
250
|
-
const widthPer1000 = glyph?.widthPer1000 ?? FALLBACK_GLYPH_WIDTH_PER_1000;
|
|
251
|
-
const byteLength = glyph?.byteLengthConsumed ?? 1;
|
|
252
|
-
const isSingleByteSpace = byteLength === 1 && codes[offset] === ASCII_SPACE;
|
|
253
|
-
const spacing = gs.charSpace + (isSingleByteSpace ? gs.wordSpace : 0);
|
|
254
|
-
const vertical = glyph?.vertical;
|
|
255
|
-
text.tm = vertical === void 0 ? require_matrix.multiplyMatrices(require_matrix.translationMatrix((widthPer1000 / GLYPH_SPACE_PER_TEXT_SPACE_UNIT * gs.fontSizePt + spacing) * gs.horizScale, 0), text.tm) : require_matrix.multiplyMatrices(require_matrix.translationMatrix(0, vertical.displacementPer1000 / GLYPH_SPACE_PER_TEXT_SPACE_UNIT * gs.fontSizePt + spacing), text.tm);
|
|
256
|
-
offset += byteLength;
|
|
257
|
-
}
|
|
209
|
+
const advanceThroughGlyph = (fontResourceName, codes, offset) => {
|
|
210
|
+
const glyph = context.fontMetrics.glyphAdvance(fontResourceName, resources, codes, offset);
|
|
211
|
+
if (glyph === void 0) context.sink({
|
|
212
|
+
code: "pdf/font-not-resolved",
|
|
213
|
+
severity: "warning",
|
|
214
|
+
message: `could not resolve font resource /${fontResourceName} to compute a glyph advance; assuming a fallback width`
|
|
215
|
+
});
|
|
216
|
+
const step = require_interpret_state.stepPastGlyph(gs, text.tm, glyph, codes, offset);
|
|
217
|
+
text.tm = step.tm;
|
|
218
|
+
return step;
|
|
258
219
|
};
|
|
259
220
|
const positionVectorOf = (codes) => {
|
|
260
221
|
const fontResourceName = gs.fontResourceName;
|
|
@@ -262,18 +223,22 @@ function runContentStream(bytes, resources, initialState, context, depth, marked
|
|
|
262
223
|
const vertical = context.fontMetrics.glyphAdvance(fontResourceName, resources, codes, 0)?.vertical;
|
|
263
224
|
if (vertical === void 0) return;
|
|
264
225
|
return {
|
|
265
|
-
x: vertical.positionXPer1000 / GLYPH_SPACE_PER_TEXT_SPACE_UNIT,
|
|
266
|
-
y: vertical.positionYPer1000 / GLYPH_SPACE_PER_TEXT_SPACE_UNIT
|
|
226
|
+
x: vertical.positionXPer1000 / require_interpret_state.GLYPH_SPACE_PER_TEXT_SPACE_UNIT,
|
|
227
|
+
y: vertical.positionYPer1000 / require_interpret_state.GLYPH_SPACE_PER_TEXT_SPACE_UNIT
|
|
267
228
|
};
|
|
268
229
|
};
|
|
269
230
|
const showTextArray = (elements) => {
|
|
270
231
|
const fontResourceName = gs.fontResourceName;
|
|
271
232
|
if (fontResourceName === void 0) return;
|
|
272
233
|
const vertical = context.fontMetrics.isVertical(fontResourceName, resources);
|
|
273
|
-
|
|
234
|
+
const wordGap = require_text_group.DEFAULT_WORD_GAP_EM * gs.fontSizePt;
|
|
235
|
+
let startMatrix = require_interpret_state.computeTrm(gs, text);
|
|
274
236
|
let chunks = [];
|
|
275
237
|
let totalLength = 0;
|
|
276
238
|
let firstGlyphPosition;
|
|
239
|
+
let lastWidthEndTm;
|
|
240
|
+
let gapSinceLastGlyph = 0;
|
|
241
|
+
const gapIsWordWide = () => !vertical && totalLength > 0 && gapSinceLastGlyph >= wordGap;
|
|
277
242
|
const flushRun = () => {
|
|
278
243
|
if (totalLength === 0) return;
|
|
279
244
|
const combined = new Uint8Array(totalLength);
|
|
@@ -282,7 +247,10 @@ function runContentStream(bytes, resources, initialState, context, depth, marked
|
|
|
282
247
|
combined.set(chunk, at);
|
|
283
248
|
at += chunk.length;
|
|
284
249
|
}
|
|
285
|
-
const endMatrix = computeTrm(gs,
|
|
250
|
+
const endMatrix = require_interpret_state.computeTrm(gs, gapIsWordWide() && lastWidthEndTm !== void 0 ? {
|
|
251
|
+
...text,
|
|
252
|
+
tm: lastWidthEndTm
|
|
253
|
+
} : text);
|
|
286
254
|
const shift = firstGlyphPosition === void 0 ? void 0 : require_matrix.translationMatrix(-firstGlyphPosition.x, -firstGlyphPosition.y);
|
|
287
255
|
pushItem({
|
|
288
256
|
kind: "text",
|
|
@@ -300,15 +268,22 @@ function runContentStream(bytes, resources, initialState, context, depth, marked
|
|
|
300
268
|
firstGlyphPosition = void 0;
|
|
301
269
|
};
|
|
302
270
|
for (const el of elements) if (el.kind === "string") {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
271
|
+
let offset = 0;
|
|
272
|
+
while (offset < el.bytes.length) {
|
|
273
|
+
if (gapIsWordWide()) flushRun();
|
|
274
|
+
if (totalLength === 0) startMatrix = require_interpret_state.computeTrm(gs, text);
|
|
275
|
+
firstGlyphPosition ??= vertical ? positionVectorOf(el.bytes.subarray(offset)) : void 0;
|
|
276
|
+
const glyph = advanceThroughGlyph(fontResourceName, el.bytes, offset);
|
|
277
|
+
chunks.push(el.bytes.subarray(offset, offset + glyph.byteLength));
|
|
278
|
+
totalLength += glyph.byteLength;
|
|
279
|
+
offset += glyph.byteLength;
|
|
280
|
+
lastWidthEndTm = glyph.widthEndTm;
|
|
281
|
+
gapSinceLastGlyph = glyph.charSpaceAfter;
|
|
282
|
+
}
|
|
307
283
|
} else if (el.kind === "number") {
|
|
308
|
-
const adjustment = -(el.value / GLYPH_SPACE_PER_TEXT_SPACE_UNIT) * gs.fontSizePt;
|
|
309
|
-
|
|
284
|
+
const adjustment = -(el.value / require_interpret_state.GLYPH_SPACE_PER_TEXT_SPACE_UNIT) * gs.fontSizePt;
|
|
285
|
+
gapSinceLastGlyph += adjustment;
|
|
310
286
|
text.tm = require_matrix.multiplyMatrices(vertical ? require_matrix.translationMatrix(0, adjustment) : require_matrix.translationMatrix(adjustment * gs.horizScale, 0), text.tm);
|
|
311
|
-
if (totalLength === 0) startMatrix = computeTrm(gs, text);
|
|
312
287
|
}
|
|
313
288
|
flushRun();
|
|
314
289
|
};
|
|
@@ -573,7 +548,7 @@ function runContentStream(bytes, resources, initialState, context, depth, marked
|
|
|
573
548
|
emitPaint(operator);
|
|
574
549
|
break;
|
|
575
550
|
case "BT":
|
|
576
|
-
text = defaultTextObjectState();
|
|
551
|
+
text = require_interpret_state.defaultTextObjectState();
|
|
577
552
|
break;
|
|
578
553
|
case "Tf":
|
|
579
554
|
gs = {
|
|
@@ -2,7 +2,8 @@ import { asArray, asName, asNumber, dictGet } from "./objects.js";
|
|
|
2
2
|
import { IDENTITY_MATRIX, applyMatrix, multiplyMatrices, translationMatrix } from "./matrix.js";
|
|
3
3
|
import { decodeStream } from "./filters.js";
|
|
4
4
|
import { readContentStream } from "./content-read.js";
|
|
5
|
-
import "./text-group.js";
|
|
5
|
+
import { DEFAULT_WORD_GAP_EM } from "./text-group.js";
|
|
6
|
+
import { GLYPH_SPACE_PER_TEXT_SPACE_UNIT, computeTrm, defaultTextObjectState, initialTextParameters, stepPastGlyph } from "./interpret-state.js";
|
|
6
7
|
import { MarkedContentStack, classifyShape, strokeStyleFromDashArray } from "./interpret-shapes.js";
|
|
7
8
|
import { markedContentProperties, markedContentScopeProps } from "./interpret-marked.js";
|
|
8
9
|
import { COLOR_BLACK } from "document-schema.js";
|
|
@@ -44,38 +45,7 @@ function genericColor(operands) {
|
|
|
44
45
|
//#endregion
|
|
45
46
|
//#region src/interpret.ts
|
|
46
47
|
const MAX_FORM_XOBJECT_DEPTH = 12;
|
|
47
|
-
const FALLBACK_GLYPH_WIDTH_PER_1000 = 500;
|
|
48
|
-
const GLYPH_SPACE_PER_TEXT_SPACE_UNIT = 1e3;
|
|
49
|
-
const ASCII_SPACE = 32;
|
|
50
48
|
const DEFAULT_LINE_WIDTH_PT = 1;
|
|
51
|
-
function initialTextParameters() {
|
|
52
|
-
return {
|
|
53
|
-
fontResourceName: void 0,
|
|
54
|
-
fontSizePt: 0,
|
|
55
|
-
charSpace: 0,
|
|
56
|
-
wordSpace: 0,
|
|
57
|
-
horizScale: 1,
|
|
58
|
-
leading: 0,
|
|
59
|
-
rise: 0
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
function defaultTextObjectState() {
|
|
63
|
-
return {
|
|
64
|
-
tm: IDENTITY_MATRIX,
|
|
65
|
-
tlm: IDENTITY_MATRIX
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
function computeTrm(gs, text) {
|
|
69
|
-
const fontMatrix = [
|
|
70
|
-
gs.fontSizePt * gs.horizScale,
|
|
71
|
-
0,
|
|
72
|
-
0,
|
|
73
|
-
gs.fontSizePt,
|
|
74
|
-
0,
|
|
75
|
-
gs.rise
|
|
76
|
-
];
|
|
77
|
-
return multiplyMatrices(multiplyMatrices(fontMatrix, text.tm), gs.ctm);
|
|
78
|
-
}
|
|
79
49
|
function numAt(operands, index) {
|
|
80
50
|
return asNumber(operands[index]) ?? 0;
|
|
81
51
|
}
|
|
@@ -236,25 +206,16 @@ function runContentStream(bytes, resources, initialState, context, depth, marked
|
|
|
236
206
|
}
|
|
237
207
|
resetPath();
|
|
238
208
|
};
|
|
239
|
-
const
|
|
240
|
-
const
|
|
241
|
-
if (
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
});
|
|
250
|
-
const widthPer1000 = glyph?.widthPer1000 ?? FALLBACK_GLYPH_WIDTH_PER_1000;
|
|
251
|
-
const byteLength = glyph?.byteLengthConsumed ?? 1;
|
|
252
|
-
const isSingleByteSpace = byteLength === 1 && codes[offset] === ASCII_SPACE;
|
|
253
|
-
const spacing = gs.charSpace + (isSingleByteSpace ? gs.wordSpace : 0);
|
|
254
|
-
const vertical = glyph?.vertical;
|
|
255
|
-
text.tm = vertical === void 0 ? multiplyMatrices(translationMatrix((widthPer1000 / GLYPH_SPACE_PER_TEXT_SPACE_UNIT * gs.fontSizePt + spacing) * gs.horizScale, 0), text.tm) : multiplyMatrices(translationMatrix(0, vertical.displacementPer1000 / GLYPH_SPACE_PER_TEXT_SPACE_UNIT * gs.fontSizePt + spacing), text.tm);
|
|
256
|
-
offset += byteLength;
|
|
257
|
-
}
|
|
209
|
+
const advanceThroughGlyph = (fontResourceName, codes, offset) => {
|
|
210
|
+
const glyph = context.fontMetrics.glyphAdvance(fontResourceName, resources, codes, offset);
|
|
211
|
+
if (glyph === void 0) context.sink({
|
|
212
|
+
code: "pdf/font-not-resolved",
|
|
213
|
+
severity: "warning",
|
|
214
|
+
message: `could not resolve font resource /${fontResourceName} to compute a glyph advance; assuming a fallback width`
|
|
215
|
+
});
|
|
216
|
+
const step = stepPastGlyph(gs, text.tm, glyph, codes, offset);
|
|
217
|
+
text.tm = step.tm;
|
|
218
|
+
return step;
|
|
258
219
|
};
|
|
259
220
|
const positionVectorOf = (codes) => {
|
|
260
221
|
const fontResourceName = gs.fontResourceName;
|
|
@@ -270,10 +231,14 @@ function runContentStream(bytes, resources, initialState, context, depth, marked
|
|
|
270
231
|
const fontResourceName = gs.fontResourceName;
|
|
271
232
|
if (fontResourceName === void 0) return;
|
|
272
233
|
const vertical = context.fontMetrics.isVertical(fontResourceName, resources);
|
|
234
|
+
const wordGap = DEFAULT_WORD_GAP_EM * gs.fontSizePt;
|
|
273
235
|
let startMatrix = computeTrm(gs, text);
|
|
274
236
|
let chunks = [];
|
|
275
237
|
let totalLength = 0;
|
|
276
238
|
let firstGlyphPosition;
|
|
239
|
+
let lastWidthEndTm;
|
|
240
|
+
let gapSinceLastGlyph = 0;
|
|
241
|
+
const gapIsWordWide = () => !vertical && totalLength > 0 && gapSinceLastGlyph >= wordGap;
|
|
277
242
|
const flushRun = () => {
|
|
278
243
|
if (totalLength === 0) return;
|
|
279
244
|
const combined = new Uint8Array(totalLength);
|
|
@@ -282,7 +247,10 @@ function runContentStream(bytes, resources, initialState, context, depth, marked
|
|
|
282
247
|
combined.set(chunk, at);
|
|
283
248
|
at += chunk.length;
|
|
284
249
|
}
|
|
285
|
-
const endMatrix = computeTrm(gs,
|
|
250
|
+
const endMatrix = computeTrm(gs, gapIsWordWide() && lastWidthEndTm !== void 0 ? {
|
|
251
|
+
...text,
|
|
252
|
+
tm: lastWidthEndTm
|
|
253
|
+
} : text);
|
|
286
254
|
const shift = firstGlyphPosition === void 0 ? void 0 : translationMatrix(-firstGlyphPosition.x, -firstGlyphPosition.y);
|
|
287
255
|
pushItem({
|
|
288
256
|
kind: "text",
|
|
@@ -300,15 +268,22 @@ function runContentStream(bytes, resources, initialState, context, depth, marked
|
|
|
300
268
|
firstGlyphPosition = void 0;
|
|
301
269
|
};
|
|
302
270
|
for (const el of elements) if (el.kind === "string") {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
271
|
+
let offset = 0;
|
|
272
|
+
while (offset < el.bytes.length) {
|
|
273
|
+
if (gapIsWordWide()) flushRun();
|
|
274
|
+
if (totalLength === 0) startMatrix = computeTrm(gs, text);
|
|
275
|
+
firstGlyphPosition ??= vertical ? positionVectorOf(el.bytes.subarray(offset)) : void 0;
|
|
276
|
+
const glyph = advanceThroughGlyph(fontResourceName, el.bytes, offset);
|
|
277
|
+
chunks.push(el.bytes.subarray(offset, offset + glyph.byteLength));
|
|
278
|
+
totalLength += glyph.byteLength;
|
|
279
|
+
offset += glyph.byteLength;
|
|
280
|
+
lastWidthEndTm = glyph.widthEndTm;
|
|
281
|
+
gapSinceLastGlyph = glyph.charSpaceAfter;
|
|
282
|
+
}
|
|
307
283
|
} else if (el.kind === "number") {
|
|
308
284
|
const adjustment = -(el.value / GLYPH_SPACE_PER_TEXT_SPACE_UNIT) * gs.fontSizePt;
|
|
309
|
-
|
|
285
|
+
gapSinceLastGlyph += adjustment;
|
|
310
286
|
text.tm = multiplyMatrices(vertical ? translationMatrix(0, adjustment) : translationMatrix(adjustment * gs.horizScale, 0), text.tm);
|
|
311
|
-
if (totalLength === 0) startMatrix = computeTrm(gs, text);
|
|
312
287
|
}
|
|
313
288
|
flushRun();
|
|
314
289
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_interpret = require("./interpret-
|
|
2
|
+
const require_interpret = require("./interpret-BkDxq0QA.cjs");
|
|
3
3
|
exports.cmykColor = require_interpret.cmykColor;
|
|
4
4
|
exports.genericColor = require_interpret.genericColor;
|
|
5
5
|
exports.grayColor = require_interpret.grayColor;
|
package/dist/interpret-colors.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as grayColor, i as genericColor, o as rgbColor, r as cmykColor } from "./interpret-
|
|
1
|
+
import { a as grayColor, i as genericColor, o as rgbColor, r as cmykColor } from "./interpret-BtzX-LWm.js";
|
|
2
2
|
export { cmykColor, genericColor, grayColor, rgbColor };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_matrix = require("./matrix.cjs");
|
|
3
|
+
//#region src/interpret-state.ts
|
|
4
|
+
const FALLBACK_GLYPH_WIDTH_PER_1000 = 500;
|
|
5
|
+
const GLYPH_SPACE_PER_TEXT_SPACE_UNIT = 1e3;
|
|
6
|
+
const ASCII_SPACE = 32;
|
|
7
|
+
function initialTextParameters() {
|
|
8
|
+
return {
|
|
9
|
+
fontResourceName: void 0,
|
|
10
|
+
fontSizePt: 0,
|
|
11
|
+
charSpace: 0,
|
|
12
|
+
wordSpace: 0,
|
|
13
|
+
horizScale: 1,
|
|
14
|
+
leading: 0,
|
|
15
|
+
rise: 0
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function defaultTextObjectState() {
|
|
19
|
+
return {
|
|
20
|
+
tm: require_matrix.IDENTITY_MATRIX,
|
|
21
|
+
tlm: require_matrix.IDENTITY_MATRIX
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function computeTrm(gs, text) {
|
|
25
|
+
const fontMatrix = [
|
|
26
|
+
gs.fontSizePt * gs.horizScale,
|
|
27
|
+
0,
|
|
28
|
+
0,
|
|
29
|
+
gs.fontSizePt,
|
|
30
|
+
0,
|
|
31
|
+
gs.rise
|
|
32
|
+
];
|
|
33
|
+
return require_matrix.multiplyMatrices(require_matrix.multiplyMatrices(fontMatrix, text.tm), gs.ctm);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Moves a text matrix past one glyph.
|
|
37
|
+
* @param gs - the graphics state whose font size, spacing and horizontal scaling apply
|
|
38
|
+
* @param tm - the text matrix where the glyph starts
|
|
39
|
+
* @param glyph - the font's advance for the glyph's code, or undefined when the font could not be resolved, in which case a fallback width is assumed and the code is taken as one byte
|
|
40
|
+
* @param codes - the shown string
|
|
41
|
+
* @param offset - where the glyph's code starts in `codes`
|
|
42
|
+
* @returns the step, with the pen's new position and the end of the glyph's own width reported apart so a caller can tell the glyph's extent from the gap after it
|
|
43
|
+
*/
|
|
44
|
+
function stepPastGlyph(gs, tm, glyph, codes, offset) {
|
|
45
|
+
const widthPer1000 = glyph?.widthPer1000 ?? 500;
|
|
46
|
+
const byteLength = glyph?.byteLengthConsumed ?? 1;
|
|
47
|
+
const isSingleByteSpace = byteLength === 1 && codes[offset] === 32;
|
|
48
|
+
const spacing = gs.charSpace + (isSingleByteSpace ? gs.wordSpace : 0);
|
|
49
|
+
const vertical = glyph?.vertical;
|
|
50
|
+
const widthAdvance = vertical === void 0 ? widthPer1000 / GLYPH_SPACE_PER_TEXT_SPACE_UNIT * gs.fontSizePt : vertical.displacementPer1000 / GLYPH_SPACE_PER_TEXT_SPACE_UNIT * gs.fontSizePt;
|
|
51
|
+
const along = (distance) => vertical === void 0 ? require_matrix.translationMatrix(distance * gs.horizScale, 0) : require_matrix.translationMatrix(0, distance);
|
|
52
|
+
return {
|
|
53
|
+
byteLength,
|
|
54
|
+
tm: require_matrix.multiplyMatrices(along(widthAdvance + spacing), tm),
|
|
55
|
+
widthEndTm: require_matrix.multiplyMatrices(along(widthAdvance), tm),
|
|
56
|
+
charSpaceAfter: gs.charSpace
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
//#endregion
|
|
60
|
+
exports.ASCII_SPACE = ASCII_SPACE;
|
|
61
|
+
exports.FALLBACK_GLYPH_WIDTH_PER_1000 = FALLBACK_GLYPH_WIDTH_PER_1000;
|
|
62
|
+
exports.GLYPH_SPACE_PER_TEXT_SPACE_UNIT = GLYPH_SPACE_PER_TEXT_SPACE_UNIT;
|
|
63
|
+
exports.computeTrm = computeTrm;
|
|
64
|
+
exports.defaultTextObjectState = defaultTextObjectState;
|
|
65
|
+
exports.initialTextParameters = initialTextParameters;
|
|
66
|
+
exports.stepPastGlyph = stepPastGlyph;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { r as Matrix } from "./matrix-B7_SBKQ5.cjs";
|
|
2
|
+
import { GlyphAdvance } from "./interpret-types.cjs";
|
|
3
|
+
import { Color } from "document-schema.js";
|
|
4
|
+
//#region src/interpret-state.d.ts
|
|
5
|
+
declare const FALLBACK_GLYPH_WIDTH_PER_1000 = 500;
|
|
6
|
+
declare const GLYPH_SPACE_PER_TEXT_SPACE_UNIT = 1000;
|
|
7
|
+
declare const ASCII_SPACE = 32;
|
|
8
|
+
interface GraphicsState {
|
|
9
|
+
readonly ctm: Matrix;
|
|
10
|
+
readonly fillColor: Color;
|
|
11
|
+
readonly strokeColor: Color;
|
|
12
|
+
readonly lineWidth: number;
|
|
13
|
+
readonly dashArray: readonly number[];
|
|
14
|
+
readonly fontResourceName: string | undefined;
|
|
15
|
+
readonly fontSizePt: number;
|
|
16
|
+
readonly charSpace: number;
|
|
17
|
+
readonly wordSpace: number;
|
|
18
|
+
readonly horizScale: number;
|
|
19
|
+
readonly leading: number;
|
|
20
|
+
readonly rise: number;
|
|
21
|
+
}
|
|
22
|
+
interface TextObjectState {
|
|
23
|
+
tm: Matrix;
|
|
24
|
+
tlm: Matrix;
|
|
25
|
+
}
|
|
26
|
+
declare function initialTextParameters(): Omit<GraphicsState, "ctm" | "fillColor" | "strokeColor" | "lineWidth" | "dashArray">;
|
|
27
|
+
declare function defaultTextObjectState(): TextObjectState;
|
|
28
|
+
declare function computeTrm(gs: GraphicsState, text: TextObjectState): Matrix;
|
|
29
|
+
/** Where one glyph leaves the text matrix, and what lies between the glyph and the next one. */
|
|
30
|
+
interface GlyphStep {
|
|
31
|
+
/** How many bytes of the shown string the glyph's code took. */
|
|
32
|
+
readonly byteLength: number;
|
|
33
|
+
/** The text matrix after the glyph's width and its spacing, where the next glyph starts. */
|
|
34
|
+
readonly tm: Matrix;
|
|
35
|
+
/** The text matrix at the end of the glyph's own advance width, before any spacing. */
|
|
36
|
+
readonly widthEndTm: Matrix;
|
|
37
|
+
/** The character spacing added after the glyph's width, in unscaled text space units. The word spacing a single-byte space takes is not counted: the space character already records that word boundary in the run's text. */
|
|
38
|
+
readonly charSpaceAfter: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Moves a text matrix past one glyph.
|
|
42
|
+
* @param gs - the graphics state whose font size, spacing and horizontal scaling apply
|
|
43
|
+
* @param tm - the text matrix where the glyph starts
|
|
44
|
+
* @param glyph - the font's advance for the glyph's code, or undefined when the font could not be resolved, in which case a fallback width is assumed and the code is taken as one byte
|
|
45
|
+
* @param codes - the shown string
|
|
46
|
+
* @param offset - where the glyph's code starts in `codes`
|
|
47
|
+
* @returns the step, with the pen's new position and the end of the glyph's own width reported apart so a caller can tell the glyph's extent from the gap after it
|
|
48
|
+
*/
|
|
49
|
+
declare function stepPastGlyph(gs: GraphicsState, tm: Matrix, glyph: GlyphAdvance | undefined, codes: Uint8Array<ArrayBuffer>, offset: number): GlyphStep;
|
|
50
|
+
//#endregion
|
|
51
|
+
export { ASCII_SPACE, FALLBACK_GLYPH_WIDTH_PER_1000, GLYPH_SPACE_PER_TEXT_SPACE_UNIT, GlyphStep, GraphicsState, TextObjectState, computeTrm, defaultTextObjectState, initialTextParameters, stepPastGlyph };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { r as Matrix } from "./matrix-B7_SBKQ5.js";
|
|
2
|
+
import { GlyphAdvance } from "./interpret-types.js";
|
|
3
|
+
import { Color } from "document-schema.js";
|
|
4
|
+
//#region src/interpret-state.d.ts
|
|
5
|
+
declare const FALLBACK_GLYPH_WIDTH_PER_1000 = 500;
|
|
6
|
+
declare const GLYPH_SPACE_PER_TEXT_SPACE_UNIT = 1000;
|
|
7
|
+
declare const ASCII_SPACE = 32;
|
|
8
|
+
interface GraphicsState {
|
|
9
|
+
readonly ctm: Matrix;
|
|
10
|
+
readonly fillColor: Color;
|
|
11
|
+
readonly strokeColor: Color;
|
|
12
|
+
readonly lineWidth: number;
|
|
13
|
+
readonly dashArray: readonly number[];
|
|
14
|
+
readonly fontResourceName: string | undefined;
|
|
15
|
+
readonly fontSizePt: number;
|
|
16
|
+
readonly charSpace: number;
|
|
17
|
+
readonly wordSpace: number;
|
|
18
|
+
readonly horizScale: number;
|
|
19
|
+
readonly leading: number;
|
|
20
|
+
readonly rise: number;
|
|
21
|
+
}
|
|
22
|
+
interface TextObjectState {
|
|
23
|
+
tm: Matrix;
|
|
24
|
+
tlm: Matrix;
|
|
25
|
+
}
|
|
26
|
+
declare function initialTextParameters(): Omit<GraphicsState, "ctm" | "fillColor" | "strokeColor" | "lineWidth" | "dashArray">;
|
|
27
|
+
declare function defaultTextObjectState(): TextObjectState;
|
|
28
|
+
declare function computeTrm(gs: GraphicsState, text: TextObjectState): Matrix;
|
|
29
|
+
/** Where one glyph leaves the text matrix, and what lies between the glyph and the next one. */
|
|
30
|
+
interface GlyphStep {
|
|
31
|
+
/** How many bytes of the shown string the glyph's code took. */
|
|
32
|
+
readonly byteLength: number;
|
|
33
|
+
/** The text matrix after the glyph's width and its spacing, where the next glyph starts. */
|
|
34
|
+
readonly tm: Matrix;
|
|
35
|
+
/** The text matrix at the end of the glyph's own advance width, before any spacing. */
|
|
36
|
+
readonly widthEndTm: Matrix;
|
|
37
|
+
/** The character spacing added after the glyph's width, in unscaled text space units. The word spacing a single-byte space takes is not counted: the space character already records that word boundary in the run's text. */
|
|
38
|
+
readonly charSpaceAfter: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Moves a text matrix past one glyph.
|
|
42
|
+
* @param gs - the graphics state whose font size, spacing and horizontal scaling apply
|
|
43
|
+
* @param tm - the text matrix where the glyph starts
|
|
44
|
+
* @param glyph - the font's advance for the glyph's code, or undefined when the font could not be resolved, in which case a fallback width is assumed and the code is taken as one byte
|
|
45
|
+
* @param codes - the shown string
|
|
46
|
+
* @param offset - where the glyph's code starts in `codes`
|
|
47
|
+
* @returns the step, with the pen's new position and the end of the glyph's own width reported apart so a caller can tell the glyph's extent from the gap after it
|
|
48
|
+
*/
|
|
49
|
+
declare function stepPastGlyph(gs: GraphicsState, tm: Matrix, glyph: GlyphAdvance | undefined, codes: Uint8Array<ArrayBuffer>, offset: number): GlyphStep;
|
|
50
|
+
//#endregion
|
|
51
|
+
export { ASCII_SPACE, FALLBACK_GLYPH_WIDTH_PER_1000, GLYPH_SPACE_PER_TEXT_SPACE_UNIT, GlyphStep, GraphicsState, TextObjectState, computeTrm, defaultTextObjectState, initialTextParameters, stepPastGlyph };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { IDENTITY_MATRIX, multiplyMatrices, translationMatrix } from "./matrix.js";
|
|
2
|
+
//#region src/interpret-state.ts
|
|
3
|
+
const FALLBACK_GLYPH_WIDTH_PER_1000 = 500;
|
|
4
|
+
const GLYPH_SPACE_PER_TEXT_SPACE_UNIT = 1e3;
|
|
5
|
+
const ASCII_SPACE = 32;
|
|
6
|
+
function initialTextParameters() {
|
|
7
|
+
return {
|
|
8
|
+
fontResourceName: void 0,
|
|
9
|
+
fontSizePt: 0,
|
|
10
|
+
charSpace: 0,
|
|
11
|
+
wordSpace: 0,
|
|
12
|
+
horizScale: 1,
|
|
13
|
+
leading: 0,
|
|
14
|
+
rise: 0
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function defaultTextObjectState() {
|
|
18
|
+
return {
|
|
19
|
+
tm: IDENTITY_MATRIX,
|
|
20
|
+
tlm: IDENTITY_MATRIX
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function computeTrm(gs, text) {
|
|
24
|
+
const fontMatrix = [
|
|
25
|
+
gs.fontSizePt * gs.horizScale,
|
|
26
|
+
0,
|
|
27
|
+
0,
|
|
28
|
+
gs.fontSizePt,
|
|
29
|
+
0,
|
|
30
|
+
gs.rise
|
|
31
|
+
];
|
|
32
|
+
return multiplyMatrices(multiplyMatrices(fontMatrix, text.tm), gs.ctm);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Moves a text matrix past one glyph.
|
|
36
|
+
* @param gs - the graphics state whose font size, spacing and horizontal scaling apply
|
|
37
|
+
* @param tm - the text matrix where the glyph starts
|
|
38
|
+
* @param glyph - the font's advance for the glyph's code, or undefined when the font could not be resolved, in which case a fallback width is assumed and the code is taken as one byte
|
|
39
|
+
* @param codes - the shown string
|
|
40
|
+
* @param offset - where the glyph's code starts in `codes`
|
|
41
|
+
* @returns the step, with the pen's new position and the end of the glyph's own width reported apart so a caller can tell the glyph's extent from the gap after it
|
|
42
|
+
*/
|
|
43
|
+
function stepPastGlyph(gs, tm, glyph, codes, offset) {
|
|
44
|
+
const widthPer1000 = glyph?.widthPer1000 ?? 500;
|
|
45
|
+
const byteLength = glyph?.byteLengthConsumed ?? 1;
|
|
46
|
+
const isSingleByteSpace = byteLength === 1 && codes[offset] === 32;
|
|
47
|
+
const spacing = gs.charSpace + (isSingleByteSpace ? gs.wordSpace : 0);
|
|
48
|
+
const vertical = glyph?.vertical;
|
|
49
|
+
const widthAdvance = vertical === void 0 ? widthPer1000 / GLYPH_SPACE_PER_TEXT_SPACE_UNIT * gs.fontSizePt : vertical.displacementPer1000 / GLYPH_SPACE_PER_TEXT_SPACE_UNIT * gs.fontSizePt;
|
|
50
|
+
const along = (distance) => vertical === void 0 ? translationMatrix(distance * gs.horizScale, 0) : translationMatrix(0, distance);
|
|
51
|
+
return {
|
|
52
|
+
byteLength,
|
|
53
|
+
tm: multiplyMatrices(along(widthAdvance + spacing), tm),
|
|
54
|
+
widthEndTm: multiplyMatrices(along(widthAdvance), tm),
|
|
55
|
+
charSpaceAfter: gs.charSpace
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
export { ASCII_SPACE, FALLBACK_GLYPH_WIDTH_PER_1000, GLYPH_SPACE_PER_TEXT_SPACE_UNIT, computeTrm, defaultTextObjectState, initialTextParameters, stepPastGlyph };
|
package/dist/interpret.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_interpret = require("./interpret-
|
|
2
|
+
const require_interpret = require("./interpret-BkDxq0QA.cjs");
|
|
3
3
|
exports.interpretContentStream = require_interpret.interpretContentStream;
|
|
4
4
|
exports.numAt = require_interpret.numAt;
|
package/dist/interpret.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as numAt, t as interpretContentStream } from "./interpret-
|
|
1
|
+
import { n as numAt, t as interpretContentStream } from "./interpret-BtzX-LWm.js";
|
|
2
2
|
export { interpretContentStream, numAt };
|
|
@@ -11,7 +11,7 @@ import { NOOP_DIAGNOSTIC_SINK, PdfParseError } from "./diagnostics.js";
|
|
|
11
11
|
import { openPdfDocument } from "./document.js";
|
|
12
12
|
import { throwIfAborted } from "./util/abort.js";
|
|
13
13
|
import { createFontResolver } from "./font-read.js";
|
|
14
|
-
import { t as interpretContentStream } from "./interpret-
|
|
14
|
+
import { t as interpretContentStream } from "./interpret-BtzX-LWm.js";
|
|
15
15
|
import { normalizeRotation, pageRotationTransform } from "./read.js";
|
|
16
16
|
import { parseGlyf } from "./glyf.js";
|
|
17
17
|
import { decodeGlyphOutline } from "./glyf-contours.js";
|
|
@@ -11,7 +11,7 @@ const require_diagnostics = require("./diagnostics.cjs");
|
|
|
11
11
|
const require_document = require("./document.cjs");
|
|
12
12
|
const require_util_abort = require("./util/abort.cjs");
|
|
13
13
|
const require_font_read = require("./font-read.cjs");
|
|
14
|
-
const require_interpret = require("./interpret-
|
|
14
|
+
const require_interpret = require("./interpret-BkDxq0QA.cjs");
|
|
15
15
|
const require_read = require("./read.cjs");
|
|
16
16
|
const require_glyf = require("./glyf.cjs");
|
|
17
17
|
const require_glyf_contours = require("./glyf-contours.cjs");
|
package/dist/raster-text.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_raster = require("./raster-
|
|
2
|
+
const require_raster = require("./raster-De_zVqCu.cjs");
|
|
3
3
|
exports.drawGlyphOutline = require_raster.drawGlyphOutline;
|
|
4
4
|
exports.drawTextRun = require_raster.drawTextRun;
|
|
5
5
|
exports.glyphOutlineSubpaths = require_raster.glyphOutlineSubpaths;
|
package/dist/raster-text.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as drawTextRun, i as drawGlyphOutline, o as glyphOutlineSubpaths } from "./raster-
|
|
1
|
+
import { a as drawTextRun, i as drawGlyphOutline, o as glyphOutlineSubpaths } from "./raster-DCDcD7no.js";
|
|
2
2
|
export { drawGlyphOutline, drawTextRun, glyphOutlineSubpaths };
|
package/dist/raster.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_raster = require("./raster-
|
|
2
|
+
const require_raster = require("./raster-De_zVqCu.cjs");
|
|
3
3
|
exports.EXTENT_ZERO_EPSILON = require_raster.EXTENT_ZERO_EPSILON;
|
|
4
4
|
exports.flattenCubic = require_raster.flattenCubic;
|
|
5
5
|
exports.renderPdfPage = require_raster.renderPdfPage;
|
package/dist/raster.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as flattenCubic, r as renderPdfPage, t as EXTENT_ZERO_EPSILON } from "./raster-
|
|
1
|
+
import { n as flattenCubic, r as renderPdfPage, t as EXTENT_ZERO_EPSILON } from "./raster-DCDcD7no.js";
|
|
2
2
|
export { EXTENT_ZERO_EPSILON, flattenCubic, renderPdfPage };
|
package/dist/read.cjs
CHANGED
|
@@ -17,7 +17,7 @@ const require_diagnostics = require("./diagnostics.cjs");
|
|
|
17
17
|
const require_document = require("./document.cjs");
|
|
18
18
|
const require_util_abort = require("./util/abort.cjs");
|
|
19
19
|
const require_font_read = require("./font-read.cjs");
|
|
20
|
-
const require_interpret = require("./interpret-
|
|
20
|
+
const require_interpret = require("./interpret-BkDxq0QA.cjs");
|
|
21
21
|
const require_navigation = require("./navigation.cjs");
|
|
22
22
|
//#region src/read.ts
|
|
23
23
|
function skippedSurfacesOf(surfaces) {
|
package/dist/read.js
CHANGED
|
@@ -16,7 +16,7 @@ import { NOOP_DIAGNOSTIC_SINK, PdfPageSelectionError, PdfParseError } from "./di
|
|
|
16
16
|
import { openPdfDocument } from "./document.js";
|
|
17
17
|
import { throwIfAborted } from "./util/abort.js";
|
|
18
18
|
import { createFontResolver } from "./font-read.js";
|
|
19
|
-
import { t as interpretContentStream } from "./interpret-
|
|
19
|
+
import { t as interpretContentStream } from "./interpret-BtzX-LWm.js";
|
|
20
20
|
import { createDestinationRegistry, readOutline } from "./navigation.js";
|
|
21
21
|
//#region src/read.ts
|
|
22
22
|
function skippedSurfacesOf(surfaces) {
|
package/dist/text-group.cjs
CHANGED
|
@@ -63,6 +63,70 @@ function runGapPt(previous, next) {
|
|
|
63
63
|
if (previousWidthPt === void 0) return;
|
|
64
64
|
return project(next, rotationDeg).alongPt - (project(previous, rotationDeg).alongPt + previousWidthPt);
|
|
65
65
|
}
|
|
66
|
+
const SCRIPT_MAX_SIZE_RATIO = .75;
|
|
67
|
+
const SCRIPT_MIN_SHIFT_EM = .05;
|
|
68
|
+
const SCRIPT_MAX_SHIFT_EM = .5;
|
|
69
|
+
/**
|
|
70
|
+
* Whether `candidate` is a superscript or subscript of `base`: a run set smaller than `base`, with its baseline moved off `base`'s by more than positioning noise and by less than half `base`'s em, and touching it along the baseline (no wider than a word space apart, on either side).
|
|
71
|
+
*
|
|
72
|
+
* Runs at different angles or in different writing modes are never scripts of one another, and neither is a pair whose gap cannot be derived because the earlier of the two states no advance width.
|
|
73
|
+
* @param base - the run the candidate might decorate
|
|
74
|
+
* @param candidate - the run that might be its superscript or subscript
|
|
75
|
+
* @returns which side of `base`'s baseline `candidate` is set on, or undefined when it is not a script of `base`
|
|
76
|
+
*/
|
|
77
|
+
function scriptPositionOf(base, candidate) {
|
|
78
|
+
if (candidate.sizePt > SCRIPT_MAX_SIZE_RATIO * base.sizePt) return;
|
|
79
|
+
const rotationDeg = advanceAngleDeg(base);
|
|
80
|
+
if (rotationDeg !== advanceAngleDeg(candidate) || base.writingMode !== candidate.writingMode) return;
|
|
81
|
+
const baseProjected = project(base, rotationDeg);
|
|
82
|
+
const candidateProjected = project(candidate, rotationDeg);
|
|
83
|
+
const shiftPt = candidateProjected.acrossPt - baseProjected.acrossPt;
|
|
84
|
+
const magnitude = Math.abs(shiftPt);
|
|
85
|
+
if (magnitude < SCRIPT_MIN_SHIFT_EM * base.sizePt || magnitude > SCRIPT_MAX_SHIFT_EM * base.sizePt) return;
|
|
86
|
+
const gapPt = candidateProjected.alongPt >= baseProjected.alongPt ? runGapPt(base, candidate) : runGapPt(candidate, base);
|
|
87
|
+
if (gapPt === void 0 || gapPt <= -candidate.sizePt || gapPt >= .125 * candidate.sizePt) return;
|
|
88
|
+
return shiftPt > 0 ? "superscript" : "subscript";
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Moves every run that is a superscript or subscript of a run on another line onto that run's line.
|
|
92
|
+
*
|
|
93
|
+
* A same-baseline tolerance that keeps two lines of type apart cannot also hold every script on its base's line: a script may be raised or lowered by up to half its base's em ({@link scriptPositionOf}), which is more than two thirds of the script's own em once it is set small, so baseline clustering can put a unit's raised exponent on a line of its own. This returns each such run to the line its base is on. Every move is decided against the lines as given, before any is made, so a run that moves is never taken for another run's base and the outcome does not depend on the order of the lines.
|
|
94
|
+
* @param lines - lines already grouped by baseline, of whatever shape the caller keeps them in
|
|
95
|
+
* @param runsOf - the runs on one of those lines, in any order
|
|
96
|
+
* @returns one entry per line, in the order given: the line itself and its runs, less every run that moved off it and followed by every run that moved onto it; a line every run moved off has no runs left, and is kept so that the caller decides what an empty line means
|
|
97
|
+
*/
|
|
98
|
+
function attachScriptRuns(lines, runsOf) {
|
|
99
|
+
const runsByLine = lines.map((line) => runsOf(line));
|
|
100
|
+
const maxSizePt = Math.max(0, ...runsByLine.flatMap((runs) => runs.map((run) => run.sizePt)));
|
|
101
|
+
const reachPt = 1.5 * maxSizePt;
|
|
102
|
+
const placed = runsByLine.flatMap((runs, index) => runs.slice(0, 1).map((first) => {
|
|
103
|
+
const rotationDeg = advanceAngleDeg(first);
|
|
104
|
+
return {
|
|
105
|
+
index,
|
|
106
|
+
runs,
|
|
107
|
+
rotationDeg,
|
|
108
|
+
acrossPt: project(first, rotationDeg).acrossPt
|
|
109
|
+
};
|
|
110
|
+
}));
|
|
111
|
+
const moves = [];
|
|
112
|
+
runsByLine.forEach((runs, lineIndex) => {
|
|
113
|
+
for (const candidate of runs) {
|
|
114
|
+
if (candidate.sizePt > SCRIPT_MAX_SIZE_RATIO * maxSizePt) continue;
|
|
115
|
+
const rotationDeg = advanceAngleDeg(candidate);
|
|
116
|
+
const acrossPt = project(candidate, rotationDeg).acrossPt;
|
|
117
|
+
const target = placed.find((other) => other.index !== lineIndex && other.rotationDeg === rotationDeg && Math.abs(other.acrossPt - acrossPt) <= reachPt && other.runs.some((base) => scriptPositionOf(base, candidate) !== void 0));
|
|
118
|
+
if (target !== void 0) moves.push({
|
|
119
|
+
run: candidate,
|
|
120
|
+
to: target.index
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
const moved = new Set(moves.map((move) => move.run));
|
|
125
|
+
return lines.map((line, index) => ({
|
|
126
|
+
line,
|
|
127
|
+
runs: [...runsOf(line).filter((run) => !moved.has(run)), ...moves.filter((move) => move.to === index).map((move) => move.run)]
|
|
128
|
+
}));
|
|
129
|
+
}
|
|
66
130
|
function clusterIntoLines(entries, toleranceEm) {
|
|
67
131
|
const lines = [];
|
|
68
132
|
for (const entry of entries) {
|
|
@@ -209,8 +273,15 @@ function groupPdfTextRuns(runs, options = {}) {
|
|
|
209
273
|
const result = [];
|
|
210
274
|
const ordered = [...buckets.values()].sort((a, b) => a.rotationDeg - b.rotationDeg || Number(a.vertical) - Number(b.vertical));
|
|
211
275
|
for (const bucket of ordered) {
|
|
212
|
-
const
|
|
213
|
-
for (const line of
|
|
276
|
+
const attached = attachScriptRuns(clusterIntoLines(bucket.runs.map((run) => project(run, bucket.rotationDeg)).sort((a, b) => b.acrossPt - a.acrossPt || a.alongPt - b.alongPt), toleranceEm), (line) => line.entries.map((entry) => entry.run));
|
|
277
|
+
for (const { line: clusteredLine, runs: runsOnLine } of attached) {
|
|
278
|
+
const lineEntries = runsOnLine.map((run) => project(run, bucket.rotationDeg));
|
|
279
|
+
const anchor = runsOnLine.includes(clusteredLine.anchor.run) ? clusteredLine.anchor : lineEntries[0];
|
|
280
|
+
if (anchor === void 0) continue;
|
|
281
|
+
const line = {
|
|
282
|
+
anchor,
|
|
283
|
+
entries: lineEntries
|
|
284
|
+
};
|
|
214
285
|
line.entries.sort((a, b) => a.alongPt - b.alongPt);
|
|
215
286
|
result.push(buildLine(line, bucket.rotationDeg, bucket.vertical, wordGapEm, columnGapEm));
|
|
216
287
|
}
|
|
@@ -221,6 +292,8 @@ function groupPdfTextRuns(runs, options = {}) {
|
|
|
221
292
|
exports.DEFAULT_BASELINE_TOLERANCE_EM = DEFAULT_BASELINE_TOLERANCE_EM;
|
|
222
293
|
exports.DEFAULT_COLUMN_GAP_EM = DEFAULT_COLUMN_GAP_EM;
|
|
223
294
|
exports.DEFAULT_WORD_GAP_EM = DEFAULT_WORD_GAP_EM;
|
|
295
|
+
exports.attachScriptRuns = attachScriptRuns;
|
|
224
296
|
exports.groupPdfTextRuns = groupPdfTextRuns;
|
|
225
297
|
exports.runGapPt = runGapPt;
|
|
226
298
|
exports.runsShareBaseline = runsShareBaseline;
|
|
299
|
+
exports.scriptPositionOf = scriptPositionOf;
|
package/dist/text-group.d.cts
CHANGED
|
@@ -56,6 +56,29 @@ declare function runsShareBaseline(a: PdfTextRunGeometry, b: PdfTextRunGeometry,
|
|
|
56
56
|
* @returns the gap in points, or undefined when it cannot be derived
|
|
57
57
|
*/
|
|
58
58
|
declare function runGapPt(previous: PdfTextRunGeometry, next: PdfTextRunGeometry): number | undefined;
|
|
59
|
+
type PdfScriptPosition = "superscript" | "subscript";
|
|
60
|
+
/**
|
|
61
|
+
* Whether `candidate` is a superscript or subscript of `base`: a run set smaller than `base`, with its baseline moved off `base`'s by more than positioning noise and by less than half `base`'s em, and touching it along the baseline (no wider than a word space apart, on either side).
|
|
62
|
+
*
|
|
63
|
+
* Runs at different angles or in different writing modes are never scripts of one another, and neither is a pair whose gap cannot be derived because the earlier of the two states no advance width.
|
|
64
|
+
* @param base - the run the candidate might decorate
|
|
65
|
+
* @param candidate - the run that might be its superscript or subscript
|
|
66
|
+
* @returns which side of `base`'s baseline `candidate` is set on, or undefined when it is not a script of `base`
|
|
67
|
+
*/
|
|
68
|
+
declare function scriptPositionOf(base: PdfTextRunGeometry, candidate: PdfTextRunGeometry): PdfScriptPosition | undefined;
|
|
69
|
+
interface PdfLineWithScripts<TLine, TRun extends PdfTextRunGeometry> {
|
|
70
|
+
readonly line: TLine;
|
|
71
|
+
readonly runs: TRun[];
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Moves every run that is a superscript or subscript of a run on another line onto that run's line.
|
|
75
|
+
*
|
|
76
|
+
* A same-baseline tolerance that keeps two lines of type apart cannot also hold every script on its base's line: a script may be raised or lowered by up to half its base's em ({@link scriptPositionOf}), which is more than two thirds of the script's own em once it is set small, so baseline clustering can put a unit's raised exponent on a line of its own. This returns each such run to the line its base is on. Every move is decided against the lines as given, before any is made, so a run that moves is never taken for another run's base and the outcome does not depend on the order of the lines.
|
|
77
|
+
* @param lines - lines already grouped by baseline, of whatever shape the caller keeps them in
|
|
78
|
+
* @param runsOf - the runs on one of those lines, in any order
|
|
79
|
+
* @returns one entry per line, in the order given: the line itself and its runs, less every run that moved off it and followed by every run that moved onto it; a line every run moved off has no runs left, and is kept so that the caller decides what an empty line means
|
|
80
|
+
*/
|
|
81
|
+
declare function attachScriptRuns<TLine, TRun extends PdfTextRunGeometry>(lines: readonly TLine[], runsOf: (line: TLine) => readonly TRun[]): PdfLineWithScripts<TLine, TRun>[];
|
|
59
82
|
/**
|
|
60
83
|
* Groups positioned PDF text runs into lines of words.
|
|
61
84
|
*
|
|
@@ -72,4 +95,4 @@ declare function runGapPt(previous: PdfTextRunGeometry, next: PdfTextRunGeometry
|
|
|
72
95
|
*/
|
|
73
96
|
declare function groupPdfTextRuns<TRun extends PdfTextRunGeometry>(runs: readonly TRun[], options?: PdfTextGroupingOptions): PdfTextLine<TRun>[];
|
|
74
97
|
//#endregion
|
|
75
|
-
export { DEFAULT_BASELINE_TOLERANCE_EM, DEFAULT_COLUMN_GAP_EM, DEFAULT_WORD_GAP_EM, PdfTextBox, PdfTextGroupingOptions, PdfTextLine, PdfTextRunGeometry, PdfTextWord, PdfWordSeparator, groupPdfTextRuns, runGapPt, runsShareBaseline };
|
|
98
|
+
export { DEFAULT_BASELINE_TOLERANCE_EM, DEFAULT_COLUMN_GAP_EM, DEFAULT_WORD_GAP_EM, PdfLineWithScripts, PdfScriptPosition, PdfTextBox, PdfTextGroupingOptions, PdfTextLine, PdfTextRunGeometry, PdfTextWord, PdfWordSeparator, attachScriptRuns, groupPdfTextRuns, runGapPt, runsShareBaseline, scriptPositionOf };
|
package/dist/text-group.d.ts
CHANGED
|
@@ -56,6 +56,29 @@ declare function runsShareBaseline(a: PdfTextRunGeometry, b: PdfTextRunGeometry,
|
|
|
56
56
|
* @returns the gap in points, or undefined when it cannot be derived
|
|
57
57
|
*/
|
|
58
58
|
declare function runGapPt(previous: PdfTextRunGeometry, next: PdfTextRunGeometry): number | undefined;
|
|
59
|
+
type PdfScriptPosition = "superscript" | "subscript";
|
|
60
|
+
/**
|
|
61
|
+
* Whether `candidate` is a superscript or subscript of `base`: a run set smaller than `base`, with its baseline moved off `base`'s by more than positioning noise and by less than half `base`'s em, and touching it along the baseline (no wider than a word space apart, on either side).
|
|
62
|
+
*
|
|
63
|
+
* Runs at different angles or in different writing modes are never scripts of one another, and neither is a pair whose gap cannot be derived because the earlier of the two states no advance width.
|
|
64
|
+
* @param base - the run the candidate might decorate
|
|
65
|
+
* @param candidate - the run that might be its superscript or subscript
|
|
66
|
+
* @returns which side of `base`'s baseline `candidate` is set on, or undefined when it is not a script of `base`
|
|
67
|
+
*/
|
|
68
|
+
declare function scriptPositionOf(base: PdfTextRunGeometry, candidate: PdfTextRunGeometry): PdfScriptPosition | undefined;
|
|
69
|
+
interface PdfLineWithScripts<TLine, TRun extends PdfTextRunGeometry> {
|
|
70
|
+
readonly line: TLine;
|
|
71
|
+
readonly runs: TRun[];
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Moves every run that is a superscript or subscript of a run on another line onto that run's line.
|
|
75
|
+
*
|
|
76
|
+
* A same-baseline tolerance that keeps two lines of type apart cannot also hold every script on its base's line: a script may be raised or lowered by up to half its base's em ({@link scriptPositionOf}), which is more than two thirds of the script's own em once it is set small, so baseline clustering can put a unit's raised exponent on a line of its own. This returns each such run to the line its base is on. Every move is decided against the lines as given, before any is made, so a run that moves is never taken for another run's base and the outcome does not depend on the order of the lines.
|
|
77
|
+
* @param lines - lines already grouped by baseline, of whatever shape the caller keeps them in
|
|
78
|
+
* @param runsOf - the runs on one of those lines, in any order
|
|
79
|
+
* @returns one entry per line, in the order given: the line itself and its runs, less every run that moved off it and followed by every run that moved onto it; a line every run moved off has no runs left, and is kept so that the caller decides what an empty line means
|
|
80
|
+
*/
|
|
81
|
+
declare function attachScriptRuns<TLine, TRun extends PdfTextRunGeometry>(lines: readonly TLine[], runsOf: (line: TLine) => readonly TRun[]): PdfLineWithScripts<TLine, TRun>[];
|
|
59
82
|
/**
|
|
60
83
|
* Groups positioned PDF text runs into lines of words.
|
|
61
84
|
*
|
|
@@ -72,4 +95,4 @@ declare function runGapPt(previous: PdfTextRunGeometry, next: PdfTextRunGeometry
|
|
|
72
95
|
*/
|
|
73
96
|
declare function groupPdfTextRuns<TRun extends PdfTextRunGeometry>(runs: readonly TRun[], options?: PdfTextGroupingOptions): PdfTextLine<TRun>[];
|
|
74
97
|
//#endregion
|
|
75
|
-
export { DEFAULT_BASELINE_TOLERANCE_EM, DEFAULT_COLUMN_GAP_EM, DEFAULT_WORD_GAP_EM, PdfTextBox, PdfTextGroupingOptions, PdfTextLine, PdfTextRunGeometry, PdfTextWord, PdfWordSeparator, groupPdfTextRuns, runGapPt, runsShareBaseline };
|
|
98
|
+
export { DEFAULT_BASELINE_TOLERANCE_EM, DEFAULT_COLUMN_GAP_EM, DEFAULT_WORD_GAP_EM, PdfLineWithScripts, PdfScriptPosition, PdfTextBox, PdfTextGroupingOptions, PdfTextLine, PdfTextRunGeometry, PdfTextWord, PdfWordSeparator, attachScriptRuns, groupPdfTextRuns, runGapPt, runsShareBaseline, scriptPositionOf };
|
package/dist/text-group.js
CHANGED
|
@@ -62,6 +62,70 @@ function runGapPt(previous, next) {
|
|
|
62
62
|
if (previousWidthPt === void 0) return;
|
|
63
63
|
return project(next, rotationDeg).alongPt - (project(previous, rotationDeg).alongPt + previousWidthPt);
|
|
64
64
|
}
|
|
65
|
+
const SCRIPT_MAX_SIZE_RATIO = .75;
|
|
66
|
+
const SCRIPT_MIN_SHIFT_EM = .05;
|
|
67
|
+
const SCRIPT_MAX_SHIFT_EM = .5;
|
|
68
|
+
/**
|
|
69
|
+
* Whether `candidate` is a superscript or subscript of `base`: a run set smaller than `base`, with its baseline moved off `base`'s by more than positioning noise and by less than half `base`'s em, and touching it along the baseline (no wider than a word space apart, on either side).
|
|
70
|
+
*
|
|
71
|
+
* Runs at different angles or in different writing modes are never scripts of one another, and neither is a pair whose gap cannot be derived because the earlier of the two states no advance width.
|
|
72
|
+
* @param base - the run the candidate might decorate
|
|
73
|
+
* @param candidate - the run that might be its superscript or subscript
|
|
74
|
+
* @returns which side of `base`'s baseline `candidate` is set on, or undefined when it is not a script of `base`
|
|
75
|
+
*/
|
|
76
|
+
function scriptPositionOf(base, candidate) {
|
|
77
|
+
if (candidate.sizePt > SCRIPT_MAX_SIZE_RATIO * base.sizePt) return;
|
|
78
|
+
const rotationDeg = advanceAngleDeg(base);
|
|
79
|
+
if (rotationDeg !== advanceAngleDeg(candidate) || base.writingMode !== candidate.writingMode) return;
|
|
80
|
+
const baseProjected = project(base, rotationDeg);
|
|
81
|
+
const candidateProjected = project(candidate, rotationDeg);
|
|
82
|
+
const shiftPt = candidateProjected.acrossPt - baseProjected.acrossPt;
|
|
83
|
+
const magnitude = Math.abs(shiftPt);
|
|
84
|
+
if (magnitude < SCRIPT_MIN_SHIFT_EM * base.sizePt || magnitude > SCRIPT_MAX_SHIFT_EM * base.sizePt) return;
|
|
85
|
+
const gapPt = candidateProjected.alongPt >= baseProjected.alongPt ? runGapPt(base, candidate) : runGapPt(candidate, base);
|
|
86
|
+
if (gapPt === void 0 || gapPt <= -candidate.sizePt || gapPt >= .125 * candidate.sizePt) return;
|
|
87
|
+
return shiftPt > 0 ? "superscript" : "subscript";
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Moves every run that is a superscript or subscript of a run on another line onto that run's line.
|
|
91
|
+
*
|
|
92
|
+
* A same-baseline tolerance that keeps two lines of type apart cannot also hold every script on its base's line: a script may be raised or lowered by up to half its base's em ({@link scriptPositionOf}), which is more than two thirds of the script's own em once it is set small, so baseline clustering can put a unit's raised exponent on a line of its own. This returns each such run to the line its base is on. Every move is decided against the lines as given, before any is made, so a run that moves is never taken for another run's base and the outcome does not depend on the order of the lines.
|
|
93
|
+
* @param lines - lines already grouped by baseline, of whatever shape the caller keeps them in
|
|
94
|
+
* @param runsOf - the runs on one of those lines, in any order
|
|
95
|
+
* @returns one entry per line, in the order given: the line itself and its runs, less every run that moved off it and followed by every run that moved onto it; a line every run moved off has no runs left, and is kept so that the caller decides what an empty line means
|
|
96
|
+
*/
|
|
97
|
+
function attachScriptRuns(lines, runsOf) {
|
|
98
|
+
const runsByLine = lines.map((line) => runsOf(line));
|
|
99
|
+
const maxSizePt = Math.max(0, ...runsByLine.flatMap((runs) => runs.map((run) => run.sizePt)));
|
|
100
|
+
const reachPt = 1.5 * maxSizePt;
|
|
101
|
+
const placed = runsByLine.flatMap((runs, index) => runs.slice(0, 1).map((first) => {
|
|
102
|
+
const rotationDeg = advanceAngleDeg(first);
|
|
103
|
+
return {
|
|
104
|
+
index,
|
|
105
|
+
runs,
|
|
106
|
+
rotationDeg,
|
|
107
|
+
acrossPt: project(first, rotationDeg).acrossPt
|
|
108
|
+
};
|
|
109
|
+
}));
|
|
110
|
+
const moves = [];
|
|
111
|
+
runsByLine.forEach((runs, lineIndex) => {
|
|
112
|
+
for (const candidate of runs) {
|
|
113
|
+
if (candidate.sizePt > SCRIPT_MAX_SIZE_RATIO * maxSizePt) continue;
|
|
114
|
+
const rotationDeg = advanceAngleDeg(candidate);
|
|
115
|
+
const acrossPt = project(candidate, rotationDeg).acrossPt;
|
|
116
|
+
const target = placed.find((other) => other.index !== lineIndex && other.rotationDeg === rotationDeg && Math.abs(other.acrossPt - acrossPt) <= reachPt && other.runs.some((base) => scriptPositionOf(base, candidate) !== void 0));
|
|
117
|
+
if (target !== void 0) moves.push({
|
|
118
|
+
run: candidate,
|
|
119
|
+
to: target.index
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
const moved = new Set(moves.map((move) => move.run));
|
|
124
|
+
return lines.map((line, index) => ({
|
|
125
|
+
line,
|
|
126
|
+
runs: [...runsOf(line).filter((run) => !moved.has(run)), ...moves.filter((move) => move.to === index).map((move) => move.run)]
|
|
127
|
+
}));
|
|
128
|
+
}
|
|
65
129
|
function clusterIntoLines(entries, toleranceEm) {
|
|
66
130
|
const lines = [];
|
|
67
131
|
for (const entry of entries) {
|
|
@@ -208,8 +272,15 @@ function groupPdfTextRuns(runs, options = {}) {
|
|
|
208
272
|
const result = [];
|
|
209
273
|
const ordered = [...buckets.values()].sort((a, b) => a.rotationDeg - b.rotationDeg || Number(a.vertical) - Number(b.vertical));
|
|
210
274
|
for (const bucket of ordered) {
|
|
211
|
-
const
|
|
212
|
-
for (const line of
|
|
275
|
+
const attached = attachScriptRuns(clusterIntoLines(bucket.runs.map((run) => project(run, bucket.rotationDeg)).sort((a, b) => b.acrossPt - a.acrossPt || a.alongPt - b.alongPt), toleranceEm), (line) => line.entries.map((entry) => entry.run));
|
|
276
|
+
for (const { line: clusteredLine, runs: runsOnLine } of attached) {
|
|
277
|
+
const lineEntries = runsOnLine.map((run) => project(run, bucket.rotationDeg));
|
|
278
|
+
const anchor = runsOnLine.includes(clusteredLine.anchor.run) ? clusteredLine.anchor : lineEntries[0];
|
|
279
|
+
if (anchor === void 0) continue;
|
|
280
|
+
const line = {
|
|
281
|
+
anchor,
|
|
282
|
+
entries: lineEntries
|
|
283
|
+
};
|
|
213
284
|
line.entries.sort((a, b) => a.alongPt - b.alongPt);
|
|
214
285
|
result.push(buildLine(line, bucket.rotationDeg, bucket.vertical, wordGapEm, columnGapEm));
|
|
215
286
|
}
|
|
@@ -217,4 +288,4 @@ function groupPdfTextRuns(runs, options = {}) {
|
|
|
217
288
|
return result;
|
|
218
289
|
}
|
|
219
290
|
//#endregion
|
|
220
|
-
export { DEFAULT_BASELINE_TOLERANCE_EM, DEFAULT_COLUMN_GAP_EM, DEFAULT_WORD_GAP_EM, groupPdfTextRuns, runGapPt, runsShareBaseline };
|
|
291
|
+
export { DEFAULT_BASELINE_TOLERANCE_EM, DEFAULT_COLUMN_GAP_EM, DEFAULT_WORD_GAP_EM, attachScriptRuns, groupPdfTextRuns, runGapPt, runsShareBaseline, scriptPositionOf };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pdf-codec",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.7.1",
|
|
4
4
|
"description": "Hand-written, dependency-minimal PDF codec: parses arbitrary real-world PDFs and generates new ones, built on its own codec-owned LayoutDocument item model and Zod 4 codecs.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|