pdf-codec 1.3.1 → 1.4.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 (198) hide show
  1. package/README.md +9 -0
  2. package/dist/afm-widths-BoeTOK2r.cjs +826 -0
  3. package/dist/afm-widths-Dxucrg7D.js +779 -0
  4. package/dist/afm-widths-DyDq56Ph.d.cts +19 -0
  5. package/dist/afm-widths-DyDq56Ph.d.ts +19 -0
  6. package/dist/afm-widths.cjs +4 -0
  7. package/dist/afm-widths.d.cts +2 -0
  8. package/dist/afm-widths.d.ts +2 -0
  9. package/dist/afm-widths.js +2 -0
  10. package/dist/assets/stix-two-math-font.cjs +5 -0
  11. package/dist/assets/stix-two-math-font.d.cts +4 -0
  12. package/dist/assets/stix-two-math-font.d.ts +4 -0
  13. package/dist/assets/stix-two-math-font.js +4 -0
  14. package/dist/bytes/crc32.cjs +21 -0
  15. package/dist/bytes/crc32.d.cts +4 -0
  16. package/dist/bytes/crc32.d.ts +4 -0
  17. package/dist/bytes/crc32.js +20 -0
  18. package/dist/bytes/flate.cjs +53 -0
  19. package/dist/bytes/flate.d.cts +12 -0
  20. package/dist/bytes/flate.d.ts +12 -0
  21. package/dist/bytes/flate.js +49 -0
  22. package/dist/bytes/reader.cjs +60 -0
  23. package/dist/bytes/reader.d.cts +20 -0
  24. package/dist/bytes/reader.d.ts +20 -0
  25. package/dist/bytes/reader.js +58 -0
  26. package/dist/bytes/writer.cjs +37 -0
  27. package/dist/bytes/writer.d.cts +13 -0
  28. package/dist/bytes/writer.d.ts +13 -0
  29. package/dist/bytes/writer.js +35 -0
  30. package/dist/cmap.cjs +110 -0
  31. package/dist/cmap.d.cts +8 -0
  32. package/dist/cmap.d.ts +8 -0
  33. package/dist/cmap.js +109 -0
  34. package/dist/codec.cjs +34 -0
  35. package/dist/codec.d.cts +167 -0
  36. package/dist/codec.d.ts +167 -0
  37. package/dist/codec.js +32 -0
  38. package/dist/content-read.cjs +126 -0
  39. package/dist/content-read.d.cts +21 -0
  40. package/dist/content-read.d.ts +21 -0
  41. package/dist/content-read.js +125 -0
  42. package/dist/content-write.cjs +138 -0
  43. package/dist/content-write.d.cts +24 -0
  44. package/dist/content-write.d.ts +24 -0
  45. package/dist/content-write.js +137 -0
  46. package/dist/diagnostics.cjs +21 -0
  47. package/dist/diagnostics.d.cts +19 -0
  48. package/dist/diagnostics.d.ts +19 -0
  49. package/dist/diagnostics.js +18 -0
  50. package/dist/document.cjs +162 -0
  51. package/dist/document.d.cts +12 -0
  52. package/dist/document.d.ts +12 -0
  53. package/dist/document.js +161 -0
  54. package/dist/encoding.cjs +5 -0
  55. package/dist/encoding.d.cts +6 -0
  56. package/dist/encoding.d.ts +6 -0
  57. package/dist/encoding.js +2 -0
  58. package/dist/filters.cjs +223 -0
  59. package/dist/filters.d.cts +14 -0
  60. package/dist/filters.d.ts +14 -0
  61. package/dist/filters.js +218 -0
  62. package/dist/font-read.cjs +199 -0
  63. package/dist/font-read.d.cts +23 -0
  64. package/dist/font-read.d.ts +23 -0
  65. package/dist/font-read.js +198 -0
  66. package/dist/font-style.cjs +35 -0
  67. package/dist/font-style.d.cts +14 -0
  68. package/dist/font-style.d.ts +14 -0
  69. package/dist/font-style.js +34 -0
  70. package/dist/fonts.cjs +124 -0
  71. package/dist/fonts.d.cts +15 -0
  72. package/dist/fonts.d.ts +15 -0
  73. package/dist/fonts.js +122 -0
  74. package/dist/formula.cjs +0 -0
  75. package/dist/formula.d.cts +10 -0
  76. package/dist/formula.d.ts +10 -0
  77. package/dist/formula.js +0 -0
  78. package/dist/image/jpeg-info.cjs +71 -0
  79. package/dist/image/jpeg-info.d.cts +12 -0
  80. package/dist/image/jpeg-info.d.ts +12 -0
  81. package/dist/image/jpeg-info.js +70 -0
  82. package/dist/image/png-decode.cjs +181 -0
  83. package/dist/image/png-decode.d.cts +14 -0
  84. package/dist/image/png-decode.d.ts +14 -0
  85. package/dist/image/png-decode.js +180 -0
  86. package/dist/image/png-encode.cjs +64 -0
  87. package/dist/image/png-encode.d.cts +8 -0
  88. package/dist/image/png-encode.d.ts +8 -0
  89. package/dist/image/png-encode.js +63 -0
  90. package/dist/image/png-filter.cjs +95 -0
  91. package/dist/image/png-filter.d.cts +6 -0
  92. package/dist/image/png-filter.d.ts +6 -0
  93. package/dist/image/png-filter.js +93 -0
  94. package/dist/images-read.cjs +250 -0
  95. package/dist/images-read.d.cts +13 -0
  96. package/dist/images-read.d.ts +13 -0
  97. package/dist/images-read.js +249 -0
  98. package/dist/index.cjs +45 -5912
  99. package/dist/index.d.cts +21 -483
  100. package/dist/index.d.ts +21 -483
  101. package/dist/index.js +18 -5885
  102. package/dist/interpret.cjs +587 -0
  103. package/dist/interpret.d.cts +84 -0
  104. package/dist/interpret.d.ts +84 -0
  105. package/dist/interpret.js +586 -0
  106. package/dist/lexer.cjs +180 -0
  107. package/dist/lexer.d.cts +29 -0
  108. package/dist/lexer.d.ts +29 -0
  109. package/dist/lexer.js +179 -0
  110. package/dist/math-cmap.cjs +81 -0
  111. package/dist/math-cmap.d.cts +6 -0
  112. package/dist/math-cmap.d.ts +6 -0
  113. package/dist/math-cmap.js +80 -0
  114. package/dist/math-content-write.cjs +83 -0
  115. package/dist/math-content-write.d.cts +11 -0
  116. package/dist/math-content-write.d.ts +11 -0
  117. package/dist/math-content-write.js +81 -0
  118. package/dist/math-font-write.cjs +100 -0
  119. package/dist/math-font-write.d.cts +19 -0
  120. package/dist/math-font-write.d.ts +19 -0
  121. package/dist/math-font-write.js +99 -0
  122. package/dist/math-font.cjs +103 -0
  123. package/dist/math-font.d.cts +25 -0
  124. package/dist/math-font.d.ts +25 -0
  125. package/dist/math-font.js +102 -0
  126. package/dist/math-hmtx.cjs +17 -0
  127. package/dist/math-hmtx.d.cts +8 -0
  128. package/dist/math-hmtx.d.ts +8 -0
  129. package/dist/math-hmtx.js +16 -0
  130. package/dist/math-table.cjs +117 -0
  131. package/dist/math-table.d.cts +45 -0
  132. package/dist/math-table.d.ts +45 -0
  133. package/dist/math-table.js +116 -0
  134. package/dist/math-types-Ba8qAf1p.d.cts +82 -0
  135. package/dist/math-types-Ba8qAf1p.d.ts +82 -0
  136. package/dist/math-types.cjs +0 -0
  137. package/dist/math-types.d.cts +2 -0
  138. package/dist/math-types.d.ts +2 -0
  139. package/dist/math-types.js +0 -0
  140. package/dist/matrix-B3c2_a2f.d.cts +18 -0
  141. package/dist/matrix-B3c2_a2f.d.ts +18 -0
  142. package/dist/matrix.cjs +93 -0
  143. package/dist/matrix.d.cts +2 -0
  144. package/dist/matrix.d.ts +2 -0
  145. package/dist/matrix.js +83 -0
  146. package/dist/measure.cjs +54 -0
  147. package/dist/measure.d.cts +20 -0
  148. package/dist/measure.d.ts +20 -0
  149. package/dist/measure.js +53 -0
  150. package/dist/objects.cjs +100 -0
  151. package/dist/objects.d.cts +58 -0
  152. package/dist/objects.d.ts +58 -0
  153. package/dist/objects.js +84 -0
  154. package/dist/parse.cjs +230 -0
  155. package/dist/parse.d.cts +13 -0
  156. package/dist/parse.d.ts +13 -0
  157. package/dist/parse.js +228 -0
  158. package/dist/predictors.cjs +64 -0
  159. package/dist/predictors.d.cts +13 -0
  160. package/dist/predictors.d.ts +13 -0
  161. package/dist/predictors.js +62 -0
  162. package/dist/read.cjs +418 -0
  163. package/dist/read.d.cts +21 -0
  164. package/dist/read.d.ts +21 -0
  165. package/dist/read.js +413 -0
  166. package/dist/serialize.cjs +69 -0
  167. package/dist/serialize.d.cts +8 -0
  168. package/dist/serialize.d.ts +8 -0
  169. package/dist/serialize.js +66 -0
  170. package/dist/sfnt.cjs +52 -0
  171. package/dist/sfnt.d.cts +17 -0
  172. package/dist/sfnt.d.ts +17 -0
  173. package/dist/sfnt.js +46 -0
  174. package/dist/text-layout.cjs +224 -0
  175. package/dist/text-layout.d.cts +37 -0
  176. package/dist/text-layout.d.ts +37 -0
  177. package/dist/text-layout.js +222 -0
  178. package/dist/util/abort.cjs +7 -0
  179. package/dist/util/abort.d.cts +4 -0
  180. package/dist/util/abort.d.ts +4 -0
  181. package/dist/util/abort.js +6 -0
  182. package/dist/util/base64.cjs +48 -0
  183. package/dist/util/base64.d.cts +5 -0
  184. package/dist/util/base64.d.ts +5 -0
  185. package/dist/util/base64.js +46 -0
  186. package/dist/winansi.cjs +5 -0
  187. package/dist/winansi.d.cts +20 -0
  188. package/dist/winansi.d.ts +20 -0
  189. package/dist/winansi.js +2 -0
  190. package/dist/write.cjs +421 -0
  191. package/dist/write.d.cts +16 -0
  192. package/dist/write.d.ts +16 -0
  193. package/dist/write.js +419 -0
  194. package/dist/xref.cjs +325 -0
  195. package/dist/xref.d.cts +21 -0
  196. package/dist/xref.d.ts +21 -0
  197. package/dist/xref.js +324 -0
  198. package/package.json +9 -1
