reamkit 0.1.0-alpha.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 (162) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +95 -0
  3. package/dist/esm/bidi/algorithm.d.ts +9 -0
  4. package/dist/esm/bidi/algorithm.js +458 -0
  5. package/dist/esm/bidi/char-types.d.ts +2 -0
  6. package/dist/esm/bidi/char-types.js +439 -0
  7. package/dist/esm/bidi/index.d.ts +14 -0
  8. package/dist/esm/bidi/index.js +25 -0
  9. package/dist/esm/converter/docx-to-pdf.d.ts +15 -0
  10. package/dist/esm/converter/docx-to-pdf.js +227 -0
  11. package/dist/esm/converter/index.d.ts +4 -0
  12. package/dist/esm/converter/index.js +2 -0
  13. package/dist/esm/converter/xlsx-to-pdf.d.ts +13 -0
  14. package/dist/esm/converter/xlsx-to-pdf.js +515 -0
  15. package/dist/esm/crypto/asn1.d.ts +23 -0
  16. package/dist/esm/crypto/asn1.js +123 -0
  17. package/dist/esm/crypto/cms.d.ts +9 -0
  18. package/dist/esm/crypto/cms.js +34 -0
  19. package/dist/esm/crypto/index.d.ts +2 -0
  20. package/dist/esm/crypto/index.js +1 -0
  21. package/dist/esm/document-model/index.d.ts +1 -0
  22. package/dist/esm/document-model/index.js +0 -0
  23. package/dist/esm/document-model/types.d.ts +403 -0
  24. package/dist/esm/font/arabic-joining.d.ts +4 -0
  25. package/dist/esm/font/arabic-joining.js +97 -0
  26. package/dist/esm/font/binary-reader.d.ts +13 -0
  27. package/dist/esm/font/binary-reader.js +44 -0
  28. package/dist/esm/font/font-registry.d.ts +19 -0
  29. package/dist/esm/font/font-registry.js +39 -0
  30. package/dist/esm/font/index.d.ts +7 -0
  31. package/dist/esm/font/opentype-layout.d.ts +21 -0
  32. package/dist/esm/font/opentype-layout.js +329 -0
  33. package/dist/esm/font/ttf-parser.d.ts +29 -0
  34. package/dist/esm/font/ttf-parser.js +290 -0
  35. package/dist/esm/font/ttf-subset.d.ts +3 -0
  36. package/dist/esm/font/ttf-subset.js +201 -0
  37. package/dist/esm/fonts/index.d.ts +2 -0
  38. package/dist/esm/fonts/remote-fonts.d.ts +13 -0
  39. package/dist/esm/fonts/remote-fonts.js +94 -0
  40. package/dist/esm/hyphenation/index.d.ts +10 -0
  41. package/dist/esm/hyphenation/index.js +38 -0
  42. package/dist/esm/hyphenation/liang.d.ts +10 -0
  43. package/dist/esm/hyphenation/liang.js +79 -0
  44. package/dist/esm/hyphenation/patterns-en-us.d.ts +2 -0
  45. package/dist/esm/hyphenation/patterns-en-us.js +5 -0
  46. package/dist/esm/hyphenation/patterns-ru.d.ts +2 -0
  47. package/dist/esm/hyphenation/patterns-ru.js +5 -0
  48. package/dist/esm/index.d.ts +12 -0
  49. package/dist/esm/index.js +13 -0
  50. package/dist/esm/line-breaker/index.d.ts +2 -0
  51. package/dist/esm/line-breaker/knuth-plass.d.ts +30 -0
  52. package/dist/esm/line-breaker/knuth-plass.js +172 -0
  53. package/dist/esm/numbering/index.d.ts +1 -0
  54. package/dist/esm/numbering/state.d.ts +6 -0
  55. package/dist/esm/numbering/state.js +83 -0
  56. package/dist/esm/ooxml/drawingml/chart-parser.d.ts +3 -0
  57. package/dist/esm/ooxml/drawingml/chart-parser.js +218 -0
  58. package/dist/esm/ooxml/drawingml/colors.d.ts +17 -0
  59. package/dist/esm/ooxml/drawingml/colors.js +125 -0
  60. package/dist/esm/ooxml/drawingml/theme-parser.d.ts +1 -0
  61. package/dist/esm/ooxml/drawingml/theme-parser.js +55 -0
  62. package/dist/esm/ooxml/index.d.ts +1 -0
  63. package/dist/esm/ooxml/math/omml-parser.d.ts +4 -0
  64. package/dist/esm/ooxml/math/omml-parser.js +217 -0
  65. package/dist/esm/ooxml/spreadsheet/cell-reference.d.ts +6 -0
  66. package/dist/esm/ooxml/spreadsheet/cell-reference.js +26 -0
  67. package/dist/esm/ooxml/spreadsheet/defined-name-ref.d.ts +11 -0
  68. package/dist/esm/ooxml/spreadsheet/defined-name-ref.js +64 -0
  69. package/dist/esm/ooxml/spreadsheet/index.d.ts +12 -0
  70. package/dist/esm/ooxml/spreadsheet/index.js +7 -0
  71. package/dist/esm/ooxml/spreadsheet/number-format.d.ts +1 -0
  72. package/dist/esm/ooxml/spreadsheet/number-format.js +438 -0
  73. package/dist/esm/ooxml/spreadsheet/shared-strings-parser.d.ts +1 -0
  74. package/dist/esm/ooxml/spreadsheet/shared-strings-parser.js +47 -0
  75. package/dist/esm/ooxml/spreadsheet/styles-parser.d.ts +52 -0
  76. package/dist/esm/ooxml/spreadsheet/styles-parser.js +225 -0
  77. package/dist/esm/ooxml/spreadsheet/workbook-parser.d.ts +16 -0
  78. package/dist/esm/ooxml/spreadsheet/workbook-parser.js +90 -0
  79. package/dist/esm/ooxml/spreadsheet/worksheet-parser.d.ts +60 -0
  80. package/dist/esm/ooxml/spreadsheet/worksheet-parser.js +311 -0
  81. package/dist/esm/ooxml/wordproc/document-parser.d.ts +9 -0
  82. package/dist/esm/ooxml/wordproc/document-parser.js +274 -0
  83. package/dist/esm/ooxml/wordproc/drawing-parser.d.ts +33 -0
  84. package/dist/esm/ooxml/wordproc/drawing-parser.js +374 -0
  85. package/dist/esm/ooxml/wordproc/font-table.d.ts +15 -0
  86. package/dist/esm/ooxml/wordproc/font-table.js +82 -0
  87. package/dist/esm/ooxml/wordproc/index.d.ts +10 -0
  88. package/dist/esm/ooxml/wordproc/index.js +9 -0
  89. package/dist/esm/ooxml/wordproc/numbering-parser.d.ts +3 -0
  90. package/dist/esm/ooxml/wordproc/numbering-parser.js +89 -0
  91. package/dist/esm/ooxml/wordproc/paragraph-properties.d.ts +2 -0
  92. package/dist/esm/ooxml/wordproc/paragraph-properties.js +85 -0
  93. package/dist/esm/ooxml/wordproc/po-helpers.d.ts +14 -0
  94. package/dist/esm/ooxml/wordproc/po-helpers.js +76 -0
  95. package/dist/esm/ooxml/wordproc/po-to-flat.d.ts +2 -0
  96. package/dist/esm/ooxml/wordproc/po-to-flat.js +28 -0
  97. package/dist/esm/ooxml/wordproc/run-properties.d.ts +2 -0
  98. package/dist/esm/ooxml/wordproc/run-properties.js +82 -0
  99. package/dist/esm/ooxml/wordproc/settings-parser.d.ts +5 -0
  100. package/dist/esm/ooxml/wordproc/settings-parser.js +26 -0
  101. package/dist/esm/ooxml/wordproc/styles-parser.d.ts +3 -0
  102. package/dist/esm/ooxml/wordproc/styles-parser.js +67 -0
  103. package/dist/esm/ooxml/wordproc/table-parser.d.ts +3 -0
  104. package/dist/esm/ooxml/wordproc/table-parser.js +162 -0
  105. package/dist/esm/ooxml/wordproc/text-extractor.d.ts +1 -0
  106. package/dist/esm/ooxml/wordproc/text-extractor.js +1 -0
  107. package/dist/esm/ooxml/wordproc/xml-helpers.d.ts +9 -0
  108. package/dist/esm/ooxml/wordproc/xml-helpers.js +36 -0
  109. package/dist/esm/opc/core-properties.d.ts +11 -0
  110. package/dist/esm/opc/core-properties.js +51 -0
  111. package/dist/esm/opc/index.d.ts +5 -0
  112. package/dist/esm/opc/index.js +3 -0
  113. package/dist/esm/opc/package.d.ts +26 -0
  114. package/dist/esm/opc/package.js +113 -0
  115. package/dist/esm/opc/relationship-types.d.ts +3 -0
  116. package/dist/esm/opc/relationship-types.js +4 -0
  117. package/dist/esm/opc/relationships.d.ts +7 -0
  118. package/dist/esm/opc/relationships.js +28 -0
  119. package/dist/esm/pdf/arc-to-bezier.d.ts +5 -0
  120. package/dist/esm/pdf/arc-to-bezier.js +58 -0
  121. package/dist/esm/pdf/builtin-fonts.d.ts +2 -0
  122. package/dist/esm/pdf/chart-geometry.d.ts +64 -0
  123. package/dist/esm/pdf/chart-geometry.js +674 -0
  124. package/dist/esm/pdf/cid-font.d.ts +15 -0
  125. package/dist/esm/pdf/cid-font.js +174 -0
  126. package/dist/esm/pdf/embedded-file.d.ts +11 -0
  127. package/dist/esm/pdf/embedded-file.js +23 -0
  128. package/dist/esm/pdf/icc-profile.d.ts +1 -0
  129. package/dist/esm/pdf/icc-profile.js +166 -0
  130. package/dist/esm/pdf/image-xobject.d.ts +13 -0
  131. package/dist/esm/pdf/image-xobject.js +335 -0
  132. package/dist/esm/pdf/index.d.ts +11 -0
  133. package/dist/esm/pdf/index.js +5 -0
  134. package/dist/esm/pdf/math-layout.d.ts +45 -0
  135. package/dist/esm/pdf/math-layout.js +1138 -0
  136. package/dist/esm/pdf/objects.d.ts +32 -0
  137. package/dist/esm/pdf/objects.js +54 -0
  138. package/dist/esm/pdf/preset-geometry.d.ts +6 -0
  139. package/dist/esm/pdf/preset-geometry.js +199 -0
  140. package/dist/esm/pdf/serialize.d.ts +3 -0
  141. package/dist/esm/pdf/serialize.js +54 -0
  142. package/dist/esm/pdf/signature.d.ts +25 -0
  143. package/dist/esm/pdf/signature.js +126 -0
  144. package/dist/esm/pdf/struct-tree.d.ts +31 -0
  145. package/dist/esm/pdf/struct-tree.js +109 -0
  146. package/dist/esm/pdf/styled-page-renderer.d.ts +43 -0
  147. package/dist/esm/pdf/styled-page-renderer.js +2317 -0
  148. package/dist/esm/pdf/text-encoding.d.ts +2 -0
  149. package/dist/esm/pdf/text-page-renderer.d.ts +16 -0
  150. package/dist/esm/pdf/text-page-renderer.js +4 -0
  151. package/dist/esm/pdf/vector-graphics.d.ts +46 -0
  152. package/dist/esm/pdf/vector-graphics.js +103 -0
  153. package/dist/esm/pdf/writer.d.ts +10 -0
  154. package/dist/esm/pdf/writer.js +81 -0
  155. package/dist/esm/pdf/xmp.d.ts +13 -0
  156. package/dist/esm/pdf/xmp.js +38 -0
  157. package/dist/esm/style-cascade/index.d.ts +3 -0
  158. package/dist/esm/style-cascade/resolver.d.ts +4 -0
  159. package/dist/esm/style-cascade/resolver.js +96 -0
  160. package/dist/esm/style-cascade/types.d.ts +29 -0
  161. package/dist/esm/style-cascade/types.js +26 -0
  162. package/package.json +90 -0
