reamkit 1.7.0 → 1.10.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.
Files changed (46) hide show
  1. package/README.md +21 -3
  2. package/dist/esm/core/converter/facade.js +2 -0
  3. package/dist/esm/core/converter/ream.d.ts +1 -0
  4. package/dist/esm/core/converter/ream.js +2 -1
  5. package/dist/esm/core/document-model/types.d.ts +3 -1
  6. package/dist/esm/core/drawingml/shape-render.d.ts +3 -1
  7. package/dist/esm/core/drawingml/shape-render.js +27 -1
  8. package/dist/esm/core/vector.d.ts +10 -0
  9. package/dist/esm/html/html-writer.js +4 -2
  10. package/dist/esm/layout/styled-layout.js +5 -2
  11. package/dist/esm/pdf/shading.d.ts +12 -0
  12. package/dist/esm/pdf/shading.js +152 -0
  13. package/dist/esm/pdf/styled-page-emitter.js +29 -4
  14. package/dist/esm/pdf/vector-graphics.d.ts +1 -1
  15. package/dist/esm/pdf/vector-graphics.js +5 -3
  16. package/dist/esm/pdf-reader/ccitt.d.ts +15 -0
  17. package/dist/esm/pdf-reader/ccitt.js +394 -0
  18. package/dist/esm/pdf-reader/content.d.ts +6 -2
  19. package/dist/esm/pdf-reader/content.js +54 -13
  20. package/dist/esm/pdf-reader/decrypt.d.ts +1 -1
  21. package/dist/esm/pdf-reader/decrypt.js +20 -8
  22. package/dist/esm/pdf-reader/document.d.ts +1 -1
  23. package/dist/esm/pdf-reader/document.js +4 -4
  24. package/dist/esm/pdf-reader/flow-build.js +17 -6
  25. package/dist/esm/pdf-reader/image-decode.js +115 -7
  26. package/dist/esm/pdf-reader/layout.js +45 -7
  27. package/dist/esm/pdf-reader/reader.d.ts +1 -1
  28. package/dist/esm/pdf-reader/reader.js +5 -5
  29. package/dist/esm/pdf-reader/shading.d.ts +3 -0
  30. package/dist/esm/pdf-reader/shading.js +147 -0
  31. package/dist/esm/pdf-reader/text.js +47 -13
  32. package/dist/esm/pdf-reader/vector.d.ts +5 -1
  33. package/dist/esm/pdf-reader/vector.js +15 -6
  34. package/dist/esm/pptx/placeholder-cascade.d.ts +9 -0
  35. package/dist/esm/pptx/placeholder-cascade.js +77 -0
  36. package/dist/esm/pptx/pptx-reader.d.ts +4 -0
  37. package/dist/esm/pptx/pptx-reader.js +213 -0
  38. package/dist/esm/pptx/slide-parser.d.ts +18 -0
  39. package/dist/esm/pptx/slide-parser.js +359 -0
  40. package/dist/esm/pptx/sp-helpers.d.ts +17 -0
  41. package/dist/esm/pptx/sp-helpers.js +60 -0
  42. package/dist/esm/svg/svg-writer.js +12 -5
  43. package/dist/esm/word/docx-writer.js +8 -1
  44. package/dist/esm/word/drawing-parser.d.ts +4 -0
  45. package/dist/esm/word/drawing-parser.js +29 -18
  46. package/package.json +4 -2