package/dist/sfnt.js ADDED
@@ -0,0 +1,46 @@
1
+ //#region src/sfnt.ts
2
+ function readUint16(bytes, offset) {
3
+ return bytes[offset] << 8 | bytes[offset + 1];
4
+ }
5
+ function readUint32(bytes, offset) {
6
+ return (bytes[offset] << 24 | bytes[offset + 1] << 16 | bytes[offset + 2] << 8 | bytes[offset + 3]) >>> 0;
7
+ }
8
+ const TABLE_DIRECTORY_HEADER_SIZE = 12;
9
+ const TABLE_RECORD_SIZE = 16;
10
+ function parseSfnt(bytes) {
11
+ const numTables = readUint16(bytes, 4);
12
+ const tables = /* @__PURE__ */ new Map();
13
+ for (let i = 0; i < numTables; i++) {
14
+ const recordOffset = TABLE_DIRECTORY_HEADER_SIZE + i * TABLE_RECORD_SIZE;
15
+ const tag = new TextDecoder("ascii").decode(bytes.subarray(recordOffset, recordOffset + 4));
16
+ const offset = readUint32(bytes, recordOffset + 8);
17
+ const length = readUint32(bytes, recordOffset + 12);
18
+ tables.set(tag, {
19
+ offset,
20
+ length
21
+ });
22
+ }
23
+ return {
24
+ bytes,
25
+ tables
26
+ };
27
+ }
28
+ function sfntTableBytes(font, tag) {
29
+ const table = font.tables.get(tag);
30
+ return table === void 0 ? void 0 : font.bytes.subarray(table.offset, table.offset + table.length);
31
+ }
32
+ function u8(bytes, offset) {
33
+ return bytes[offset];
34
+ }
35
+ function u16(bytes, offset) {
36
+ return readUint16(bytes, offset);
37
+ }
38
+ function i16(bytes, offset) {
39
+ const value = readUint16(bytes, offset);
40
+ return value >= 32768 ? value - 65536 : value;
41
+ }
42
+ function u32(bytes, offset) {
43
+ return readUint32(bytes, offset);
44
+ }
45
+ //#endregion
46
+ export { i16, parseSfnt, sfntTableBytes, u16, u32, u8 };
@@ -0,0 +1,224 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/text-layout.ts
3
+ const WORD_OR_WHITESPACE_PATTERN = /\n|\s+|\S+/g;
4
+ function atomizeRuns(runs, measurer) {
5
+ const atoms = [];
6
+ let wordFragments = [];
7
+ let wordWidth = 0;
8
+ function flushWord() {
9
+ if (wordFragments.length > 0) {
10
+ atoms.push({
11
+ kind: "box",
12
+ fragments: wordFragments,
13
+ widthPt: wordWidth
14
+ });
15
+ wordFragments = [];
16
+ wordWidth = 0;
17
+ }
18
+ }
19
+ for (const run of runs) {
20
+ const tokens = run.text.match(WORD_OR_WHITESPACE_PATTERN) ?? [];
21
+ for (const token of tokens) if (token === "\n") {
22
+ flushWord();
23
+ atoms.push({
24
+ kind: "break",
25
+ widthPt: 0
26
+ });
27
+ } else if (/^\s+$/.test(token)) {
28
+ flushWord();
29
+ atoms.push({
30
+ kind: "glue",
31
+ widthPt: measurer.widthOfTextAtSize(token, run.font, run.sizePt)
32
+ });
33
+ } else {
34
+ wordFragments.push({
35
+ text: token,
36
+ font: run.font,
37
+ sizePt: run.sizePt,
38
+ color: run.color,
39
+ underline: run.underline,
40
+ hyperlink: run.hyperlink,
41
+ sourcePath: run.sourcePath
42
+ });
43
+ wordWidth += measurer.widthOfTextAtSize(token, run.font, run.sizePt);
44
+ }
45
+ }
46
+ flushWord();
47
+ return atoms;
48
+ }
49
+ function fragmentsWidth(fragments, measurer) {
50
+ let total = 0;
51
+ for (const f of fragments) total += measurer.widthOfTextAtSize(f.text, f.font, f.sizePt);
52
+ return total;
53
+ }
54
+ function splitTextToWidth(text, font, sizePt, measurer, maxWidthPt) {
55
+ const chars = Array.from(text);
56
+ let width = 0;
57
+ let splitIndex = 0;
58
+ for (let i = 0; i < chars.length; i++) {
59
+ const charWidth = measurer.widthOfTextAtSize(chars[i], font, sizePt);
60
+ if (width + charWidth > maxWidthPt && splitIndex > 0) break;
61
+ width += charWidth;
62
+ splitIndex = i + 1;
63
+ }
64
+ if (splitIndex === 0 && chars.length > 0) splitIndex = 1;
65
+ return {
66
+ fitText: chars.slice(0, splitIndex).join(""),
67
+ restText: chars.slice(splitIndex).join("")
68
+ };
69
+ }
70
+ function splitBoxToWidth(atom, measurer, maxWidthPt) {
71
+ const fitFragments = [];
72
+ let fitWidth = 0;
73
+ for (let idx = 0; idx < atom.fragments.length; idx++) {
74
+ const fragment = atom.fragments[idx];
75
+ const fragmentWidth = measurer.widthOfTextAtSize(fragment.text, fragment.font, fragment.sizePt);
76
+ if (fitWidth + fragmentWidth <= maxWidthPt) {
77
+ fitFragments.push(fragment);
78
+ fitWidth += fragmentWidth;
79
+ continue;
80
+ }
81
+ const { fitText, restText } = splitTextToWidth(fragment.text, fragment.font, fragment.sizePt, measurer, maxWidthPt - fitWidth);
82
+ if (fitText.length > 0) fitFragments.push({
83
+ ...fragment,
84
+ text: fitText
85
+ });
86
+ const restFragments = [];
87
+ if (restText.length > 0) restFragments.push({
88
+ ...fragment,
89
+ text: restText
90
+ });
91
+ restFragments.push(...atom.fragments.slice(idx + 1));
92
+ if (restFragments.length === 0) return {
93
+ fit: {
94
+ kind: "box",
95
+ fragments: fitFragments,
96
+ widthPt: fragmentsWidth(fitFragments, measurer)
97
+ },
98
+ rest: void 0
99
+ };
100
+ return {
101
+ fit: {
102
+ kind: "box",
103
+ fragments: fitFragments,
104
+ widthPt: fragmentsWidth(fitFragments, measurer)
105
+ },
106
+ rest: {
107
+ kind: "box",
108
+ fragments: restFragments,
109
+ widthPt: fragmentsWidth(restFragments, measurer)
110
+ }
111
+ };
112
+ }
113
+ return {
114
+ fit: atom,
115
+ rest: void 0
116
+ };
117
+ }
118
+ function buildLine(atoms, measurer) {
119
+ const fragments = [];
120
+ let xOffsetPt = 0;
121
+ let maxSizePt = 0;
122
+ let ascentPt = 0;
123
+ let descentPt = 0;
124
+ for (const atom of atoms) if (atom.kind === "box") for (const fragment of atom.fragments) {
125
+ fragments.push({
126
+ ...fragment,
127
+ xOffsetPt
128
+ });
129
+ xOffsetPt += measurer.widthOfTextAtSize(fragment.text, fragment.font, fragment.sizePt);
130
+ maxSizePt = Math.max(maxSizePt, fragment.sizePt);
131
+ ascentPt = Math.max(ascentPt, measurer.ascenderAtSize(fragment.font, fragment.sizePt));
132
+ descentPt = Math.min(descentPt, measurer.descenderAtSize(fragment.font, fragment.sizePt));
133
+ }
134
+ else xOffsetPt += atom.widthPt;
135
+ return {
136
+ fragments,
137
+ widthPt: xOffsetPt,
138
+ maxSizePt,
139
+ ascentPt,
140
+ descentPt
141
+ };
142
+ }
143
+ function buildEmptyLine(runs, measurer) {
144
+ const first = runs[0];
145
+ if (first === void 0) return {
146
+ fragments: [],
147
+ widthPt: 0,
148
+ maxSizePt: 0,
149
+ ascentPt: 0,
150
+ descentPt: 0
151
+ };
152
+ return {
153
+ fragments: [],
154
+ widthPt: 0,
155
+ maxSizePt: first.sizePt,
156
+ ascentPt: measurer.ascenderAtSize(first.font, first.sizePt),
157
+ descentPt: measurer.descenderAtSize(first.font, first.sizePt)
158
+ };
159
+ }
160
+ function wrapRunsToWidth(runs, measurer, maxWidthPt, options = {}) {
161
+ const breakLongWords = options.breakLongWords ?? true;
162
+ if (maxWidthPt <= 0) {
163
+ const atoms = atomizeRuns(runs, measurer).filter((a) => a.kind !== "break");
164
+ return atoms.length === 0 ? [buildEmptyLine(runs, measurer)] : [buildLine(atoms, measurer)];
165
+ }
166
+ const queue = atomizeRuns(runs, measurer);
167
+ const lines = [];
168
+ let current = [];
169
+ let currentWidth = 0;
170
+ function pushLine() {
171
+ while (current.length > 0 && current[current.length - 1]?.kind === "glue") {
172
+ const removed = current.pop();
173
+ currentWidth -= removed?.widthPt ?? 0;
174
+ }
175
+ lines.push(current.length === 0 ? buildEmptyLine(runs, measurer) : buildLine(current, measurer));
176
+ current = [];
177
+ currentWidth = 0;
178
+ }
179
+ let i = 0;
180
+ while (i < queue.length) {
181
+ const atom = queue[i];
182
+ if (atom.kind === "break") {
183
+ pushLine();
184
+ i++;
185
+ continue;
186
+ }
187
+ if (currentWidth + atom.widthPt <= maxWidthPt) {
188
+ current.push(atom);
189
+ currentWidth += atom.widthPt;
190
+ i++;
191
+ continue;
192
+ }
193
+ if (current.length > 0) {
194
+ pushLine();
195
+ continue;
196
+ }
197
+ if (atom.kind === "box" && breakLongWords) {
198
+ const { fit, rest } = splitBoxToWidth(atom, measurer, maxWidthPt);
199
+ current.push(fit);
200
+ currentWidth += fit.widthPt;
201
+ if (rest === void 0) i++;
202
+ else queue[i] = rest;
203
+ pushLine();
204
+ continue;
205
+ }
206
+ current.push(atom);
207
+ currentWidth += atom.widthPt;
208
+ i++;
209
+ pushLine();
210
+ }
211
+ if (current.length > 0 || lines.length === 0) pushLine();
212
+ return lines;
213
+ }
214
+ function wrapTextToWidth(text, font, sizePt, color, measurer, maxWidthPt) {
215
+ return wrapRunsToWidth([{
216
+ text,
217
+ font,
218
+ sizePt,
219
+ color
220
+ }], measurer, maxWidthPt).map((line) => line.fragments.map((f) => f.text).join(""));
221
+ }
222
+ //#endregion
223
+ exports.wrapRunsToWidth = wrapRunsToWidth;
224
+ exports.wrapTextToWidth = wrapTextToWidth;
@@ -0,0 +1,37 @@
1
+ import { TextMeasurer } from "./measure.cjs";
2
+ import { Color, LayoutFont } from "document-schema.js";
3
+ //#region src/text-layout.d.ts
4
+ interface StyledRun {
5
+ readonly text: string;
6
+ readonly font: LayoutFont;
7
+ readonly sizePt: number;
8
+ readonly color: Color;
9
+ readonly underline?: boolean;
10
+ readonly hyperlink?: string;
11
+ readonly sourcePath?: string;
12
+ }
13
+ interface StyledFragment {
14
+ readonly text: string;
15
+ readonly font: LayoutFont;
16
+ readonly sizePt: number;
17
+ readonly color: Color;
18
+ readonly underline?: boolean;
19
+ readonly hyperlink?: string;
20
+ readonly sourcePath?: string;
21
+ }
22
+ interface WrappedLine {
23
+ readonly fragments: readonly (StyledFragment & {
24
+ readonly xOffsetPt: number;
25
+ })[];
26
+ readonly widthPt: number;
27
+ readonly maxSizePt: number;
28
+ readonly ascentPt: number;
29
+ readonly descentPt: number;
30
+ }
31
+ interface WrapOptions {
32
+ readonly breakLongWords?: boolean;
33
+ }
34
+ declare function wrapRunsToWidth(runs: readonly StyledRun[], measurer: TextMeasurer, maxWidthPt: number, options?: WrapOptions): WrappedLine[];
35
+ declare function wrapTextToWidth(text: string, font: LayoutFont, sizePt: number, color: Color, measurer: TextMeasurer, maxWidthPt: number): string[];
36
+ //#endregion
37
+ export { StyledFragment, StyledRun, WrapOptions, WrappedLine, wrapRunsToWidth, wrapTextToWidth };
@@ -0,0 +1,37 @@
1
+ import { TextMeasurer } from "./measure.js";
2
+ import { Color, LayoutFont } from "document-schema.js";
3
+ //#region src/text-layout.d.ts
4
+ interface StyledRun {
5
+ readonly text: string;
6
+ readonly font: LayoutFont;
7
+ readonly sizePt: number;
8
+ readonly color: Color;
9
+ readonly underline?: boolean;
10
+ readonly hyperlink?: string;
11
+ readonly sourcePath?: string;
12
+ }
13
+ interface StyledFragment {
14
+ readonly text: string;
15
+ readonly font: LayoutFont;
16
+ readonly sizePt: number;
17
+ readonly color: Color;
18
+ readonly underline?: boolean;
19
+ readonly hyperlink?: string;
20
+ readonly sourcePath?: string;
21
+ }
22
+ interface WrappedLine {
23
+ readonly fragments: readonly (StyledFragment & {
24
+ readonly xOffsetPt: number;
25
+ })[];
26
+ readonly widthPt: number;
27
+ readonly maxSizePt: number;
28
+ readonly ascentPt: number;
29
+ readonly descentPt: number;
30
+ }
31
+ interface WrapOptions {
32
+ readonly breakLongWords?: boolean;
33
+ }
34
+ declare function wrapRunsToWidth(runs: readonly StyledRun[], measurer: TextMeasurer, maxWidthPt: number, options?: WrapOptions): WrappedLine[];
35
+ declare function wrapTextToWidth(text: string, font: LayoutFont, sizePt: number, color: Color, measurer: TextMeasurer, maxWidthPt: number): string[];
36
+ //#endregion
37
+ export { StyledFragment, StyledRun, WrapOptions, WrappedLine, wrapRunsToWidth, wrapTextToWidth };
@@ -0,0 +1,222 @@
1
+ //#region src/text-layout.ts
2
+ const WORD_OR_WHITESPACE_PATTERN = /\n|\s+|\S+/g;
3
+ function atomizeRuns(runs, measurer) {
4
+ const atoms = [];
5
+ let wordFragments = [];
6
+ let wordWidth = 0;
7
+ function flushWord() {
8
+ if (wordFragments.length > 0) {
9
+ atoms.push({
10
+ kind: "box",
11
+ fragments: wordFragments,
12
+ widthPt: wordWidth
13
+ });
14
+ wordFragments = [];
15
+ wordWidth = 0;
16
+ }
17
+ }
18
+ for (const run of runs) {
19
+ const tokens = run.text.match(WORD_OR_WHITESPACE_PATTERN) ?? [];
20
+ for (const token of tokens) if (token === "\n") {
21
+ flushWord();
22
+ atoms.push({
23
+ kind: "break",
24
+ widthPt: 0
25
+ });
26
+ } else if (/^\s+$/.test(token)) {
27
+ flushWord();
28
+ atoms.push({
29
+ kind: "glue",
30
+ widthPt: measurer.widthOfTextAtSize(token, run.font, run.sizePt)
31
+ });
32
+ } else {
33
+ wordFragments.push({
34
+ text: token,
35
+ font: run.font,
36
+ sizePt: run.sizePt,
37
+ color: run.color,
38
+ underline: run.underline,
39
+ hyperlink: run.hyperlink,
40
+ sourcePath: run.sourcePath
41
+ });
42
+ wordWidth += measurer.widthOfTextAtSize(token, run.font, run.sizePt);
43
+ }
44
+ }
45
+ flushWord();
46
+ return atoms;
47
+ }
48
+ function fragmentsWidth(fragments, measurer) {
49
+ let total = 0;
50
+ for (const f of fragments) total += measurer.widthOfTextAtSize(f.text, f.font, f.sizePt);
51
+ return total;
52
+ }
53
+ function splitTextToWidth(text, font, sizePt, measurer, maxWidthPt) {
54
+ const chars = Array.from(text);
55
+ let width = 0;
56
+ let splitIndex = 0;
57
+ for (let i = 0; i < chars.length; i++) {
58
+ const charWidth = measurer.widthOfTextAtSize(chars[i], font, sizePt);
59
+ if (width + charWidth > maxWidthPt && splitIndex > 0) break;
60
+ width += charWidth;
61
+ splitIndex = i + 1;
62
+ }
63
+ if (splitIndex === 0 && chars.length > 0) splitIndex = 1;
64
+ return {
65
+ fitText: chars.slice(0, splitIndex).join(""),
66
+ restText: chars.slice(splitIndex).join("")
67
+ };
68
+ }
69
+ function splitBoxToWidth(atom, measurer, maxWidthPt) {
70
+ const fitFragments = [];
71
+ let fitWidth = 0;
72
+ for (let idx = 0; idx < atom.fragments.length; idx++) {
73
+ const fragment = atom.fragments[idx];
74
+ const fragmentWidth = measurer.widthOfTextAtSize(fragment.text, fragment.font, fragment.sizePt);
75
+ if (fitWidth + fragmentWidth <= maxWidthPt) {
76
+ fitFragments.push(fragment);
77
+ fitWidth += fragmentWidth;
78
+ continue;
79
+ }
80
+ const { fitText, restText } = splitTextToWidth(fragment.text, fragment.font, fragment.sizePt, measurer, maxWidthPt - fitWidth);
81
+ if (fitText.length > 0) fitFragments.push({
82
+ ...fragment,
83
+ text: fitText
84
+ });
85
+ const restFragments = [];
86
+ if (restText.length > 0) restFragments.push({
87
+ ...fragment,
88
+ text: restText
89
+ });
90
+ restFragments.push(...atom.fragments.slice(idx + 1));
91
+ if (restFragments.length === 0) return {
92
+ fit: {
93
+ kind: "box",
94
+ fragments: fitFragments,
95
+ widthPt: fragmentsWidth(fitFragments, measurer)
96
+ },
97
+ rest: void 0
98
+ };
99
+ return {
100
+ fit: {
101
+ kind: "box",
102
+ fragments: fitFragments,
103
+ widthPt: fragmentsWidth(fitFragments, measurer)
104
+ },
105
+ rest: {
106
+ kind: "box",
107
+ fragments: restFragments,
108
+ widthPt: fragmentsWidth(restFragments, measurer)
109
+ }
110
+ };
111
+ }
112
+ return {
113
+ fit: atom,
114
+ rest: void 0
115
+ };
116
+ }
117
+ function buildLine(atoms, measurer) {
118
+ const fragments = [];
119
+ let xOffsetPt = 0;
120
+ let maxSizePt = 0;
121
+ let ascentPt = 0;
122
+ let descentPt = 0;
123
+ for (const atom of atoms) if (atom.kind === "box") for (const fragment of atom.fragments) {
124
+ fragments.push({
125
+ ...fragment,
126
+ xOffsetPt
127
+ });
128
+ xOffsetPt += measurer.widthOfTextAtSize(fragment.text, fragment.font, fragment.sizePt);
129
+ maxSizePt = Math.max(maxSizePt, fragment.sizePt);
130
+ ascentPt = Math.max(ascentPt, measurer.ascenderAtSize(fragment.font, fragment.sizePt));
131
+ descentPt = Math.min(descentPt, measurer.descenderAtSize(fragment.font, fragment.sizePt));
132
+ }
133
+ else xOffsetPt += atom.widthPt;
134
+ return {
135
+ fragments,
136
+ widthPt: xOffsetPt,
137
+ maxSizePt,
138
+ ascentPt,
139
+ descentPt
140
+ };
141
+ }
142
+ function buildEmptyLine(runs, measurer) {
143
+ const first = runs[0];
144
+ if (first === void 0) return {
145
+ fragments: [],
146
+ widthPt: 0,
147
+ maxSizePt: 0,
148
+ ascentPt: 0,
149
+ descentPt: 0
150
+ };
151
+ return {
152
+ fragments: [],
153
+ widthPt: 0,
154
+ maxSizePt: first.sizePt,
155
+ ascentPt: measurer.ascenderAtSize(first.font, first.sizePt),
156
+ descentPt: measurer.descenderAtSize(first.font, first.sizePt)
157
+ };
158
+ }
159
+ function wrapRunsToWidth(runs, measurer, maxWidthPt, options = {}) {
160
+ const breakLongWords = options.breakLongWords ?? true;
161
+ if (maxWidthPt <= 0) {
162
+ const atoms = atomizeRuns(runs, measurer).filter((a) => a.kind !== "break");
163
+ return atoms.length === 0 ? [buildEmptyLine(runs, measurer)] : [buildLine(atoms, measurer)];
164
+ }
165
+ const queue = atomizeRuns(runs, measurer);
166
+ const lines = [];
167
+ let current = [];
168
+ let currentWidth = 0;
169
+ function pushLine() {
170
+ while (current.length > 0 && current[current.length - 1]?.kind === "glue") {
171
+ const removed = current.pop();
172
+ currentWidth -= removed?.widthPt ?? 0;
173
+ }
174
+ lines.push(current.length === 0 ? buildEmptyLine(runs, measurer) : buildLine(current, measurer));
175
+ current = [];
176
+ currentWidth = 0;
177
+ }
178
+ let i = 0;
179
+ while (i < queue.length) {
180
+ const atom = queue[i];
181
+ if (atom.kind === "break") {
182
+ pushLine();
183
+ i++;
184
+ continue;
185
+ }
186
+ if (currentWidth + atom.widthPt <= maxWidthPt) {
187
+ current.push(atom);
188
+ currentWidth += atom.widthPt;
189
+ i++;
190
+ continue;
191
+ }
192
+ if (current.length > 0) {
193
+ pushLine();
194
+ continue;
195
+ }
196
+ if (atom.kind === "box" && breakLongWords) {
197
+ const { fit, rest } = splitBoxToWidth(atom, measurer, maxWidthPt);
198
+ current.push(fit);
199
+ currentWidth += fit.widthPt;
200
+ if (rest === void 0) i++;
201
+ else queue[i] = rest;
202
+ pushLine();
203
+ continue;
204
+ }
205
+ current.push(atom);
206
+ currentWidth += atom.widthPt;
207
+ i++;
208
+ pushLine();
209
+ }
210
+ if (current.length > 0 || lines.length === 0) pushLine();
211
+ return lines;
212
+ }
213
+ function wrapTextToWidth(text, font, sizePt, color, measurer, maxWidthPt) {
214
+ return wrapRunsToWidth([{
215
+ text,
216
+ font,
217
+ sizePt,
218
+ color
219
+ }], measurer, maxWidthPt).map((line) => line.fragments.map((f) => f.text).join(""));
220
+ }
221
+ //#endregion
222
+ export { wrapRunsToWidth, wrapTextToWidth };
@@ -0,0 +1,7 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/util/abort.ts
3
+ function throwIfAborted(signal) {
4
+ if (signal?.aborted === true) throw new DOMException("Aborted", "AbortError");
5
+ }
6
+ //#endregion
7
+ exports.throwIfAborted = throwIfAborted;
@@ -0,0 +1,4 @@
1
+ //#region src/util/abort.d.ts
2
+ declare function throwIfAborted(signal: AbortSignal | undefined): void;
3
+ //#endregion
4
+ export { throwIfAborted };
@@ -0,0 +1,4 @@
1
+ //#region src/util/abort.d.ts
2
+ declare function throwIfAborted(signal: AbortSignal | undefined): void;
3
+ //#endregion
4
+ export { throwIfAborted };
@@ -0,0 +1,6 @@
1
+ //#region src/util/abort.ts
2
+ function throwIfAborted(signal) {
3
+ if (signal?.aborted === true) throw new DOMException("Aborted", "AbortError");
4
+ }
5
+ //#endregion
6
+ export { throwIfAborted };
@@ -0,0 +1,48 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/util/base64.ts
3
+ const TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
4
+ const DECODE = (() => {
5
+ const map = (/* @__PURE__ */ new Uint8Array(256)).fill(255);
6
+ for (let i = 0; i < 64; i = i + 1) map[TABLE.charCodeAt(i)] = i;
7
+ return map;
8
+ })();
9
+ function bytesToBase64(bytes) {
10
+ let out = "";
11
+ const len = bytes.length;
12
+ for (let i = 0; i < len; i = i + 3) {
13
+ const b0 = bytes[i];
14
+ const b1 = i + 1 < len ? bytes[i + 1] : 0;
15
+ const b2 = i + 2 < len ? bytes[i + 2] : 0;
16
+ out += TABLE[b0 >> 2];
17
+ out += TABLE[(b0 & 3) << 4 | b1 >> 4];
18
+ out += i + 1 < len ? TABLE[(b1 & 15) << 2 | b2 >> 6] : "=";
19
+ out += i + 2 < len ? TABLE[b2 & 63] : "=";
20
+ }
21
+ return out;
22
+ }
23
+ function base64ToBytes(b64) {
24
+ const clean = b64.replace(/[^A-Za-z0-9+/=]/g, "");
25
+ const len = clean.length;
26
+ const out = new Uint8Array(len * 3 / 4 | 0);
27
+ let p = 0;
28
+ for (let i = 0; i < len; i = i + 4) {
29
+ const c0 = DECODE[clean.charCodeAt(i)];
30
+ const c1 = DECODE[clean.charCodeAt(i + 1)];
31
+ const c2 = clean.charCodeAt(i + 2);
32
+ const c3 = clean.charCodeAt(i + 3);
33
+ if (c0 === 255 || c1 === 255) throw new Error("invalid base64 input");
34
+ out[p++] = c0 << 2 | c1 >> 4;
35
+ if (c2 !== 61) {
36
+ const d2 = DECODE[c2];
37
+ out[p++] = (c1 & 15) << 4 | d2 >> 2;
38
+ if (c3 !== 61) {
39
+ const d3 = DECODE[c3];
40
+ out[p++] = (d2 & 3) << 6 | d3;
41
+ }
42
+ }
43
+ }
44
+ return out.subarray(0, p);
45
+ }
46
+ //#endregion
47
+ exports.base64ToBytes = base64ToBytes;
48
+ exports.bytesToBase64 = bytesToBase64;
@@ -0,0 +1,5 @@
1
+ //#region src/util/base64.d.ts
2
+ declare function bytesToBase64(bytes: Uint8Array<ArrayBuffer>): string;
3
+ declare function base64ToBytes(b64: string): Uint8Array<ArrayBuffer>;
4
+ //#endregion
5
+ export { base64ToBytes, bytesToBase64 };
@@ -0,0 +1,5 @@
1
+ //#region src/util/base64.d.ts
2
+ declare function bytesToBase64(bytes: Uint8Array<ArrayBuffer>): string;
3
+ declare function base64ToBytes(b64: string): Uint8Array<ArrayBuffer>;
4
+ //#endregion
5
+ export { base64ToBytes, bytesToBase64 };
@@ -0,0 +1,46 @@
1
+ //#region src/util/base64.ts
2
+ const TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
3
+ const DECODE = (() => {
4
+ const map = (/* @__PURE__ */ new Uint8Array(256)).fill(255);
5
+ for (let i = 0; i < 64; i = i + 1) map[TABLE.charCodeAt(i)] = i;
6
+ return map;
7
+ })();
8
+ function bytesToBase64(bytes) {
9
+ let out = "";
10
+ const len = bytes.length;
11
+ for (let i = 0; i < len; i = i + 3) {
12
+ const b0 = bytes[i];
13
+ const b1 = i + 1 < len ? bytes[i + 1] : 0;
14
+ const b2 = i + 2 < len ? bytes[i + 2] : 0;
15
+ out += TABLE[b0 >> 2];
16
+ out += TABLE[(b0 & 3) << 4 | b1 >> 4];
17
+ out += i + 1 < len ? TABLE[(b1 & 15) << 2 | b2 >> 6] : "=";
18
+ out += i + 2 < len ? TABLE[b2 & 63] : "=";
19
+ }
20
+ return out;
21
+ }
22
+ function base64ToBytes(b64) {
23
+ const clean = b64.replace(/[^A-Za-z0-9+/=]/g, "");
24
+ const len = clean.length;
25
+ const out = new Uint8Array(len * 3 / 4 | 0);
26
+ let p = 0;
27
+ for (let i = 0; i < len; i = i + 4) {
28
+ const c0 = DECODE[clean.charCodeAt(i)];
29
+ const c1 = DECODE[clean.charCodeAt(i + 1)];
30
+ const c2 = clean.charCodeAt(i + 2);
31
+ const c3 = clean.charCodeAt(i + 3);
32
+ if (c0 === 255 || c1 === 255) throw new Error("invalid base64 input");
33
+ out[p++] = c0 << 2 | c1 >> 4;
34
+ if (c2 !== 61) {
35
+ const d2 = DECODE[c2];
36
+ out[p++] = (c1 & 15) << 4 | d2 >> 2;
37
+ if (c3 !== 61) {
38
+ const d3 = DECODE[c3];
39
+ out[p++] = (d2 & 3) << 6 | d3;
40
+ }
41
+ }
42
+ }
43
+ return out.subarray(0, p);
44
+ }
45
+ //#endregion
46
+ export { base64ToBytes, bytesToBase64 };