reamkit 1.32.1 → 1.33.1

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 (165) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +16 -11
  3. package/dist/esm/core/bidi/algorithm.js +2 -2
  4. package/dist/esm/core/bidi/char-types.js +1 -1
  5. package/dist/esm/core/bidi/index.js +3 -3
  6. package/dist/esm/core/bytes.js +1 -1
  7. package/dist/esm/core/converter/facade.js +10 -5
  8. package/dist/esm/core/converter/ream.d.ts +9 -0
  9. package/dist/esm/core/converter/ream.js +40 -10
  10. package/dist/esm/core/crypto/asn1.js +2 -2
  11. package/dist/esm/core/crypto/cms.js +5 -3
  12. package/dist/esm/core/crypto/index.js +2 -1
  13. package/dist/esm/core/crypto/offcrypto.d.ts +2 -5
  14. package/dist/esm/core/crypto/offcrypto.js +9 -15
  15. package/dist/esm/core/crypto/password-error.d.ts +8 -0
  16. package/dist/esm/core/crypto/password-error.js +14 -0
  17. package/dist/esm/core/crypto/primitives.js +16 -16
  18. package/dist/esm/core/document-model/index.d.ts +1 -1
  19. package/dist/esm/core/document-model/types.d.ts +174 -2
  20. package/dist/esm/core/drawingml/chart-geometry.d.ts +24 -6
  21. package/dist/esm/core/drawingml/chart-geometry.js +905 -208
  22. package/dist/esm/core/drawingml/chart-parser.d.ts +5 -1
  23. package/dist/esm/core/drawingml/chart-parser.js +275 -19
  24. package/dist/esm/core/drawingml/chart-text.d.ts +41 -0
  25. package/dist/esm/core/drawingml/chart-text.js +93 -0
  26. package/dist/esm/core/drawingml/colors.js +5 -5
  27. package/dist/esm/core/drawingml/diagram/layout-engine.js +1 -4
  28. package/dist/esm/core/drawingml/diagram/run.js +2 -1
  29. package/dist/esm/core/drawingml/preset-geometry.js +4 -6
  30. package/dist/esm/core/drawingml/shape-render.js +1 -1
  31. package/dist/esm/core/drawingml/text-warp.js +4 -16
  32. package/dist/esm/core/drawingml/theme-parser.js +14 -8
  33. package/dist/esm/core/font/arabic-joining.js +2 -2
  34. package/dist/esm/core/font/binary-reader.js +2 -0
  35. package/dist/esm/core/font/font-registry.js +1 -0
  36. package/dist/esm/core/font/ligatures.js +1 -1
  37. package/dist/esm/core/font/opentype-layout.js +11 -5
  38. package/dist/esm/core/font/ttf-build.js +6 -10
  39. package/dist/esm/core/font/ttf-parser.js +2 -1
  40. package/dist/esm/core/font/ttf-subset.js +8 -8
  41. package/dist/esm/core/fonts/families.js +1 -1
  42. package/dist/esm/core/fonts/remote-fonts.js +4 -4
  43. package/dist/esm/core/hyphenation/index.js +1 -1
  44. package/dist/esm/core/images.js +8 -8
  45. package/dist/esm/core/ir/adapters.d.ts +9 -0
  46. package/dist/esm/core/ir/loss.js +1 -0
  47. package/dist/esm/core/line-breaker/cjk.js +1 -1
  48. package/dist/esm/core/line-breaker/index.js +4 -3
  49. package/dist/esm/core/links.js +1 -1
  50. package/dist/esm/core/lzw.js +1 -1
  51. package/dist/esm/core/metafile/blit.js +1 -1
  52. package/dist/esm/core/metafile/emf.js +5 -7
  53. package/dist/esm/core/metafile/picture.js +1 -1
  54. package/dist/esm/core/metafile/symbol-fonts.js +7 -7
  55. package/dist/esm/core/metafile/wmf.js +5 -7
  56. package/dist/esm/core/number-format.js +4 -6
  57. package/dist/esm/core/numbering/index.js +3 -2
  58. package/dist/esm/core/ole/cfb.js +4 -4
  59. package/dist/esm/core/ole/escher-blip.js +1 -1
  60. package/dist/esm/core/opc/index.js +5 -4
  61. package/dist/esm/core/opc/package.js +3 -1
  62. package/dist/esm/core/opc/xml-entities.js +1 -1
  63. package/dist/esm/core/outline.js +1 -1
  64. package/dist/esm/core/png-encode.js +3 -3
  65. package/dist/esm/core/po-helpers.js +1 -1
  66. package/dist/esm/core/spreadsheet-model/types.d.ts +6 -0
  67. package/dist/esm/core/style-cascade/index.js +4 -3
  68. package/dist/esm/core/tiff.js +3 -1
  69. package/dist/esm/excel/activex-parser.js +1 -1
  70. package/dist/esm/excel/conditional-format.js +7 -7
  71. package/dist/esm/excel/formula/functions.js +8 -4
  72. package/dist/esm/excel/formula/index.js +3 -3
  73. package/dist/esm/excel/formula/lexer.js +2 -2
  74. package/dist/esm/excel/formula/parser.js +4 -3
  75. package/dist/esm/excel/formula/value.js +1 -1
  76. package/dist/esm/excel/index.js +7 -6
  77. package/dist/esm/excel/print-model.d.ts +1 -0
  78. package/dist/esm/excel/print-model.js +7 -32
  79. package/dist/esm/excel/printer-settings.js +6 -7
  80. package/dist/esm/excel/rich-value.js +1 -1
  81. package/dist/esm/excel/sheet-shape-parser.js +4 -2
  82. package/dist/esm/excel/sheet-to-flow.d.ts +8 -0
  83. package/dist/esm/excel/sheet-to-flow.js +14 -11
  84. package/dist/esm/excel/styles-parser.js +5 -3
  85. package/dist/esm/excel/tint.js +5 -5
  86. package/dist/esm/excel/vml-drawing.js +2 -2
  87. package/dist/esm/excel/worksheet-parser.js +5 -5
  88. package/dist/esm/excel/xls/biff-chart.js +1 -3
  89. package/dist/esm/excel/xls/biff-reader.js +10 -11
  90. package/dist/esm/excel/xls/xls-reader.js +1 -1
  91. package/dist/esm/excel/xlsx-reader.js +17 -4
  92. package/dist/esm/excel/xlsx-to-pdf.js +1 -1
  93. package/dist/esm/excel/xlsx-writer.js +2 -2
  94. package/dist/esm/html/html-writer.js +18 -10
  95. package/dist/esm/index.js +2 -1
  96. package/dist/esm/layout/line-paint.js +1 -1
  97. package/dist/esm/layout/math-layout.js +5 -8
  98. package/dist/esm/layout/styled-layout.js +133 -75
  99. package/dist/esm/layout/turned-section.js +2 -2
  100. package/dist/esm/markdown/markdown-writer.js +50 -9
  101. package/dist/esm/pdf/encryption.js +9 -9
  102. package/dist/esm/pdf/icc-profile.js +2 -2
  103. package/dist/esm/pdf/index.js +3 -2
  104. package/dist/esm/pdf/objects.js +7 -0
  105. package/dist/esm/pdf/serialize.js +1 -1
  106. package/dist/esm/pdf/struct-tree.js +3 -1
  107. package/dist/esm/pdf/styled-page-emitter.js +23 -15
  108. package/dist/esm/pdf/styled-page-renderer.js +9 -5
  109. package/dist/esm/pdf-reader/annot-draw.js +3 -3
  110. package/dist/esm/pdf-reader/ccitt.js +2 -1
  111. package/dist/esm/pdf-reader/cff-outline.js +1 -4
  112. package/dist/esm/pdf-reader/content.js +13 -15
  113. package/dist/esm/pdf-reader/decrypt.d.ts +18 -6
  114. package/dist/esm/pdf-reader/decrypt.js +90 -45
  115. package/dist/esm/pdf-reader/document.d.ts +7 -1
  116. package/dist/esm/pdf-reader/document.js +18 -4
  117. package/dist/esm/pdf-reader/encodings.js +1 -1
  118. package/dist/esm/pdf-reader/flow-build.js +4 -6
  119. package/dist/esm/pdf-reader/font.js +3 -3
  120. package/dist/esm/pdf-reader/function.js +8 -7
  121. package/dist/esm/pdf-reader/icc.js +1 -1
  122. package/dist/esm/pdf-reader/images.js +1 -1
  123. package/dist/esm/pdf-reader/jbig2.js +36 -38
  124. package/dist/esm/pdf-reader/jpeg.js +14 -13
  125. package/dist/esm/pdf-reader/layout.js +12 -9
  126. package/dist/esm/pdf-reader/lexer.js +2 -1
  127. package/dist/esm/pdf-reader/math-rows.js +2 -2
  128. package/dist/esm/pdf-reader/optional-content.js +1 -1
  129. package/dist/esm/pdf-reader/page-numbers.js +1 -1
  130. package/dist/esm/pdf-reader/pattern-tint.js +1 -2
  131. package/dist/esm/pdf-reader/reader.d.ts +5 -1
  132. package/dist/esm/pdf-reader/reader.js +83 -16
  133. package/dist/esm/pdf-reader/struct-tree.js +1 -1
  134. package/dist/esm/pdf-reader/tagged.js +3 -2
  135. package/dist/esm/pdf-reader/text.js +2 -2
  136. package/dist/esm/pdf-reader/type1-outline.js +1 -3
  137. package/dist/esm/pptx/embedded-fonts.js +3 -5
  138. package/dist/esm/pptx/placeholder-cascade.js +1 -1
  139. package/dist/esm/pptx/ppt/ppt-reader.js +5 -4
  140. package/dist/esm/pptx/ppt/ppt-text.js +9 -10
  141. package/dist/esm/pptx/pptx-reader.js +6 -5
  142. package/dist/esm/pptx/preset-table-styles.js +1 -1
  143. package/dist/esm/pptx/slide-parser.js +6 -4
  144. package/dist/esm/pptx/sp-helpers.js +1 -1
  145. package/dist/esm/pptx/table-style.js +2 -1
  146. package/dist/esm/svg/svg-writer.js +1 -1
  147. package/dist/esm/word/doc/doc-reader.js +2 -2
  148. package/dist/esm/word/doc/doc-text.js +20 -22
  149. package/dist/esm/word/document-parser.js +26 -21
  150. package/dist/esm/word/docx-reader.js +2 -2
  151. package/dist/esm/word/docx-to-pdf.js +3 -3
  152. package/dist/esm/word/docx-writer.js +10 -6
  153. package/dist/esm/word/drawing-parser.js +18 -18
  154. package/dist/esm/word/font-table.js +1 -1
  155. package/dist/esm/word/index.js +6 -5
  156. package/dist/esm/word/numbering-parser.js +4 -3
  157. package/dist/esm/word/omml-parser.js +1 -1
  158. package/dist/esm/word/paragraph-properties.js +11 -10
  159. package/dist/esm/word/run-properties.js +4 -4
  160. package/dist/esm/word/settings-parser.js +2 -1
  161. package/dist/esm/word/shading.js +1 -1
  162. package/dist/esm/word/styles-parser.js +5 -4
  163. package/dist/esm/word/table-parser.js +4 -4
  164. package/dist/esm/word/theme-fonts.js +1 -1
  165. package/package.json +9 -3
