reamkit 1.22.0 → 1.24.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 (101) hide show
  1. package/dist/esm/core/bmp.d.ts +33 -0
  2. package/dist/esm/core/bmp.js +276 -0
  3. package/dist/esm/core/converter/ream.d.ts +16 -0
  4. package/dist/esm/core/converter/ream.js +59 -9
  5. package/dist/esm/core/document-model/types.d.ts +55 -0
  6. package/dist/esm/core/drawingml/chart-geometry.js +14 -7
  7. package/dist/esm/core/drawingml/colors.d.ts +4 -2
  8. package/dist/esm/core/drawingml/colors.js +15 -0
  9. package/dist/esm/core/drawingml/diagram/colors.d.ts +52 -0
  10. package/dist/esm/core/drawingml/diagram/colors.js +125 -0
  11. package/dist/esm/core/drawingml/diagram/data-model.d.ts +47 -0
  12. package/dist/esm/core/drawingml/diagram/data-model.js +119 -0
  13. package/dist/esm/core/drawingml/diagram/layout-engine.d.ts +46 -0
  14. package/dist/esm/core/drawingml/diagram/layout-engine.js +948 -0
  15. package/dist/esm/core/drawingml/diagram/run.d.ts +37 -0
  16. package/dist/esm/core/drawingml/diagram/run.js +50 -0
  17. package/dist/esm/core/drawingml/diagram/to-drawing.d.ts +16 -0
  18. package/dist/esm/core/drawingml/diagram/to-drawing.js +86 -0
  19. package/dist/esm/core/drawingml/preset-geometry.js +116 -6
  20. package/dist/esm/core/drawingml/text-warp.d.ts +58 -0
  21. package/dist/esm/core/drawingml/text-warp.js +355 -0
  22. package/dist/esm/core/drawingml/theme-parser.d.ts +38 -0
  23. package/dist/esm/core/drawingml/theme-parser.js +73 -4
  24. package/dist/esm/core/font/measure.d.ts +12 -0
  25. package/dist/esm/core/font/measure.js +36 -0
  26. package/dist/esm/core/fonts/families.d.ts +10 -0
  27. package/dist/esm/core/fonts/families.js +44 -0
  28. package/dist/esm/core/fonts/index.d.ts +3 -2
  29. package/dist/esm/core/fonts/remote-fonts.d.ts +50 -0
  30. package/dist/esm/core/fonts/remote-fonts.js +114 -8
  31. package/dist/esm/core/fonts/scripts.d.ts +26 -0
  32. package/dist/esm/core/fonts/scripts.js +177 -0
  33. package/dist/esm/core/images.d.ts +30 -2
  34. package/dist/esm/core/images.js +121 -5
  35. package/dist/esm/core/metafile/blit.d.ts +33 -0
  36. package/dist/esm/core/metafile/blit.js +67 -0
  37. package/dist/esm/core/metafile/dib.d.ts +61 -0
  38. package/dist/esm/core/metafile/dib.js +205 -0
  39. package/dist/esm/core/metafile/emf.js +280 -38
  40. package/dist/esm/core/metafile/picture.d.ts +61 -1
  41. package/dist/esm/core/metafile/picture.js +70 -1
  42. package/dist/esm/core/metafile/wmf.js +202 -13
  43. package/dist/esm/core/ole/escher-blip.d.ts +12 -0
  44. package/dist/esm/core/ole/escher-blip.js +98 -0
  45. package/dist/esm/{pdf-reader → core}/png-encode.js +1 -1
  46. package/dist/esm/excel/print-model.js +5 -3
  47. package/dist/esm/excel/sheet-drawing.js +1 -1
  48. package/dist/esm/excel/sheet-to-flow.js +16 -2
  49. package/dist/esm/excel/styles-parser.js +1 -1
  50. package/dist/esm/excel/xls/biff-reader.js +53 -18
  51. package/dist/esm/excel/xls/biff-styles.d.ts +5 -2
  52. package/dist/esm/excel/xls/biff-styles.js +9 -7
  53. package/dist/esm/excel/xls/escher.js +90 -24
  54. package/dist/esm/html/html-writer.js +2 -1
  55. package/dist/esm/layout/page-doc.d.ts +74 -0
  56. package/dist/esm/layout/page-doc.js +14 -1
  57. package/dist/esm/layout/styled-layout.d.ts +2 -2
  58. package/dist/esm/layout/styled-layout.js +475 -48
  59. package/dist/esm/pdf/shading.js +8 -6
  60. package/dist/esm/pdf/styled-page-emitter.js +77 -5
  61. package/dist/esm/pdf/vector-graphics.js +1 -1
  62. package/dist/esm/pdf-reader/image-decode.js +1 -1
  63. package/dist/esm/pptx/embedded-fonts.d.ts +31 -0
  64. package/dist/esm/pptx/embedded-fonts.js +104 -0
  65. package/dist/esm/pptx/placeholder-cascade.d.ts +73 -6
  66. package/dist/esm/pptx/placeholder-cascade.js +114 -18
  67. package/dist/esm/pptx/ppt/ppt-reader.js +191 -13
  68. package/dist/esm/pptx/ppt/ppt-text.d.ts +107 -1
  69. package/dist/esm/pptx/ppt/ppt-text.js +873 -144
  70. package/dist/esm/pptx/pptx-reader.d.ts +8 -0
  71. package/dist/esm/pptx/pptx-reader.js +117 -15
  72. package/dist/esm/pptx/preset-table-styles.d.ts +9 -0
  73. package/dist/esm/pptx/preset-table-styles.js +27 -0
  74. package/dist/esm/pptx/slide-parser.d.ts +11 -2
  75. package/dist/esm/pptx/slide-parser.js +203 -44
  76. package/dist/esm/pptx/sp-helpers.d.ts +9 -4
  77. package/dist/esm/pptx/sp-helpers.js +48 -9
  78. package/dist/esm/pptx/table-style.d.ts +16 -1
  79. package/dist/esm/pptx/table-style.js +104 -10
  80. package/dist/esm/svg/svg-writer.js +1 -0
  81. package/dist/esm/word/document-parser.d.ts +11 -2
  82. package/dist/esm/word/document-parser.js +10 -7
  83. package/dist/esm/word/docx-reader.js +32 -16
  84. package/dist/esm/word/docx-to-pdf.d.ts +8 -7
  85. package/dist/esm/word/docx-to-pdf.js +25 -7
  86. package/dist/esm/word/docx-writer.js +4 -0
  87. package/dist/esm/word/drawing-parser.d.ts +20 -0
  88. package/dist/esm/word/drawing-parser.js +67 -22
  89. package/dist/esm/word/numbering-parser.d.ts +2 -1
  90. package/dist/esm/word/numbering-parser.js +6 -6
  91. package/dist/esm/word/paragraph-properties.d.ts +2 -1
  92. package/dist/esm/word/paragraph-properties.js +2 -2
  93. package/dist/esm/word/run-properties.d.ts +5 -2
  94. package/dist/esm/word/run-properties.js +13 -8
  95. package/dist/esm/word/styles-parser.d.ts +2 -1
  96. package/dist/esm/word/styles-parser.js +12 -12
  97. package/dist/esm/word/table-parser.js +6 -3
  98. package/dist/esm/word/theme-fonts.d.ts +10 -0
  99. package/dist/esm/word/theme-fonts.js +28 -0
  100. package/package.json +1 -1
  101. /package/dist/esm/{pdf-reader → core}/png-encode.d.ts +0 -0
