@stll/folio-core 0.32.2 → 0.33.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 (222) hide show
  1. package/dist/ai-edits/__fixtures__/paragraphs.d.ts +17 -0
  2. package/dist/ai-edits/__fixtures__/paragraphs.js +33 -0
  3. package/dist/ai-edits/apply.d.ts +49 -3
  4. package/dist/ai-edits/apply.js +649 -85
  5. package/dist/ai-edits/blockRange.d.ts +7 -3
  6. package/dist/ai-edits/blockRange.js +14 -6
  7. package/dist/ai-edits/headless.d.ts +39 -5
  8. package/dist/ai-edits/headless.js +76 -17
  9. package/dist/ai-edits/index.d.ts +6 -6
  10. package/dist/ai-edits/index.js +3 -3
  11. package/dist/ai-edits/read.d.ts +4 -0
  12. package/dist/ai-edits/read.js +30 -6
  13. package/dist/ai-edits/scoped-reading.js +4 -3
  14. package/dist/ai-edits/snapshot.d.ts +42 -2
  15. package/dist/ai-edits/snapshot.js +127 -62
  16. package/dist/ai-edits/table-row-column-mutations.d.ts +24 -1
  17. package/dist/ai-edits/table-row-column-mutations.js +98 -6
  18. package/dist/ai-edits/table-targets.d.ts +12 -3
  19. package/dist/ai-edits/table-targets.js +15 -5
  20. package/dist/ai-edits/types.d.ts +219 -15
  21. package/dist/ai-edits/word-diff.d.ts +54 -11
  22. package/dist/ai-edits/word-diff.js +221 -61
  23. package/dist/compare/__fixtures__/body-sequence.d.ts +33 -0
  24. package/dist/compare/__fixtures__/body-sequence.js +67 -0
  25. package/dist/compare/__fixtures__/nested-table.d.ts +16 -0
  26. package/dist/compare/__fixtures__/nested-table.js +50 -0
  27. package/dist/compare/__fixtures__/numbered-list.d.ts +34 -0
  28. package/dist/compare/__fixtures__/numbered-list.js +85 -0
  29. package/dist/compare/column-alignment.d.ts +27 -0
  30. package/dist/compare/column-alignment.js +162 -0
  31. package/dist/compare/compare.d.ts +107 -0
  32. package/dist/compare/compare.js +406 -0
  33. package/dist/compare/formatting.d.ts +29 -0
  34. package/dist/compare/formatting.js +84 -0
  35. package/dist/compare/plan.d.ts +22 -0
  36. package/dist/compare/plan.js +1059 -0
  37. package/dist/compare/reproducible-package.d.ts +17 -0
  38. package/dist/compare/reproducible-package.js +30 -0
  39. package/dist/compare/scenario.d.ts +77 -0
  40. package/dist/compare/scenario.js +263 -0
  41. package/dist/compare/types.d.ts +282 -0
  42. package/dist/compare/types.js +32 -0
  43. package/dist/compare/verification.d.ts +55 -0
  44. package/dist/compare/verification.js +146 -0
  45. package/dist/compat/eigenpal.d.ts +9 -6
  46. package/dist/compat/eigenpal.js +6 -3
  47. package/dist/controller/layoutPipeline.d.ts +13 -0
  48. package/dist/controller/layoutPipeline.js +15 -1
  49. package/dist/display-list/build/buildContext.d.ts +39 -0
  50. package/dist/display-list/build/buildContext.js +31 -0
  51. package/dist/display-list/build/buildDisplayList.d.ts +79 -0
  52. package/dist/display-list/build/buildDisplayList.js +283 -0
  53. package/dist/display-list/build/colors.d.ts +20 -0
  54. package/dist/display-list/build/colors.js +136 -0
  55. package/dist/display-list/build/floatingImages.d.ts +24 -0
  56. package/dist/display-list/build/floatingImages.js +41 -0
  57. package/dist/display-list/build/fontTable.d.ts +31 -0
  58. package/dist/display-list/build/fontTable.js +97 -0
  59. package/dist/display-list/build/furniture.d.ts +86 -0
  60. package/dist/display-list/build/furniture.js +98 -0
  61. package/dist/display-list/build/glyphs.d.ts +55 -0
  62. package/dist/display-list/build/glyphs.js +103 -0
  63. package/dist/display-list/build/headerFooterPrimitives.d.ts +17 -0
  64. package/dist/display-list/build/headerFooterPrimitives.js +40 -0
  65. package/dist/display-list/build/imagePrimitives.d.ts +35 -0
  66. package/dist/display-list/build/imagePrimitives.js +264 -0
  67. package/dist/display-list/build/pageBorderPrimitives.d.ts +23 -0
  68. package/dist/display-list/build/pageBorderPrimitives.js +111 -0
  69. package/dist/display-list/build/pageFurniture.d.ts +35 -0
  70. package/dist/display-list/build/pageFurniture.js +141 -0
  71. package/dist/display-list/build/paragraphPrimitives.d.ts +19 -0
  72. package/dist/display-list/build/paragraphPrimitives.js +819 -0
  73. package/dist/display-list/build/regions.d.ts +46 -0
  74. package/dist/display-list/build/regions.js +56 -0
  75. package/dist/display-list/build/storyPrimitives.d.ts +29 -0
  76. package/dist/display-list/build/storyPrimitives.js +279 -0
  77. package/dist/display-list/build/strokes.d.ts +19 -0
  78. package/dist/display-list/build/strokes.js +78 -0
  79. package/dist/display-list/build/tablePrimitives.d.ts +38 -0
  80. package/dist/display-list/build/tablePrimitives.js +409 -0
  81. package/dist/display-list/build/textBoxPrimitives.d.ts +14 -0
  82. package/dist/display-list/build/textBoxPrimitives.js +129 -0
  83. package/dist/display-list/build/textDecorations.d.ts +29 -0
  84. package/dist/display-list/build/textDecorations.js +29 -0
  85. package/dist/display-list/build/unsupported.d.ts +57 -0
  86. package/dist/display-list/build/unsupported.js +0 -0
  87. package/dist/display-list/build/watermarkPrimitives.d.ts +15 -0
  88. package/dist/display-list/build/watermarkPrimitives.js +128 -0
  89. package/dist/display-list/dom/renderDisplayListToDom.d.ts +26 -0
  90. package/dist/display-list/dom/renderDisplayListToDom.js +620 -0
  91. package/dist/display-list/editor/displayListPagePainter.d.ts +22 -0
  92. package/dist/display-list/editor/displayListPagePainter.js +63 -0
  93. package/dist/display-list/editor/pageRenderer.d.ts +24 -0
  94. package/dist/display-list/editor/pageRenderer.js +36 -0
  95. package/dist/display-list/primitives.d.ts +95 -0
  96. package/dist/display-list/primitives.js +127 -0
  97. package/dist/display-list/types.d.ts +472 -0
  98. package/dist/display-list/types.js +0 -0
  99. package/dist/document-operations.d.ts +39 -8
  100. package/dist/document-operations.js +169 -16
  101. package/dist/document-stories.d.ts +16 -0
  102. package/dist/document-stories.js +48 -4
  103. package/dist/docx/packageParts.d.ts +35 -0
  104. package/dist/docx/packageParts.js +120 -0
  105. package/dist/docx/paragraphParser.js +22 -22
  106. package/dist/docx/paragraphTraversal.js +1 -1
  107. package/dist/docx/renderedPageBreakNormalization.js +3 -1
  108. package/dist/docx/revisionIdNormalization.d.ts +13 -0
  109. package/dist/docx/revisionIdNormalization.js +103 -0
  110. package/dist/docx/rezip.js +26 -17
  111. package/dist/docx/selectiveSave.js +2 -2
  112. package/dist/docx/serializer/commentSerializer.js +6 -1
  113. package/dist/docx/serializer/paragraphSerializer.js +33 -4
  114. package/dist/docx/serializer/runSerializer.js +11 -10
  115. package/dist/docx/serializer/tableSerializer.js +2 -1
  116. package/dist/docx/server/applyDocxXmlPatchProposal.js +1 -1
  117. package/dist/docx/server/createBilingualDocx.js +3 -2
  118. package/dist/docx/streamingXmlParser.d.ts +13 -1
  119. package/dist/docx/streamingXmlParser.js +49 -11
  120. package/dist/docx/unzip.d.ts +1 -2
  121. package/dist/docx/unzip.js +25 -6
  122. package/dist/docx/xmlParser.d.ts +3 -1
  123. package/dist/docx/xmlParser.js +33 -27
  124. package/dist/export-pdf.d.ts +43 -0
  125. package/dist/export-pdf.js +98 -0
  126. package/dist/fonts/headlessMeasure.d.ts +76 -0
  127. package/dist/fonts/headlessMeasure.js +0 -0
  128. package/dist/fonts/sfnt/parse.d.ts +51 -0
  129. package/dist/fonts/sfnt/parse.js +525 -0
  130. package/dist/fonts/sfnt/subset.d.ts +20 -0
  131. package/dist/fonts/sfnt/subset.js +350 -0
  132. package/dist/fonts/sfnt/tables.d.ts +88 -0
  133. package/dist/fonts/sfnt/tables.js +131 -0
  134. package/dist/fonts/sfnt/woff.d.ts +14 -0
  135. package/dist/fonts/sfnt/woff.js +163 -0
  136. package/dist/generated/text_shaper.js +324 -0
  137. package/dist/generated/text_shaper_bg.wasm +0 -0
  138. package/dist/headless-layout.d.ts +75 -0
  139. package/dist/headless-layout.js +350 -0
  140. package/dist/index.d.ts +9 -6
  141. package/dist/index.js +6 -3
  142. package/dist/layout-bridge/convert/footnoteLayout.d.ts +1 -0
  143. package/dist/layout-bridge/convert/footnoteLayout.js +1 -0
  144. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -0
  145. package/dist/layout-bridge/convert/headerFooterLayout.js +2 -0
  146. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +3 -1
  147. package/dist/layout-bridge/convert/toFlowBlocks.js +2 -0
  148. package/dist/layout-engine/measure/advanceComposition.d.ts +62 -0
  149. package/dist/layout-engine/measure/advanceComposition.js +148 -0
  150. package/dist/layout-engine/measure/cache.d.ts +2 -0
  151. package/dist/layout-engine/measure/measureContainer.js +13 -0
  152. package/dist/layout-engine/measure/measureParagraph.js +1 -2
  153. package/dist/layout-engine/measure/measureTypes.d.ts +12 -0
  154. package/dist/layout-engine/measure/tableInlinePlacement.d.ts +3 -2
  155. package/dist/layout-engine/measure/tableInlinePlacement.js +14 -1
  156. package/dist/layout-engine/tableIndentCompatibility.d.ts +5 -0
  157. package/dist/layout-engine/tableIndentCompatibility.js +15 -0
  158. package/dist/layout-engine/types.d.ts +8 -0
  159. package/dist/layout-painter/renderPage.d.ts +29 -1
  160. package/dist/layout-painter/renderPage.js +47 -19
  161. package/dist/layout-painter/renderParagraph.d.ts +21 -2
  162. package/dist/layout-painter/renderParagraph.js +1 -1
  163. package/dist/layout-painter/renderTable.js +37 -4
  164. package/dist/managers/editorShortcuts.d.ts +33 -1
  165. package/dist/managers/editorShortcuts.js +20 -1
  166. package/dist/markdown/renderRuns.js +7 -2
  167. package/dist/markdown/renderTable.js +5 -1
  168. package/dist/model.d.ts +3 -3
  169. package/dist/model.js +2 -2
  170. package/dist/pdf/contentStream.d.ts +73 -0
  171. package/dist/pdf/contentStream.js +143 -0
  172. package/dist/pdf/fonts.d.ts +96 -0
  173. package/dist/pdf/fonts.js +593 -0
  174. package/dist/pdf/images.d.ts +28 -0
  175. package/dist/pdf/images.js +439 -0
  176. package/dist/pdf/objects.d.ts +93 -0
  177. package/dist/pdf/objects.js +237 -0
  178. package/dist/pdf/pageSpace.d.ts +43 -0
  179. package/dist/pdf/pageSpace.js +57 -0
  180. package/dist/pdf/paint.d.ts +32 -0
  181. package/dist/pdf/paint.js +442 -0
  182. package/dist/pdf/writePdf.d.ts +56 -0
  183. package/dist/pdf/writePdf.js +345 -0
  184. package/dist/prosemirror/commands/comments.js +91 -6
  185. package/dist/prosemirror/conversion/fromProseDoc.js +41 -7
  186. package/dist/prosemirror/conversion/toProseDoc.js +41 -4
  187. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.d.ts +15 -2
  188. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +35 -6
  189. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +2 -2
  190. package/dist/prosemirror/extensions/features/pasteCleanup.js +4 -3
  191. package/dist/prosemirror/extensions/nodes/BookmarkBoundaryExtension.d.ts +3 -1
  192. package/dist/prosemirror/extensions/nodes/BookmarkBoundaryExtension.js +5 -3
  193. package/dist/prosemirror/extensions/nodes/RenderedPageBreakExtension.d.ts +7 -1
  194. package/dist/prosemirror/extensions/nodes/RenderedPageBreakExtension.js +9 -3
  195. package/dist/prosemirror/extensions/nodes/TableExtension.js +56 -39
  196. package/dist/prosemirror/extensions/nodes/TextBoxAnchorExtension.d.ts +3 -1
  197. package/dist/prosemirror/extensions/nodes/TextBoxAnchorExtension.js +5 -3
  198. package/dist/prosemirror/plugins/suggestionMode.js +1 -0
  199. package/dist/prosemirror/revisionCarriers.js +19 -2
  200. package/dist/prosemirror/utils/extractTrackedChanges.d.ts +2 -2
  201. package/dist/prosemirror/utils/extractTrackedChanges.js +59 -23
  202. package/dist/prosemirror/validation.js +55 -27
  203. package/dist/prosemirror/zeroWidthAnchors.d.ts +10 -0
  204. package/dist/prosemirror/zeroWidthAnchors.js +23 -0
  205. package/dist/redline.js +12 -79
  206. package/dist/server.d.ts +3 -3
  207. package/dist/server.js +2 -2
  208. package/dist/shaping/placeRun.d.ts +51 -0
  209. package/dist/shaping/placeRun.js +84 -0
  210. package/dist/shaping/shaper.d.ts +92 -0
  211. package/dist/shaping/shaper.js +102 -0
  212. package/dist/types/block-id.d.ts +18 -2
  213. package/dist/types/block-id.js +49 -5
  214. package/dist/types/content.d.ts +2 -2
  215. package/dist/utils/clipboard.js +4 -3
  216. package/dist/utils/fontResolver.js +183 -0
  217. package/dist/utils/htmlComments.d.ts +17 -0
  218. package/dist/utils/htmlComments.js +22 -0
  219. package/dist/utils/scriptSegments.d.ts +12 -1
  220. package/dist/utils/scriptSegments.js +17 -1
  221. package/dist/version-comparison.d.ts +1 -1
  222. package/package.json +7 -3
