@awacloud/pdf 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +609 -0
- package/LICENSE +661 -0
- package/NOTICE +77 -0
- package/README.md +363 -2
- package/dist/build/index.js +21 -0
- package/dist/build/pdf-full-rw.js +10972 -0
- package/dist/build/pdf-full-rw.meta.json +105 -0
- package/dist/build/pdf-full-rw.min.js +53 -0
- package/dist/build/pdf-full.js +6078 -0
- package/dist/build/pdf-full.meta.json +90 -0
- package/dist/build/pdf-full.min.js +32 -0
- package/dist/build/pdf-large-rw.js +10367 -0
- package/dist/build/pdf-large-rw.meta.json +99 -0
- package/dist/build/pdf-large-rw.min.js +53 -0
- package/dist/build/pdf-large.js +5473 -0
- package/dist/build/pdf-large.meta.json +84 -0
- package/dist/build/pdf-large.min.js +32 -0
- package/dist/build/pdf-legacy-rw.js +12402 -0
- package/dist/build/pdf-legacy-rw.meta.json +110 -0
- package/dist/build/pdf-legacy-rw.min.js +53 -0
- package/dist/build/pdf-legacy.js +7508 -0
- package/dist/build/pdf-legacy.meta.json +95 -0
- package/dist/build/pdf-legacy.min.js +32 -0
- package/dist/build/pdf-rw.js +7578 -0
- package/dist/build/pdf-rw.meta.json +77 -0
- package/dist/build/pdf-rw.min.js +53 -0
- package/dist/build/pdf.js +2684 -0
- package/dist/build/pdf.meta.json +62 -0
- package/dist/build/pdf.min.js +32 -0
- package/dist/standalone/pdf-full-rw.js +16798 -0
- package/dist/standalone/pdf-full-rw.meta.json +78 -0
- package/dist/standalone/pdf-full-rw.min.js +56 -0
- package/dist/standalone/pdf-full.js +11904 -0
- package/dist/standalone/pdf-full.meta.json +63 -0
- package/dist/standalone/pdf-full.min.js +35 -0
- package/dist/standalone/pdf-large-rw.js +16193 -0
- package/dist/standalone/pdf-large-rw.meta.json +72 -0
- package/dist/standalone/pdf-large-rw.min.js +56 -0
- package/dist/standalone/pdf-large.js +11299 -0
- package/dist/standalone/pdf-large.meta.json +57 -0
- package/dist/standalone/pdf-large.min.js +35 -0
- package/dist/standalone/pdf-legacy-rw.js +18228 -0
- package/dist/standalone/pdf-legacy-rw.meta.json +83 -0
- package/dist/standalone/pdf-legacy-rw.min.js +56 -0
- package/dist/standalone/pdf-legacy.js +13334 -0
- package/dist/standalone/pdf-legacy.meta.json +68 -0
- package/dist/standalone/pdf-legacy.min.js +35 -0
- package/dist/standalone/pdf-rw.js +13404 -0
- package/dist/standalone/pdf-rw.meta.json +50 -0
- package/dist/standalone/pdf-rw.min.js +56 -0
- package/dist/standalone/pdf.js +8510 -0
- package/dist/standalone/pdf.meta.json +35 -0
- package/dist/standalone/pdf.min.js +35 -0
- package/docs/README.md +53 -0
- package/docs/api/README.md +38 -0
- package/docs/api/_shared/README.md +91 -0
- package/docs/api/action/README.md +29 -0
- package/docs/api/action/action.md +81 -0
- package/docs/api/action/goTo.md +66 -0
- package/docs/api/action/launch.md +58 -0
- package/docs/api/action/named.md +55 -0
- package/docs/api/action/uri.md +54 -0
- package/docs/api/annot/README.md +53 -0
- package/docs/api/annot/annot.md +114 -0
- package/docs/api/annot/fileAttach.md +53 -0
- package/docs/api/annot/freeText.md +68 -0
- package/docs/api/annot/ink.md +69 -0
- package/docs/api/annot/link.md +74 -0
- package/docs/api/annot/markup.md +83 -0
- package/docs/api/annot/popup.md +52 -0
- package/docs/api/annot/projection.md +56 -0
- package/docs/api/annot/redact.md +67 -0
- package/docs/api/annot/square.md +87 -0
- package/docs/api/annot/stamp.md +54 -0
- package/docs/api/annot/text.md +69 -0
- package/docs/api/annot/widget.md +69 -0
- package/docs/api/associatedFiles/README.md +9 -0
- package/docs/api/associatedFiles/associatedFiles.md +78 -0
- package/docs/api/bundles/README.md +68 -0
- package/docs/api/bundles/dist-matrix.md +165 -0
- package/docs/api/bundles/pdf-full.md +148 -0
- package/docs/api/bundles/pdf-large.md +144 -0
- package/docs/api/bundles/pdf-legacy.md +169 -0
- package/docs/api/content/README.md +29 -0
- package/docs/api/content/color.md +99 -0
- package/docs/api/content/graphics.md +114 -0
- package/docs/api/content/images.md +124 -0
- package/docs/api/content/ops.md +100 -0
- package/docs/api/content/stream.md +107 -0
- package/docs/api/content/text.md +98 -0
- package/docs/api/crypto/README.md +29 -0
- package/docs/api/crypto/aesGcm.md +72 -0
- package/docs/api/crypto/permissions.md +79 -0
- package/docs/api/crypto/security.md +98 -0
- package/docs/api/crypto/standardV4.md +104 -0
- package/docs/api/crypto/standardV5.md +84 -0
- package/docs/api/crypto/standardV6.md +93 -0
- package/docs/api/destination/README.md +9 -0
- package/docs/api/destination/destination.md +79 -0
- package/docs/api/document/README.md +29 -0
- package/docs/api/document/builder.md +281 -0
- package/docs/api/document/catalog.md +98 -0
- package/docs/api/document/document.md +187 -0
- package/docs/api/document/encryptedWriter.md +149 -0
- package/docs/api/document/incrementalWriter.md +148 -0
- package/docs/api/document/page.md +99 -0
- package/docs/api/document/pages.md +82 -0
- package/docs/api/document/resources.md +102 -0
- package/docs/api/document/writer.md +157 -0
- package/docs/api/document/xrefStreamWriter.md +122 -0
- package/docs/api/embedded/README.md +13 -0
- package/docs/api/embedded/collection.md +80 -0
- package/docs/api/embedded/embeddedFile.md +86 -0
- package/docs/api/embedded/fileSpec.md +87 -0
- package/docs/api/errors.md +110 -0
- package/docs/api/extra/3d-richmedia.md +76 -0
- package/docs/api/extra/README.md +99 -0
- package/docs/api/extra/annot-extended.md +71 -0
- package/docs/api/extra/associated-files.md +70 -0
- package/docs/api/extra/ccitt-fax-decoder.md +74 -0
- package/docs/api/extra/color-spaces-extended.md +72 -0
- package/docs/api/extra/content-ops-extended.md +82 -0
- package/docs/api/extra/document-parts.md +69 -0
- package/docs/api/extra/embedded-files-portfolio.md +87 -0
- package/docs/api/extra/font-cid-typed.md +77 -0
- package/docs/api/extra/font-color-tagging.md +76 -0
- package/docs/api/extra/form-actions-extended.md +75 -0
- package/docs/api/extra/info-dict-deprecated.md +72 -0
- package/docs/api/extra/jbig2-read.md +80 -0
- package/docs/api/extra/legacy-deprecated-annots.md +89 -0
- package/docs/api/extra/legacy-deprecated-filters.md +78 -0
- package/docs/api/extra/legacy-rc4-read.md +74 -0
- package/docs/api/extra/legacy-xfa-read.md +65 -0
- package/docs/api/extra/linearization-write.md +71 -0
- package/docs/api/extra/misc.md +93 -0
- package/docs/api/extra/optional-content-extended.md +83 -0
- package/docs/api/extra/pdf-a-output-intent.md +65 -0
- package/docs/api/extra/pdf-sandbox.md +76 -0
- package/docs/api/extra/pdf-ua-tagged.md +63 -0
- package/docs/api/extra/pdf-x-prepress.md +65 -0
- package/docs/api/extra/redaction-iso32005.md +65 -0
- package/docs/api/extra/shading-typed.md +73 -0
- package/docs/api/extra/sig-aes-gcm.md +69 -0
- package/docs/api/extra/sig-pades.md +103 -0
- package/docs/api/extra/tagged-pdf-typed.md +78 -0
- package/docs/api/extra/transparency-typed.md +74 -0
- package/docs/api/extra/well-tagged-pdf.md +61 -0
- package/docs/api/extra/xmp-extended.md +65 -0
- package/docs/api/font/README.md +25 -0
- package/docs/api/font/embed.md +157 -0
- package/docs/api/font/encoding.md +95 -0
- package/docs/api/font/font.md +97 -0
- package/docs/api/font/type3.md +89 -0
- package/docs/api/form/README.md +35 -0
- package/docs/api/form/acroform.md +88 -0
- package/docs/api/form/appearance.md +87 -0
- package/docs/api/form/button.md +97 -0
- package/docs/api/form/choice.md +96 -0
- package/docs/api/form/fieldTree.md +93 -0
- package/docs/api/form/signature.md +90 -0
- package/docs/api/form/text.md +88 -0
- package/docs/api/linearization/README.md +11 -0
- package/docs/api/linearization/linearization.md +81 -0
- package/docs/api/main.md +116 -0
- package/docs/api/metadata/README.md +10 -0
- package/docs/api/metadata/info.md +70 -0
- package/docs/api/metadata/xmp.md +62 -0
- package/docs/api/ocg/README.md +23 -0
- package/docs/api/ocg/config.md +95 -0
- package/docs/api/ocg/ocg.md +77 -0
- package/docs/api/outline/README.md +11 -0
- package/docs/api/outline/outline.md +107 -0
- package/docs/api/pdf.md +152 -0
- package/docs/api/prepress/README.md +10 -0
- package/docs/api/prepress/outputIntent.md +79 -0
- package/docs/api/prepress/pageBoundary.md +75 -0
- package/docs/api/sig/README.md +32 -0
- package/docs/api/sig/byteRange.md +120 -0
- package/docs/api/sig/certChain.md +84 -0
- package/docs/api/sig/dss.md +111 -0
- package/docs/api/sig/oids.md +76 -0
- package/docs/api/sig/sha1.md +72 -0
- package/docs/api/sig/sign.md +317 -0
- package/docs/api/sig/signature.md +178 -0
- package/docs/api/sig/timestamp.md +84 -0
- package/docs/api/syntax/README.md +29 -0
- package/docs/api/syntax/crossRefStream.md +115 -0
- package/docs/api/syntax/filters/README.md +50 -0
- package/docs/api/syntax/filters/ascii85.md +76 -0
- package/docs/api/syntax/filters/asciiHex.md +73 -0
- package/docs/api/syntax/filters/dispatch.md +125 -0
- package/docs/api/syntax/filters/flate.md +134 -0
- package/docs/api/syntax/filters/runLength.md +78 -0
- package/docs/api/syntax/objStream.md +88 -0
- package/docs/api/syntax/parser-obj.md +97 -0
- package/docs/api/syntax/parser.md +151 -0
- package/docs/api/syntax/serializer.md +109 -0
- package/docs/api/syntax/tokenizer.md +104 -0
- package/docs/api/syntax/trailer.md +85 -0
- package/docs/api/syntax/xref.md +139 -0
- package/docs/api/tagged/README.md +25 -0
- package/docs/api/tagged/classMap.md +67 -0
- package/docs/api/tagged/markedContent.md +62 -0
- package/docs/api/tagged/parentTree.md +67 -0
- package/docs/api/tagged/roleMap.md +67 -0
- package/docs/api/tagged/structElement.md +76 -0
- package/docs/api/tagged/structTree.md +75 -0
- package/docs/guide/coverage.md +113 -0
- package/docs/guide/crypto.md +121 -0
- package/docs/guide/extending.md +76 -0
- package/docs/guide/getting-started.md +75 -0
- package/docs/guide/legacy-1.7.md +42 -0
- package/docs/guide/pades-integration.md +579 -0
- package/docs/guide/read-pdf.md +89 -0
- package/package.json +97 -4
- package/src/_shared/index.js +179 -0
- package/src/action/action.js +119 -0
- package/src/action/goTo.js +89 -0
- package/src/action/launch.js +61 -0
- package/src/action/named.js +54 -0
- package/src/action/uri.js +51 -0
- package/src/annot/annot.js +212 -0
- package/src/annot/fileAttach.js +55 -0
- package/src/annot/freeText.js +82 -0
- package/src/annot/ink.js +77 -0
- package/src/annot/link.js +77 -0
- package/src/annot/markup.js +91 -0
- package/src/annot/popup.js +53 -0
- package/src/annot/projection.js +52 -0
- package/src/annot/redact.js +87 -0
- package/src/annot/square.js +132 -0
- package/src/annot/stamp.js +48 -0
- package/src/annot/text.js +54 -0
- package/src/annot/widget.js +61 -0
- package/src/associatedFiles/associatedFiles.js +86 -0
- package/src/bundles/pdf-full.js +91 -0
- package/src/bundles/pdf-large.js +81 -0
- package/src/bundles/pdf-legacy.js +107 -0
- package/src/content/color.js +114 -0
- package/src/content/graphics.js +192 -0
- package/src/content/images.js +160 -0
- package/src/content/ops.js +137 -0
- package/src/content/stream.js +154 -0
- package/src/content/text.js +125 -0
- package/src/crypto/aesGcm.js +123 -0
- package/src/crypto/permissions.js +112 -0
- package/src/crypto/security.js +327 -0
- package/src/crypto/standardV4.js +443 -0
- package/src/crypto/standardV5.js +306 -0
- package/src/crypto/standardV6.js +334 -0
- package/src/destination/destination.js +183 -0
- package/src/document/builder.js +618 -0
- package/src/document/catalog.js +100 -0
- package/src/document/document.js +472 -0
- package/src/document/encryptedWriter.js +554 -0
- package/src/document/incrementalWriter.js +514 -0
- package/src/document/page.js +131 -0
- package/src/document/pages.js +103 -0
- package/src/document/resources.js +146 -0
- package/src/document/writer.js +211 -0
- package/src/document/xrefStreamWriter.js +353 -0
- package/src/embedded/collection.js +102 -0
- package/src/embedded/embeddedFile.js +99 -0
- package/src/embedded/fileSpec.js +137 -0
- package/src/errors.js +78 -0
- package/src/extra/3d-richmedia.js +171 -0
- package/src/extra/annot-extended.js +200 -0
- package/src/extra/associated-files.js +131 -0
- package/src/extra/ccitt-fax-decoder.js +776 -0
- package/src/extra/color-spaces-extended.js +196 -0
- package/src/extra/content-ops-extended.js +153 -0
- package/src/extra/document-parts.js +149 -0
- package/src/extra/embedded-files-portfolio.js +234 -0
- package/src/extra/font-cid-typed.js +185 -0
- package/src/extra/font-color-tagging.js +144 -0
- package/src/extra/form-actions-extended.js +196 -0
- package/src/extra/info-dict-deprecated.js +137 -0
- package/src/extra/jbig2-read.js +169 -0
- package/src/extra/legacy-deprecated-annots.js +198 -0
- package/src/extra/legacy-deprecated-filters.js +167 -0
- package/src/extra/legacy-rc4-read.js +235 -0
- package/src/extra/legacy-xfa-read.js +104 -0
- package/src/extra/linearization-write.js +97 -0
- package/src/extra/misc.js +217 -0
- package/src/extra/optional-content-extended.js +142 -0
- package/src/extra/pdf-a-output-intent.js +112 -0
- package/src/extra/pdf-sandbox.js +88 -0
- package/src/extra/pdf-ua-tagged.js +116 -0
- package/src/extra/pdf-x-prepress.js +114 -0
- package/src/extra/redaction-iso32005.js +136 -0
- package/src/extra/shading-typed.js +222 -0
- package/src/extra/sig-aes-gcm.js +135 -0
- package/src/extra/sig-pades.js +242 -0
- package/src/extra/tagged-pdf-typed.js +203 -0
- package/src/extra/transparency-typed.js +135 -0
- package/src/extra/well-tagged-pdf.js +138 -0
- package/src/extra/xmp-extended.js +190 -0
- package/src/font/embed.js +480 -0
- package/src/font/encoding.js +92 -0
- package/src/font/font.js +101 -0
- package/src/font/type3.js +75 -0
- package/src/form/acroform.js +94 -0
- package/src/form/appearance.js +90 -0
- package/src/form/button.js +105 -0
- package/src/form/choice.js +152 -0
- package/src/form/fieldTree.js +120 -0
- package/src/form/signature.js +100 -0
- package/src/form/text.js +101 -0
- package/src/linearization/linearization.js +107 -0
- package/src/main.js +411 -0
- package/src/metadata/info.js +87 -0
- package/src/metadata/xmp.js +62 -0
- package/src/ocg/config.js +156 -0
- package/src/ocg/ocg.js +124 -0
- package/src/outline/outline.js +157 -0
- package/src/pdf.js +133 -0
- package/src/prepress/outputIntent.js +118 -0
- package/src/prepress/pageBoundary.js +108 -0
- package/src/sig/byteRange.js +306 -0
- package/src/sig/certChain.js +247 -0
- package/src/sig/dss.js +317 -0
- package/src/sig/oids.js +157 -0
- package/src/sig/sha1.js +142 -0
- package/src/sig/sign.js +1899 -0
- package/src/sig/signature.js +1441 -0
- package/src/sig/timestamp.js +236 -0
- package/src/syntax/crossRefStream.js +133 -0
- package/src/syntax/filters/ascii85.js +122 -0
- package/src/syntax/filters/asciiHex.js +83 -0
- package/src/syntax/filters/dispatch.js +176 -0
- package/src/syntax/filters/flate.js +316 -0
- package/src/syntax/filters/runLength.js +96 -0
- package/src/syntax/objStream.js +99 -0
- package/src/syntax/parser-obj.js +52 -0
- package/src/syntax/parser.js +321 -0
- package/src/syntax/serializer.js +221 -0
- package/src/syntax/tokenizer.js +290 -0
- package/src/syntax/trailer.js +76 -0
- package/src/syntax/xref.js +341 -0
- package/src/tagged/classMap.js +81 -0
- package/src/tagged/markedContent.js +123 -0
- package/src/tagged/parentTree.js +126 -0
- package/src/tagged/roleMap.js +107 -0
- package/src/tagged/structElement.js +138 -0
- package/src/tagged/structTree.js +94 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// Copyright (c) 2026 AwaCloud SAS
|
|
2
|
+
// Author: Matthieu Bouilloux
|
|
3
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
4
|
+
// Dual-licensed; see the NOTICE file for licensing and any additional terms.
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @fileoverview `@awacloud/pdf/bundles/pdf-large` — extended PDF coverage bundle.
|
|
8
|
+
*
|
|
9
|
+
* Pure fw factory descriptor. Declares the core `pdf` orchestrator and
|
|
10
|
+
* the P0+P1 opt-in extras as dependencies. The runtime resolves every
|
|
11
|
+
* dependency transitively and passes the already-constructed instances
|
|
12
|
+
* to the factory, which wires them into the `pdf` core via `pdf.use(...)`
|
|
13
|
+
* and returns the enriched instance.
|
|
14
|
+
*
|
|
15
|
+
* Consumption is exclusively declarative — register the descriptor in a
|
|
16
|
+
* `ModuleRuntime` and call `runtime.resolve('pdfLargeBundle')`.
|
|
17
|
+
*
|
|
18
|
+
* For 100% PDF 2.0 strict coverage (adds P2 phases + misc + deprecated
|
|
19
|
+
* info dict), use `pdf-full`. For PDF 1.7 read + 1.7→2.0 conversion,
|
|
20
|
+
* use `pdf-legacy`.
|
|
21
|
+
*
|
|
22
|
+
* @module pdf/bundles/pdf-large
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import { pdf } from '../pdf.js';
|
|
26
|
+
import { pdfContentOpsExtended } from '../extra/content-ops-extended.js';
|
|
27
|
+
import { pdfFontCidTyped } from '../extra/font-cid-typed.js';
|
|
28
|
+
import { pdfFontColorTagging } from '../extra/font-color-tagging.js';
|
|
29
|
+
import { pdfTaggedPdfTyped } from '../extra/tagged-pdf-typed.js';
|
|
30
|
+
import { pdfAnnotExtended } from '../extra/annot-extended.js';
|
|
31
|
+
import { pdfAOutputIntent } from '../extra/pdf-a-output-intent.js';
|
|
32
|
+
import { pdfUaTagged } from '../extra/pdf-ua-tagged.js';
|
|
33
|
+
import { pdfFormActionsExtended } from '../extra/form-actions-extended.js';
|
|
34
|
+
import { pdfColorSpacesExtended } from '../extra/color-spaces-extended.js';
|
|
35
|
+
import { pdfShadingTyped } from '../extra/shading-typed.js';
|
|
36
|
+
import { pdfTransparencyTyped } from '../extra/transparency-typed.js';
|
|
37
|
+
import { pdfSigPades } from '../extra/sig-pades.js';
|
|
38
|
+
import { pdfSigAesGcm } from '../extra/sig-aes-gcm.js';
|
|
39
|
+
import { pdfDocumentParts } from '../extra/document-parts.js';
|
|
40
|
+
import { pdfRedactionIso32005 } from '../extra/redaction-iso32005.js';
|
|
41
|
+
import { pdfXPrepress } from '../extra/pdf-x-prepress.js';
|
|
42
|
+
import { pdfWellTagged } from '../extra/well-tagged-pdf.js';
|
|
43
|
+
import { pdfOptionalContentExtended } from '../extra/optional-content-extended.js';
|
|
44
|
+
import { pdfEmbeddedFilesPortfolio } from '../extra/embedded-files-portfolio.js';
|
|
45
|
+
import { pdfAssociatedFiles2 } from '../extra/associated-files.js';
|
|
46
|
+
import { pdfXmpExtended } from '../extra/xmp-extended.js';
|
|
47
|
+
|
|
48
|
+
export const pdfLargeBundle = {
|
|
49
|
+
name: 'pdfLargeBundle',
|
|
50
|
+
dependencies: [
|
|
51
|
+
'pdf',
|
|
52
|
+
'pdfContentOpsExtended', 'pdfFontCidTyped', 'pdfFontColorTagging',
|
|
53
|
+
'pdfTaggedPdfTyped', 'pdfAnnotExtended', 'pdfAOutputIntent', 'pdfUaTagged',
|
|
54
|
+
'pdfFormActionsExtended', 'pdfColorSpacesExtended', 'pdfShadingTyped',
|
|
55
|
+
'pdfTransparencyTyped', 'pdfSigPades', 'pdfSigAesGcm', 'pdfDocumentParts',
|
|
56
|
+
'pdfRedactionIso32005', 'pdfXPrepress', 'pdfWellTagged',
|
|
57
|
+
'pdfOptionalContentExtended', 'pdfEmbeddedFilesPortfolio',
|
|
58
|
+
'pdfAssociatedFiles2', 'pdfXmpExtended'
|
|
59
|
+
],
|
|
60
|
+
deps: [pdf, pdfContentOpsExtended, pdfFontCidTyped, pdfFontColorTagging, pdfTaggedPdfTyped, pdfAnnotExtended, pdfAOutputIntent, pdfUaTagged, pdfFormActionsExtended, pdfColorSpacesExtended, pdfShadingTyped, pdfTransparencyTyped, pdfSigPades, pdfSigAesGcm, pdfDocumentParts, pdfRedactionIso32005, pdfXPrepress, pdfWellTagged, pdfOptionalContentExtended, pdfEmbeddedFilesPortfolio, pdfAssociatedFiles2, pdfXmpExtended],
|
|
61
|
+
factory(pdf, ...instances) {
|
|
62
|
+
const names = [
|
|
63
|
+
'pdfContentOpsExtended', 'pdfFontCidTyped', 'pdfFontColorTagging',
|
|
64
|
+
'pdfTaggedPdfTyped', 'pdfAnnotExtended', 'pdfAOutputIntent', 'pdfUaTagged',
|
|
65
|
+
'pdfFormActionsExtended', 'pdfColorSpacesExtended', 'pdfShadingTyped',
|
|
66
|
+
'pdfTransparencyTyped', 'pdfSigPades', 'pdfSigAesGcm', 'pdfDocumentParts',
|
|
67
|
+
'pdfRedactionIso32005', 'pdfXPrepress', 'pdfWellTagged',
|
|
68
|
+
'pdfOptionalContentExtended', 'pdfEmbeddedFilesPortfolio',
|
|
69
|
+
'pdfAssociatedFiles2', 'pdfXmpExtended'
|
|
70
|
+
];
|
|
71
|
+
for (let i = 0; i < names.length; i++) {
|
|
72
|
+
const name = names[i];
|
|
73
|
+
const inst = instances[i];
|
|
74
|
+
pdf.use({
|
|
75
|
+
name,
|
|
76
|
+
register() { return { [name]: inst }; }
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
return pdf;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// Copyright (c) 2026 AwaCloud SAS
|
|
2
|
+
// Author: Matthieu Bouilloux
|
|
3
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
4
|
+
// Dual-licensed; see the NOTICE file for licensing and any additional terms.
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @fileoverview `@awacloud/pdf/bundles/pdf-legacy` — full + PDF 1.7 legacy read.
|
|
8
|
+
*
|
|
9
|
+
* Pure fw factory descriptor. Declares the core `pdf` orchestrator,
|
|
10
|
+
* every PDF 2.0 strict extra, and the
|
|
11
|
+
* `legacy-*` extras as dependencies. The runtime resolves every
|
|
12
|
+
* dependency transitively and passes the already-constructed instances
|
|
13
|
+
* to the factory, which wires them into the `pdf` core via
|
|
14
|
+
* `pdf.use(...)` and returns the enriched instance.
|
|
15
|
+
*
|
|
16
|
+
* Consumption is exclusively declarative — register the descriptor in a
|
|
17
|
+
* `ModuleRuntime` and call `runtime.resolve('pdfLegacyBundle')`.
|
|
18
|
+
*
|
|
19
|
+
* Adds the `legacy-*` extras on top of `pdf-full`:
|
|
20
|
+
*
|
|
21
|
+
* - `legacy-xfa-read` — accepts /XFA on read, surfaces as opaque XML.
|
|
22
|
+
* - `legacy-rc4-read` — RC4 v2/v3 password validation + stream decrypt.
|
|
23
|
+
* - `legacy-deprecated-filters` — LZWDecode (via fw) + CCITTFax + DCT/JPX passthrough.
|
|
24
|
+
* - `legacy-deprecated-annots` — full Sound/Movie/Screen typing.
|
|
25
|
+
* - `info-dict-deprecated` — Info dict lint (deprecated PDF 2.0).
|
|
26
|
+
*
|
|
27
|
+
* Write never converts: `pdf.write` emits a `%PDF-2.0` header and `pdfWriter`
|
|
28
|
+
* re-emits the model's objects as they were read, legacy content included.
|
|
29
|
+
*
|
|
30
|
+
* @module pdf/bundles/pdf-legacy
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import { pdf } from '../pdf.js';
|
|
34
|
+
import { pdfContentOpsExtended } from '../extra/content-ops-extended.js';
|
|
35
|
+
import { pdfFontCidTyped } from '../extra/font-cid-typed.js';
|
|
36
|
+
import { pdfFontColorTagging } from '../extra/font-color-tagging.js';
|
|
37
|
+
import { pdfTaggedPdfTyped } from '../extra/tagged-pdf-typed.js';
|
|
38
|
+
import { pdfAnnotExtended } from '../extra/annot-extended.js';
|
|
39
|
+
import { pdfAOutputIntent } from '../extra/pdf-a-output-intent.js';
|
|
40
|
+
import { pdfUaTagged } from '../extra/pdf-ua-tagged.js';
|
|
41
|
+
import { pdfFormActionsExtended } from '../extra/form-actions-extended.js';
|
|
42
|
+
import { pdfColorSpacesExtended } from '../extra/color-spaces-extended.js';
|
|
43
|
+
import { pdfShadingTyped } from '../extra/shading-typed.js';
|
|
44
|
+
import { pdfTransparencyTyped } from '../extra/transparency-typed.js';
|
|
45
|
+
import { pdfSigPades } from '../extra/sig-pades.js';
|
|
46
|
+
import { pdfSigAesGcm } from '../extra/sig-aes-gcm.js';
|
|
47
|
+
import { pdfDocumentParts } from '../extra/document-parts.js';
|
|
48
|
+
import { pdfRedactionIso32005 } from '../extra/redaction-iso32005.js';
|
|
49
|
+
import { pdfXPrepress } from '../extra/pdf-x-prepress.js';
|
|
50
|
+
import { pdfWellTagged } from '../extra/well-tagged-pdf.js';
|
|
51
|
+
import { pdfOptionalContentExtended } from '../extra/optional-content-extended.js';
|
|
52
|
+
import { pdfEmbeddedFilesPortfolio } from '../extra/embedded-files-portfolio.js';
|
|
53
|
+
import { pdfAssociatedFiles2 } from '../extra/associated-files.js';
|
|
54
|
+
import { pdfXmpExtended } from '../extra/xmp-extended.js';
|
|
55
|
+
import { pdfLinearizationWrite } from '../extra/linearization-write.js';
|
|
56
|
+
import { pdf3dRichMedia } from '../extra/3d-richmedia.js';
|
|
57
|
+
import { pdfJbig2Read } from '../extra/jbig2-read.js';
|
|
58
|
+
import { pdfMisc } from '../extra/misc.js';
|
|
59
|
+
import { pdfInfoDictDeprecated } from '../extra/info-dict-deprecated.js';
|
|
60
|
+
import { pdfSandbox } from '../extra/pdf-sandbox.js';
|
|
61
|
+
import { pdfLegacyXfaRead } from '../extra/legacy-xfa-read.js';
|
|
62
|
+
import { pdfLegacyRc4Read } from '../extra/legacy-rc4-read.js';
|
|
63
|
+
import { pdfLegacyDeprecatedFilters } from '../extra/legacy-deprecated-filters.js';
|
|
64
|
+
import { pdfLegacyDeprecatedAnnots } from '../extra/legacy-deprecated-annots.js';
|
|
65
|
+
|
|
66
|
+
export const pdfLegacyBundle = {
|
|
67
|
+
name: 'pdfLegacyBundle',
|
|
68
|
+
dependencies: [
|
|
69
|
+
'pdf',
|
|
70
|
+
'pdfContentOpsExtended', 'pdfFontCidTyped', 'pdfFontColorTagging',
|
|
71
|
+
'pdfTaggedPdfTyped', 'pdfAnnotExtended', 'pdfAOutputIntent', 'pdfUaTagged',
|
|
72
|
+
'pdfFormActionsExtended', 'pdfColorSpacesExtended', 'pdfShadingTyped',
|
|
73
|
+
'pdfTransparencyTyped', 'pdfSigPades', 'pdfSigAesGcm', 'pdfDocumentParts',
|
|
74
|
+
'pdfRedactionIso32005', 'pdfXPrepress', 'pdfWellTagged',
|
|
75
|
+
'pdfOptionalContentExtended', 'pdfEmbeddedFilesPortfolio',
|
|
76
|
+
'pdfAssociatedFiles2', 'pdfXmpExtended',
|
|
77
|
+
'pdfLinearizationWrite', 'pdf3dRichMedia', 'pdfJbig2Read', 'pdfMisc',
|
|
78
|
+
'pdfInfoDictDeprecated', 'pdfSandbox',
|
|
79
|
+
'pdfLegacyXfaRead', 'pdfLegacyRc4Read', 'pdfLegacyDeprecatedFilters',
|
|
80
|
+
'pdfLegacyDeprecatedAnnots'
|
|
81
|
+
],
|
|
82
|
+
deps: [pdf, pdfContentOpsExtended, pdfFontCidTyped, pdfFontColorTagging, pdfTaggedPdfTyped, pdfAnnotExtended, pdfAOutputIntent, pdfUaTagged, pdfFormActionsExtended, pdfColorSpacesExtended, pdfShadingTyped, pdfTransparencyTyped, pdfSigPades, pdfSigAesGcm, pdfDocumentParts, pdfRedactionIso32005, pdfXPrepress, pdfWellTagged, pdfOptionalContentExtended, pdfEmbeddedFilesPortfolio, pdfAssociatedFiles2, pdfXmpExtended, pdfLinearizationWrite, pdf3dRichMedia, pdfJbig2Read, pdfMisc, pdfInfoDictDeprecated, pdfSandbox, pdfLegacyXfaRead, pdfLegacyRc4Read, pdfLegacyDeprecatedFilters, pdfLegacyDeprecatedAnnots],
|
|
83
|
+
factory(pdf, ...instances) {
|
|
84
|
+
const names = [
|
|
85
|
+
'pdfContentOpsExtended', 'pdfFontCidTyped', 'pdfFontColorTagging',
|
|
86
|
+
'pdfTaggedPdfTyped', 'pdfAnnotExtended', 'pdfAOutputIntent', 'pdfUaTagged',
|
|
87
|
+
'pdfFormActionsExtended', 'pdfColorSpacesExtended', 'pdfShadingTyped',
|
|
88
|
+
'pdfTransparencyTyped', 'pdfSigPades', 'pdfSigAesGcm', 'pdfDocumentParts',
|
|
89
|
+
'pdfRedactionIso32005', 'pdfXPrepress', 'pdfWellTagged',
|
|
90
|
+
'pdfOptionalContentExtended', 'pdfEmbeddedFilesPortfolio',
|
|
91
|
+
'pdfAssociatedFiles2', 'pdfXmpExtended',
|
|
92
|
+
'pdfLinearizationWrite', 'pdf3dRichMedia', 'pdfJbig2Read', 'pdfMisc',
|
|
93
|
+
'pdfInfoDictDeprecated', 'pdfSandbox',
|
|
94
|
+
'pdfLegacyXfaRead', 'pdfLegacyRc4Read', 'pdfLegacyDeprecatedFilters',
|
|
95
|
+
'pdfLegacyDeprecatedAnnots'
|
|
96
|
+
];
|
|
97
|
+
for (let i = 0; i < names.length; i++) {
|
|
98
|
+
const name = names[i];
|
|
99
|
+
const inst = instances[i];
|
|
100
|
+
pdf.use({
|
|
101
|
+
name,
|
|
102
|
+
register() { return { [name]: inst }; }
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return pdf;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// Copyright (c) 2026 AwaCloud SAS
|
|
2
|
+
// Author: Matthieu Bouilloux
|
|
3
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
4
|
+
// Dual-licensed; see the NOTICE file for licensing and any additional terms.
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @fileoverview Color operators + DeviceGray/RGB/CMYK helpers per
|
|
8
|
+
* ISO 32000-2:2020 §8.6.
|
|
9
|
+
*
|
|
10
|
+
* Applies `g`/`G`/`rg`/`RG`/`k`/`K`/`cs`/`CS`/`sc`/`SC`/`scn`/`SCN`
|
|
11
|
+
* operators to the graphics state. Returns the typed color record
|
|
12
|
+
* `{ space: string, components: number[] }`.
|
|
13
|
+
*
|
|
14
|
+
* Patterns and Separation/DeviceN spaces accept a trailing `/PatternName`
|
|
15
|
+
* argument via `scn`/`SCN` — captured in the record as
|
|
16
|
+
* `{ space, components, pattern? }`.
|
|
17
|
+
*
|
|
18
|
+
* @module pdf/content/color
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Module factory — worker-safe, self-contained.
|
|
23
|
+
*/
|
|
24
|
+
import { pdfErrors } from '../errors.js';
|
|
25
|
+
|
|
26
|
+
export const pdfColor = {
|
|
27
|
+
name: 'pdfColor',
|
|
28
|
+
dependencies: ['pdfErrors'],
|
|
29
|
+
deps: [pdfErrors],
|
|
30
|
+
factory(errors) {
|
|
31
|
+
const { ContractError } = errors;
|
|
32
|
+
|
|
33
|
+
function nameArg(args, i) {
|
|
34
|
+
const a = args[i];
|
|
35
|
+
if (!a || a.type !== 'name') {
|
|
36
|
+
throw new ContractError('pdf/color/bad-name',
|
|
37
|
+
`expected name arg at position ${i}`,
|
|
38
|
+
{ context: { index: i, kind: a && a.type } });
|
|
39
|
+
}
|
|
40
|
+
return a.value;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function nums(args, n) {
|
|
44
|
+
if (args.length < n) {
|
|
45
|
+
throw new ContractError('pdf/color/short-args',
|
|
46
|
+
`expected ${n} numeric args, got ${args.length}`);
|
|
47
|
+
}
|
|
48
|
+
const out = new Array(n);
|
|
49
|
+
for (let i = 0; i < n; i++) {
|
|
50
|
+
const a = args[i];
|
|
51
|
+
if (!a || (a.type !== 'int' && a.type !== 'real')) {
|
|
52
|
+
throw new ContractError('pdf/color/bad-num',
|
|
53
|
+
`arg ${i} is not numeric`,
|
|
54
|
+
{ context: { index: i, kind: a && a.type } });
|
|
55
|
+
}
|
|
56
|
+
out[i] = a.value;
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function numArgs(args) {
|
|
62
|
+
return args
|
|
63
|
+
.filter(a => a && (a.type === 'int' || a.type === 'real'))
|
|
64
|
+
.map(a => a.value);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function deviceDefault(spaceName) {
|
|
68
|
+
if (spaceName === 'DeviceGray') return [0];
|
|
69
|
+
if (spaceName === 'DeviceRGB') return [0, 0, 0];
|
|
70
|
+
if (spaceName === 'DeviceCMYK') return [0, 0, 0, 1];
|
|
71
|
+
return [];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function applyScn(gstate, slot, args) {
|
|
75
|
+
if (args.length === 0) return;
|
|
76
|
+
const last = args[args.length - 1];
|
|
77
|
+
if (last && last.type === 'name') {
|
|
78
|
+
gstate[slot].components = numArgs(args.slice(0, -1));
|
|
79
|
+
gstate[slot].pattern = last.value;
|
|
80
|
+
} else {
|
|
81
|
+
gstate[slot].components = numArgs(args);
|
|
82
|
+
delete gstate[slot].pattern;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Apply a color operator to a gstate.
|
|
88
|
+
*
|
|
89
|
+
* @param {object} gstate
|
|
90
|
+
* @param {{ op: string, args: object[] }} ops
|
|
91
|
+
*/
|
|
92
|
+
function applyColorOp(gstate, ops) {
|
|
93
|
+
switch (ops.op) {
|
|
94
|
+
case 'g': gstate.fillColor = { space: 'DeviceGray', components: nums(ops.args, 1) }; break;
|
|
95
|
+
case 'G': gstate.strokeColor = { space: 'DeviceGray', components: nums(ops.args, 1) }; break;
|
|
96
|
+
case 'rg': gstate.fillColor = { space: 'DeviceRGB', components: nums(ops.args, 3) }; break;
|
|
97
|
+
case 'RG': gstate.strokeColor = { space: 'DeviceRGB', components: nums(ops.args, 3) }; break;
|
|
98
|
+
case 'k': gstate.fillColor = { space: 'DeviceCMYK', components: nums(ops.args, 4) }; break;
|
|
99
|
+
case 'K': gstate.strokeColor = { space: 'DeviceCMYK', components: nums(ops.args, 4) }; break;
|
|
100
|
+
case 'cs': gstate.fillColor = { space: nameArg(ops.args, 0), components: deviceDefault(nameArg(ops.args, 0)) }; break;
|
|
101
|
+
case 'CS': gstate.strokeColor = { space: nameArg(ops.args, 0), components: deviceDefault(nameArg(ops.args, 0)) }; break;
|
|
102
|
+
case 'sc': gstate.fillColor.components = numArgs(ops.args); break;
|
|
103
|
+
case 'SC': gstate.strokeColor.components = numArgs(ops.args); break;
|
|
104
|
+
case 'scn': applyScn(gstate, 'fillColor', ops.args); break;
|
|
105
|
+
case 'SCN': applyScn(gstate, 'strokeColor', ops.args); break;
|
|
106
|
+
default:
|
|
107
|
+
throw new ContractError('pdf/color/unknown-op',
|
|
108
|
+
`applyColorOp called with non-color op "${ops.op}"`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return { applyColorOp };
|
|
113
|
+
}
|
|
114
|
+
};
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
// Copyright (c) 2026 AwaCloud SAS
|
|
2
|
+
// Author: Matthieu Bouilloux
|
|
3
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
4
|
+
// Dual-licensed; see the NOTICE file for licensing and any additional terms.
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @fileoverview Graphics state stack per ISO 32000-2:2020 §8.4.
|
|
8
|
+
*
|
|
9
|
+
* Implements a saveable / restorable state for a content-stream
|
|
10
|
+
* interpreter. The set of state parameters covered here is the
|
|
11
|
+
* **device-independent** subset (§8.4.1, Table 53) that L2 needs:
|
|
12
|
+
*
|
|
13
|
+
* - CTM (current transformation matrix, 2x3 affine)
|
|
14
|
+
* - line width, cap, join, miter limit, dash pattern
|
|
15
|
+
* - rendering intent, flatness tolerance
|
|
16
|
+
* - text state nested via `text.js`
|
|
17
|
+
* - color state (stroking + non-stroking) — see `color.js`
|
|
18
|
+
*
|
|
19
|
+
* Output is **not** a renderer; it is a faithful model of the
|
|
20
|
+
* `gstate` chain that downstream layers (tagged-PDF MCID tracking,
|
|
21
|
+
* text extraction, redaction) consume.
|
|
22
|
+
*
|
|
23
|
+
* @module pdf/content/graphics
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Module factory — worker-safe, self-contained.
|
|
28
|
+
*/
|
|
29
|
+
import { pdfErrors } from '../errors.js';
|
|
30
|
+
|
|
31
|
+
export const pdfGraphics = {
|
|
32
|
+
name: 'pdfGraphics',
|
|
33
|
+
dependencies: ['pdfErrors'],
|
|
34
|
+
deps: [pdfErrors],
|
|
35
|
+
factory(errors) {
|
|
36
|
+
const { ContractError } = errors;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Construct an identity initial graphics state.
|
|
40
|
+
*/
|
|
41
|
+
function initialGState() {
|
|
42
|
+
return {
|
|
43
|
+
ctm: [1, 0, 0, 1, 0, 0],
|
|
44
|
+
lineWidth: 1.0,
|
|
45
|
+
lineCap: 0, // butt
|
|
46
|
+
lineJoin: 0, // miter
|
|
47
|
+
miterLimit: 10.0,
|
|
48
|
+
dash: { array: [], phase: 0 },
|
|
49
|
+
renderingIntent: 'RelativeColorimetric',
|
|
50
|
+
flatness: 1.0,
|
|
51
|
+
text: {
|
|
52
|
+
charSpace: 0,
|
|
53
|
+
wordSpace: 0,
|
|
54
|
+
scale: 100,
|
|
55
|
+
leading: 0,
|
|
56
|
+
font: null,
|
|
57
|
+
fontSize: 0,
|
|
58
|
+
renderMode: 0,
|
|
59
|
+
rise: 0
|
|
60
|
+
},
|
|
61
|
+
strokeColor: { space: 'DeviceGray', components: [0] },
|
|
62
|
+
fillColor: { space: 'DeviceGray', components: [0] }
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Multiply two 2x3 affine matrices (PDF row-vector convention).
|
|
68
|
+
*/
|
|
69
|
+
function mulCtm(a, b) {
|
|
70
|
+
return [
|
|
71
|
+
a[0] * b[0] + a[1] * b[2],
|
|
72
|
+
a[0] * b[1] + a[1] * b[3],
|
|
73
|
+
a[2] * b[0] + a[3] * b[2],
|
|
74
|
+
a[2] * b[1] + a[3] * b[3],
|
|
75
|
+
a[4] * b[0] + a[5] * b[2] + b[4],
|
|
76
|
+
a[4] * b[1] + a[5] * b[3] + b[5]
|
|
77
|
+
];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Closure-based stack constructor — avoids `this.` references so
|
|
81
|
+
// `factory.toString()` stays transportable across the worker
|
|
82
|
+
// boundary (integration test contract). Returned objects support
|
|
83
|
+
// `instanceof GStateStack` via the shared prototype path.
|
|
84
|
+
function GStateStack() {
|
|
85
|
+
const stack = [initialGState()];
|
|
86
|
+
const api = Object.create(GStateStack.prototype);
|
|
87
|
+
api.current = function () { return stack[stack.length - 1]; };
|
|
88
|
+
api.save = function () {
|
|
89
|
+
const cur = stack[stack.length - 1];
|
|
90
|
+
stack.push({
|
|
91
|
+
...cur,
|
|
92
|
+
ctm: cur.ctm.slice(),
|
|
93
|
+
dash: { array: cur.dash.array.slice(), phase: cur.dash.phase },
|
|
94
|
+
text: { ...cur.text },
|
|
95
|
+
strokeColor: { space: cur.strokeColor.space, components: cur.strokeColor.components.slice() },
|
|
96
|
+
fillColor: { space: cur.fillColor.space, components: cur.fillColor.components.slice() }
|
|
97
|
+
});
|
|
98
|
+
};
|
|
99
|
+
api.restore = function () {
|
|
100
|
+
if (stack.length <= 1) {
|
|
101
|
+
throw new ContractError('pdf/gstate/unbalanced-Q',
|
|
102
|
+
'Q without matching q');
|
|
103
|
+
}
|
|
104
|
+
stack.pop();
|
|
105
|
+
};
|
|
106
|
+
api.depth = function () { return stack.length; };
|
|
107
|
+
api.concatCtm = function (matrix) {
|
|
108
|
+
if (!Array.isArray(matrix) || matrix.length !== 6) {
|
|
109
|
+
throw new ContractError('pdf/gstate/bad-cm',
|
|
110
|
+
'cm matrix must have 6 elements');
|
|
111
|
+
}
|
|
112
|
+
const cur = stack[stack.length - 1];
|
|
113
|
+
cur.ctm = mulCtm(matrix, cur.ctm);
|
|
114
|
+
};
|
|
115
|
+
return api;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function numArg(args, i) {
|
|
119
|
+
const a = args[i];
|
|
120
|
+
if (!a || (a.type !== 'int' && a.type !== 'real')) {
|
|
121
|
+
throw new ContractError('pdf/gstate/bad-arg-type',
|
|
122
|
+
`expected numeric argument at position ${i}`,
|
|
123
|
+
{ context: { index: i, kind: a && a.type } });
|
|
124
|
+
}
|
|
125
|
+
return a.value;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function numArgs(args, n) {
|
|
129
|
+
const out = new Array(n);
|
|
130
|
+
for (let i = 0; i < n; i++) out[i] = numArg(args, i);
|
|
131
|
+
return out;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function nameArg(args, i) {
|
|
135
|
+
const a = args[i];
|
|
136
|
+
if (!a || a.type !== 'name') {
|
|
137
|
+
throw new ContractError('pdf/gstate/bad-name-arg',
|
|
138
|
+
`expected name argument at position ${i}`,
|
|
139
|
+
{ context: { index: i, kind: a && a.type } });
|
|
140
|
+
}
|
|
141
|
+
return a.value;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function arrArg(args, i) {
|
|
145
|
+
const a = args[i];
|
|
146
|
+
if (!a || a.type !== 'array') return [];
|
|
147
|
+
return a.items
|
|
148
|
+
.filter(x => x.type === 'int' || x.type === 'real')
|
|
149
|
+
.map(x => x.value);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Apply an op + args pair to a `GStateStack` instance.
|
|
154
|
+
*/
|
|
155
|
+
function applyOp(stack, ops, handlers) {
|
|
156
|
+
const cur = stack.current();
|
|
157
|
+
switch (ops.op) {
|
|
158
|
+
case 'q': stack.save(); break;
|
|
159
|
+
case 'Q': stack.restore(); break;
|
|
160
|
+
case 'cm':
|
|
161
|
+
stack.concatCtm(numArgs(ops.args, 6));
|
|
162
|
+
break;
|
|
163
|
+
case 'w': cur.lineWidth = numArg(ops.args, 0); break;
|
|
164
|
+
case 'J': cur.lineCap = numArg(ops.args, 0) | 0; break;
|
|
165
|
+
case 'j': cur.lineJoin = numArg(ops.args, 0) | 0; break;
|
|
166
|
+
case 'M': cur.miterLimit = numArg(ops.args, 0); break;
|
|
167
|
+
case 'd':
|
|
168
|
+
cur.dash = {
|
|
169
|
+
array: arrArg(ops.args, 0),
|
|
170
|
+
phase: numArg(ops.args, 1)
|
|
171
|
+
};
|
|
172
|
+
break;
|
|
173
|
+
case 'ri': cur.renderingIntent = nameArg(ops.args, 0); break;
|
|
174
|
+
case 'i': cur.flatness = numArg(ops.args, 0); break;
|
|
175
|
+
default:
|
|
176
|
+
if (handlers && typeof handlers.unhandled === 'function') {
|
|
177
|
+
handlers.unhandled(ops, stack);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function createStack() { return new GStateStack(); }
|
|
183
|
+
|
|
184
|
+
return {
|
|
185
|
+
GStateStack,
|
|
186
|
+
createStack,
|
|
187
|
+
applyOp,
|
|
188
|
+
initialGState,
|
|
189
|
+
mulCtm
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
};
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// Copyright (c) 2026 AwaCloud SAS
|
|
2
|
+
// Author: Matthieu Bouilloux
|
|
3
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
4
|
+
// Dual-licensed; see the NOTICE file for licensing and any additional terms.
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @fileoverview Image XObject + Form XObject typing per
|
|
8
|
+
* ISO 32000-2:2020 §8.9.
|
|
9
|
+
*
|
|
10
|
+
* Image XObject (`/Subtype /Image`) carries Width, Height, ColorSpace,
|
|
11
|
+
* BitsPerComponent, Filter, DecodeParms, Decode, ImageMask, Mask,
|
|
12
|
+
* SMask, Interpolate, Intent, Metadata, OC.
|
|
13
|
+
*
|
|
14
|
+
* Form XObject (`/Subtype /Form`) carries FormType, BBox, Matrix,
|
|
15
|
+
* Resources, Group, Ref, Metadata, PieceInfo, LastModified,
|
|
16
|
+
* StructParent(s), OPI, OC, Name (deprecated).
|
|
17
|
+
*
|
|
18
|
+
* Both are streams whose raw bytes pass through unchanged at L2 ; the
|
|
19
|
+
* caller (renderer) decodes `Filter` on demand via
|
|
20
|
+
* `pdfFilterDispatch`.
|
|
21
|
+
*
|
|
22
|
+
* @module pdf/content/images
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Module factory — worker-safe, self-contained.
|
|
27
|
+
*/
|
|
28
|
+
import { pdfErrors } from '../errors.js';
|
|
29
|
+
import { pdfParser } from '../syntax/parser.js';
|
|
30
|
+
|
|
31
|
+
export const pdfImages = {
|
|
32
|
+
name: 'pdfImages',
|
|
33
|
+
dependencies: ['pdfErrors', 'pdfParser'],
|
|
34
|
+
deps: [pdfErrors, pdfParser],
|
|
35
|
+
factory(errors, parserMod) {
|
|
36
|
+
const { ParseError } = errors;
|
|
37
|
+
const isType = (parserMod && parserMod.isType)
|
|
38
|
+
|| ((v, kind) => !!(v && v.type === kind));
|
|
39
|
+
|
|
40
|
+
function intOrZero(entry, label) {
|
|
41
|
+
if (!entry || entry.type !== 'int') {
|
|
42
|
+
if (label === 'Width' || label === 'Height') {
|
|
43
|
+
throw new ParseError('pdf/image/missing-dim',
|
|
44
|
+
`Image XObject missing required /${label}`);
|
|
45
|
+
}
|
|
46
|
+
return 0;
|
|
47
|
+
}
|
|
48
|
+
return entry.value;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function toBox(v) {
|
|
52
|
+
if (!v || v.type !== 'array' || v.items.length !== 4) return null;
|
|
53
|
+
const r = new Array(4);
|
|
54
|
+
for (let i = 0; i < 4; i++) {
|
|
55
|
+
const it = v.items[i];
|
|
56
|
+
if (!it || (it.type !== 'int' && it.type !== 'real')) return null;
|
|
57
|
+
r[i] = it.value;
|
|
58
|
+
}
|
|
59
|
+
return r;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function toMatrix(v) {
|
|
63
|
+
if (!v || v.type !== 'array' || v.items.length !== 6) {
|
|
64
|
+
return [1, 0, 0, 1, 0, 0];
|
|
65
|
+
}
|
|
66
|
+
const r = new Array(6);
|
|
67
|
+
for (let i = 0; i < 6; i++) {
|
|
68
|
+
const it = v.items[i];
|
|
69
|
+
if (!it || (it.type !== 'int' && it.type !== 'real')) {
|
|
70
|
+
return [1, 0, 0, 1, 0, 0];
|
|
71
|
+
}
|
|
72
|
+
r[i] = it.value;
|
|
73
|
+
}
|
|
74
|
+
return r;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function typeImageXObject(stream) {
|
|
78
|
+
if (!isType(stream, 'stream')) {
|
|
79
|
+
throw new ParseError('pdf/image/not-stream',
|
|
80
|
+
'Image XObject must be a stream object');
|
|
81
|
+
}
|
|
82
|
+
const e = stream.dict.entries;
|
|
83
|
+
if (e.Subtype && (e.Subtype.type !== 'name' || e.Subtype.value !== 'Image')) {
|
|
84
|
+
throw new ParseError('pdf/image/wrong-subtype',
|
|
85
|
+
'Image XObject /Subtype must be /Image',
|
|
86
|
+
{ context: { actual: e.Subtype.value } });
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
kind: 'image',
|
|
90
|
+
width: intOrZero(e.Width, 'Width'),
|
|
91
|
+
height: intOrZero(e.Height, 'Height'),
|
|
92
|
+
bitsPerComponent: e.BitsPerComponent && e.BitsPerComponent.type === 'int'
|
|
93
|
+
? e.BitsPerComponent.value : null,
|
|
94
|
+
colorSpace: e.ColorSpace || null,
|
|
95
|
+
filter: e.Filter || null,
|
|
96
|
+
decodeParms: e.DecodeParms || null,
|
|
97
|
+
decode: e.Decode || null,
|
|
98
|
+
imageMask: e.ImageMask && e.ImageMask.type === 'bool' ? e.ImageMask.value : false,
|
|
99
|
+
mask: e.Mask || null,
|
|
100
|
+
sMask: e.SMask || null,
|
|
101
|
+
interpolate: e.Interpolate && e.Interpolate.type === 'bool' ? e.Interpolate.value : false,
|
|
102
|
+
intent: e.Intent && e.Intent.type === 'name' ? e.Intent.value : null,
|
|
103
|
+
metadata: e.Metadata || null,
|
|
104
|
+
raw: stream.raw,
|
|
105
|
+
dict: stream.dict
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function typeFormXObject(stream) {
|
|
110
|
+
if (!isType(stream, 'stream')) {
|
|
111
|
+
throw new ParseError('pdf/form-xobj/not-stream',
|
|
112
|
+
'Form XObject must be a stream object');
|
|
113
|
+
}
|
|
114
|
+
const e = stream.dict.entries;
|
|
115
|
+
if (e.Subtype && (e.Subtype.type !== 'name' || e.Subtype.value !== 'Form')) {
|
|
116
|
+
throw new ParseError('pdf/form-xobj/wrong-subtype',
|
|
117
|
+
'Form XObject /Subtype must be /Form',
|
|
118
|
+
{ context: { actual: e.Subtype.value } });
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
kind: 'form',
|
|
122
|
+
formType: e.FormType && e.FormType.type === 'int' ? e.FormType.value : 1,
|
|
123
|
+
bbox: toBox(e.BBox),
|
|
124
|
+
matrix: toMatrix(e.Matrix),
|
|
125
|
+
resources: e.Resources || null,
|
|
126
|
+
group: e.Group || null,
|
|
127
|
+
metadata: e.Metadata || null,
|
|
128
|
+
structParents: e.StructParents && e.StructParents.type === 'int'
|
|
129
|
+
? e.StructParents.value : null,
|
|
130
|
+
structParent: e.StructParent && e.StructParent.type === 'int'
|
|
131
|
+
? e.StructParent.value : null,
|
|
132
|
+
raw: stream.raw,
|
|
133
|
+
dict: stream.dict
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function typeXObject(stream) {
|
|
138
|
+
if (!isType(stream, 'stream')) {
|
|
139
|
+
throw new ParseError('pdf/xobject/not-stream',
|
|
140
|
+
'XObject must be a stream object');
|
|
141
|
+
}
|
|
142
|
+
const t = stream.dict.entries.Type;
|
|
143
|
+
if (t && (t.type !== 'name' || t.value !== 'XObject')) {
|
|
144
|
+
throw new ParseError('pdf/xobject/bad-type',
|
|
145
|
+
'/Type must be /XObject when present',
|
|
146
|
+
{ context: { actual: t.value } });
|
|
147
|
+
}
|
|
148
|
+
const s = stream.dict.entries.Subtype;
|
|
149
|
+
if (!s || s.type !== 'name') {
|
|
150
|
+
throw new ParseError('pdf/xobject/missing-subtype',
|
|
151
|
+
'XObject must have /Subtype');
|
|
152
|
+
}
|
|
153
|
+
if (s.value === 'Image') return typeImageXObject(stream);
|
|
154
|
+
if (s.value === 'Form') return typeFormXObject(stream);
|
|
155
|
+
return { kind: s.value, raw: stream.raw, dict: stream.dict };
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return { typeImageXObject, typeFormXObject, typeXObject };
|
|
159
|
+
}
|
|
160
|
+
};
|