@@ -98,7 +98,7 @@ var WORD_LINE_METRICS = (() => {
98
98
  0,
99
99
  432
100
100
  ];
101
- return new Map([
101
+ return /* @__PURE__ */ new Map([
102
102
  ["calibri", [
103
103
  1950,
104
104
  0,
@@ -670,7 +670,7 @@ function layoutStyledDocument(body, options) {
670
670
  const commentNums = noteAssigned.comments;
671
671
  const threadDepth = (id) => {
672
672
  let depth = 0;
673
- const seen = new Set([id]);
673
+ const seen = /* @__PURE__ */ new Set([id]);
674
674
  let cur = options.comments?.get(id)?.parentId;
675
675
  while (cur !== void 0 && commentNums.has(cur) && !seen.has(cur)) {
676
676
  depth++;
@@ -926,6 +926,7 @@ function balancedColumnHeight(bandHeightPt, colCount, roomPt) {
926
926
  * between takes its share of both sides. Elsewhere the two add up.
927
927
  */
928
928
  var SpacingStack = class {
929
+ collapse;
929
930
  /** The space after the last block, which a paragraph right below may share. */
930
931
  shared = 0;
931
932
  constructor(collapse) {
@@ -1822,7 +1823,7 @@ function metafileDrawing(pic, widthPt, heightPt, options, fontResources, colorCh
1822
1823
  seq++;
1823
1824
  continue;
1824
1825
  }
1825
- const line = makeChartLabelLine(prim.text, font, sizePt, textHex ?? prim.colorHex);
1826
+ const line = makeChartLabelLine(prim.text, { font }, sizePt, textHex ?? prim.colorHex);
1826
1827
  const shift = prim.alignH === "center" ? -line.contentWidthPt / 2 : prim.alignH === "right" ? -line.contentWidthPt : 0;
1827
1828
  const baselineY = mapY(prim.y) - (prim.alignBaseline ? 0 : sizePt * .8);
1828
1829
  texts.push({
@@ -1854,8 +1855,8 @@ function layoutChartBlock(block, options, fontResources, contentWidth, maxHeight
1854
1855
  }
1855
1856
  const chart = options.charts?.get(block.chartRelId);
1856
1857
  const { variant } = options.registry.resolveByStyle(false, false);
1857
- const font = fontResources.get(variant);
1858
- const layout = chart && font ? buildChartLayout(chart, widthPt, heightPt, font) : {
1858
+ const faceFor = chart ? chartFaceResolver(options, fontResources, fontResources.get(variant)) : void 0;
1859
+ const layout = chart && faceFor ? buildChartLayout(chart, widthPt, heightPt, faceFor) : {
1859
1860
  shapes: [],
1860
1861
  texts: []
1861
1862
  };
@@ -1882,8 +1883,54 @@ function layoutChartBlock(block, options, fontResources, contentWidth, maxHeight
1882
1883
  ...block.float ? { float: block.float } : {}
1883
1884
  };
1884
1885
  }
1885
- function buildChartLayout(chart, widthPt, heightPt, font) {
1886
- const measure = (text, sizePt) => font.measure.textWidthPt(text, sizePt);
1886
+ /**
1887
+ * Where a chart's text finds its face: the family and weight the chart sets it
1888
+ * in, resolved as a run's are (runFontKeyAndParsed), and the document's base
1889
+ * face for text that names none — which is all of a chart's text unless its
1890
+ * reader resolved the chart's own (Chart.text).
1891
+ */
1892
+ function chartFaceResolver(options, fontResources, base) {
1893
+ const fallback = base ?? fontResources.values().next().value;
1894
+ if (!fallback) return void 0;
1895
+ return (font) => {
1896
+ if (!font || font.family === void 0 && !font.bold && !font.italic) return { font: fallback };
1897
+ const { fontKey, synthetic } = runFontKeyAndParsed(options, font.family, font.bold === true, font.italic === true);
1898
+ const resource = fontResources.get(fontKey);
1899
+ return resource ? {
1900
+ font: resource,
1901
+ ...synthetic ? { synthetic } : {}
1902
+ } : { font: fallback };
1903
+ };
1904
+ }
1905
+ /**
1906
+ * The faces a chart's text is drawn in, one per distinct family and weight;
1907
+ * `undefined` stands for the document's base face, which text naming none is
1908
+ * drawn in.
1909
+ */
1910
+ function chartFonts(chart) {
1911
+ if (!chart.text) return [void 0];
1912
+ const seen = /* @__PURE__ */ new Map();
1913
+ let base = false;
1914
+ for (const style of Object.values(chart.text)) {
1915
+ if (!style) continue;
1916
+ if (style.family === void 0 && !style.bold && !style.italic) {
1917
+ base = true;
1918
+ continue;
1919
+ }
1920
+ const font = {
1921
+ ...style.family !== void 0 ? { family: style.family } : {},
1922
+ ...style.bold ? { bold: true } : {},
1923
+ ...style.italic ? { italic: true } : {}
1924
+ };
1925
+ seen.set(`${font.family ?? ""}|${font.bold === true}|${font.italic === true}`, font);
1926
+ }
1927
+ return base ? [void 0, ...seen.values()] : [...seen.values()];
1928
+ }
1929
+ function buildChartLayout(chart, widthPt, heightPt, faceFor) {
1930
+ const measure = (text, sizePt, font) => {
1931
+ const face = faceFor(font);
1932
+ return face.font.measure.textWidthPt(text, sizePt) * (face.synthetic?.widthScale ?? 1);
1933
+ };
1887
1934
  const scene = buildChartScene(chart, widthPt, heightPt, measure);
1888
1935
  if (!scene) return {
1889
1936
  shapes: [{
@@ -1898,6 +1945,7 @@ function buildChartLayout(chart, widthPt, heightPt, font) {
1898
1945
  const shapes = [];
1899
1946
  if (scene.background) shapes.push(rectPrim(scene.background));
1900
1947
  if (scene.plotBackground) shapes.push(rectPrim(scene.plotBackground));
1948
+ for (const w of scene.walls ?? []) shapes.push(polygonPrim(w));
1901
1949
  for (const g of scene.gridlines ?? []) shapes.push(polylinePrim(g));
1902
1950
  for (const pg of scene.polygons ?? []) shapes.push(polygonPrim(pg));
1903
1951
  for (const r of scene.rects) shapes.push(rectPrim(r));
@@ -1905,7 +1953,7 @@ function buildChartLayout(chart, widthPt, heightPt, font) {
1905
1953
  for (const w of scene.wedges) shapes.push(wedgePrim(w));
1906
1954
  return {
1907
1955
  shapes,
1908
- texts: scene.labels.map((l) => labelPrim(l, font))
1956
+ texts: scene.labels.map((l) => labelPrim(l, faceFor(l)))
1909
1957
  };
1910
1958
  }
1911
1959
  function rectAtPath(x, y, w, h) {
@@ -2061,7 +2109,7 @@ function polygonPrim(p) {
2061
2109
  b.close();
2062
2110
  return {
2063
2111
  paths: [b.build()],
2064
- fillColorHex: p.fillHex,
2112
+ ...p.fillHex ? { fillColorHex: p.fillHex } : {},
2065
2113
  ...p.strokeHex ? { stroke: {
2066
2114
  colorHex: p.strokeHex,
2067
2115
  widthPt: p.widthPt ?? 1
@@ -2079,8 +2127,8 @@ function wedgePrim(w) {
2079
2127
  } } : {}
2080
2128
  };
2081
2129
  }
2082
- function labelPrim(l, font) {
2083
- const line = makeChartLabelLine(l.text, font, l.sizePt, l.colorHex);
2130
+ function labelPrim(l, face) {
2131
+ const line = makeChartLabelLine(l.text, face, l.sizePt, l.colorHex);
2084
2132
  const w = line.contentWidthPt;
2085
2133
  const shift = l.align === "center" ? -w / 2 : l.align === "right" ? -w : 0;
2086
2134
  if (l.rotationDeg) return {
@@ -2095,8 +2143,9 @@ function labelPrim(l, font) {
2095
2143
  y: l.y
2096
2144
  };
2097
2145
  }
2098
- function makeChartLabelLine(text, font, sizePt, colorHex) {
2099
- const widthPt = font.measure.textWidthPt(text, sizePt);
2146
+ function makeChartLabelLine(text, face, sizePt, colorHex) {
2147
+ const { font, synthetic } = face;
2148
+ const widthPt = font.measure.textWidthPt(text, sizePt) * (synthetic?.widthScale ?? 1);
2100
2149
  return {
2101
2150
  tokens: [{
2102
2151
  kind: "text",
@@ -2110,7 +2159,8 @@ function makeChartLabelLine(text, font, sizePt, colorHex) {
2110
2159
  font,
2111
2160
  fontSizePt: sizePt,
2112
2161
  widthPt,
2113
- bidiLevel: 0
2162
+ bidiLevel: 0,
2163
+ ...synthetic ? { synthetic } : {}
2114
2164
  }],
2115
2165
  contentWidthPt: widthPt,
2116
2166
  maxFontSizePt: sizePt,
@@ -2862,7 +2912,8 @@ function runFontKeyAndParsed(options, ascii, bold, italic) {
2862
2912
  function fallbackFaceKey(options, cp, bold, italic) {
2863
2913
  const byFamily = options.registriesByFamily;
2864
2914
  if (!byFamily || byFamily.size === 0) return void 0;
2865
- const script = scriptForCodepoint(cp, byFamily.has("jp") ? "jp" : byFamily.has("kr") ? "kr" : "sc");
2915
+ const hanFace = byFamily.has("jp") ? "jp" : byFamily.has("kr") ? "kr" : "sc";
2916
+ const script = scriptForCodepoint(cp, hanFace);
2866
2917
  const order = script ? [script] : [];
2867
2918
  for (const key of byFamily.keys()) if (key !== script) order.push(key);
2868
2919
  for (const key of order) {
@@ -3156,17 +3207,26 @@ function collectFontResources(body, headersFooters, options, imageResources) {
3156
3207
  else {
3157
3208
  const chart = options.charts?.get(el.chart.chartRelId);
3158
3209
  if (chart) {
3159
- const reg = options.registry.resolveByStyle(false, false);
3160
- let bucket = used.get(reg.variant);
3161
- if (!bucket) {
3162
- bucket = {
3163
- parsed: reg.parsed,
3164
- gids: /* @__PURE__ */ new Set()
3165
- };
3166
- used.set(reg.variant, bucket);
3167
- }
3210
+ const buckets = chartFonts(chart).map((font) => {
3211
+ const face = font === void 0 ? (() => {
3212
+ const reg = options.registry.resolveByStyle(false, false);
3213
+ return {
3214
+ fontKey: reg.variant,
3215
+ parsed: reg.parsed
3216
+ };
3217
+ })() : runFontKeyAndParsed(options, font.family, font.bold === true, font.italic === true);
3218
+ let bucket = used.get(face.fontKey);
3219
+ if (!bucket) {
3220
+ bucket = {
3221
+ parsed: face.parsed,
3222
+ gids: /* @__PURE__ */ new Set()
3223
+ };
3224
+ used.set(face.fontKey, bucket);
3225
+ }
3226
+ return bucket;
3227
+ });
3168
3228
  const add = (s) => {
3169
- for (const ch of s) bucket.gids.add(reg.parsed.glyphForCodepoint(ch.codePointAt(0)));
3229
+ for (const bucket of buckets) for (const ch of s) bucket.gids.add(bucket.parsed.glyphForCodepoint(ch.codePointAt(0)));
3170
3230
  };
3171
3231
  if (chart.title) add(chart.title);
3172
3232
  for (const c of chart.categories) add(c);
@@ -3766,7 +3826,7 @@ function paragraphMaxWidth(p, contentWidth, firstLine) {
3766
3826
  const firstLineExtra = firstLine ? p.indentFirstLine : 0;
3767
3827
  return Math.max(1, contentWidth - indentLeft - indentRight - firstLineExtra);
3768
3828
  }
3769
- var HYPHENS = new Set([
3829
+ var HYPHENS = /* @__PURE__ */ new Set([
3770
3830
  45,
3771
3831
  8208,
3772
3832
  8211,
@@ -3960,7 +4020,7 @@ function paragraphItemStream(tokens, hyphenator, maxLineWidthPt) {
3960
4020
  }
3961
4021
  /** Word's own default when a document names none (§17.15.1.25): half an inch. */
3962
4022
  var DEFAULT_TAB_STOP_PT = 36;
3963
- var TAB_LEADER_CHARS = new Map([
4023
+ var TAB_LEADER_CHARS = /* @__PURE__ */ new Map([
3964
4024
  ["dot", "."],
3965
4025
  ["hyphen", "-"],
3966
4026
  ["underscore", "_"],
@@ -4923,7 +4983,7 @@ function layoutTableCell(cell, tableProps, widthPt, options, fontResources, imag
4923
4983
  const block = layoutParagraphBlock(el.paragraph, options, fontResources, imageResources, noWrap ? NO_WRAP_MEASURE_WIDTH : measureWidth);
4924
4984
  const cutAt = widthPt - padLeftPt;
4925
4985
  if (noWrap && (block.lines[0]?.contentWidthPt ?? 0) > cutAt) clipped = true;
4926
- const keep = noWrap ? clipLineToWidth(block.lines, cutAt, cell.properties.hashOnOverflow === true) : block.lines;
4986
+ const keep = noWrap ? oneLineInBox(block.lines, cutAt, cell.properties.hashOnOverflow === true) : block.lines;
4927
4987
  const markOnly = cell.properties.hideMark === true && el.paragraph.runs.every((r) => r.text === "");
4928
4988
  if (!markOnly) openParagraph(block.spacingBeforePt);
4929
4989
  for (const line of keep) {
@@ -5116,6 +5176,11 @@ function listItemParagraphNode(builder, stack, list, wantLbl) {
5116
5176
  * bodies move unchanged.
5117
5177
  */
5118
5178
  var PageAssembler = class PageAssembler {
5179
+ sectionCtxs;
5180
+ builder;
5181
+ notes;
5182
+ bookmarkPositions;
5183
+ backgroundImage;
5119
5184
  /**
5120
5185
  * @param sectionCtxs The per-section render contexts, in order; assembly
5121
5186
  * starts on the first section's first page.
@@ -5892,6 +5957,9 @@ var PageAssembler = class PageAssembler {
5892
5957
  * every page that repeats them — which is what Excel prints.
5893
5958
  */
5894
5959
  var SheetView = class {
5960
+ overlay;
5961
+ tableX;
5962
+ builder;
5895
5963
  runs = [];
5896
5964
  figures = /* @__PURE__ */ new Map();
5897
5965
  /**
@@ -6518,13 +6586,15 @@ function emitRowChunk(out, row, marginLeft, cursorY, pageHeight, colCount, cellS
6518
6586
  if (cell.icon && cell.mergeRole !== "middle" && cell.mergeRole !== "end") {
6519
6587
  const iconSize = Math.min(CF_ICON_SIZE_PT, Math.max(0, row.heightPt - 1));
6520
6588
  if (iconSize > 0) {
6589
+ const iconX = cellX + (CF_ICON_GUTTER_PT - iconSize) / 2;
6590
+ const iconBottomYUp = rowBottom + (row.heightPt - iconSize) / 2;
6521
6591
  const iconTransform = flipTransform([
6522
6592
  1,
6523
6593
  0,
6524
6594
  0,
6525
6595
  1,
6526
- cellX + (CF_ICON_GUTTER_PT - iconSize) / 2,
6527
- rowBottom + (row.heightPt - iconSize) / 2
6596
+ iconX,
6597
+ iconBottomYUp
6528
6598
  ], pageHeight);
6529
6599
  for (const prim of buildCellIconShape(cell.icon, iconSize)) out.push({
6530
6600
  type: "shape",
@@ -6540,13 +6610,15 @@ function emitRowChunk(out, row, marginLeft, cursorY, pageHeight, colCount, cellS
6540
6610
  if (cell.dropdown && cell.mergeRole !== "middle" && cell.mergeRole !== "end") {
6541
6611
  const btn = Math.min(DROPDOWN_BUTTON_PT, Math.max(0, row.heightPt - 2));
6542
6612
  if (btn > 1) {
6613
+ const btnX = cellX + cell.widthPt - btn - 1.5;
6614
+ const btnBottomYUp = rowBottom + (row.heightPt - btn) / 2;
6543
6615
  const btnTransform = flipTransform([
6544
6616
  1,
6545
6617
  0,
6546
6618
  0,
6547
6619
  1,
6548
- cellX + cell.widthPt - btn - 1.5,
6549
- rowBottom + (row.heightPt - btn) / 2
6620
+ btnX,
6621
+ btnBottomYUp
6550
6622
  ], pageHeight);
6551
6623
  for (const prim of buildDropdownPrims(btn)) out.push({
6552
6624
  type: "shape",
@@ -6709,7 +6781,7 @@ function emitRowChunk(out, row, marginLeft, cursorY, pageHeight, colCount, cellS
6709
6781
  textY -= cell.lineGaps?.get(lineIdx) ?? 0;
6710
6782
  const h = computeLineHeight(line, line.resolved);
6711
6783
  textY -= h;
6712
- const offset = alignmentOffset(line.resolved.alignment, line.contentWidthPt, cell.widthPt - cell.padLeftPt - cell.padRightPt);
6784
+ const offset = (cell.clipped === true ? overrunOffset : alignmentOffset)(line.resolved.alignment, line.contentWidthPt, cell.widthPt - cell.padLeftPt - cell.padRightPt);
6713
6785
  const indentLeft = line.resolved.indentLeft + (line.firstLine ? line.resolved.indentFirstLine : 0);
6714
6786
  out.push({
6715
6787
  type: "line",
@@ -6848,51 +6920,37 @@ function emitCellBorders(out, cell, cellX, cellY, rowHeight, pageHeight, rowIdx,
6848
6920
  }
6849
6921
  var NO_WRAP_MEASURE_WIDTH = 1e6;
6850
6922
  /**
6851
- * One line, trimmed to the glyph that STRADDLES `widthPt` — what a non-wrapping
6852
- * spreadsheet cell shows. Excel and LibreOffice paint that glyph and cut it
6853
- * through the middle, and so do we now: the caller marks the cell and the
6854
- * emitters clip the line to its box (TextLineItem.clip). Stopping at the last
6855
- * glyph that wholly fits is what dropped a character off every cut cell.
6923
+ * The one line a non-wrapping spreadsheet cell shows — WHOLE. Excel and
6924
+ * LibreOffice set such a cell's text on one line and let its box cut it, through
6925
+ * the glyph the edge falls on: on the right of left-aligned text, on both sides
6926
+ * of centred text, on the left of right-aligned text. So the caller marks the
6927
+ * cell, sets the line by its alignment (see {@link overrunOffset}) and the
6928
+ * emitters clip it to the box (TextLineItem.clip).
6929
+ *
6930
+ * It was trimmed to the glyph that straddles the edge instead, which cut every
6931
+ * centred and right-aligned cell on the wrong side and left the page's text
6932
+ * holding only what showed — "Монтаж кровл" of "Монтаж кровли".
6933
+ *
6934
+ * @param lines The cell paragraph's lines, laid out unbroken.
6935
+ * @param widthPt How far the cell's box reaches.
6936
+ * @param hashOnOverflow Whether a number too wide for the box shows as `#`.
6937
+ * @returns The first line, or the `#` that stand for it.
6856
6938
  */
6857
- function clipLineToWidth(lines, widthPt, hashOnOverflow = false) {
6939
+ function oneLineInBox(lines, widthPt, hashOnOverflow = false) {
6858
6940
  const line = lines[0];
6859
6941
  if (!line) return [];
6860
- if (line.contentWidthPt <= widthPt) return [line];
6861
- if (hashOnOverflow) return [hashFill(line, widthPt)];
6862
- const tokens = [];
6863
- let used = 0;
6864
- for (const token of line.tokens) {
6865
- const advance = token.widthPt;
6866
- if (used + advance <= widthPt) {
6867
- tokens.push(token);
6868
- used += advance;
6869
- continue;
6870
- }
6871
- if (token.kind === "text") {
6872
- const room = widthPt - used;
6873
- let text = "";
6874
- let textWidth = 0;
6875
- for (const ch of token.text) {
6876
- if (textWidth >= room) break;
6877
- text += ch;
6878
- textWidth = token.font.measure.textWidthPt(text, token.fontSizePt);
6879
- }
6880
- if (text.length > 0) {
6881
- tokens.push({
6882
- ...token,
6883
- text,
6884
- widthPt: textWidth
6885
- });
6886
- used += textWidth;
6887
- }
6888
- }
6889
- break;
6890
- }
6891
- return [{
6892
- ...line,
6893
- tokens,
6894
- contentWidthPt: used
6895
- }];
6942
+ if (hashOnOverflow && line.contentWidthPt > widthPt) return [hashFill(line, widthPt)];
6943
+ return [line];
6944
+ }
6945
+ /**
6946
+ * {@link alignmentOffset} for a line that may be wider than its room: the
6947
+ * offset may go below zero, putting the start of a centred or right-aligned
6948
+ * line before the box for the box's clip to cut.
6949
+ */
6950
+ function overrunOffset(alignment, lineWidth, available) {
6951
+ if (alignment === "right") return available - lineWidth;
6952
+ if (alignment === "center") return (available - lineWidth) / 2;
6953
+ return 0;
6896
6954
  }
6897
6955
  /**
6898
6956
  * The line as a row of `#` filling `widthPt` — what Excel and LibreOffice put in
@@ -1,7 +1,7 @@
1
1
  import { pt } from "../core/ir/units.js";
2
2
  //#region src/layout/turned-section.ts
3
3
  /** A quarter turn in the 1/60000° a DrawingML rotation is stated in (§20.1.7.6). */
4
- var QUARTER_60K = 90 * 6e4;
4
+ var QUARTER_60K = 54e5;
5
5
  /**
6
6
  * One item of a turned section's body, carried from the frame the text reads
7
7
  * in onto the sheet: a point `(x, y)` of the frame (top-left origin, y down)
@@ -161,7 +161,7 @@ function floatIntoFrame(el, sheet) {
161
161
  }
162
162
  /** A clockwise turn with a quarter taken off, kept in the one full turn. */
163
163
  function backedOff(rotation60k) {
164
- const full = 360 * 6e4;
164
+ const full = 216e5;
165
165
  return (((rotation60k ?? 0) - QUARTER_60K) % full + full) % full;
166
166
  }
167
167
  /**
@@ -51,7 +51,7 @@ function writeMarkdown(flow, options = {}) {
51
51
  var markdownWriter = {
52
52
  id: "md",
53
53
  consumes: "flow",
54
- supports: new Set([
54
+ supports: /* @__PURE__ */ new Set([
55
55
  FEATURES.text,
56
56
  FEATURES.lists,
57
57
  FEATURES.tables,
@@ -145,13 +145,14 @@ function emitShape(out, shape, ctx) {
145
145
  function emitParagraph(out, p, ctx) {
146
146
  const resolved = resolveParagraphProperties(p.properties, EMPTY_STYLE_SHEET);
147
147
  const anchors = bookmarkAnchors(p, ctx);
148
- const text = inlineRuns(p.runs, p, ctx).replace(/^[ \t]+/, "");
148
+ const level = headingLevelOf(resolved);
149
+ const asHeading = level !== void 0 && !ctx.inCell;
150
+ const text = inlineRuns(p.runs, p, ctx, asHeading).replace(/^[ \t]+/, "");
149
151
  const inline = anchors + text;
150
152
  const marker = markerText(p, ctx);
151
153
  reportParagraphLosses(resolved, ctx);
152
154
  if (breaksPage(p, resolved)) emitRule(out, ctx);
153
155
  const empty = isBlank(text) && anchors.length === 0;
154
- const level = headingLevelOf(resolved);
155
156
  if (level !== void 0) {
156
157
  if (empty) return;
157
158
  ctx.list.length = 0;
@@ -602,8 +603,11 @@ function cellInline(cell, ctx) {
602
603
  * characters on either side of it (§6.2), and those belong to the NEIGHBOURING
603
604
  * spans: the first pass coalesces runs into spans, the second dresses each
604
605
  * span knowing what stands beside it.
606
+ *
607
+ * @param heading Whether the paragraph is a heading, which every renderer of
608
+ * one sets strong already.
605
609
  */
606
- function inlineRuns(runs, p, ctx) {
610
+ function inlineRuns(runs, p, ctx, heading = false) {
607
611
  const pieces = [];
608
612
  let pending;
609
613
  const flush = () => {
@@ -621,8 +625,11 @@ function inlineRuns(runs, p, ctx) {
621
625
  const resolved = resolveRunProperties(run.properties, p.properties, EMPTY_STYLE_SHEET);
622
626
  reportRunLosses(resolved, ctx);
623
627
  const marks = marksOf(resolved, run);
624
- if (pending && sameMarks(pending.marks, marks)) pending.text += run.text;
625
- else {
628
+ const joined = pending && joinedMarks(pending, marks, run.text);
629
+ if (pending && joined) {
630
+ pending.marks = joined;
631
+ pending.text += run.text;
632
+ } else {
626
633
  flush();
627
634
  pending = {
628
635
  marks,
@@ -631,18 +638,52 @@ function inlineRuns(runs, p, ctx) {
631
638
  }
632
639
  }
633
640
  flush();
641
+ const spans = pieces.filter((piece) => "marks" in piece && !isWhitespace(piece.text));
642
+ const plain = heading && spans.length > 0 && spans.every((piece) => piece.marks.bold) ? pieces.map((piece) => "marks" in piece ? {
643
+ ...piece,
644
+ marks: {
645
+ ...piece.marks,
646
+ bold: false
647
+ }
648
+ } : piece) : pieces;
634
649
  let out = "";
635
- for (let i = 0; i < pieces.length; i++) {
636
- const piece = pieces[i];
650
+ for (let i = 0; i < plain.length; i++) {
651
+ const piece = plain[i];
637
652
  if ("literal" in piece) {
638
653
  out += piece.literal;
639
654
  continue;
640
655
  }
641
- out += applyMarks(piece.text, piece.marks, ctx, out.slice(-1), leadOf(pieces, i + 1));
656
+ out += applyMarks(piece.text, piece.marks, ctx, out.slice(-1), leadOf(plain, i + 1));
642
657
  }
643
658
  return out;
644
659
  }
645
660
  /**
661
+ * The marks a span keeps when the next run joins it, or nothing where the two
662
+ * must stay apart.
663
+ *
664
+ * The same marks join, as they always did. And a run of WHITESPACE joins its
665
+ * neighbour whatever its emphasis, for emphasis does not show on a space: a
666
+ * PDF from TeX sets no space between two words at all, the reader writes one
667
+ * in the plain face, and a bold title came back `**Trace-based**
668
+ * **Just-in-Time** **Type**`, broken at every word. A line under or through a
669
+ * space does show, and so does a link over it — those must still agree.
670
+ *
671
+ * @param span The span so far.
672
+ * @param next The next run's marks.
673
+ * @param text The next run's text.
674
+ * @returns The marks the joined span carries, or `undefined`.
675
+ */
676
+ function joinedMarks(span, next, text) {
677
+ if (sameMarks(span.marks, next)) return span.marks;
678
+ if (span.marks.strike !== next.strike || span.marks.underline !== next.underline || span.marks.href !== next.href || span.marks.anchor !== next.anchor) return void 0;
679
+ if (isWhitespace(text)) return span.marks;
680
+ if (isWhitespace(span.text)) return next;
681
+ }
682
+ /** Whether the text is whitespace and nothing else — a space, a tab, a break. */
683
+ function isWhitespace(text) {
684
+ return /^\s+$/u.test(text);
685
+ }
686
+ /**
646
687
  * The first character the next span will contribute. A dressed span always
647
688
  * begins with its delimiter or its html tag — both punctuation — so a marked
648
689
  * neighbour answers without being rendered first.
@@ -82,20 +82,20 @@ async function hardHash(password, salt, userData) {
82
82
  async function preparePdfEncryption(options) {
83
83
  const user = passwordBytes(options.userPassword ?? "");
84
84
  const owner = passwordBytes(options.ownerPassword ?? options.userPassword ?? "");
85
- const fileKey = new Uint8Array(32);
85
+ const fileKey = /* @__PURE__ */ new Uint8Array(32);
86
86
  globalThis.crypto.getRandomValues(fileKey);
87
- const salts = new Uint8Array(36);
87
+ const salts = /* @__PURE__ */ new Uint8Array(36);
88
88
  globalThis.crypto.getRandomValues(salts);
89
89
  const uvs = salts.slice(0, 8);
90
90
  const uks = salts.slice(8, 16);
91
91
  const ovs = salts.slice(16, 24);
92
92
  const oks = salts.slice(24, 32);
93
- const U = concat(await hardHash(user, uvs, new Uint8Array(0)), uvs, uks);
94
- const UE = await aesCbcNoPad(await hardHash(user, uks, new Uint8Array(0)), new Uint8Array(16), fileKey);
93
+ const U = concat(await hardHash(user, uvs, /* @__PURE__ */ new Uint8Array(0)), uvs, uks);
94
+ const UE = await aesCbcNoPad(await hardHash(user, uks, /* @__PURE__ */ new Uint8Array(0)), /* @__PURE__ */ new Uint8Array(16), fileKey);
95
95
  const O = concat(await hardHash(owner, ovs, U), ovs, oks);
96
- const OE = await aesCbcNoPad(await hardHash(owner, oks, U), new Uint8Array(16), fileKey);
96
+ const OE = await aesCbcNoPad(await hardHash(owner, oks, U), /* @__PURE__ */ new Uint8Array(16), fileKey);
97
97
  const p = permissionBits(options.permissions);
98
- const permsPlain = new Uint8Array(16);
98
+ const permsPlain = /* @__PURE__ */ new Uint8Array(16);
99
99
  new DataView(permsPlain.buffer).setInt32(0, p, true);
100
100
  permsPlain.set([
101
101
  255,
@@ -110,7 +110,7 @@ async function preparePdfEncryption(options) {
110
110
  98
111
111
  ], 8);
112
112
  permsPlain.set(salts.slice(32, 36), 12);
113
- const perms = await aesCbcNoPad(fileKey, new Uint8Array(16), permsPlain);
113
+ const perms = await aesCbcNoPad(fileKey, /* @__PURE__ */ new Uint8Array(16), permsPlain);
114
114
  return {
115
115
  fileKey,
116
116
  encryptDict: dict({
@@ -136,7 +136,7 @@ async function preparePdfEncryption(options) {
136
136
  };
137
137
  }
138
138
  async function encryptBytes(fileKey, data) {
139
- const iv = new Uint8Array(16);
139
+ const iv = /* @__PURE__ */ new Uint8Array(16);
140
140
  globalThis.crypto.getRandomValues(iv);
141
141
  const k = await subtle.importKey("raw", fileKey, "AES-CBC", false, ["encrypt"]);
142
142
  return concat(iv, new Uint8Array(await subtle.encrypt({
@@ -177,4 +177,4 @@ async function encryptObjectGraph(value, fileKey) {
177
177
  return value;
178
178
  }
179
179
  //#endregion
180
- export { encryptObjectGraph, preparePdfEncryption };
180
+ export { encryptObjectGraph, hardHash, permissionBits, preparePdfEncryption };
@@ -53,7 +53,7 @@ function buildText(text) {
53
53
  return buf;
54
54
  }
55
55
  function buildXYZ(x, y, z) {
56
- const buf = new Uint8Array(20);
56
+ const buf = /* @__PURE__ */ new Uint8Array(20);
57
57
  const view = new DataView(buf.buffer);
58
58
  writeU32BE(view, 0, tag("XYZ "));
59
59
  writeU32BE(view, 4, 0);
@@ -159,7 +159,7 @@ function buildSrgbIccProfile() {
159
159
  view.setInt32(72, s15Fixed16(D50.y), false);
160
160
  view.setInt32(76, s15Fixed16(D50.z), false);
161
161
  writeU32BE(view, headerSize, tagCount);
162
- let p = headerSize + 4;
162
+ let p = 132;
163
163
  for (const e of entries) {
164
164
  const off = blockOffsets.get(e.data);
165
165
  writeU32BE(view, p, tag(e.sig));
@@ -2,5 +2,6 @@ import "./cid-font.js";
2
2
  import "./text-page-renderer.js";
3
3
  import "../core/images.js";
4
4
  import "./image-xobject.js";
5
- import "./signature.js";
6
- import "./styled-page-renderer.js";
5
+ import { signPdf } from "./signature.js";
6
+ import { renderStyledPdf, renderStyledPdfEncrypted } from "./styled-page-renderer.js";
7
+ export { renderStyledPdf, renderStyledPdfEncrypted, signPdf };
@@ -4,6 +4,7 @@ import { zlibSync } from "fflate";
4
4
  var PDF_NULL = Symbol("PDF_NULL");
5
5
  /** A PDF name object (§7.3.5), e.g. `/Type` — the leading slash is added on serialization. */
6
6
  var PdfName = class {
7
+ value;
7
8
  /** @param value The name's text, without the leading `/`. */
8
9
  constructor(value) {
9
10
  this.value = value;
@@ -11,6 +12,8 @@ var PdfName = class {
11
12
  };
12
13
  /** An indirect reference (§7.3.10), written `id gen R`. */
13
14
  var PdfRef = class {
15
+ id;
16
+ generation;
14
17
  /**
15
18
  * @param id The referenced object number.
16
19
  * @param generation The generation number (0 for freshly written objects).
@@ -22,6 +25,8 @@ var PdfRef = class {
22
25
  };
23
26
  /** A PDF stream object (§7.3.8): a dictionary plus its raw byte payload. */
24
27
  var PdfStream = class {
28
+ dict;
29
+ data;
25
30
  /**
26
31
  * @param dict The stream dictionary (`/Length` is filled in on serialization).
27
32
  * @param data The raw stream bytes.
@@ -37,6 +42,7 @@ var PdfStream = class {
37
42
  * UTF-16BE with a leading BOM, the PDF-standard form for Unicode strings.
38
43
  */
39
44
  var PdfHexString = class {
45
+ bytes;
40
46
  /** @param bytes The raw bytes to emit as hex. */
41
47
  constructor(bytes) {
42
48
  this.bytes = bytes;
@@ -48,6 +54,7 @@ var PdfHexString = class {
48
54
  * place after the byte offsets are known (ISO 32000 §12.8.1).
49
55
  */
50
56
  var PdfRawToken = class {
57
+ token;
51
58
  /** @param token The literal text to emit unchanged. */
52
59
  constructor(token) {
53
60
  this.token = token;
@@ -69,4 +69,4 @@ function serializeStreamObject(id, generation, s) {
69
69
  return out;
70
70
  }
71
71
  //#endregion
72
- export { serializeIndirectObject };
72
+ export { serializeIndirectObject, serializeValue };
@@ -2,6 +2,8 @@ import { PDF_NULL, dict, name, unicodeString } from "./objects.js";
2
2
  //#region src/pdf/struct-tree.ts
3
3
  /** One node in the logical structure tree: a {@link StructType} plus its children, marked-content and attributes. */
4
4
  var StructNode = class {
5
+ id;
6
+ type;
5
7
  children = [];
6
8
  mcrefs = [];
7
9
  /**
@@ -182,4 +184,4 @@ var StructTreeBuilder = class {
182
184
  }
183
185
  };
184
186
  //#endregion
185
- export { StructTreeBuilder };
187
+ export { StructNode, StructTreeBuilder };