@@ -0,0 +1,86 @@
1
+ import { document_d_exports } from "../../types/document.js";
2
+ import { FootnoteContent, HeaderFooterContent, Page } from "../../layout-engine/types.js";
3
+ import { DisplayPrimitive } from "../types.js";
4
+ import { BuildContext } from "./buildContext.js";
5
+ import { PageBorders } from "./pageBorderPrimitives.js";
6
+ import { PageComposer } from "./regions.js";
7
+ //#region src/display-list/build/furniture.d.ts
8
+ /**
9
+ * Everything the builder cannot derive from a `Layout`. Every field is
10
+ * optional, and every one of them means the same thing when absent: the
11
+ * construct is not painted, and it is reported wherever the layout or the
12
+ * caller's `documentFeatures` shows the document had one.
13
+ */
14
+ type PageFurnitureInputs = {
15
+ /**
16
+ * `w:pgBorders` for the section. Absent: no border is painted, and the gap is
17
+ * reported unless `documentFeatures` says the document has none.
18
+ */
19
+ readonly pageBorders?: PageBorders;
20
+ /** Resolves `w:themeColor` on a page border. Absent: authored colours only. */
21
+ readonly theme?: document_d_exports.Theme | null;
22
+ /**
23
+ * The watermark for every page with no more specific match in
24
+ * {@link watermarkByHeaderRId}. Absent with that map also absent: no
25
+ * watermark is painted, and the gap is reported unless `documentFeatures`
26
+ * says the document has none.
27
+ */
28
+ readonly watermark?: document_d_exports.Watermark;
29
+ /**
30
+ * Per-header-rId watermarks, authoritative when present: a page whose active
31
+ * header carries none paints none, rather than inheriting {@link watermark}.
32
+ */
33
+ readonly watermarkByHeaderRId?: ReadonlyMap<string, document_d_exports.Watermark>;
34
+ /**
35
+ * Resolved `data:` source for a picture watermark. Absent: the picture is
36
+ * reported, because the relationship id → asset mapping belongs to the
37
+ * package layer and the builder does no I/O.
38
+ */
39
+ readonly watermarkImageSrc?: string;
40
+ /**
41
+ * The header for every page, or for pages 2+ when `titlePg` is set. Absent
42
+ * with the per-rId map also absent: no header is painted, and a page whose
43
+ * `headerFooterRefs` name one says so through `unsupported`.
44
+ */
45
+ readonly headerContent?: HeaderFooterContent;
46
+ /** The footer counterpart of {@link headerContent}. */
47
+ readonly footerContent?: HeaderFooterContent;
48
+ /** Headers by part relationship id, for section-scoped and even/odd headers. */
49
+ readonly headerContentByRId?: ReadonlyMap<string, HeaderFooterContent>;
50
+ /** Footers by part relationship id. */
51
+ readonly footerContentByRId?: ReadonlyMap<string, HeaderFooterContent>;
52
+ /** The first page's header when `titlePg` is set and the layout carries no section refs. */
53
+ readonly firstPageHeaderContent?: HeaderFooterContent;
54
+ /** The first page's footer when `titlePg` is set and the layout carries no section refs. */
55
+ readonly firstPageFooterContent?: HeaderFooterContent;
56
+ /** `w:titlePg` for the first section. Absent: the first page is not special-cased. */
57
+ readonly titlePg?: boolean;
58
+ /** Overrides `w:pgMar`'s `w:header`. Absent: the page's own margin is used. */
59
+ readonly headerDistancePx?: number;
60
+ /** Overrides `w:pgMar`'s `w:footer`. Absent: the page's own margin is used. */
61
+ readonly footerDistancePx?: number;
62
+ /**
63
+ * Footnote bodies by `w:footnote` id. Absent, or missing an id a page
64
+ * carries: the band still opens with its rule and reserves the paginator's
65
+ * height, and the missing bodies are reported.
66
+ */
67
+ readonly footnoteContentById?: ReadonlyMap<number, FootnoteContent>;
68
+ };
69
+ /**
70
+ * Furniture split by where it sits in the page's paint order: `behind` goes
71
+ * under the body, `above` over it. `renderPage.ts` establishes both.
72
+ */
73
+ type PageFurniturePrimitives = {
74
+ /** Painted under the body: a back page border, the watermark. */
75
+ readonly behind: readonly DisplayPrimitive[];
76
+ /** Painted over it, into the composer, so its regions nest. */
77
+ readonly above: (composer: PageComposer) => void;
78
+ };
79
+ type PaintPageFurnitureOptions = {
80
+ readonly page: Page;
81
+ readonly furniture: PageFurnitureInputs;
82
+ readonly context: BuildContext;
83
+ };
84
+ declare const paintPageFurniture: ({ page, furniture, context }: PaintPageFurnitureOptions) => PageFurniturePrimitives;
85
+ //#endregion
86
+ export { PageFurnitureInputs, PageFurniturePrimitives, PaintPageFurnitureOptions, paintPageFurniture };
@@ -0,0 +1,98 @@
1
+ import { applySectionHeaderFooterOptions, selectSectionHeaderFooterRIds } from "../../layout-painter/renderPage.js";
2
+ import { paintHeaderFooter } from "./headerFooterPrimitives.js";
3
+ import { paintPageBorders } from "./pageBorderPrimitives.js";
4
+ import { paintFootnoteArea } from "./pageFurniture.js";
5
+ import { UNSUPPORTED_CONSTRUCT } from "./unsupported.js";
6
+ import { paintWatermark } from "./watermarkPrimitives.js";
7
+ //#region src/display-list/build/furniture.ts
8
+ const suppliesHeaderFooter = (furniture) => furniture.headerContent !== void 0 || furniture.footerContent !== void 0 || furniture.headerContentByRId !== void 0 || furniture.footerContentByRId !== void 0 || furniture.firstPageHeaderContent !== void 0 || furniture.firstPageFooterContent !== void 0;
9
+ const suppliesWatermark = (furniture) => furniture.watermark !== void 0 || furniture.watermarkByHeaderRId !== void 0;
10
+ /**
11
+ * The header, footer and watermark this page paints, chosen by the painter's
12
+ * own rule (`w:titlePg` first-page swap, `w:evenAndOddHeaders`, section-scoped
13
+ * parts) rather than by a second implementation of it.
14
+ */
15
+ const selectForPage = (page, furniture) => {
16
+ const source = {
17
+ ...furniture.headerContent === void 0 ? {} : { headerContent: furniture.headerContent },
18
+ ...furniture.footerContent === void 0 ? {} : { footerContent: furniture.footerContent },
19
+ ...furniture.headerContentByRId === void 0 ? {} : { headerContentByRId: furniture.headerContentByRId },
20
+ ...furniture.footerContentByRId === void 0 ? {} : { footerContentByRId: furniture.footerContentByRId },
21
+ ...furniture.watermark === void 0 ? {} : { watermark: furniture.watermark },
22
+ ...furniture.watermarkByHeaderRId === void 0 ? {} : { watermarkByHeaderRId: furniture.watermarkByHeaderRId }
23
+ };
24
+ const selected = { ...source };
25
+ if (applySectionHeaderFooterOptions(page, selected, source)) return selected;
26
+ if (furniture.titlePg !== true || page.number !== 1) return selected;
27
+ if (furniture.firstPageHeaderContent === void 0) delete selected.headerContent;
28
+ else selected.headerContent = furniture.firstPageHeaderContent;
29
+ if (furniture.firstPageFooterContent === void 0) delete selected.footerContent;
30
+ else selected.footerContent = furniture.firstPageFooterContent;
31
+ return selected;
32
+ };
33
+ /**
34
+ * Name a header or footer the page asks for and the caller did not supply. A
35
+ * backend cannot tell a page with no header from a page whose header never
36
+ * reached the producer.
37
+ */
38
+ const reportMissingStories = (page, furniture, selected, context) => {
39
+ if (page.headerFooterRefs === void 0) return;
40
+ if (!suppliesHeaderFooter(furniture)) {
41
+ context.unsupported.report(UNSUPPORTED_CONSTRUCT.headerFooterContent, context.pageIndex, "the page names header and footer parts, but no story content was supplied to the builder");
42
+ return;
43
+ }
44
+ const { headerRId, footerRId } = selectSectionHeaderFooterRIds(page);
45
+ const namesHeader = headerRId !== void 0;
46
+ const namesFooter = footerRId !== void 0;
47
+ const headerCarriedAWatermark = headerRId !== void 0 && furniture.watermarkByHeaderRId?.has(headerRId) === true;
48
+ if (namesHeader && !headerCarriedAWatermark && selected.headerContent === void 0) context.unsupported.report(UNSUPPORTED_CONSTRUCT.headerFooterContent, context.pageIndex, "the header part this page selects was not among the supplied stories");
49
+ if (namesFooter && selected.footerContent === void 0) context.unsupported.report(UNSUPPORTED_CONSTRUCT.headerFooterContent, context.pageIndex, "the footer part this page selects was not among the supplied stories");
50
+ };
51
+ const paintPageFurniture = ({ page, furniture, context }) => {
52
+ const selected = selectForPage(page, furniture);
53
+ reportMissingStories(page, furniture, selected, context);
54
+ const borders = furniture.pageBorders === void 0 ? [] : paintPageBorders({
55
+ page,
56
+ borders: furniture.pageBorders,
57
+ ...furniture.theme === void 0 ? {} : { theme: furniture.theme },
58
+ context
59
+ });
60
+ const paintsBorderBehind = furniture.pageBorders?.zOrder === "back";
61
+ const watermark = !suppliesWatermark(furniture) || selected.watermark === void 0 ? [] : paintWatermark({
62
+ page,
63
+ watermark: selected.watermark,
64
+ ...furniture.watermarkImageSrc === void 0 ? {} : { imageSrc: furniture.watermarkImageSrc },
65
+ context
66
+ });
67
+ const above = (composer) => {
68
+ paintFootnoteArea({
69
+ composer,
70
+ page,
71
+ context,
72
+ ...furniture.footnoteContentById === void 0 ? {} : { contentById: furniture.footnoteContentById }
73
+ });
74
+ if (selected.headerContent !== void 0) paintHeaderFooter({
75
+ composer,
76
+ page,
77
+ section: "header",
78
+ content: selected.headerContent,
79
+ ...furniture.headerDistancePx === void 0 ? {} : { distancePx: furniture.headerDistancePx },
80
+ context
81
+ });
82
+ if (selected.footerContent !== void 0) paintHeaderFooter({
83
+ composer,
84
+ page,
85
+ section: "footer",
86
+ content: selected.footerContent,
87
+ ...furniture.footerDistancePx === void 0 ? {} : { distancePx: furniture.footerDistancePx },
88
+ context
89
+ });
90
+ if (!paintsBorderBehind) composer.push(borders);
91
+ };
92
+ return {
93
+ behind: [...paintsBorderBehind ? borders : [], ...watermark],
94
+ above
95
+ };
96
+ };
97
+ //#endregion
98
+ export { paintPageFurniture };
@@ -0,0 +1,55 @@
1
+ import { DisplayRunAdjustments } from "../types.js";
2
+ import { FontStyle } from "../../layout-engine/measure/measureTypes.js";
3
+ //#region src/display-list/build/glyphs.d.ts
4
+ type Glyphs = {
5
+ readonly text: string;
6
+ readonly advancesPx: number[];
7
+ readonly widthPx: number;
8
+ /** Whether these advances were measured with kerning on. */
9
+ readonly kerning: boolean;
10
+ /** Whether they were measured as small capitals. */
11
+ readonly smallCaps: boolean;
12
+ /**
13
+ * What went into the advances beyond the glyphs' own widths. Absent when
14
+ * nothing did, which keeps the common run's primitive as small as it was.
15
+ */
16
+ readonly adjustments?: DisplayRunAdjustments;
17
+ };
18
+ type BuildGlyphsOptions = {
19
+ readonly text: string;
20
+ readonly style: FontStyle;
21
+ readonly allCaps: boolean;
22
+ /** Justification delta applied to every compressible space. */
23
+ readonly spaceDeltaPx: number;
24
+ /**
25
+ * A line-edge space run Word keeps addressable but paints with no advance
26
+ * (the painter zeroes the split-off span's font size instead).
27
+ */
28
+ readonly collapsed: boolean;
29
+ };
30
+ /**
31
+ * `measureRun` returns `charWidths` indexed by UTF-16 unit with the trailing
32
+ * unit of a surrogate pair set to 0, because that is what ProseMirror offsets
33
+ * need. The display list wants code points, so the pair folds into one entry.
34
+ * An uppercase transform that expands a code point (ß → SS) keeps the source
35
+ * advance on the first output code point and gives the rest zero, so the sum
36
+ * still equals what the measurer decided the line on.
37
+ */
38
+ declare const buildGlyphs: (options: BuildGlyphsOptions) => Glyphs;
39
+ /**
40
+ * Everything a measured run contributes to a `glyphRun`.
41
+ *
42
+ * One helper rather than three fields at each emission site: what went into the
43
+ * advances has to travel with them, and a call site that carried the advances
44
+ * and forgot the adjustments would silently paint a run the line was not fitted
45
+ * with.
46
+ */
47
+ declare const glyphRunText: (glyphs: Glyphs) => {
48
+ adjustments?: DisplayRunAdjustments;
49
+ text: string;
50
+ advancesPx: number[];
51
+ kerning: boolean;
52
+ smallCaps: boolean;
53
+ };
54
+ //#endregion
55
+ export { BuildGlyphsOptions, Glyphs, buildGlyphs, glyphRunText };
@@ -0,0 +1,103 @@
1
+ import { measureRun, measureTextWidth } from "../../layout-engine/measure/measureProvider.js";
2
+ import { FONT_KERNING_MODE, getFontKerningMode } from "../../layout-engine/measure/textMeasurementPolicy.js";
3
+ import { getHorizontalScaleFactor } from "../../utils/horizontalScale.js";
4
+ //#region src/display-list/build/glyphs.ts
5
+ /**
6
+ * Text → one advance per code point, taken from the measure seam.
7
+ *
8
+ * Shared by everything that paints glyphs (body lines, list markers, tab
9
+ * leaders, watermark text) so no caller invents a width of its own: the numbers
10
+ * here are the numbers line breaking and pagination were decided on.
11
+ */
12
+ /**
13
+ * `measureRun` returns `charWidths` indexed by UTF-16 unit with the trailing
14
+ * unit of a surrogate pair set to 0, because that is what ProseMirror offsets
15
+ * need. The display list wants code points, so the pair folds into one entry.
16
+ * An uppercase transform that expands a code point (ß → SS) keeps the source
17
+ * advance on the first output code point and gives the rest zero, so the sum
18
+ * still equals what the measurer decided the line on.
19
+ */
20
+ const buildGlyphs = (options) => {
21
+ const { text, style, allCaps, spaceDeltaPx, collapsed } = options;
22
+ const adjustments = adjustmentsOf(options);
23
+ const { charWidths } = measureRun(text, style);
24
+ const advancesPx = [];
25
+ let painted = "";
26
+ let widthPx = 0;
27
+ let unitOffset = 0;
28
+ const shapedScale = shapedScaleOf(text, style, charWidths);
29
+ for (const char of text) {
30
+ const measured = (charWidths[unitOffset] ?? 0) * shapedScale;
31
+ unitOffset += char.length;
32
+ const advance = collapsed ? 0 : measured + (char === " " ? spaceDeltaPx : 0);
33
+ widthPx += advance;
34
+ let isFirst = true;
35
+ for (const outputChar of allCaps ? char.toLocaleUpperCase() : char) {
36
+ painted += outputChar;
37
+ advancesPx.push(isFirst ? advance : 0);
38
+ isFirst = false;
39
+ }
40
+ }
41
+ return {
42
+ text: painted,
43
+ advancesPx,
44
+ widthPx,
45
+ kerning: getFontKerningMode(style) === FONT_KERNING_MODE.enabled,
46
+ smallCaps: style.fontVariant === "small-caps",
47
+ ...adjustments === void 0 ? {} : { adjustments }
48
+ };
49
+ };
50
+ /**
51
+ * What every per-character width has to be multiplied by for the run to occupy
52
+ * the width the line was fitted at.
53
+ *
54
+ * The two numbers come from the same measurer and differ by what shaping does
55
+ * across a boundary: a pair that kerns or ligates is narrower in the string
56
+ * than the two characters are apart. Line breaking used the string's width, so
57
+ * that is the run's width, and advances that summed to anything else would
58
+ * declare an extent no backend paints.
59
+ *
60
+ * Spread over every character rather than dropped on the last, because the
61
+ * difference is not one boundary's: concentrating it would move the run's final
62
+ * glyph by the whole of it.
63
+ */
64
+ const shapedScaleOf = (text, style, charWidths) => {
65
+ const perCharacterPx = charWidths.reduce((total, width) => total + width, 0);
66
+ if (perCharacterPx <= 0) return 1;
67
+ return measureTextWidth(text, style) / perCharacterPx;
68
+ };
69
+ /**
70
+ * The three adjustments named, or nothing when none applies.
71
+ *
72
+ * A collapsed run carries no advances at all, so it has nothing to reapply
73
+ * either: naming a spacing on a run painted at zero width would have a backend
74
+ * widen what the line was fitted without.
75
+ */
76
+ const adjustmentsOf = ({ style, spaceDeltaPx, collapsed }) => {
77
+ const horizontalScale = getHorizontalScaleFactor(style.horizontalScale);
78
+ const letterSpacingPx = collapsed ? 0 : (style.letterSpacing ?? 0) * horizontalScale;
79
+ const wordSpacingPx = collapsed ? 0 : spaceDeltaPx;
80
+ if (letterSpacingPx === 0 && wordSpacingPx === 0 && horizontalScale === 1) return;
81
+ return {
82
+ letterSpacingPx,
83
+ horizontalScale,
84
+ wordSpacingPx
85
+ };
86
+ };
87
+ /**
88
+ * Everything a measured run contributes to a `glyphRun`.
89
+ *
90
+ * One helper rather than three fields at each emission site: what went into the
91
+ * advances has to travel with them, and a call site that carried the advances
92
+ * and forgot the adjustments would silently paint a run the line was not fitted
93
+ * with.
94
+ */
95
+ const glyphRunText = (glyphs) => ({
96
+ text: glyphs.text,
97
+ advancesPx: glyphs.advancesPx,
98
+ kerning: glyphs.kerning,
99
+ smallCaps: glyphs.smallCaps,
100
+ ...glyphs.adjustments === void 0 ? {} : { adjustments: glyphs.adjustments }
101
+ });
102
+ //#endregion
103
+ export { buildGlyphs, glyphRunText };
@@ -0,0 +1,17 @@
1
+ import { HeaderFooterContent, Page } from "../../layout-engine/types.js";
2
+ import { BuildContext } from "./buildContext.js";
3
+ import { PageComposer } from "./regions.js";
4
+ //#region src/display-list/build/headerFooterPrimitives.d.ts
5
+ type HeaderFooterSection = "header" | "footer";
6
+ type HeaderFooterPaintOptions = {
7
+ readonly composer: PageComposer;
8
+ readonly page: Page;
9
+ readonly section: HeaderFooterSection;
10
+ readonly content: HeaderFooterContent;
11
+ /** Overrides `w:pgMar`'s `w:header` / `w:footer` for this page. */
12
+ readonly distancePx?: number;
13
+ readonly context: BuildContext;
14
+ };
15
+ declare const paintHeaderFooter: ({ composer, page, section, content, distancePx, context }: HeaderFooterPaintOptions) => void;
16
+ //#endregion
17
+ export { HeaderFooterPaintOptions, HeaderFooterSection, paintHeaderFooter };
@@ -0,0 +1,40 @@
1
+ import { HIT_REGION_KINDS } from "../primitives.js";
2
+ import { paintHeaderFooterBlocks } from "./storyPrimitives.js";
3
+ //#region src/display-list/build/headerFooterPrimitives.ts
4
+ /** `renderPage.ts`: the fallback when neither the caller nor `w:pgMar` states one. */
5
+ const DEFAULT_DISTANCE_PX = 48;
6
+ const paintHeaderFooter = ({ composer, page, section, content, distancePx, context }) => {
7
+ if (content.blocks.length === 0) return;
8
+ const distance = distancePx ?? (section === "header" ? page.margins.header : page.margins.footer) ?? DEFAULT_DISTANCE_PX;
9
+ const originYPx = section === "header" ? distance : page.size.h - distance - content.height;
10
+ const story = {
11
+ kind: section,
12
+ rId: content.rId ?? null
13
+ };
14
+ composer.region({
15
+ kind: section === "header" ? HIT_REGION_KINDS.headerSlot : HIT_REGION_KINDS.footerSlot,
16
+ rect: {
17
+ xPx: page.margins.left,
18
+ yPx: originYPx,
19
+ widthPx: page.size.w - page.margins.left - page.margins.right,
20
+ heightPx: content.height
21
+ },
22
+ model: { story }
23
+ }, () => {
24
+ paintHeaderFooterBlocks({
25
+ composer,
26
+ blocks: content.blocks,
27
+ measures: content.measures,
28
+ xPx: page.margins.left,
29
+ yPx: originYPx,
30
+ widthPx: page.size.w - page.margins.left - page.margins.right,
31
+ context: {
32
+ ...context,
33
+ story
34
+ },
35
+ label: content.rId === void 0 ? section : `${section} ${content.rId}`
36
+ });
37
+ });
38
+ };
39
+ //#endregion
40
+ export { paintHeaderFooter };
@@ -0,0 +1,35 @@
1
+ import { ImageBlock, ImageFragment } from "../../layout-engine/types.js";
2
+ import { DisplayImageRef, DisplayImageSource, DisplayPrimitive, DisplayRect } from "../types.js";
3
+ import { BuildContext } from "./buildContext.js";
4
+ //#region src/display-list/build/imagePrimitives.d.ts
5
+ /**
6
+ * Sources interned in first-use order, so two builds of one layout produce the
7
+ * same `DisplayImageRef` for the same picture.
8
+ */
9
+ declare class ImageTable {
10
+ private readonly sources;
11
+ private readonly refBySrc;
12
+ private readonly failureBySrc;
13
+ /** `undefined` means "do not paint"; the reason is available via {@link failureFor}. */
14
+ intern(src: string): DisplayImageRef | undefined;
15
+ failureFor(src: string): string | undefined;
16
+ snapshot(): readonly DisplayImageSource[];
17
+ }
18
+ type ImageVisualSource = Pick<ImageBlock, "src" | "opacity" | "cropTop" | "cropRight" | "cropBottom" | "cropLeft" | "borderWidth" | "borderColor" | "borderStyle" | "transform">;
19
+ type PaintImageOptions = {
20
+ readonly source: ImageVisualSource;
21
+ readonly rect: DisplayRect;
22
+ readonly context: BuildContext;
23
+ /** Names the construct in an `unsupported` entry, e.g. `"anchored image"`. */
24
+ readonly label: string;
25
+ };
26
+ /**
27
+ * The primitives one picture draws: the bitmap (rotated and/or washed as the
28
+ * source asks) followed by its border. Empty when the bytes are unusable, with
29
+ * the reason already reported.
30
+ */
31
+ declare const paintImage: ({ source, rect, context, label }: PaintImageOptions) => readonly DisplayPrimitive[];
32
+ /** An anchored or block image fragment placed by the layout engine. */
33
+ declare const paintImageFragment: (fragment: ImageFragment, block: ImageBlock, context: BuildContext) => readonly DisplayPrimitive[];
34
+ //#endregion
35
+ export { ImageTable, PaintImageOptions, paintImage, paintImageFragment };