@@ -0,0 +1,32 @@
1
+ export declare const PDF_NULL: unique symbol;
2
+ export type PdfNull = typeof PDF_NULL;
3
+ export declare class PdfName {
4
+ readonly value: string;
5
+ constructor(value: string);
6
+ }
7
+ export declare class PdfRef {
8
+ readonly id: number;
9
+ readonly generation: number;
10
+ constructor(id: number, generation?: number);
11
+ }
12
+ export declare class PdfStream {
13
+ readonly dict: PdfDict;
14
+ readonly data: Uint8Array;
15
+ constructor(dict: PdfDict, data: Uint8Array);
16
+ }
17
+ export declare class PdfHexString {
18
+ readonly bytes: Uint8Array;
19
+ constructor(bytes: Uint8Array);
20
+ }
21
+ export declare class PdfRawToken {
22
+ readonly token: string;
23
+ constructor(token: string);
24
+ }
25
+ export type PdfDict = Map<string, PdfValue>;
26
+ export type PdfArray = Array<PdfValue>;
27
+ export type PdfValue = PdfNull | boolean | number | string | PdfName | PdfHexString | PdfRawToken | PdfArray | PdfDict | PdfRef | PdfStream;
28
+ export declare const name: (v: string) => PdfName;
29
+ export declare const ref: (id: number, gen?: number) => PdfRef;
30
+ export declare const dict: (entries: Record<string, PdfValue>) => PdfDict;
31
+ export declare const stream: (entries: Record<string, PdfValue>, data: Uint8Array) => PdfStream;
32
+ export declare const unicodeString: (s: string) => PdfHexString;
@@ -0,0 +1,54 @@
1
+ //#region src/pdf/objects.ts
2
+ var PDF_NULL = Symbol("PDF_NULL");
3
+ var PdfName = class {
4
+ constructor(value) {
5
+ this.value = value;
6
+ }
7
+ };
8
+ var PdfRef = class {
9
+ constructor(id, generation = 0) {
10
+ this.id = id;
11
+ this.generation = generation;
12
+ }
13
+ };
14
+ var PdfStream = class {
15
+ constructor(dict, data) {
16
+ this.dict = dict;
17
+ this.data = data;
18
+ }
19
+ };
20
+ var PdfHexString = class {
21
+ constructor(bytes) {
22
+ this.bytes = bytes;
23
+ }
24
+ };
25
+ var PdfRawToken = class {
26
+ constructor(token) {
27
+ this.token = token;
28
+ }
29
+ };
30
+ var name = (v) => new PdfName(v);
31
+ var ref = (id, gen = 0) => new PdfRef(id, gen);
32
+ var dict = (entries) => new Map(Object.entries(entries));
33
+ var stream = (entries, data) => new PdfStream(dict(entries), data);
34
+ var unicodeString = (s) => {
35
+ const codepoints = [];
36
+ for (const ch of s) codepoints.push(ch.codePointAt(0));
37
+ const units = [];
38
+ for (const cp of codepoints) if (cp < 65536) units.push(cp);
39
+ else {
40
+ const adj = cp - 65536;
41
+ units.push(55296 + (adj >> 10));
42
+ units.push(56320 + (adj & 1023));
43
+ }
44
+ const out = new Uint8Array(2 + units.length * 2);
45
+ out[0] = 254;
46
+ out[1] = 255;
47
+ for (let i = 0; i < units.length; i++) {
48
+ out[2 + i * 2] = units[i] >> 8 & 255;
49
+ out[2 + i * 2 + 1] = units[i] & 255;
50
+ }
51
+ return new PdfHexString(out);
52
+ };
53
+ //#endregion
54
+ export { PDF_NULL, PdfHexString, PdfName, PdfRawToken, PdfRef, PdfStream, dict, name, ref, stream, unicodeString };
@@ -0,0 +1,6 @@
1
+ import { CustomGeometry } from '../document-model/index.js';
2
+ import { PathSegment, VectorPath } from './vector-graphics.js';
3
+ export declare function rectSegments(w: number, h: number): ReadonlyArray<PathSegment>;
4
+ export declare function rectPath(w: number, h: number): VectorPath;
5
+ export declare function presetPaths(preset: string, w: number, h: number, adjust: ReadonlyMap<string, number>): Array<VectorPath> | null;
6
+ export declare function customPaths(geom: CustomGeometry, wPt: number, hPt: number): Array<VectorPath>;
@@ -0,0 +1,199 @@
1
+ import { PathBuilder } from "./vector-graphics.js";
2
+ import { arcToBeziers, ellipseSegments, roundRectSegments } from "./arc-to-bezier.js";
3
+ //#region src/pdf/preset-geometry.ts
4
+ function rectSegments(w, h) {
5
+ return new PathBuilder().moveTo(0, 0).lineTo(w, 0).lineTo(w, h).lineTo(0, h).close().build().segments;
6
+ }
7
+ function rectPath(w, h) {
8
+ return { segments: rectSegments(w, h) };
9
+ }
10
+ function polygon(points) {
11
+ const b = new PathBuilder();
12
+ points.forEach(([x, y], i) => i === 0 ? b.moveTo(x, y) : b.lineTo(x, y));
13
+ return b.close().build();
14
+ }
15
+ var clamp = (v, lo, hi) => Math.max(lo, Math.min(hi, v));
16
+ var frac = (adjust, key, def) => (adjust.get(key) ?? def) / 1e5;
17
+ function presetPaths(preset, w, h, adjust) {
18
+ switch (preset) {
19
+ case "rect": return [rectPath(w, h)];
20
+ case "roundRect": return [{ segments: roundRectSegments(w, h, frac(adjust, "adj", 16667) * Math.min(w, h)) }];
21
+ case "ellipse": return [{ segments: ellipseSegments(w, h) }];
22
+ case "triangle": {
23
+ const apexX = clamp(frac(adjust, "adj", 5e4), 0, 1) * w;
24
+ return [polygon([
25
+ [0, 0],
26
+ [w, 0],
27
+ [apexX, h]
28
+ ])];
29
+ }
30
+ case "rtTriangle": return [polygon([
31
+ [0, 0],
32
+ [w, 0],
33
+ [0, h]
34
+ ])];
35
+ case "diamond": return [polygon([
36
+ [w / 2, 0],
37
+ [w, h / 2],
38
+ [w / 2, h],
39
+ [0, h / 2]
40
+ ])];
41
+ case "parallelogram": {
42
+ const s = clamp(frac(adjust, "adj", 25e3) * w, 0, w);
43
+ return [polygon([
44
+ [0, 0],
45
+ [w - s, 0],
46
+ [w, h],
47
+ [s, h]
48
+ ])];
49
+ }
50
+ case "trapezoid": {
51
+ const t = clamp(frac(adjust, "adj", 25e3) * w, 0, w / 2);
52
+ return [polygon([
53
+ [0, 0],
54
+ [w, 0],
55
+ [w - t, h],
56
+ [t, h]
57
+ ])];
58
+ }
59
+ case "pentagon": return [regularPolygon(w, h, 5)];
60
+ case "hexagon": {
61
+ const inset = clamp(frac(adjust, "adj", 25e3) * w, 0, w / 2);
62
+ return [polygon([
63
+ [inset, 0],
64
+ [w - inset, 0],
65
+ [w, h / 2],
66
+ [w - inset, h],
67
+ [inset, h],
68
+ [0, h / 2]
69
+ ])];
70
+ }
71
+ case "line":
72
+ case "straightConnector1": return [new PathBuilder().moveTo(0, h).lineTo(w, 0).build()];
73
+ case "rightArrow": return [blockArrow(w, h, adjust, "right")];
74
+ case "leftArrow": return [blockArrow(w, h, adjust, "left")];
75
+ case "upArrow": return [blockArrow(w, h, adjust, "up")];
76
+ case "downArrow": return [blockArrow(w, h, adjust, "down")];
77
+ default: return null;
78
+ }
79
+ }
80
+ function customPaths(geom, wPt, hPt) {
81
+ const sx = geom.pathWidth > 0 ? wPt / geom.pathWidth : 1;
82
+ const sy = geom.pathHeight > 0 ? hPt / geom.pathHeight : 1;
83
+ const tx = (x) => x * sx;
84
+ const ty = (y) => hPt - y * sy;
85
+ const b = new PathBuilder();
86
+ let curX = 0;
87
+ let curY = 0;
88
+ for (const cmd of geom.commands) switch (cmd.cmd) {
89
+ case "move":
90
+ b.moveTo(tx(cmd.x), ty(cmd.y));
91
+ curX = cmd.x;
92
+ curY = cmd.y;
93
+ break;
94
+ case "line":
95
+ b.lineTo(tx(cmd.x), ty(cmd.y));
96
+ curX = cmd.x;
97
+ curY = cmd.y;
98
+ break;
99
+ case "cubic":
100
+ b.cubicTo(tx(cmd.x1), ty(cmd.y1), tx(cmd.x2), ty(cmd.y2), tx(cmd.x), ty(cmd.y));
101
+ curX = cmd.x;
102
+ curY = cmd.y;
103
+ break;
104
+ case "quad": {
105
+ const c1x = curX + 2 / 3 * (cmd.x1 - curX);
106
+ const c1y = curY + 2 / 3 * (cmd.y1 - curY);
107
+ const c2x = cmd.x + 2 / 3 * (cmd.x1 - cmd.x);
108
+ const c2y = cmd.y + 2 / 3 * (cmd.y1 - cmd.y);
109
+ b.cubicTo(tx(c1x), ty(c1y), tx(c2x), ty(c2y), tx(cmd.x), ty(cmd.y));
110
+ curX = cmd.x;
111
+ curY = cmd.y;
112
+ break;
113
+ }
114
+ case "arc": {
115
+ const st = cmd.stAng / 6e4 * (Math.PI / 180);
116
+ const sw = cmd.swAng / 6e4 * (Math.PI / 180);
117
+ const cxP = curX - cmd.wR * Math.cos(st);
118
+ const cyP = curY - cmd.hR * Math.sin(st);
119
+ b.append(arcToBeziers(tx(cxP), ty(cyP), cmd.wR * sx, cmd.hR * sy, -st, -sw));
120
+ curX = cxP + cmd.wR * Math.cos(st + sw);
121
+ curY = cyP + cmd.hR * Math.sin(st + sw);
122
+ break;
123
+ }
124
+ case "close":
125
+ b.close();
126
+ break;
127
+ }
128
+ return [b.build()];
129
+ }
130
+ function regularPolygon(w, h, n) {
131
+ const cx = w / 2;
132
+ const cy = h / 2;
133
+ const rx = w / 2;
134
+ const ry = h / 2;
135
+ const pts = [];
136
+ for (let i = 0; i < n; i++) {
137
+ const a = Math.PI / 2 + i * 2 * Math.PI / n;
138
+ pts.push([cx + rx * Math.cos(a), cy + ry * Math.sin(a)]);
139
+ }
140
+ return polygon(pts);
141
+ }
142
+ function blockArrow(w, h, adjust, dir) {
143
+ const thick = clamp(frac(adjust, "adj1", 5e4), 0, 1);
144
+ const head = clamp(frac(adjust, "adj2", 5e4), 0, 1);
145
+ if (dir === "right" || dir === "left") {
146
+ const sb = h * (1 - thick) / 2;
147
+ const st = h * (1 + thick) / 2;
148
+ const hl = head * w;
149
+ if (dir === "right") {
150
+ const bx = w - hl;
151
+ return polygon([
152
+ [0, sb],
153
+ [bx, sb],
154
+ [bx, 0],
155
+ [w, h / 2],
156
+ [bx, h],
157
+ [bx, st],
158
+ [0, st]
159
+ ]);
160
+ }
161
+ const bx = hl;
162
+ return polygon([
163
+ [w, sb],
164
+ [bx, sb],
165
+ [bx, 0],
166
+ [0, h / 2],
167
+ [bx, h],
168
+ [bx, st],
169
+ [w, st]
170
+ ]);
171
+ }
172
+ const sl = w * (1 - thick) / 2;
173
+ const sr = w * (1 + thick) / 2;
174
+ const hh = head * h;
175
+ if (dir === "up") {
176
+ const by = h - hh;
177
+ return polygon([
178
+ [sl, 0],
179
+ [sr, 0],
180
+ [sr, by],
181
+ [w, by],
182
+ [w / 2, h],
183
+ [0, by],
184
+ [sl, by]
185
+ ]);
186
+ }
187
+ const ty = hh;
188
+ return polygon([
189
+ [sl, h],
190
+ [sr, h],
191
+ [sr, ty],
192
+ [w, ty],
193
+ [w / 2, 0],
194
+ [0, ty],
195
+ [sl, ty]
196
+ ]);
197
+ }
198
+ //#endregion
199
+ export { customPaths, presetPaths, rectPath };
@@ -0,0 +1,3 @@
1
+ import { PdfValue } from './objects.js';
2
+ export declare function serializeValue(v: PdfValue): string;
3
+ export declare function serializeIndirectObject(id: number, generation: number, value: PdfValue): Uint8Array;
@@ -0,0 +1,54 @@
1
+ import { PDF_NULL, PdfHexString, PdfName, PdfRawToken, PdfRef, PdfStream } from "./objects.js";
2
+ //#region src/pdf/serialize.ts
3
+ var encoder = new TextEncoder();
4
+ var NAME_ESCAPE = /[^!-~]|[#%()/<>[\]{}]/g;
5
+ var escapeName = (s) => s.replace(NAME_ESCAPE, (c) => `#${c.charCodeAt(0).toString(16).padStart(2, "0").toUpperCase()}`);
6
+ var escapeLiteralString = (s) => s.replace(/\\/g, "\\\\").replace(/\(/g, "\\(").replace(/\)/g, "\\)");
7
+ var formatNumber = (n) => {
8
+ if (Number.isInteger(n)) return String(n);
9
+ return n.toFixed(6).replace(/0+$/, "").replace(/\.$/, "");
10
+ };
11
+ function serializeValue(v) {
12
+ if (v === PDF_NULL) return "null";
13
+ if (typeof v === "boolean") return v ? "true" : "false";
14
+ if (typeof v === "number") {
15
+ if (!Number.isFinite(v)) throw new Error(`Non-finite number in PDF: ${v}`);
16
+ return formatNumber(v);
17
+ }
18
+ if (typeof v === "string") return `(${escapeLiteralString(v)})`;
19
+ if (v instanceof PdfHexString) {
20
+ let hex = "";
21
+ for (const b of v.bytes) hex += b.toString(16).padStart(2, "0").toUpperCase();
22
+ return `<${hex}>`;
23
+ }
24
+ if (v instanceof PdfRawToken) return v.token;
25
+ if (v instanceof PdfName) return `/${escapeName(v.value)}`;
26
+ if (Array.isArray(v)) return `[${v.map(serializeValue).join(" ")}]`;
27
+ if (v instanceof PdfRef) return `${v.id} ${v.generation} R`;
28
+ if (v instanceof Map) return serializeDict(v);
29
+ if (v instanceof PdfStream) throw new Error("PdfStream must be emitted as an indirect object, not inlined");
30
+ throw new Error(`Unknown PDF value: ${String(v)}`);
31
+ }
32
+ function serializeDict(d) {
33
+ const entries = [];
34
+ for (const [k, v] of d) entries.push(`/${escapeName(k)} ${serializeValue(v)}`);
35
+ return `<<${entries.join(" ")}>>`;
36
+ }
37
+ function serializeIndirectObject(id, generation, value) {
38
+ if (value instanceof PdfStream) return serializeStreamObject(id, generation, value);
39
+ const body = `${id} ${generation} obj\n${serializeValue(value)}\nendobj\n`;
40
+ return encoder.encode(body);
41
+ }
42
+ function serializeStreamObject(id, generation, s) {
43
+ const length = s.data.byteLength;
44
+ if (!s.dict.has("Length")) s.dict.set("Length", length);
45
+ const header = encoder.encode(`${id} ${generation} obj\n${serializeDict(s.dict)}\nstream\n`);
46
+ const footer = encoder.encode("\nendstream\nendobj\n");
47
+ const out = new Uint8Array(header.length + s.data.length + footer.length);
48
+ out.set(header, 0);
49
+ out.set(s.data, header.length);
50
+ out.set(footer, header.length + s.data.length);
51
+ return out;
52
+ }
53
+ //#endregion
54
+ export { serializeIndirectObject };
@@ -0,0 +1,25 @@
1
+ import { PdfDict, PdfRef } from './objects.js';
2
+ import { PdfDocument } from './writer.js';
3
+ export interface SignaturePlaceholder {
4
+ readonly reason?: string;
5
+ readonly location?: string;
6
+ readonly name?: string;
7
+ readonly contactInfo?: string;
8
+ readonly signingTime?: Date;
9
+ readonly fieldName?: string;
10
+ readonly reserveBytes?: number;
11
+ }
12
+ export interface SignerCredentials {
13
+ readonly certificate: Uint8Array;
14
+ readonly privateKey: CryptoKey;
15
+ readonly algorithm?: 'rsa' | 'ecdsa';
16
+ readonly extraCertificates?: ReadonlyArray<Uint8Array>;
17
+ readonly signingTime?: Date;
18
+ }
19
+ export interface SignatureOptions extends SignaturePlaceholder, SignerCredentials {
20
+ }
21
+ export declare function addSignaturePlaceholder(doc: PdfDocument, ph: SignaturePlaceholder, pageRef: PdfRef): {
22
+ readonly fieldRef: PdfRef;
23
+ readonly acroForm: PdfDict;
24
+ };
25
+ export declare function signPdf(pdf: Uint8Array, cred: SignerCredentials): Promise<Uint8Array>;
@@ -0,0 +1,126 @@
1
+ import { PdfHexString, PdfRawToken, dict, name, ref } from "./objects.js";
2
+ import { integer, seq } from "../crypto/asn1.js";
3
+ import { buildPkcs7Detached } from "../crypto/cms.js";
4
+ import "../crypto/index.js";
5
+ //#region src/pdf/signature.ts
6
+ var BYTE_RANGE_PLACEHOLDER = "[0 0000000000 0000000000 0000000000]";
7
+ var DEFAULT_RESERVE_BYTES = 8192;
8
+ function pad2(n) {
9
+ return n.toString().padStart(2, "0");
10
+ }
11
+ function pdfDate(d) {
12
+ return `D:${d.getUTCFullYear()}${pad2(d.getUTCMonth() + 1)}${pad2(d.getUTCDate())}${pad2(d.getUTCHours())}${pad2(d.getUTCMinutes())}${pad2(d.getUTCSeconds())}+00'00'`;
13
+ }
14
+ function addSignaturePlaceholder(doc, ph, pageRef) {
15
+ const reserve = ph.reserveBytes ?? DEFAULT_RESERVE_BYTES;
16
+ const sigEntries = {
17
+ Type: name("Sig"),
18
+ Filter: name("Adobe.PPKLite"),
19
+ SubFilter: name("adbe.pkcs7.detached"),
20
+ ByteRange: new PdfRawToken(BYTE_RANGE_PLACEHOLDER),
21
+ Contents: new PdfHexString(new Uint8Array(reserve))
22
+ };
23
+ if (ph.signingTime) sigEntries["M"] = pdfDate(ph.signingTime);
24
+ if (ph.reason) sigEntries["Reason"] = ph.reason;
25
+ if (ph.location) sigEntries["Location"] = ph.location;
26
+ if (ph.name) sigEntries["Name"] = ph.name;
27
+ if (ph.contactInfo) sigEntries["ContactInfo"] = ph.contactInfo;
28
+ const sigRef = doc.add(dict(sigEntries));
29
+ const fieldRef = doc.add(dict({
30
+ FT: name("Sig"),
31
+ Type: name("Annot"),
32
+ Subtype: name("Widget"),
33
+ T: ph.fieldName ?? "Signature1",
34
+ V: ref(sigRef.id),
35
+ P: ref(pageRef.id),
36
+ Rect: [
37
+ 0,
38
+ 0,
39
+ 0,
40
+ 0
41
+ ],
42
+ F: 132
43
+ }));
44
+ return {
45
+ fieldRef,
46
+ acroForm: dict({
47
+ Fields: [ref(fieldRef.id)],
48
+ SigFlags: 3
49
+ })
50
+ };
51
+ }
52
+ function indexOfAscii(buf, needle, from = 0) {
53
+ const n = needle.length;
54
+ outer: for (let i = from; i <= buf.length - n; i++) {
55
+ for (let j = 0; j < n; j++) if (buf[i + j] !== needle.charCodeAt(j)) continue outer;
56
+ return i;
57
+ }
58
+ return -1;
59
+ }
60
+ function writeAscii(buf, at, s) {
61
+ for (let i = 0; i < s.length; i++) buf[at + i] = s.charCodeAt(i);
62
+ }
63
+ function getSubtle() {
64
+ const c = globalThis.crypto;
65
+ if (!c?.subtle) throw new Error("Signing requires WebCrypto (globalThis.crypto.subtle)");
66
+ return c.subtle;
67
+ }
68
+ function asData(u) {
69
+ return u.buffer instanceof ArrayBuffer ? u : new Uint8Array(u);
70
+ }
71
+ function ecdsaRawToDer(raw) {
72
+ const half = raw.length >> 1;
73
+ return seq(integer(raw.slice(0, half)), integer(raw.slice(half)));
74
+ }
75
+ var HEX = "0123456789ABCDEF";
76
+ function toHex(bytes) {
77
+ let s = "";
78
+ for (const b of bytes) s += HEX[b >> 4] + HEX[b & 15];
79
+ return s;
80
+ }
81
+ async function signPdf(pdf, cred) {
82
+ const out = pdf.slice();
83
+ const brKey = indexOfAscii(out, "/ByteRange");
84
+ if (brKey < 0) throw new Error("signPdf: no /ByteRange placeholder found");
85
+ const brOpen = indexOfAscii(out, "[", brKey);
86
+ const brClose = indexOfAscii(out, "]", brOpen);
87
+ const ctOpen = indexOfAscii(out, "<", indexOfAscii(out, "/Contents", brClose));
88
+ const ctClose = indexOfAscii(out, ">", ctOpen);
89
+ if (brOpen < 0 || brClose < 0 || ctOpen < 0 || ctClose < 0) throw new Error("signPdf: malformed signature placeholder");
90
+ const a = 0;
91
+ const b = ctOpen + 1;
92
+ const c = ctClose;
93
+ const d = out.length - ctClose;
94
+ const brStr = `[${a} ${b} ${c} ${d}]`;
95
+ const brWidth = brClose - brOpen + 1;
96
+ if (brStr.length > brWidth) throw new Error("signPdf: /ByteRange placeholder too small");
97
+ writeAscii(out, brOpen, brStr.slice(0, -1) + " ".repeat(brWidth - brStr.length) + "]");
98
+ const segment = new Uint8Array(b + d);
99
+ segment.set(out.subarray(a, a + b), 0);
100
+ segment.set(out.subarray(c, c + d), b);
101
+ const subtle = getSubtle();
102
+ const digest = new Uint8Array(await subtle.digest("SHA-256", asData(segment)));
103
+ const signingTime = cred.signingTime ?? /* @__PURE__ */ new Date();
104
+ const isEcdsa = cred.algorithm === "ecdsa";
105
+ const cms = await buildPkcs7Detached({
106
+ certificate: cred.certificate,
107
+ ...cred.extraCertificates ? { extraCertificates: cred.extraCertificates } : {},
108
+ messageDigest: digest,
109
+ signingTime,
110
+ signatureAlgorithm: isEcdsa ? "ecdsa" : "rsa",
111
+ sign: async (attrs) => {
112
+ if (isEcdsa) return ecdsaRawToDer(new Uint8Array(await subtle.sign({
113
+ name: "ECDSA",
114
+ hash: "SHA-256"
115
+ }, cred.privateKey, asData(attrs))));
116
+ return new Uint8Array(await subtle.sign("RSASSA-PKCS1-v1_5", cred.privateKey, asData(attrs)));
117
+ }
118
+ });
119
+ const holeLen = ctClose - ctOpen - 1;
120
+ const hex = toHex(cms);
121
+ if (hex.length > holeLen) throw new Error(`signPdf: signature (${hex.length} hex) exceeds reserved /Contents (${holeLen}); raise reserveBytes`);
122
+ writeAscii(out, ctOpen + 1, hex + "0".repeat(holeLen - hex.length));
123
+ return out;
124
+ }
125
+ //#endregion
126
+ export { addSignaturePlaceholder, signPdf };
@@ -0,0 +1,31 @@
1
+ import { PdfRef } from './objects.js';
2
+ import { PdfDocument } from './writer.js';
3
+ export type StructType = 'Document' | 'Part' | 'Sect' | 'H1' | 'H2' | 'H3' | 'H4' | 'H5' | 'H6' | 'P' | 'L' | 'LI' | 'Lbl' | 'LBody' | 'Table' | 'TR' | 'TH' | 'TD' | 'Caption' | 'Figure' | 'Span';
4
+ interface Mcref {
5
+ readonly pageIndex: number;
6
+ readonly mcid: number;
7
+ }
8
+ export declare class StructNode {
9
+ readonly id: number;
10
+ type: StructType;
11
+ readonly children: Array<StructNode>;
12
+ readonly mcrefs: Array<Mcref>;
13
+ parent: StructNode | null;
14
+ ref: PdfRef | null;
15
+ alt: string | null;
16
+ lang: string | null;
17
+ scope: 'Row' | 'Column' | null;
18
+ colSpan: number | null;
19
+ rowSpan: number | null;
20
+ constructor(id: number, type: StructType);
21
+ }
22
+ export declare class StructTreeBuilder {
23
+ private readonly nodes;
24
+ readonly root: StructNode;
25
+ constructor();
26
+ create(type: StructType, parent: StructNode | null): StructNode;
27
+ node(id: number): StructNode;
28
+ addMcref(nodeId: number, pageIndex: number, mcid: number): void;
29
+ emit(doc: PdfDocument, pageRefs: ReadonlyArray<PdfRef>): PdfRef;
30
+ }
31
+ export {};
@@ -0,0 +1,109 @@
1
+ import { PDF_NULL, dict, name, unicodeString } from "./objects.js";
2
+ //#region src/pdf/struct-tree.ts
3
+ var StructNode = class {
4
+ children = [];
5
+ mcrefs = [];
6
+ parent = null;
7
+ ref = null;
8
+ alt = null;
9
+ lang = null;
10
+ scope = null;
11
+ colSpan = null;
12
+ rowSpan = null;
13
+ constructor(id, type) {
14
+ this.id = id;
15
+ this.type = type;
16
+ }
17
+ };
18
+ var StructTreeBuilder = class {
19
+ nodes = [];
20
+ root;
21
+ constructor() {
22
+ this.root = this.create("Document", null);
23
+ }
24
+ create(type, parent) {
25
+ const node = new StructNode(this.nodes.length, type);
26
+ node.parent = parent;
27
+ if (parent) parent.children.push(node);
28
+ this.nodes.push(node);
29
+ return node;
30
+ }
31
+ node(id) {
32
+ const n = this.nodes[id];
33
+ if (!n) throw new Error(`Unknown struct node id ${id}`);
34
+ return n;
35
+ }
36
+ addMcref(nodeId, pageIndex, mcid) {
37
+ this.node(nodeId).mcrefs.push({
38
+ pageIndex,
39
+ mcid
40
+ });
41
+ }
42
+ emit(doc, pageRefs) {
43
+ const order = [];
44
+ const walk = (n) => {
45
+ order.push(n);
46
+ for (const c of n.children) walk(c);
47
+ };
48
+ walk(this.root);
49
+ const dicts = /* @__PURE__ */ new Map();
50
+ for (const n of order) {
51
+ const d = dict({
52
+ Type: name("StructElem"),
53
+ S: name(n.type)
54
+ });
55
+ n.ref = doc.add(d);
56
+ dicts.set(n.id, d);
57
+ }
58
+ const rootDict = dict({ Type: name("StructTreeRoot") });
59
+ const rootRef = doc.add(rootDict);
60
+ for (const n of order) {
61
+ const d = dicts.get(n.id);
62
+ d.set("P", n.parent ? n.parent.ref : rootRef);
63
+ const firstPage = n.mcrefs.length > 0 ? n.mcrefs[0].pageIndex : void 0;
64
+ if (firstPage !== void 0) d.set("Pg", pageRefs[firstPage]);
65
+ const kids = [];
66
+ for (const c of n.children) kids.push(c.ref);
67
+ for (const m of n.mcrefs) kids.push(dict({
68
+ Type: name("MCR"),
69
+ Pg: pageRefs[m.pageIndex],
70
+ MCID: m.mcid
71
+ }));
72
+ if (kids.length === 1) d.set("K", kids[0]);
73
+ else if (kids.length > 1) d.set("K", kids);
74
+ if (n.alt !== null) d.set("Alt", unicodeString(n.alt));
75
+ if (n.lang !== null) d.set("Lang", n.lang);
76
+ if (n.scope !== null || n.colSpan !== null || n.rowSpan !== null) {
77
+ const attrs = { O: name("Table") };
78
+ if (n.scope !== null) attrs["Scope"] = name(n.scope);
79
+ if (n.colSpan !== null) attrs["ColSpan"] = n.colSpan;
80
+ if (n.rowSpan !== null) attrs["RowSpan"] = n.rowSpan;
81
+ d.set("A", dict(attrs));
82
+ }
83
+ }
84
+ const perPage = /* @__PURE__ */ new Map();
85
+ for (const n of order) for (const m of n.mcrefs) {
86
+ let arr = perPage.get(m.pageIndex);
87
+ if (!arr) {
88
+ arr = [];
89
+ perPage.set(m.pageIndex, arr);
90
+ }
91
+ arr[m.mcid] = n.ref;
92
+ }
93
+ const sortedKeys = [...perPage.keys()].sort((a, b) => a - b);
94
+ const nums = [];
95
+ for (const k of sortedKeys) {
96
+ const arr = perPage.get(k);
97
+ const dense = [];
98
+ for (let i = 0; i < arr.length; i++) dense.push(arr[i] ?? PDF_NULL);
99
+ nums.push(k, dense);
100
+ }
101
+ const parentTreeRef = doc.add(dict({ Nums: nums }));
102
+ rootDict.set("K", this.root.ref);
103
+ rootDict.set("ParentTree", parentTreeRef);
104
+ rootDict.set("ParentTreeNextKey", sortedKeys.length > 0 ? sortedKeys[sortedKeys.length - 1] + 1 : 0);
105
+ return rootRef;
106
+ }
107
+ };
108
+ //#endregion
109
+ export { StructTreeBuilder };
@@ -0,0 +1,43 @@
1
+ import { BodyElement, Chart, Numbering, Section, SectionProperties, StyleSheet } from '../document-model/index.js';
2
+ import { FontRegistry } from '../font/index.js';
3
+ import { FamilyKey } from '../fonts/index.js';
4
+ import { Hyphenator } from '../hyphenation/index.js';
5
+ import { AttachedFile } from './embedded-file.js';
6
+ import { SignaturePlaceholder } from './signature.js';
7
+ export type PdfALevel = 'PDF/A-1b' | 'PDF/A-1a' | 'PDF/A-2b' | 'PDF/A-2u' | 'PDF/A-2a' | 'PDF/A-3b' | 'PDF/A-3u' | 'PDF/A-3a';
8
+ export interface StyledRenderOptions {
9
+ readonly registry: FontRegistry;
10
+ readonly registriesByFamily?: ReadonlyMap<FamilyKey, FontRegistry>;
11
+ readonly embeddedFonts?: ReadonlyMap<string, FontRegistry>;
12
+ readonly styles: StyleSheet;
13
+ readonly numbering?: Numbering;
14
+ readonly section?: SectionProperties;
15
+ readonly sections?: ReadonlyArray<Section>;
16
+ readonly headersFooters?: ReadonlyMap<string, ReadonlyArray<BodyElement>>;
17
+ readonly images?: ReadonlyMap<string, Uint8Array>;
18
+ readonly charts?: ReadonlyMap<string, Chart>;
19
+ readonly pageWidth?: number;
20
+ readonly pageHeight?: number;
21
+ readonly marginLeft?: number;
22
+ readonly marginRight?: number;
23
+ readonly marginTop?: number;
24
+ readonly marginBottom?: number;
25
+ readonly hyphenator?: Hyphenator;
26
+ readonly info?: DocumentInfo;
27
+ readonly pdfA?: PdfALevel;
28
+ readonly tagged?: boolean;
29
+ readonly language?: string;
30
+ readonly attachments?: ReadonlyArray<AttachedFile>;
31
+ readonly signaturePlaceholder?: SignaturePlaceholder;
32
+ }
33
+ export interface DocumentInfo {
34
+ readonly title?: string;
35
+ readonly author?: string;
36
+ readonly subject?: string;
37
+ readonly keywords?: string;
38
+ readonly creator?: string;
39
+ readonly producer?: string;
40
+ readonly creationDate?: Date;
41
+ readonly modificationDate?: Date;
42
+ }
43
+ export declare function renderStyledPdf(body: ReadonlyArray<BodyElement>, options: StyledRenderOptions): Uint8Array;