@cj-tech-master/excelts 9.1.0 → 9.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -1
- package/dist/browser/modules/archive/compression/crc32.js +1 -1
- package/dist/browser/modules/archive/crypto/aes.d.ts +0 -8
- package/dist/browser/modules/archive/crypto/aes.js +1 -20
- package/dist/browser/modules/archive/crypto/index.d.ts +2 -1
- package/dist/browser/modules/archive/crypto/index.js +3 -1
- package/dist/browser/modules/csv/parse/row-processor.d.ts +1 -1
- package/dist/browser/modules/csv/worker/worker-script.generated.js +1 -1
- package/dist/browser/modules/excel/utils/cell-matrix.js +1 -0
- package/dist/browser/modules/excel/utils/encryptor.browser.d.ts +4 -5
- package/dist/browser/modules/excel/utils/encryptor.browser.js +7 -12
- package/dist/browser/modules/excel/utils/encryptor.d.ts +1 -1
- package/dist/browser/modules/excel/utils/encryptor.js +4 -7
- package/dist/browser/modules/pdf/builder/document-builder.d.ts +517 -0
- package/dist/browser/modules/pdf/builder/document-builder.js +1493 -0
- package/dist/browser/modules/pdf/builder/form-appearance.d.ts +56 -0
- package/dist/browser/modules/pdf/builder/form-appearance.js +140 -0
- package/dist/browser/modules/pdf/builder/image-utils.d.ts +39 -0
- package/dist/browser/modules/pdf/builder/image-utils.js +129 -0
- package/dist/browser/modules/pdf/builder/pdf-editor.d.ts +230 -0
- package/dist/browser/modules/pdf/builder/pdf-editor.js +1574 -0
- package/dist/browser/modules/pdf/builder/resource-merger.d.ts +41 -0
- package/dist/browser/modules/pdf/builder/resource-merger.js +258 -0
- package/dist/browser/modules/pdf/core/digital-signature.d.ts +109 -0
- package/dist/browser/modules/pdf/core/digital-signature.js +659 -0
- package/dist/browser/modules/pdf/core/encryption.js +8 -7
- package/dist/browser/modules/pdf/core/pdf-object.d.ts +11 -0
- package/dist/browser/modules/pdf/core/pdf-object.js +38 -0
- package/dist/browser/modules/pdf/core/pdf-stream.d.ts +32 -0
- package/dist/browser/modules/pdf/core/pdf-stream.js +66 -0
- package/dist/browser/modules/pdf/core/pdf-writer.d.ts +55 -1
- package/dist/browser/modules/pdf/core/pdf-writer.js +271 -6
- package/dist/browser/modules/pdf/core/pdfa.d.ts +62 -0
- package/dist/browser/modules/pdf/core/pdfa.js +261 -0
- package/dist/browser/modules/pdf/index.d.ts +11 -0
- package/dist/browser/modules/pdf/index.js +9 -0
- package/dist/browser/modules/pdf/reader/bookmark-extractor.d.ts +35 -0
- package/dist/browser/modules/pdf/reader/bookmark-extractor.js +324 -0
- package/dist/browser/modules/pdf/reader/pdf-decrypt.js +6 -5
- package/dist/browser/modules/pdf/reader/pdf-reader.d.ts +17 -0
- package/dist/browser/modules/pdf/reader/pdf-reader.js +26 -2
- package/dist/browser/modules/pdf/reader/table-extractor.d.ts +69 -0
- package/dist/browser/modules/pdf/reader/table-extractor.js +365 -0
- package/dist/browser/modules/pdf/render/layout-engine.d.ts +21 -1
- package/dist/browser/modules/pdf/render/layout-engine.js +112 -5
- package/dist/browser/modules/pdf/render/page-renderer.d.ts +2 -9
- package/dist/browser/modules/pdf/render/page-renderer.js +62 -103
- package/dist/browser/modules/pdf/render/pdf-exporter.js +2 -61
- package/dist/browser/modules/pdf/render/style-converter.d.ts +4 -0
- package/dist/browser/modules/pdf/render/style-converter.js +1 -1
- package/dist/browser/modules/pdf/types.d.ts +14 -1
- package/dist/browser/modules/stream/browser/readable.js +8 -2
- package/dist/browser/utils/crypto.browser.d.ts +64 -0
- package/dist/browser/{modules/pdf/core/crypto.js → utils/crypto.browser.js} +91 -101
- package/dist/browser/utils/crypto.d.ts +97 -0
- package/dist/browser/utils/crypto.js +209 -0
- package/dist/cjs/modules/archive/compression/crc32.js +1 -1
- package/dist/cjs/modules/archive/crypto/aes.js +2 -23
- package/dist/cjs/modules/archive/crypto/index.js +3 -1
- package/dist/cjs/modules/csv/worker/worker-script.generated.js +1 -1
- package/dist/cjs/modules/excel/utils/cell-matrix.js +1 -0
- package/dist/cjs/modules/excel/utils/encryptor.browser.js +7 -12
- package/dist/cjs/modules/excel/utils/encryptor.js +4 -10
- package/dist/cjs/modules/pdf/builder/document-builder.js +1532 -0
- package/dist/cjs/modules/pdf/builder/form-appearance.js +145 -0
- package/dist/cjs/modules/pdf/builder/image-utils.js +135 -0
- package/dist/cjs/modules/pdf/builder/pdf-editor.js +1612 -0
- package/dist/cjs/modules/pdf/builder/resource-merger.js +263 -0
- package/dist/cjs/modules/pdf/core/digital-signature.js +667 -0
- package/dist/cjs/modules/pdf/core/encryption.js +8 -7
- package/dist/cjs/modules/pdf/core/pdf-object.js +38 -0
- package/dist/cjs/modules/pdf/core/pdf-stream.js +66 -0
- package/dist/cjs/modules/pdf/core/pdf-writer.js +272 -6
- package/dist/cjs/modules/pdf/core/pdfa.js +266 -0
- package/dist/cjs/modules/pdf/index.js +19 -1
- package/dist/cjs/modules/pdf/reader/bookmark-extractor.js +327 -0
- package/dist/cjs/modules/pdf/reader/pdf-decrypt.js +6 -5
- package/dist/cjs/modules/pdf/reader/pdf-reader.js +26 -2
- package/dist/cjs/modules/pdf/reader/table-extractor.js +368 -0
- package/dist/cjs/modules/pdf/render/layout-engine.js +113 -4
- package/dist/cjs/modules/pdf/render/page-renderer.js +63 -105
- package/dist/cjs/modules/pdf/render/pdf-exporter.js +3 -62
- package/dist/cjs/modules/pdf/render/style-converter.js +1 -0
- package/dist/cjs/modules/stream/browser/readable.js +8 -2
- package/dist/cjs/{modules/pdf/core/crypto.js → utils/crypto.browser.js} +95 -102
- package/dist/cjs/utils/crypto.js +228 -0
- package/dist/esm/modules/archive/compression/crc32.js +1 -1
- package/dist/esm/modules/archive/crypto/aes.js +1 -20
- package/dist/esm/modules/archive/crypto/index.js +3 -1
- package/dist/esm/modules/csv/worker/worker-script.generated.js +1 -1
- package/dist/esm/modules/excel/utils/cell-matrix.js +1 -0
- package/dist/esm/modules/excel/utils/encryptor.browser.js +7 -12
- package/dist/esm/modules/excel/utils/encryptor.js +4 -7
- package/dist/esm/modules/pdf/builder/document-builder.js +1493 -0
- package/dist/esm/modules/pdf/builder/form-appearance.js +140 -0
- package/dist/esm/modules/pdf/builder/image-utils.js +129 -0
- package/dist/esm/modules/pdf/builder/pdf-editor.js +1574 -0
- package/dist/esm/modules/pdf/builder/resource-merger.js +258 -0
- package/dist/esm/modules/pdf/core/digital-signature.js +659 -0
- package/dist/esm/modules/pdf/core/encryption.js +8 -7
- package/dist/esm/modules/pdf/core/pdf-object.js +38 -0
- package/dist/esm/modules/pdf/core/pdf-stream.js +66 -0
- package/dist/esm/modules/pdf/core/pdf-writer.js +271 -6
- package/dist/esm/modules/pdf/core/pdfa.js +261 -0
- package/dist/esm/modules/pdf/index.js +9 -0
- package/dist/esm/modules/pdf/reader/bookmark-extractor.js +324 -0
- package/dist/esm/modules/pdf/reader/pdf-decrypt.js +6 -5
- package/dist/esm/modules/pdf/reader/pdf-reader.js +26 -2
- package/dist/esm/modules/pdf/reader/table-extractor.js +365 -0
- package/dist/esm/modules/pdf/render/layout-engine.js +112 -5
- package/dist/esm/modules/pdf/render/page-renderer.js +62 -103
- package/dist/esm/modules/pdf/render/pdf-exporter.js +2 -61
- package/dist/esm/modules/pdf/render/style-converter.js +1 -1
- package/dist/esm/modules/stream/browser/readable.js +8 -2
- package/dist/esm/{modules/pdf/core/crypto.js → utils/crypto.browser.js} +91 -101
- package/dist/esm/utils/crypto.js +209 -0
- package/dist/iife/excelts.iife.js +1248 -1074
- package/dist/iife/excelts.iife.js.map +1 -1
- package/dist/iife/excelts.iife.min.js +53 -54
- package/dist/types/modules/archive/crypto/aes.d.ts +0 -8
- package/dist/types/modules/archive/crypto/index.d.ts +2 -1
- package/dist/types/modules/csv/parse/row-processor.d.ts +1 -1
- package/dist/types/modules/excel/utils/encryptor.browser.d.ts +4 -5
- package/dist/types/modules/excel/utils/encryptor.d.ts +1 -1
- package/dist/types/modules/pdf/builder/document-builder.d.ts +517 -0
- package/dist/types/modules/pdf/builder/form-appearance.d.ts +56 -0
- package/dist/types/modules/pdf/builder/image-utils.d.ts +39 -0
- package/dist/types/modules/pdf/builder/pdf-editor.d.ts +230 -0
- package/dist/types/modules/pdf/builder/resource-merger.d.ts +41 -0
- package/dist/types/modules/pdf/core/digital-signature.d.ts +109 -0
- package/dist/types/modules/pdf/core/pdf-object.d.ts +11 -0
- package/dist/types/modules/pdf/core/pdf-stream.d.ts +32 -0
- package/dist/types/modules/pdf/core/pdf-writer.d.ts +55 -1
- package/dist/types/modules/pdf/core/pdfa.d.ts +62 -0
- package/dist/types/modules/pdf/index.d.ts +11 -0
- package/dist/types/modules/pdf/reader/bookmark-extractor.d.ts +35 -0
- package/dist/types/modules/pdf/reader/pdf-reader.d.ts +17 -0
- package/dist/types/modules/pdf/reader/table-extractor.d.ts +69 -0
- package/dist/types/modules/pdf/render/layout-engine.d.ts +21 -1
- package/dist/types/modules/pdf/render/page-renderer.d.ts +2 -9
- package/dist/types/modules/pdf/render/style-converter.d.ts +4 -0
- package/dist/types/modules/pdf/types.d.ts +14 -1
- package/dist/types/utils/crypto.browser.d.ts +64 -0
- package/dist/types/utils/crypto.d.ts +97 -0
- package/package.json +110 -111
- package/dist/browser/modules/pdf/core/crypto.d.ts +0 -65
- package/dist/types/modules/pdf/core/crypto.d.ts +0 -65
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Form field appearance stream generation.
|
|
3
|
+
*
|
|
4
|
+
* Generates visual appearance streams for PDF form fields so that field
|
|
5
|
+
* values are visible in all PDF viewers — even those that do not honor
|
|
6
|
+
* the `/NeedAppearances` flag.
|
|
7
|
+
*
|
|
8
|
+
* @see PDF Reference 1.7, §12.5.5 — Appearance Streams
|
|
9
|
+
* @see PDF Reference 1.7, §12.7.4 — Field Appearance
|
|
10
|
+
*/
|
|
11
|
+
import { PdfContentStream } from "../core/pdf-stream.js";
|
|
12
|
+
import { pdfNumber } from "../core/pdf-object.js";
|
|
13
|
+
// =============================================================================
|
|
14
|
+
// Text Field Appearance
|
|
15
|
+
// =============================================================================
|
|
16
|
+
/** Default padding inside the field rectangle (in points). */
|
|
17
|
+
const FIELD_PADDING = 2;
|
|
18
|
+
/**
|
|
19
|
+
* Generate an appearance stream for a text form field.
|
|
20
|
+
*
|
|
21
|
+
* Builds a minimal content stream that clips to the widget rect and
|
|
22
|
+
* draws the field value using the specified (or default) font.
|
|
23
|
+
*
|
|
24
|
+
* @returns The raw stream bytes and a resources dictionary string.
|
|
25
|
+
*/
|
|
26
|
+
export function generateTextFieldAppearance(options) {
|
|
27
|
+
const { value, rect, alignment = "left" } = options;
|
|
28
|
+
const fontName = options.fontName ?? "Helv";
|
|
29
|
+
// Derive bounding box dimensions from the widget rect
|
|
30
|
+
const x1 = rect[0] ?? 0;
|
|
31
|
+
const y1 = rect[1] ?? 0;
|
|
32
|
+
const x2 = rect[2] ?? x1;
|
|
33
|
+
const y2 = rect[3] ?? y1;
|
|
34
|
+
const width = Math.abs(x2 - x1);
|
|
35
|
+
const height = Math.abs(y2 - y1);
|
|
36
|
+
// Auto-size font: use ~70% of the field height, clamped to a reasonable range
|
|
37
|
+
let fontSize = options.fontSize ?? 0;
|
|
38
|
+
if (fontSize <= 0) {
|
|
39
|
+
fontSize = Math.max(4, Math.min(height * 0.7, 20));
|
|
40
|
+
}
|
|
41
|
+
// Approximate text width using 0.5 * fontSize per character (conservative estimate
|
|
42
|
+
// for Helvetica). This is intentionally simple — the appearance is a best-effort
|
|
43
|
+
// rendering; the authoritative value is in /V.
|
|
44
|
+
const approxCharWidth = fontSize * 0.5;
|
|
45
|
+
const textWidth = value.length * approxCharWidth;
|
|
46
|
+
// Compute horizontal offset based on alignment
|
|
47
|
+
let tx;
|
|
48
|
+
const usableWidth = width - 2 * FIELD_PADDING;
|
|
49
|
+
switch (alignment) {
|
|
50
|
+
case "center":
|
|
51
|
+
tx = FIELD_PADDING + Math.max(0, (usableWidth - textWidth) / 2);
|
|
52
|
+
break;
|
|
53
|
+
case "right":
|
|
54
|
+
tx = FIELD_PADDING + Math.max(0, usableWidth - textWidth);
|
|
55
|
+
break;
|
|
56
|
+
default:
|
|
57
|
+
tx = FIELD_PADDING;
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
// Vertical centering: place baseline so the text is roughly centered
|
|
61
|
+
// Approximate ascent ≈ 0.75 * fontSize, descent ≈ -0.25 * fontSize
|
|
62
|
+
const ascent = fontSize * 0.75;
|
|
63
|
+
const descent = fontSize * 0.25;
|
|
64
|
+
const textHeight = ascent + descent;
|
|
65
|
+
const ty = (height - textHeight) / 2 + descent;
|
|
66
|
+
// Build the content stream
|
|
67
|
+
const cs = new PdfContentStream();
|
|
68
|
+
// Clip to the bounding box (form XObject coordinate space: 0,0 to width,height)
|
|
69
|
+
cs.rect(0, 0, width, height).clip().endPath();
|
|
70
|
+
// Draw the text
|
|
71
|
+
cs.beginText().setFont(fontName, fontSize).moveText(tx, ty).showText(value).endText();
|
|
72
|
+
const stream = cs.toUint8Array();
|
|
73
|
+
// Build a minimal resources dict referencing a standard Helvetica font.
|
|
74
|
+
// The font is declared inline as a Type1 font so the appearance stream
|
|
75
|
+
// is self-contained (no dependency on the page's resources).
|
|
76
|
+
const resources = `<< /Font << /${fontName} << /Type /Font /Subtype /Type1 /BaseFont /Helvetica /Encoding /WinAnsiEncoding >> >> >>`;
|
|
77
|
+
return { stream, resources };
|
|
78
|
+
}
|
|
79
|
+
// =============================================================================
|
|
80
|
+
// Checkbox Appearance
|
|
81
|
+
// =============================================================================
|
|
82
|
+
/**
|
|
83
|
+
* Generate appearance streams for a checkbox form field.
|
|
84
|
+
*
|
|
85
|
+
* Returns two streams:
|
|
86
|
+
* - `streamOn`: draws a checkmark (✓-like shape) inside the rect
|
|
87
|
+
* - `streamOff`: empty appearance (blank field)
|
|
88
|
+
*
|
|
89
|
+
* @param checked - Whether to generate the checked or unchecked variant
|
|
90
|
+
* (both are always returned; `checked` is ignored — both
|
|
91
|
+
* on and off streams are produced).
|
|
92
|
+
* @param rect - Widget annotation rectangle [x1, y1, x2, y2].
|
|
93
|
+
*/
|
|
94
|
+
export function generateCheckboxAppearance(_checked, rect) {
|
|
95
|
+
const x1 = rect[0] ?? 0;
|
|
96
|
+
const y1 = rect[1] ?? 0;
|
|
97
|
+
const x2 = rect[2] ?? x1;
|
|
98
|
+
const y2 = rect[3] ?? y1;
|
|
99
|
+
const width = Math.abs(x2 - x1);
|
|
100
|
+
const height = Math.abs(y2 - y1);
|
|
101
|
+
// --- "On" appearance: draw an X ---
|
|
102
|
+
const onCs = new PdfContentStream();
|
|
103
|
+
const inset = Math.min(width, height) * 0.15;
|
|
104
|
+
onCs
|
|
105
|
+
.save()
|
|
106
|
+
.setStrokeColor({ r: 0, g: 0, b: 0 })
|
|
107
|
+
.setLineWidth(Math.max(1, Math.min(width, height) * 0.1))
|
|
108
|
+
// First stroke of the X: bottom-left to top-right
|
|
109
|
+
.moveTo(inset, inset)
|
|
110
|
+
.lineTo(width - inset, height - inset)
|
|
111
|
+
.stroke()
|
|
112
|
+
// Second stroke of the X: top-left to bottom-right
|
|
113
|
+
.moveTo(inset, height - inset)
|
|
114
|
+
.lineTo(width - inset, inset)
|
|
115
|
+
.stroke()
|
|
116
|
+
.restore();
|
|
117
|
+
// --- "Off" appearance: empty ---
|
|
118
|
+
const offCs = new PdfContentStream();
|
|
119
|
+
// Intentionally empty — nothing to draw for unchecked state
|
|
120
|
+
return {
|
|
121
|
+
streamOn: onCs.toUint8Array(),
|
|
122
|
+
streamOff: offCs.toUint8Array()
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
// =============================================================================
|
|
126
|
+
// Helpers
|
|
127
|
+
// =============================================================================
|
|
128
|
+
/**
|
|
129
|
+
* Build the BBox array string for a form XObject appearance stream.
|
|
130
|
+
* The bounding box is in the widget's coordinate space: [0 0 width height].
|
|
131
|
+
*/
|
|
132
|
+
export function buildAppearanceBBox(rect) {
|
|
133
|
+
const x1 = rect[0] ?? 0;
|
|
134
|
+
const y1 = rect[1] ?? 0;
|
|
135
|
+
const x2 = rect[2] ?? x1;
|
|
136
|
+
const y2 = rect[3] ?? y1;
|
|
137
|
+
const width = Math.abs(x2 - x1);
|
|
138
|
+
const height = Math.abs(y2 - y1);
|
|
139
|
+
return `[0 0 ${pdfNumber(width)} ${pdfNumber(height)}]`;
|
|
140
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared image utilities for PDF generation.
|
|
3
|
+
*
|
|
4
|
+
* Centralises JPEG/PNG dimension parsing and PDF XObject writing so that
|
|
5
|
+
* both the builder (`document-builder.ts`) and the exporter (`pdf-exporter.ts`)
|
|
6
|
+
* share a single implementation.
|
|
7
|
+
*/
|
|
8
|
+
import { PdfDict, pdfRef, pdfNumber } from "../core/pdf-object.js";
|
|
9
|
+
import { decodePng } from "../render/png-decoder.js";
|
|
10
|
+
// =============================================================================
|
|
11
|
+
// Image Dimension Parsing
|
|
12
|
+
// =============================================================================
|
|
13
|
+
/**
|
|
14
|
+
* Parse image dimensions from raw bytes.
|
|
15
|
+
*/
|
|
16
|
+
export function parseImageDimensions(data, format) {
|
|
17
|
+
if (format === "png") {
|
|
18
|
+
return parsePngDimensions(data);
|
|
19
|
+
}
|
|
20
|
+
return parseJpegDimensions(data);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Read width/height from a PNG IHDR chunk (bytes 16-23).
|
|
24
|
+
*/
|
|
25
|
+
export function parsePngDimensions(data) {
|
|
26
|
+
// PNG header: 8 byte signature, then IHDR chunk: 4 byte length, 4 byte type, 4 byte width, 4 byte height
|
|
27
|
+
if (data.length >= 24 &&
|
|
28
|
+
data[12] === 0x49 &&
|
|
29
|
+
data[13] === 0x48 &&
|
|
30
|
+
data[14] === 0x44 &&
|
|
31
|
+
data[15] === 0x52) {
|
|
32
|
+
const width = (data[16] << 24) | (data[17] << 16) | (data[18] << 8) | data[19];
|
|
33
|
+
const height = (data[20] << 24) | (data[21] << 16) | (data[22] << 8) | data[23];
|
|
34
|
+
return { width, height };
|
|
35
|
+
}
|
|
36
|
+
return { width: 1, height: 1 };
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Read width/height from JPEG SOF marker.
|
|
40
|
+
*
|
|
41
|
+
* Correctly excludes non-SOF markers in the 0xC0-0xCF range:
|
|
42
|
+
* - 0xC4 = DHT (Define Huffman Table)
|
|
43
|
+
* - 0xC8 = JPG (reserved)
|
|
44
|
+
* - 0xCC = DAC (Define Arithmetic Coding)
|
|
45
|
+
*/
|
|
46
|
+
export function parseJpegDimensions(data) {
|
|
47
|
+
let offset = 2; // skip SOI marker
|
|
48
|
+
while (offset < data.length - 1) {
|
|
49
|
+
// Skip padding 0xFF bytes
|
|
50
|
+
while (offset < data.length && data[offset] === 0xff && data[offset + 1] === 0xff) {
|
|
51
|
+
offset++;
|
|
52
|
+
}
|
|
53
|
+
if (offset >= data.length - 1 || data[offset] !== 0xff) {
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
const marker = data[offset + 1];
|
|
57
|
+
const isSof = marker >= 0xc0 && marker <= 0xcf && marker !== 0xc4 && marker !== 0xc8 && marker !== 0xcc;
|
|
58
|
+
if (isSof && offset + 8 < data.length) {
|
|
59
|
+
return {
|
|
60
|
+
width: (data[offset + 7] << 8) | data[offset + 8],
|
|
61
|
+
height: (data[offset + 5] << 8) | data[offset + 6]
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
if (offset + 3 >= data.length) {
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
const segLen = (data[offset + 2] << 8) | data[offset + 3];
|
|
68
|
+
offset += 2 + segLen;
|
|
69
|
+
}
|
|
70
|
+
return { width: 1, height: 1 };
|
|
71
|
+
}
|
|
72
|
+
// =============================================================================
|
|
73
|
+
// PDF Image XObject Writing
|
|
74
|
+
// =============================================================================
|
|
75
|
+
/**
|
|
76
|
+
* Write an image XObject (JPEG or PNG) to the writer.
|
|
77
|
+
* Returns the allocated object number.
|
|
78
|
+
*/
|
|
79
|
+
export function writeImageXObject(writer, data, format) {
|
|
80
|
+
if (format === "png") {
|
|
81
|
+
return writePngImageXObject(writer, data);
|
|
82
|
+
}
|
|
83
|
+
return writeJpegImageXObject(writer, data);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Write a JPEG image using DCTDecode (raw JPEG data embedded directly).
|
|
87
|
+
*/
|
|
88
|
+
function writeJpegImageXObject(writer, data) {
|
|
89
|
+
const objNum = writer.allocObject();
|
|
90
|
+
const dims = parseJpegDimensions(data);
|
|
91
|
+
const dict = new PdfDict()
|
|
92
|
+
.set("Type", "/XObject")
|
|
93
|
+
.set("Subtype", "/Image")
|
|
94
|
+
.set("Width", pdfNumber(dims.width))
|
|
95
|
+
.set("Height", pdfNumber(dims.height))
|
|
96
|
+
.set("ColorSpace", "/DeviceRGB")
|
|
97
|
+
.set("BitsPerComponent", "8")
|
|
98
|
+
.set("Filter", "/DCTDecode");
|
|
99
|
+
writer.addStreamObject(objNum, dict, data);
|
|
100
|
+
return objNum;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Write a PNG image: decode to raw RGB, create SMask for alpha if needed.
|
|
104
|
+
*/
|
|
105
|
+
function writePngImageXObject(writer, data) {
|
|
106
|
+
const png = decodePng(data);
|
|
107
|
+
const objNum = writer.allocObject();
|
|
108
|
+
const dict = new PdfDict()
|
|
109
|
+
.set("Type", "/XObject")
|
|
110
|
+
.set("Subtype", "/Image")
|
|
111
|
+
.set("Width", pdfNumber(png.width))
|
|
112
|
+
.set("Height", pdfNumber(png.height))
|
|
113
|
+
.set("ColorSpace", "/DeviceRGB")
|
|
114
|
+
.set("BitsPerComponent", pdfNumber(png.bitsPerComponent));
|
|
115
|
+
if (png.alpha) {
|
|
116
|
+
const smaskObjNum = writer.allocObject();
|
|
117
|
+
const smaskDict = new PdfDict()
|
|
118
|
+
.set("Type", "/XObject")
|
|
119
|
+
.set("Subtype", "/Image")
|
|
120
|
+
.set("Width", pdfNumber(png.width))
|
|
121
|
+
.set("Height", pdfNumber(png.height))
|
|
122
|
+
.set("ColorSpace", "/DeviceGray")
|
|
123
|
+
.set("BitsPerComponent", "8");
|
|
124
|
+
writer.addStreamObject(smaskObjNum, smaskDict, png.alpha);
|
|
125
|
+
dict.set("SMask", pdfRef(smaskObjNum));
|
|
126
|
+
}
|
|
127
|
+
writer.addStreamObject(objNum, dict, png.pixels);
|
|
128
|
+
return objNum;
|
|
129
|
+
}
|