@@ -1,3 +1,4 @@
1
+ import { readEscherBlip } from "../../core/ole/escher-blip.js";
1
2
  //#region src/excel/xls/escher.ts
2
3
  var FBT_BSTORE_CONTAINER = 61441;
3
4
  var FBT_BSE = 61447;
@@ -6,6 +7,7 @@ var FBT_OPT = 61451;
6
7
  var FBT_CLIENT_ANCHOR = 61456;
7
8
  var PROP_PIB = 260;
8
9
  var MAX_DEPTH = 24;
10
+ var BSE_HEADER_BYTES = 36;
9
11
  function* records(d) {
10
12
  let off = 0;
11
13
  while (off + 8 <= d.length) {
@@ -37,7 +39,11 @@ function parseBlipStore(msoDrawingGroup) {
37
39
  const store = findContainer(msoDrawingGroup, FBT_BSTORE_CONTAINER, 0);
38
40
  if (!store) return [];
39
41
  const out = [];
40
- for (const r of records(store)) if (r.type === FBT_BSE) out.push(findImageBytes(r.data));
42
+ for (const r of records(store)) {
43
+ if (r.type !== FBT_BSE) continue;
44
+ const nested = [...records(r.data.subarray(BSE_HEADER_BYTES))][0];
45
+ out.push(nested ? readEscherBlip(nested.type, nested.instance, nested.data) ?? findImageBytes(r.data) : findImageBytes(r.data));
46
+ }
41
47
  return out;
42
48
  }
43
49
  function findContainer(d, type, depth) {
@@ -74,6 +80,9 @@ function collectPictures(d, out, depth) {
74
80
  }
75
81
  var FBT_SP = 61450;
76
82
  var FBT_CLIENT_TEXTBOX = 61453;
83
+ var FBT_SPGR_CONTAINER = 61443;
84
+ var FBT_SPGR = 61449;
85
+ var FBT_CHILD_ANCHOR = 61455;
77
86
  var PROP_FILL_COLOR = 385;
78
87
  var PROP_LINE_COLOR = 448;
79
88
  /**
@@ -86,30 +95,84 @@ function parseSheetShapes(msoDrawing) {
86
95
  collectShapes(msoDrawing, out, 0);
87
96
  return out;
88
97
  }
89
- function collectShapes(d, out, depth) {
98
+ function collectShapes(d, out, depth, group) {
90
99
  if (depth > MAX_DEPTH) return;
91
- for (const r of records(d)) if (r.type === FBT_SP_CONTAINER) {
92
- let shapeType = 0;
93
- let hasText = false;
94
- let pib;
95
- let anchor;
96
- let fill;
97
- let line;
98
- for (const child of records(r.data)) if (child.type === FBT_SP) shapeType = child.instance;
99
- else if (child.type === FBT_OPT) {
100
- pib = optProperty(child.data, child.instance, PROP_PIB);
101
- fill = optColor(child.data, child.instance, PROP_FILL_COLOR);
102
- line = optColor(child.data, child.instance, PROP_LINE_COLOR);
103
- } else if (child.type === FBT_CLIENT_ANCHOR) anchor = parseAnchor(child.data);
104
- else if (child.type === FBT_CLIENT_TEXTBOX) hasText = true;
105
- if (pib === void 0 && shapeType !== 0) out.push({
106
- shapeType,
107
- hasText,
108
- ...anchor ? { anchor } : {},
109
- ...fill ? { fillColorHex: fill } : {},
110
- ...line ? { lineColorHex: line } : {}
111
- });
112
- } else if (r.isContainer) collectShapes(r.data, out, depth + 1);
100
+ for (const r of records(d)) {
101
+ if (r.type === FBT_SPGR_CONTAINER) {
102
+ collectShapes(r.data, out, depth + 1, groupFrame(r.data) ?? group);
103
+ continue;
104
+ }
105
+ if (r.type === FBT_SP_CONTAINER) {
106
+ let shapeType = 0;
107
+ let hasText = false;
108
+ let pib;
109
+ let anchor;
110
+ let fill;
111
+ let line;
112
+ for (const child of records(r.data)) if (child.type === FBT_SP) shapeType = child.instance;
113
+ else if (child.type === FBT_OPT) {
114
+ pib = optProperty(child.data, child.instance, PROP_PIB);
115
+ fill = optColor(child.data, child.instance, PROP_FILL_COLOR);
116
+ line = optColor(child.data, child.instance, PROP_LINE_COLOR);
117
+ } else if (child.type === FBT_CLIENT_ANCHOR) anchor = parseAnchor(child.data);
118
+ else if (child.type === FBT_CHILD_ANCHOR && group) anchor = childAnchor(child.data, group);
119
+ else if (child.type === FBT_CLIENT_TEXTBOX) hasText = true;
120
+ if (pib === void 0 && shapeType !== 0) out.push({
121
+ shapeType,
122
+ hasText,
123
+ ...anchor ? { anchor } : {},
124
+ ...fill ? { fillColorHex: fill } : {},
125
+ ...line ? { lineColorHex: line } : {}
126
+ });
127
+ } else if (r.isContainer) collectShapes(r.data, out, depth + 1, group);
128
+ }
129
+ }
130
+ function groupFrame(spgrData) {
131
+ const sp = [...records(spgrData)].find((r) => r.type === FBT_SP_CONTAINER);
132
+ if (!sp) return void 0;
133
+ let box;
134
+ let anchor;
135
+ for (const child of records(sp.data)) if (child.type === FBT_SPGR && child.data.length >= 16) {
136
+ const x = i32(child.data, 0);
137
+ const y = i32(child.data, 4);
138
+ box = {
139
+ x,
140
+ y,
141
+ w: i32(child.data, 8) - x,
142
+ h: i32(child.data, 12) - y
143
+ };
144
+ } else if (child.type === FBT_CLIENT_ANCHOR) anchor = parseAnchor(child.data);
145
+ if (!box || !anchor || box.w <= 0 || box.h <= 0) return void 0;
146
+ return {
147
+ anchor,
148
+ ...box
149
+ };
150
+ }
151
+ function childAnchor(d, g) {
152
+ if (d.length < 16) return void 0;
153
+ const from = (v, lo, hi, min, size) => lo + (v - min) / size * (hi - lo);
154
+ const x1 = g.anchor.col1 + g.anchor.dx1 / 1024;
155
+ const x2 = g.anchor.col2 + g.anchor.dx2 / 1024;
156
+ const y1 = g.anchor.row1 + g.anchor.dy1 / 1024;
157
+ const y2 = g.anchor.row2 + g.anchor.dy2 / 1024;
158
+ const cell = (v) => {
159
+ const whole = Math.max(0, Math.min(65535, Math.floor(v)));
160
+ return [whole, Math.max(0, Math.min(1023, Math.round((v - whole) * 1024)))];
161
+ };
162
+ const [col1, dx1] = cell(from(i32(d, 0), x1, x2, g.x, g.w));
163
+ const [row1, dy1] = cell(from(i32(d, 4), y1, y2, g.y, g.h));
164
+ const [col2, dx2] = cell(from(i32(d, 8), x1, x2, g.x, g.w));
165
+ const [row2, dy2] = cell(from(i32(d, 12), y1, y2, g.y, g.h));
166
+ return {
167
+ col1,
168
+ dx1,
169
+ row1,
170
+ dy1,
171
+ col2,
172
+ dx2,
173
+ row2,
174
+ dy2
175
+ };
113
176
  }
114
177
  function optColor(d, count, wantId) {
115
178
  const v = optProperty(d, count, wantId);
@@ -179,6 +242,9 @@ function matches(d, off, magic) {
179
242
  for (let i = 0; i < magic.length; i++) if (d[off + i] !== magic[i]) return false;
180
243
  return true;
181
244
  }
245
+ function i32(d, off) {
246
+ return u32(d, off) | 0;
247
+ }
182
248
  function u16(d, off) {
183
249
  return (d[off] ?? 0) | (d[off + 1] ?? 0) << 8;
184
250
  }
@@ -653,7 +653,8 @@ var MIME_BY_FORMAT = {
653
653
  png: "image/png",
654
654
  jpeg2000: "image/jp2",
655
655
  gif: "image/gif",
656
- tiff: "image/tiff"
656
+ tiff: "image/tiff",
657
+ bmp: "image/bmp"
657
658
  };
658
659
  function dataUri(resource, store) {
659
660
  if (resource === void 0) return void 0;
@@ -17,6 +17,23 @@ export interface FontResource {
17
17
  /** Glyphs collected by the usage walk — the emit phase subsets to these. */
18
18
  readonly gids: ReadonlySet<number>;
19
19
  }
20
+ /**
21
+ * The face a run asked for and the registry could not give — what the page has
22
+ * to draw itself. A font set carries only `regular` by contract, so a caller
23
+ * who supplies one file still asks for bold headings and italic quotes.
24
+ */
25
+ export interface SyntheticFace {
26
+ /** No bold cut: the glyphs are stroked as well as filled. */
27
+ readonly bold?: true;
28
+ /** No italic cut: the glyphs are sheared. */
29
+ readonly italic?: true;
30
+ /**
31
+ * No condensed cut: the glyphs are set at this fraction of their advance
32
+ * (`Arial Narrow` is 82 % of Arial). Layout measures through it too — the
33
+ * squeeze decides where the line breaks, not just how it looks.
34
+ */
35
+ readonly widthScale?: number;
36
+ }
20
37
  /** A run of text on a {@link Line}: the string plus its resolved font, size, width and link/tagging state. */
21
38
  export interface TextToken {
22
39
  readonly kind: 'text';
@@ -61,6 +78,8 @@ export interface TextToken {
61
78
  readonly highlight?: true;
62
79
  readonly resolvedRun: ResolvedRunProperties;
63
80
  readonly font: FontResource;
81
+ /** What the chosen face lacks and the emitter must fake (see {@link SyntheticFace}). */
82
+ readonly synthetic?: SyntheticFace;
64
83
  readonly fontSizePt: number;
65
84
  /**
66
85
  * §17.3.2.42 / §18.4.2 `vertAlign` — how far off the baseline this token
@@ -205,6 +224,19 @@ export interface MetafileDrawing {
205
224
  readonly y: number;
206
225
  readonly rotationDeg?: number;
207
226
  }>;
227
+ /**
228
+ * MS-EMF §2.3.1 — the bitmaps the picture blits into itself, each already a
229
+ * page resource of its own. `x`/`y` are the box's BOTTOM-left corner, in the
230
+ * same local frame as the shapes.
231
+ */
232
+ readonly images?: ReadonlyArray<{
233
+ readonly resourceName: string;
234
+ readonly x: number;
235
+ readonly y: number;
236
+ readonly width: number;
237
+ readonly height: number;
238
+ readonly rotationDeg?: number;
239
+ }>;
208
240
  }
209
241
  export interface ImageResource {
210
242
  readonly resourceName: string;
@@ -220,6 +252,13 @@ export interface ImageResource {
220
252
  * turns these into the same primitives a chart is made of.
221
253
  */
222
254
  readonly metafile?: MetaPicture;
255
+ /**
256
+ * The resource name of each bitmap `metafile` blits, in the order its
257
+ * primitives hold them. A metafile draws its own pictures, and each is an
258
+ * ordinary image resource — entered under a key of its own, so the emitters
259
+ * embed and name it without knowing where it came from.
260
+ */
261
+ readonly metafileImages?: ReadonlyArray<string>;
223
262
  }
224
263
  /**
225
264
  * The fields every {@link PageItem} shares (ir-design §6, frozen at stage 6.4):
@@ -287,6 +326,32 @@ export interface TextLineItem extends PageItemBase {
287
326
  * the plot's own tick labels. Absent ⇒ horizontal.
288
327
  */
289
328
  readonly rotationDeg?: number;
329
+ /**
330
+ * §20.1.9.10 `a:prstTxWarp` — the line is WordArt: each glyph is placed on
331
+ * its own, bent through the preset's curve and stretched onto the shape's
332
+ * box. Absent ⇒ the line is set flat, one text matrix for the whole of it.
333
+ */
334
+ readonly warp?: TextLineWarp;
335
+ }
336
+ /**
337
+ * What placing a warped line needs: the preset, the shape box the warped block
338
+ * is stretched onto, and the box the UN-warped block occupies — both in the
339
+ * page's top-left frame, so a glyph's position in the second maps straight into
340
+ * the first.
341
+ */
342
+ export interface TextLineWarp {
343
+ readonly preset: string;
344
+ readonly adjust?: number;
345
+ readonly boxX: Pt;
346
+ readonly boxY: Pt;
347
+ readonly boxWidth: Pt;
348
+ readonly boxHeight: Pt;
349
+ /** The un-warped block's left edge and width (its widest line). */
350
+ readonly srcX: Pt;
351
+ readonly srcWidth: Pt;
352
+ /** The un-warped block's ink top and total ink height. */
353
+ readonly srcTop: Pt;
354
+ readonly srcHeight: Pt;
290
355
  }
291
356
  /** One edge of a table-cell frame; `(x, y)` is the cell box's top-left corner. */
292
357
  export interface BorderItem extends PageItemBase {
@@ -383,6 +448,15 @@ export interface PagePaintPlan {
383
448
  * per {@link PageItemBase.pictureId}. They paint where the shape pass does.
384
449
  */
385
450
  readonly pictures: ReadonlyArray<ReadonlyArray<PageItem>>;
451
+ /**
452
+ * §19.3.1 — the items of a page that STATES its own paint order, each run in
453
+ * the order it paints, the runs sorted by the order they were given. A slide
454
+ * is such a page: its shape tree is a z-order, and a picture standing after a
455
+ * rectangle in it is drawn over that rectangle. Split by kind instead — every
456
+ * image, then every shape — the six logos of 54542_cropped_bitmap.pptx were
457
+ * painted first and the six panels they sit on were painted over them.
458
+ */
459
+ readonly ordered: ReadonlyArray<ReadonlyArray<PageItem>>;
386
460
  }
387
461
  export declare function paintPlan(commands: ReadonlyArray<PageItem>): PagePaintPlan;
388
462
  export interface LaidOutDocument {
@@ -7,11 +7,23 @@ function paintPlan(commands) {
7
7
  const lines = [];
8
8
  const pictures = /* @__PURE__ */ new Map();
9
9
  const behind = [];
10
+ const ordered = /* @__PURE__ */ new Map();
11
+ const orderOf = /* @__PURE__ */ new Map();
10
12
  for (const c of commands) {
11
13
  if (c.behind === true) {
12
14
  behind.push(c);
13
15
  continue;
14
16
  }
17
+ if (c.z !== void 0 && c.type !== "line" && c.type !== "fill" && c.type !== "border") {
18
+ const key = c.pictureId !== void 0 ? `p${c.pictureId}` : `i${orderOf.size}`;
19
+ const run = ordered.get(key);
20
+ if (run) run.push(c);
21
+ else {
22
+ ordered.set(key, [c]);
23
+ orderOf.set(key, c.z);
24
+ }
25
+ continue;
26
+ }
15
27
  if (c.pictureId !== void 0) {
16
28
  const group = pictures.get(c.pictureId);
17
29
  if (group) group.push(c);
@@ -44,7 +56,8 @@ function paintPlan(commands) {
44
56
  borders,
45
57
  shapes,
46
58
  lines,
47
- pictures: [...pictures.values()]
59
+ pictures: [...pictures.values()],
60
+ ordered: [...ordered.entries()].sort((a, b) => (orderOf.get(a[0]) ?? 0) - (orderOf.get(b[0]) ?? 0)).map(([, run]) => run)
48
61
  };
49
62
  }
50
63
  function assertNeverPageItem(item) {
@@ -1,6 +1,6 @@
1
1
  import { BodyElement, Chart, Comment, DocumentInfo, Numbering, Section, SectionProperties, ShapeFill, StyleSheet } from '../core/document-model/index.js';
2
2
  import { FontRegistry } from '../core/font/index.js';
3
- import { FamilyKey } from '../core/fonts/index.js';
3
+ import { SubstituteKey } from '../core/fonts/index.js';
4
4
  import { Hyphenator } from '../core/hyphenation/index.js';
5
5
  import { Pt, ResourceStore } from '../core/ir/index.js';
6
6
  import { LaidOutDocument, PageItem } from './page-doc.js';
@@ -53,7 +53,7 @@ export interface StyledRenderOptions {
53
53
  * run uses `registry`), byte-identical to before. `registry` remains the
54
54
  * guaranteed fallback for math/chart/default glyphs and any missing family.
55
55
  */
56
- readonly registriesByFamily?: ReadonlyMap<FamilyKey, FontRegistry>;
56
+ readonly registriesByFamily?: ReadonlyMap<SubstituteKey, FontRegistry>;
57
57
  /**
58
58
  * The document's OWN embedded fonts (`word/fonts/*.odttf`, de-obfuscated),
59
59
  * keyed by normalized font name. A run whose `w:ascii` matches one renders with