@@ -0,0 +1,394 @@
1
+ //#region src/pdf-reader/ccitt.ts
2
+ function decodeCcitt(data, params) {
3
+ const { k, columns, rows, byteAlign } = params;
4
+ if (k > 0) return void 0;
5
+ if (columns <= 0 || rows <= 0 || columns > 1 << 20) return void 0;
6
+ const reader = new BitReader(data);
7
+ const rowBytes = columns + 7 >> 3;
8
+ const out = new Uint8Array(rowBytes * rows);
9
+ let ref = [columns, columns];
10
+ for (let y = 0; y < rows; y++) {
11
+ if (byteAlign && y > 0) reader.align();
12
+ const cur = k < 0 ? decode2D(reader, ref, columns) : decode1D(reader, columns);
13
+ if (!cur) {
14
+ if (y === 0) return void 0;
15
+ break;
16
+ }
17
+ expandRow(cur, columns, out, y * rowBytes);
18
+ cur.push(columns, columns);
19
+ ref = cur;
20
+ }
21
+ return out;
22
+ }
23
+ function decode1D(reader, columns) {
24
+ const cur = [];
25
+ let pos = 0;
26
+ let color = 0;
27
+ while (pos < columns) {
28
+ const run = readRun(reader, color);
29
+ if (run < 0) return cur.length > 0 ? cur : null;
30
+ pos = Math.min(pos + run, columns);
31
+ cur.push(pos);
32
+ color ^= 1;
33
+ }
34
+ return cur;
35
+ }
36
+ function decode2D(reader, ref, columns) {
37
+ const cur = [];
38
+ let a0 = -1;
39
+ let color = 0;
40
+ while (a0 < columns) {
41
+ const [b1, b2] = findB(ref, a0, color, columns);
42
+ const mode = readMode(reader);
43
+ if (!mode) return cur.length > 0 || a0 >= 0 ? cur : null;
44
+ if (mode.kind === "pass") a0 = b2;
45
+ else if (mode.kind === "horizontal") {
46
+ const start = a0 < 0 ? 0 : a0;
47
+ const r1 = readRun(reader, color);
48
+ const r2 = readRun(reader, color ^ 1);
49
+ if (r1 < 0 || r2 < 0) return cur.length > 0 ? cur : null;
50
+ const a1 = Math.min(start + r1, columns);
51
+ const a2 = Math.min(a1 + r2, columns);
52
+ cur.push(a1, a2);
53
+ a0 = a2;
54
+ } else {
55
+ const a1 = Math.min(Math.max(b1 + mode.d, 0), columns);
56
+ cur.push(a1);
57
+ a0 = a1;
58
+ color ^= 1;
59
+ }
60
+ }
61
+ return cur;
62
+ }
63
+ function findB(ref, a0, color, columns) {
64
+ let i = 0;
65
+ while (i < ref.length && ref[i] <= a0) i++;
66
+ const wantEven = color === 0;
67
+ if (i < ref.length && i % 2 === 0 !== wantEven) i++;
68
+ return [i < ref.length ? ref[i] : columns, i + 1 < ref.length ? ref[i + 1] : columns];
69
+ }
70
+ function expandRow(cur, columns, out, rowOff) {
71
+ let prev = 0;
72
+ let color = 0;
73
+ for (const cRaw of cur) {
74
+ const c = Math.min(cRaw, columns);
75
+ if (color === 1) setBlack(out, rowOff, prev, c);
76
+ prev = c;
77
+ color ^= 1;
78
+ if (prev >= columns) return;
79
+ }
80
+ if (color === 1 && prev < columns) setBlack(out, rowOff, prev, columns);
81
+ }
82
+ function setBlack(out, rowOff, from, to) {
83
+ for (let x = from; x < to; x++) out[rowOff + (x >> 3)] |= 128 >> (x & 7);
84
+ }
85
+ function readRun(reader, color) {
86
+ const table = color === 1 ? BLACK : WHITE;
87
+ let total = 0;
88
+ for (let guard = 0; guard < 64; guard++) {
89
+ const run = readCode(reader, table);
90
+ if (run < 0) return -1;
91
+ total += run;
92
+ if (run < 64) return total;
93
+ }
94
+ return -1;
95
+ }
96
+ function readMode(reader) {
97
+ let code = 0;
98
+ for (let len = 1; len <= 7; len++) {
99
+ const b = reader.readBit();
100
+ if (b < 0) return void 0;
101
+ code = code << 1 | b;
102
+ const m = MODES.get(len << 8 | code);
103
+ if (m) return m;
104
+ }
105
+ }
106
+ function readCode(reader, table) {
107
+ let code = 0;
108
+ for (let len = 1; len <= table.maxLen; len++) {
109
+ const b = reader.readBit();
110
+ if (b < 0) return -1;
111
+ code = code << 1 | b;
112
+ const run = table.map.get(len << 16 | code);
113
+ if (run !== void 0) return run;
114
+ }
115
+ return -1;
116
+ }
117
+ var BitReader = class {
118
+ bytePos = 0;
119
+ bitPos = 0;
120
+ constructor(data) {
121
+ this.data = data;
122
+ }
123
+ readBit() {
124
+ if (this.bytePos >= this.data.length) return -1;
125
+ const bit = this.data[this.bytePos] >> 7 - this.bitPos & 1;
126
+ if (++this.bitPos === 8) {
127
+ this.bitPos = 0;
128
+ this.bytePos++;
129
+ }
130
+ return bit;
131
+ }
132
+ align() {
133
+ if (this.bitPos !== 0) {
134
+ this.bitPos = 0;
135
+ this.bytePos++;
136
+ }
137
+ }
138
+ };
139
+ var WHITE_CODES = [
140
+ [0, "00110101"],
141
+ [1, "000111"],
142
+ [2, "0111"],
143
+ [3, "1000"],
144
+ [4, "1011"],
145
+ [5, "1100"],
146
+ [6, "1110"],
147
+ [7, "1111"],
148
+ [8, "10011"],
149
+ [9, "10100"],
150
+ [10, "00111"],
151
+ [11, "01000"],
152
+ [12, "001000"],
153
+ [13, "000011"],
154
+ [14, "110100"],
155
+ [15, "110101"],
156
+ [16, "101010"],
157
+ [17, "101011"],
158
+ [18, "0100111"],
159
+ [19, "0001100"],
160
+ [20, "0001000"],
161
+ [21, "0010111"],
162
+ [22, "0000011"],
163
+ [23, "0000100"],
164
+ [24, "0101000"],
165
+ [25, "0101011"],
166
+ [26, "0010011"],
167
+ [27, "0100100"],
168
+ [28, "0011000"],
169
+ [29, "00000010"],
170
+ [30, "00000011"],
171
+ [31, "00011010"],
172
+ [32, "00011011"],
173
+ [33, "00010010"],
174
+ [34, "00010011"],
175
+ [35, "00010100"],
176
+ [36, "00010101"],
177
+ [37, "00010110"],
178
+ [38, "00010111"],
179
+ [39, "00101000"],
180
+ [40, "00101001"],
181
+ [41, "00101010"],
182
+ [42, "00101011"],
183
+ [43, "00101100"],
184
+ [44, "00101101"],
185
+ [45, "00000100"],
186
+ [46, "00000101"],
187
+ [47, "00001010"],
188
+ [48, "00001011"],
189
+ [49, "01010010"],
190
+ [50, "01010011"],
191
+ [51, "01010100"],
192
+ [52, "01010101"],
193
+ [53, "00100100"],
194
+ [54, "00100101"],
195
+ [55, "01011000"],
196
+ [56, "01011001"],
197
+ [57, "01011010"],
198
+ [58, "01011011"],
199
+ [59, "01001010"],
200
+ [60, "01001011"],
201
+ [61, "00110010"],
202
+ [62, "00110011"],
203
+ [63, "00110100"],
204
+ [64, "11011"],
205
+ [128, "10010"],
206
+ [192, "010111"],
207
+ [256, "0110111"],
208
+ [320, "00110110"],
209
+ [384, "00110111"],
210
+ [448, "01100100"],
211
+ [512, "01100101"],
212
+ [576, "01101000"],
213
+ [640, "01100111"],
214
+ [704, "011001100"],
215
+ [768, "011001101"],
216
+ [832, "011010010"],
217
+ [896, "011010011"],
218
+ [960, "011010100"],
219
+ [1024, "011010101"],
220
+ [1088, "011010110"],
221
+ [1152, "011010111"],
222
+ [1216, "011011000"],
223
+ [1280, "011011001"],
224
+ [1344, "011011010"],
225
+ [1408, "011011011"],
226
+ [1472, "010011000"],
227
+ [1536, "010011001"],
228
+ [1600, "010011010"],
229
+ [1664, "011000"],
230
+ [1728, "010011011"]
231
+ ];
232
+ var BLACK_CODES = [
233
+ [0, "0000110111"],
234
+ [1, "010"],
235
+ [2, "11"],
236
+ [3, "10"],
237
+ [4, "011"],
238
+ [5, "0011"],
239
+ [6, "0010"],
240
+ [7, "00011"],
241
+ [8, "000101"],
242
+ [9, "000100"],
243
+ [10, "0000100"],
244
+ [11, "0000101"],
245
+ [12, "0000111"],
246
+ [13, "00000100"],
247
+ [14, "00000111"],
248
+ [15, "000011000"],
249
+ [16, "0000010111"],
250
+ [17, "0000011000"],
251
+ [18, "0000001000"],
252
+ [19, "00001100111"],
253
+ [20, "00001101000"],
254
+ [21, "00001101100"],
255
+ [22, "00000110111"],
256
+ [23, "00000101000"],
257
+ [24, "00000010111"],
258
+ [25, "00000011000"],
259
+ [26, "000011001010"],
260
+ [27, "000011001011"],
261
+ [28, "000011001100"],
262
+ [29, "000011001101"],
263
+ [30, "000001101000"],
264
+ [31, "000001101001"],
265
+ [32, "000001101010"],
266
+ [33, "000001101011"],
267
+ [34, "000011010010"],
268
+ [35, "000011010011"],
269
+ [36, "000011010100"],
270
+ [37, "000011010101"],
271
+ [38, "000011010110"],
272
+ [39, "000011010111"],
273
+ [40, "000001101100"],
274
+ [41, "000001101101"],
275
+ [42, "000011011010"],
276
+ [43, "000011011011"],
277
+ [44, "000001010100"],
278
+ [45, "000001010101"],
279
+ [46, "000001010110"],
280
+ [47, "000001010111"],
281
+ [48, "000001100100"],
282
+ [49, "000001100101"],
283
+ [50, "000001010010"],
284
+ [51, "000001010011"],
285
+ [52, "000000100100"],
286
+ [53, "000000110111"],
287
+ [54, "000000111000"],
288
+ [55, "000000100111"],
289
+ [56, "000000101000"],
290
+ [57, "000001011000"],
291
+ [58, "000001011001"],
292
+ [59, "000000101011"],
293
+ [60, "000000101100"],
294
+ [61, "000001011010"],
295
+ [62, "000001100110"],
296
+ [63, "000001100111"],
297
+ [64, "0000001111"],
298
+ [128, "000011001000"],
299
+ [192, "000011001001"],
300
+ [256, "000001011011"],
301
+ [320, "000000110011"],
302
+ [384, "000000110100"],
303
+ [448, "000000110101"],
304
+ [512, "0000001101100"],
305
+ [576, "0000001101101"],
306
+ [640, "0000001001010"],
307
+ [704, "0000001001011"],
308
+ [768, "0000001001100"],
309
+ [832, "0000001001101"],
310
+ [896, "0000001110010"],
311
+ [960, "0000001110011"],
312
+ [1024, "0000001110100"],
313
+ [1088, "0000001110101"],
314
+ [1152, "0000001110110"],
315
+ [1216, "0000001110111"],
316
+ [1280, "0000001010010"],
317
+ [1344, "0000001010011"],
318
+ [1408, "0000001010100"],
319
+ [1472, "0000001010101"],
320
+ [1536, "0000001011010"],
321
+ [1600, "0000001011011"],
322
+ [1664, "0000001100100"],
323
+ [1728, "0000001100101"]
324
+ ];
325
+ var SHARED_MAKEUP = [
326
+ [1792, "00000001000"],
327
+ [1856, "00000001100"],
328
+ [1920, "00000001101"],
329
+ [1984, "000000010010"],
330
+ [2048, "000000010011"],
331
+ [2112, "000000010100"],
332
+ [2176, "000000010101"],
333
+ [2240, "000000010110"],
334
+ [2304, "000000010111"],
335
+ [2368, "000000011100"],
336
+ [2432, "000000011101"],
337
+ [2496, "000000011110"],
338
+ [2560, "000000011111"]
339
+ ];
340
+ var MODE_CODES = [
341
+ ["0001", {
342
+ kind: "pass",
343
+ d: 0
344
+ }],
345
+ ["001", {
346
+ kind: "horizontal",
347
+ d: 0
348
+ }],
349
+ ["1", {
350
+ kind: "vertical",
351
+ d: 0
352
+ }],
353
+ ["011", {
354
+ kind: "vertical",
355
+ d: 1
356
+ }],
357
+ ["000011", {
358
+ kind: "vertical",
359
+ d: 2
360
+ }],
361
+ ["0000011", {
362
+ kind: "vertical",
363
+ d: 3
364
+ }],
365
+ ["010", {
366
+ kind: "vertical",
367
+ d: -1
368
+ }],
369
+ ["000010", {
370
+ kind: "vertical",
371
+ d: -2
372
+ }],
373
+ ["0000010", {
374
+ kind: "vertical",
375
+ d: -3
376
+ }]
377
+ ];
378
+ function buildRunTable(...groups) {
379
+ const map = /* @__PURE__ */ new Map();
380
+ let maxLen = 0;
381
+ for (const group of groups) for (const [run, bits] of group) {
382
+ map.set(bits.length << 16 | parseInt(bits, 2), run);
383
+ maxLen = Math.max(maxLen, bits.length);
384
+ }
385
+ return {
386
+ map,
387
+ maxLen
388
+ };
389
+ }
390
+ var WHITE = buildRunTable(WHITE_CODES, SHARED_MAKEUP);
391
+ var BLACK = buildRunTable(BLACK_CODES, SHARED_MAKEUP);
392
+ var MODES = new Map(MODE_CODES.map(([bits, m]) => [bits.length << 8 | parseInt(bits, 2), m]));
393
+ //#endregion
394
+ export { decodeCcitt };
@@ -1,3 +1,4 @@
1
+ import { ShapeGradient } from '../core/vector.js';
1
2
  export interface ContentFont {
2
3
  readonly bytesPerCode: 1 | 2;
3
4
  decode: (codes: ReadonlyArray<number>) => string;
@@ -38,7 +39,10 @@ export type PathSeg = {
38
39
  };
39
40
  export interface VectorPlacement {
40
41
  readonly segs: ReadonlyArray<PathSeg>;
41
- readonly fillHex: string;
42
+ readonly fillHex?: string;
43
+ readonly gradient?: ShapeGradient;
44
+ readonly strokeHex?: string;
45
+ readonly lineWidth?: number;
42
46
  readonly mcid?: number;
43
47
  }
44
48
  export interface InterpretResult {
@@ -49,4 +53,4 @@ export interface InterpretResult {
49
53
  export type Matrix = readonly [number, number, number, number, number, number];
50
54
  export declare const IDENTITY: Matrix;
51
55
  export declare function multiply(a: Matrix, b: Matrix): Matrix;
52
- export declare function interpretContent(bytes: Uint8Array, fonts: ReadonlyMap<string, ContentFont>, initialCtm?: Matrix): InterpretResult;
56
+ export declare function interpretContent(bytes: Uint8Array, fonts: ReadonlyMap<string, ContentFont>, initialCtm?: Matrix, shadings?: ReadonlyMap<string, ShapeGradient>): InterpretResult;
@@ -45,10 +45,13 @@ function initialState() {
45
45
  hScale: 1,
46
46
  leading: 0,
47
47
  rise: 0,
48
- fillColor: "000000"
48
+ fillColor: "000000",
49
+ strokeColor: "000000",
50
+ lineWidth: 1,
51
+ fillGradient: void 0
49
52
  };
50
53
  }
51
- function interpretContent(bytes, fonts, initialCtm = IDENTITY) {
54
+ function interpretContent(bytes, fonts, initialCtm = IDENTITY, shadings = /* @__PURE__ */ new Map()) {
52
55
  const runs = [];
53
56
  const images = [];
54
57
  const vectors = [];
@@ -99,12 +102,22 @@ function interpretContent(bytes, fonts, initialCtm = IDENTITY) {
99
102
  lineTo(x, y + h);
100
103
  path.push({ op: "close" });
101
104
  };
102
- const fillPath = () => {
103
- if (path.length >= 2) {
105
+ const ctmLineWidth = () => {
106
+ const m = state.ctm;
107
+ const scale = Math.sqrt(Math.abs(m[0] * m[3] - m[1] * m[2])) || 1;
108
+ return state.lineWidth * scale;
109
+ };
110
+ const paintPath = (fill, stroke) => {
111
+ if (path.length >= 2 && (fill || stroke)) {
104
112
  const mcid = mcStack.length > 0 ? mcStack[mcStack.length - 1] : void 0;
105
113
  vectors.push({
106
114
  segs: path,
107
- fillHex: state.fillColor,
115
+ ...fill ? { fillHex: state.fillColor } : {},
116
+ ...fill && state.fillGradient ? { gradient: state.fillGradient } : {},
117
+ ...stroke ? {
118
+ strokeHex: state.strokeColor,
119
+ lineWidth: ctmLineWidth()
120
+ } : {},
108
121
  ...mcid !== void 0 ? { mcid } : {}
109
122
  });
110
123
  }
@@ -247,12 +260,33 @@ function interpretContent(bytes, fonts, initialCtm = IDENTITY) {
247
260
  }
248
261
  case "rg":
249
262
  state.fillColor = rgbHex(num(0), num(1), num(2));
263
+ state.fillGradient = void 0;
250
264
  break;
251
265
  case "g":
252
266
  state.fillColor = grayHex(num(0));
267
+ state.fillGradient = void 0;
253
268
  break;
254
269
  case "k":
255
270
  state.fillColor = cmykHex(num(0), num(1), num(2), num(3));
271
+ state.fillGradient = void 0;
272
+ break;
273
+ case "scn":
274
+ case "sc": {
275
+ const last = operands[operands.length - 1];
276
+ state.fillGradient = last instanceof PdfName ? shadings.get(last.value) : void 0;
277
+ break;
278
+ }
279
+ case "RG":
280
+ state.strokeColor = rgbHex(num(0), num(1), num(2));
281
+ break;
282
+ case "G":
283
+ state.strokeColor = grayHex(num(0));
284
+ break;
285
+ case "K":
286
+ state.strokeColor = cmykHex(num(0), num(1), num(2), num(3));
287
+ break;
288
+ case "w":
289
+ state.lineWidth = num(0);
256
290
  break;
257
291
  case "m":
258
292
  moveTo(num(0), num(1));
@@ -272,22 +306,29 @@ function interpretContent(bytes, fonts, initialCtm = IDENTITY) {
272
306
  case "f":
273
307
  case "F":
274
308
  case "f*":
309
+ paintPath(true, false);
310
+ break;
311
+ case "S":
312
+ paintPath(false, true);
313
+ break;
314
+ case "s":
315
+ path.push({ op: "close" });
316
+ paintPath(false, true);
317
+ break;
275
318
  case "B":
276
319
  case "B*":
277
- fillPath();
320
+ paintPath(true, true);
278
321
  break;
279
322
  case "b":
280
323
  case "b*":
281
324
  path.push({ op: "close" });
282
- fillPath();
325
+ paintPath(true, true);
283
326
  break;
284
327
  case "n":
285
- case "S":
286
- case "s":
287
- case "W":
288
- case "W*":
289
- path = [];
328
+ paintPath(false, false);
290
329
  break;
330
+ case "W":
331
+ case "W*": break;
291
332
  default: break;
292
333
  }
293
334
  };
@@ -417,4 +458,4 @@ function skipInlineImage(lexer) {
417
458
  lexer.pos = ei < 0 ? lexer.length : ei + 2;
418
459
  }
419
460
  //#endregion
420
- export { interpretContent, multiply };
461
+ export { IDENTITY, interpretContent, multiply };
@@ -2,4 +2,4 @@ import { PdfDict, PdfValue } from '../pdf/objects.js';
2
2
  export interface Decryptor {
3
3
  decrypt: (value: PdfValue, objNum: number, gen: number) => PdfValue;
4
4
  }
5
- export declare function buildDecryptor(encrypt: PdfDict, idArray: PdfValue | undefined): Decryptor | undefined;
5
+ export declare function buildDecryptor(encrypt: PdfDict, idArray: PdfValue | undefined, password?: string): Decryptor | undefined;
@@ -43,7 +43,7 @@ var AES_SALT = Uint8Array.from([
43
43
  ]);
44
44
  var ZERO16 = new Uint8Array(16);
45
45
  var EMPTY = new Uint8Array(0);
46
- function buildDecryptor(encrypt, idArray) {
46
+ function buildDecryptor(encrypt, idArray, password = "") {
47
47
  const filter = encrypt.get("Filter");
48
48
  if (!(filter instanceof PdfName) || filter.value !== "Standard") return void 0;
49
49
  const v = numOf(encrypt.get("V"));
@@ -51,12 +51,12 @@ function buildDecryptor(encrypt, idArray) {
51
51
  let fileKey;
52
52
  let method;
53
53
  if (r >= 5 || v >= 5) {
54
- fileKey = deriveKeyR6(strBytes(encrypt.get("U")), strBytes(encrypt.get("UE")));
54
+ fileKey = deriveKeyR6(strBytes(encrypt.get("U")), strBytes(encrypt.get("UE")), password);
55
55
  method = "aesv3";
56
56
  } else {
57
57
  const keyLen = (numOf(encrypt.get("Length")) || 40) / 8;
58
58
  const id0 = Array.isArray(idArray) ? strBytes(idArray[0]) : EMPTY;
59
- fileKey = deriveKeyLegacy(strBytes(encrypt.get("O")), numOf(encrypt.get("P")) | 0, id0, r, Math.max(5, Math.min(16, keyLen)), encrypt.get("EncryptMetadata") !== false);
59
+ fileKey = deriveKeyLegacy(strBytes(encrypt.get("O")), numOf(encrypt.get("P")) | 0, id0, r, Math.max(5, Math.min(16, keyLen)), encrypt.get("EncryptMetadata") !== false, password);
60
60
  const m = cipherMethod(encrypt, v);
61
61
  if (m === void 0) return void 0;
62
62
  method = m;
@@ -65,23 +65,35 @@ function buildDecryptor(encrypt, idArray) {
65
65
  const key = fileKey;
66
66
  return { decrypt: (value, objNum, gen) => decryptValue(value, objNum, gen, key, method) };
67
67
  }
68
- function deriveKeyLegacy(o, p, id0, r, keyLen, encryptMetadata) {
68
+ function deriveKeyLegacy(o, p, id0, r, keyLen, encryptMetadata, password) {
69
69
  const tail = r >= 4 && !encryptMetadata ? Uint8Array.from([
70
70
  255,
71
71
  255,
72
72
  255,
73
73
  255
74
74
  ]) : EMPTY;
75
- let hash = md5(concat(PAD, o.subarray(0, 32), p32le(p), id0, tail));
75
+ let hash = md5(concat(padPassword(password), o.subarray(0, 32), p32le(p), id0, tail));
76
76
  if (r >= 3) for (let i = 0; i < 50; i++) hash = md5(hash.subarray(0, keyLen));
77
77
  return hash.subarray(0, keyLen);
78
78
  }
79
- function deriveKeyR6(u, ue) {
79
+ function deriveKeyR6(u, ue, password) {
80
80
  if (u.length < 48 || ue.length < 32) return void 0;
81
+ const pw = passwordBytes(password);
81
82
  const validationSalt = u.subarray(32, 40);
82
83
  const keySalt = u.subarray(40, 48);
83
- if (!equal(hash2B(EMPTY, validationSalt, EMPTY), u.subarray(0, 32))) return void 0;
84
- return aesCbcDecrypt(hash2B(EMPTY, keySalt, EMPTY), ZERO16, ue.subarray(0, 32), false);
84
+ if (!equal(hash2B(pw, validationSalt, EMPTY), u.subarray(0, 32))) return void 0;
85
+ return aesCbcDecrypt(hash2B(pw, keySalt, EMPTY), ZERO16, ue.subarray(0, 32), false);
86
+ }
87
+ function padPassword(password) {
88
+ const raw = strToBytes(password);
89
+ const out = new Uint8Array(32);
90
+ const n = Math.min(raw.length, 32);
91
+ out.set(raw.subarray(0, n), 0);
92
+ out.set(PAD.subarray(0, 32 - n), n);
93
+ return out;
94
+ }
95
+ function passwordBytes(password) {
96
+ return new TextEncoder().encode(password).subarray(0, 127);
85
97
  }
86
98
  function hash2B(pw, salt, udata) {
87
99
  let k = sha256(concat(pw, salt, udata));
@@ -14,7 +14,7 @@ export declare class PdfFile {
14
14
  private decryptor;
15
15
  private encryptObjNum;
16
16
  private constructor();
17
- static parse(bytes: Uint8Array): PdfFile;
17
+ static parse(bytes: Uint8Array, password?: string): PdfFile;
18
18
  private initEncryption;
19
19
  private readonly lengthResolver;
20
20
  resolve(value: PdfValue): PdfValue;
@@ -23,7 +23,7 @@ var PdfFile = class PdfFile {
23
23
  this.xref = xref;
24
24
  this.trailer = trailer;
25
25
  }
26
- static parse(bytes) {
26
+ static parse(bytes, password = "") {
27
27
  let xref = /* @__PURE__ */ new Map();
28
28
  let trailer = /* @__PURE__ */ new Map();
29
29
  try {
@@ -43,17 +43,17 @@ var PdfFile = class PdfFile {
43
43
  }
44
44
  }
45
45
  const file = new PdfFile(bytes, xref, trailer);
46
- file.initEncryption();
46
+ file.initEncryption(password);
47
47
  return file;
48
48
  }
49
- initEncryption() {
49
+ initEncryption(password) {
50
50
  const encVal = this.trailer.get("Encrypt");
51
51
  if (encVal === void 0) return;
52
52
  if (encVal instanceof PdfRef) this.encryptObjNum = encVal.id;
53
53
  const enc = this.resolve(encVal);
54
54
  if (!(enc instanceof Map)) return;
55
55
  const id = this.trailer.get("ID");
56
- this.decryptor = buildDecryptor(enc, Array.isArray(id) ? id : void 0);
56
+ this.decryptor = buildDecryptor(enc, Array.isArray(id) ? id : void 0, password);
57
57
  }
58
58
  lengthResolver = (r) => {
59
59
  const n = this.resolve(r);
@@ -92,11 +92,24 @@ function shapeBlock(v) {
92
92
  case "close": return { cmd: "close" };
93
93
  }
94
94
  });
95
+ const thick = v.strokeHex !== void 0 ? Math.max(v.lineWidth ?? .75, .5) : 0;
96
+ const fill = v.gradient !== void 0 ? {
97
+ kind: "gradient",
98
+ gradient: v.gradient
99
+ } : v.fillHex !== void 0 ? {
100
+ kind: "solid",
101
+ colorHex: v.fillHex
102
+ } : { kind: "none" };
103
+ const line = v.strokeHex !== void 0 ? {
104
+ width: pt(thick),
105
+ colorHex: v.strokeHex,
106
+ fill: "solid"
107
+ } : void 0;
95
108
  return {
96
109
  kind: "shape",
97
110
  shape: {
98
- width: pt(w),
99
- height: pt(h),
111
+ width: pt(Math.max(w, thick)),
112
+ height: pt(Math.max(h, thick)),
100
113
  geometry: {
101
114
  kind: "custom",
102
115
  custom: {
@@ -105,10 +118,8 @@ function shapeBlock(v) {
105
118
  commands
106
119
  }
107
120
  },
108
- fill: {
109
- kind: "solid",
110
- colorHex: v.fillHex
111
- },
121
+ fill,
122
+ ...line ? { line } : {},
112
123
  paragraphProperties: {}
113
124
  }
114
125
  };