@stll/folio-core 0.8.0 → 0.9.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.
- package/README.md +39 -0
- package/dist/ai-edits/apply.js +18 -4
- package/dist/ai-edits/headless.d.ts +31 -4
- package/dist/ai-edits/headless.js +148 -35
- package/dist/ai-edits/index.d.ts +3 -3
- package/dist/ai-edits/index.js +2 -1
- package/dist/ai-edits/snapshot.js +40 -3
- package/dist/ai-edits/types.d.ts +2 -1
- package/dist/compat/eigenpal.d.ts +6 -4
- package/dist/compat/eigenpal.js +5 -3
- package/dist/controller/latestRequestGate.d.ts +13 -0
- package/dist/controller/latestRequestGate.js +16 -0
- package/dist/controller/layoutPipeline.js +12 -1
- package/dist/document-operations.d.ts +10 -3
- package/dist/document-operations.js +29 -14
- package/dist/docx/blockContentParser.js +2 -2
- package/dist/docx/commentParser.js +1 -1
- package/dist/docx/compatibility.d.ts +3 -7
- package/dist/docx/compatibility.js +0 -11
- package/dist/docx/encryption/agileDecryption.js +1 -1
- package/dist/docx/encryption/encryptionInfo.js +1 -1
- package/dist/docx/encryption/openEncryptedDocx.js +1 -1
- package/dist/docx/fontTableParser.d.ts +6 -0
- package/dist/docx/fontTableParser.js +72 -0
- package/dist/docx/groupDrawingParser.js +7 -2
- package/dist/docx/headerFooterParser.js +1 -1
- package/dist/docx/normalizeBaseDirection.js +1 -1
- package/dist/docx/numberingParser.js +1 -0
- package/dist/docx/paragraphParser.js +12 -1
- package/dist/docx/parser.d.ts +1 -1
- package/dist/docx/parser.js +12 -9
- package/dist/docx/rezip.js +70 -5
- package/dist/docx/runConsolidator.js +4 -0
- package/dist/docx/runParser.js +19 -1
- package/dist/docx/selectiveSave.js +3 -3
- package/dist/docx/serializer/fontTableSerializer.d.ts +6 -0
- package/dist/docx/serializer/fontTableSerializer.js +26 -0
- package/dist/docx/serializer/headerFooterSerializer.js +1 -1
- package/dist/docx/serializer/paragraphSerializer.js +4 -0
- package/dist/docx/serializer/runSerializer.js +7 -0
- package/dist/docx/serializer/settingsSerializer.d.ts +6 -0
- package/dist/docx/serializer/settingsSerializer.js +16 -0
- package/dist/docx/serializer/stylesSerializer.d.ts +6 -0
- package/dist/docx/serializer/stylesSerializer.js +56 -0
- package/dist/docx/serializer/tableSerializer.js +25 -26
- package/dist/docx/serializer/themeSerializer.d.ts +6 -0
- package/dist/docx/serializer/themeSerializer.js +36 -0
- package/dist/docx/settingsParser.js +46 -0
- package/dist/docx/styleParser.js +26 -1
- package/dist/docx/tableParser.js +11 -1
- package/dist/docx/vmlImageParser.js +1 -0
- package/dist/i18n/messages/catalogs.gen.d.ts +5916 -5916
- package/dist/i18n/messages/catalogs.gen.js +5910 -5910
- package/dist/index.d.ts +6 -4
- package/dist/index.js +5 -3
- package/dist/layout-bridge/convert/footnoteLayout.d.ts +3 -0
- package/dist/layout-bridge/convert/footnoteLayout.js +3 -1
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +3 -0
- package/dist/layout-bridge/convert/headerFooterLayout.js +6 -1
- package/dist/layout-bridge/convert/toFlowBlocks.d.ts +14 -2
- package/dist/layout-bridge/convert/toFlowBlocks.js +51 -14
- package/dist/layout-bridge/engine/measuring/index.d.ts +2 -1
- package/dist/layout-bridge/engine/measuring/index.js +2 -1
- package/dist/layout-engine/index.js +36 -28
- package/dist/layout-engine/measure/cache.js +11 -3
- package/dist/layout-engine/measure/font-metrics.worker.js +1 -0
- package/dist/layout-engine/measure/index.d.ts +2 -1
- package/dist/layout-engine/measure/index.js +2 -1
- package/dist/layout-engine/measure/lineBreakProvider.d.ts +33 -0
- package/dist/layout-engine/measure/lineBreakProvider.js +252 -0
- package/dist/layout-engine/measure/lineBreaks.d.ts +7 -2
- package/dist/layout-engine/measure/lineBreaks.js +11 -18
- package/dist/layout-engine/measure/listMarkerWidth.d.ts +1 -0
- package/dist/layout-engine/measure/listMarkerWidth.js +12 -6
- package/dist/layout-engine/measure/measureBlocks.d.ts +1 -2
- package/dist/layout-engine/measure/measureBlocks.js +6 -36
- package/dist/layout-engine/measure/measureContainer.js +32 -9
- package/dist/layout-engine/measure/measureHelpers.js +5 -2
- package/dist/layout-engine/measure/measureParagraph.js +335 -72
- package/dist/layout-engine/measure/measureTypes.d.ts +2 -1
- package/dist/layout-engine/measure/measureWorker.d.ts +2 -2
- package/dist/layout-engine/measure/measureWorker.js +8 -19
- package/dist/layout-engine/measure/measureWorkerProtocol.d.ts +3 -14
- package/dist/layout-engine/measure/tableCellFloating.d.ts +10 -3
- package/dist/layout-engine/measure/tableCellFloating.js +37 -29
- package/dist/layout-engine/measure/tableCellFlow.d.ts +27 -0
- package/dist/layout-engine/measure/tableCellFlow.js +73 -0
- package/dist/layout-engine/measure/tableCellGrid.js +1 -1
- package/dist/layout-engine/measure/textMeasurementPolicy.d.ts +18 -0
- package/dist/layout-engine/measure/textMeasurementPolicy.js +24 -0
- package/dist/layout-engine/renderedBreakReconciliation.d.ts +6 -1
- package/dist/layout-engine/renderedBreakReconciliation.js +34 -11
- package/dist/layout-engine/tableRowBreak.d.ts +5 -2
- package/dist/layout-engine/tableRowBreak.js +62 -29
- package/dist/layout-engine/types.d.ts +40 -7
- package/dist/layout-painter/anchoredImagePosition.d.ts +23 -0
- package/dist/layout-painter/anchoredImagePosition.js +95 -0
- package/dist/layout-painter/borderStroke.d.ts +23 -0
- package/dist/layout-painter/borderStroke.js +39 -0
- package/dist/layout-painter/renderImage.d.ts +5 -4
- package/dist/layout-painter/renderImage.js +18 -4
- package/dist/layout-painter/renderPage.d.ts +2 -27
- package/dist/layout-painter/renderPage.js +13 -99
- package/dist/layout-painter/renderParagraph.js +41 -23
- package/dist/layout-painter/renderTable.d.ts +2 -0
- package/dist/layout-painter/renderTable.js +223 -43
- package/dist/managers/DocumentLoaderManager.d.ts +1 -1
- package/dist/managers/DocumentLoaderManager.js +2 -2
- package/dist/prosemirror/attrs/index.d.ts +4 -2
- package/dist/prosemirror/attrs/index.js +21 -2
- package/dist/prosemirror/commands/propertyChangeScope.js +1 -1
- package/dist/prosemirror/conversion/fromProseDoc.js +33 -18
- package/dist/prosemirror/conversion/toProseDoc.js +50 -18
- package/dist/prosemirror/extensions/StarterKit.js +2 -0
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +7 -2
- package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.js +1 -1
- package/dist/prosemirror/extensions/features/ListExtension.js +1 -0
- package/dist/prosemirror/extensions/marks/FootnoteRefExtension.js +1 -0
- package/dist/prosemirror/extensions/marks/HighlightExtension.js +1 -1
- package/dist/prosemirror/extensions/marks/LanguageExtension.d.ts +7 -0
- package/dist/prosemirror/extensions/marks/LanguageExtension.js +30 -0
- package/dist/prosemirror/extensions/marks/RunShadingExtension.js +1 -1
- package/dist/prosemirror/extensions/marks/TextColorExtension.js +1 -1
- package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +1 -1
- package/dist/prosemirror/extensions/marks/markUtils.js +12 -0
- package/dist/prosemirror/extensions/nodes/ImageExtension.js +2 -1
- package/dist/prosemirror/extensions/nodes/TableExtension.js +4 -2
- package/dist/prosemirror/schema/index.d.ts +2 -2
- package/dist/prosemirror/schema/marks.d.ts +6 -1
- package/dist/prosemirror/schema/nodes.d.ts +13 -11
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +1 -0
- package/dist/prosemirror/utils/tabCalculator.d.ts +3 -1
- package/dist/prosemirror/utils/tabCalculator.js +12 -10
- package/dist/prosemirror/validation.js +4 -1
- package/dist/redline.js +13 -3
- package/dist/server.d.ts +6 -3
- package/dist/server.js +5 -2
- package/dist/style-sets/extract.d.ts +35 -0
- package/dist/style-sets/extract.js +123 -0
- package/dist/style-sets/stellaStyle.d.ts +13 -0
- package/dist/style-sets/stellaStyle.js +516 -0
- package/dist/style-sets/types.d.ts +31 -0
- package/dist/style-sets/types.js +5 -0
- package/dist/utils/createDocument.d.ts +12 -2
- package/dist/utils/createDocument.js +42 -31
- package/dist/utils/fontResolver.js +6 -6
- package/dist/utils/formatToStyle.js +1 -1
- package/dist/utils/paragraphFormattingMerge.d.ts +14 -3
- package/dist/utils/paragraphFormattingMerge.js +14 -4
- package/package.json +5 -1
- package/dist/docx/capabilities.d.ts +0 -41
- package/dist/docx/capabilities.js +0 -322
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { eighthsToPixels, pointsToPixels } from "../utils/units.js";
|
|
2
2
|
import { resolveFontFamily } from "../utils/fontResolver.js";
|
|
3
|
+
import { borderToStyle } from "../utils/formatToStyle.js";
|
|
3
4
|
import { floatingTextBoxReservesBand, floatingTextBoxWrapsText, isFloatingImageRun, isFloatingTextBoxBlock, isTextWrappingFloatingImageRun } from "../layout-engine/types.js";
|
|
4
5
|
import { rectsToFloatingZones } from "../layout-engine/measure/floatingZones.js";
|
|
5
6
|
import { measureParagraph } from "../layout-engine/measure/measureParagraph.js";
|
|
6
|
-
import {
|
|
7
|
+
import { emuToPixels } from "./renderUtils.js";
|
|
8
|
+
import { resolveAnchoredImagePosition as resolveAnchoredImagePosition$1 } from "./anchoredImagePosition.js";
|
|
7
9
|
import { renderFragment } from "./renderFragment.js";
|
|
8
10
|
import { applyImageVisualAttrs, hasImageVisualAttrs, renderImageFragment } from "./renderImage.js";
|
|
9
|
-
import { emuToPixels } from "./renderUtils.js";
|
|
10
11
|
import { renderParagraphFragment } from "./renderParagraph.js";
|
|
11
12
|
import { renderTextBoxFragment } from "./renderTextBox.js";
|
|
12
13
|
import { renderTableFragment } from "./renderTable.js";
|
|
@@ -33,6 +34,7 @@ const PAGE_CLASS_NAMES = {
|
|
|
33
34
|
header: "layout-page-header",
|
|
34
35
|
footer: "layout-page-footer"
|
|
35
36
|
};
|
|
37
|
+
const HEADER_FOOTER_RULE_CLIP_MARGIN = pointsToPixels(1.5);
|
|
36
38
|
const getDefaultPageFontFamily = () => resolveFontFamily("Calibri").cssFallback;
|
|
37
39
|
/**
|
|
38
40
|
* Apply page styles to an element
|
|
@@ -271,57 +273,6 @@ function applyFragmentStyles(element, fragment, margins) {
|
|
|
271
273
|
element.style.width = `${fragment.width}px`;
|
|
272
274
|
if ("height" in fragment) element.style.height = `${fragment.height}px`;
|
|
273
275
|
}
|
|
274
|
-
function resolveHorizontalBand(relativeTo, geometry) {
|
|
275
|
-
switch (relativeTo) {
|
|
276
|
-
case "page": return {
|
|
277
|
-
baseX: -geometry.marginLeft,
|
|
278
|
-
bandWidth: geometry.pageWidth
|
|
279
|
-
};
|
|
280
|
-
case "leftMargin":
|
|
281
|
-
case "insideMargin": return {
|
|
282
|
-
baseX: -geometry.marginLeft,
|
|
283
|
-
bandWidth: geometry.marginLeft
|
|
284
|
-
};
|
|
285
|
-
case "rightMargin":
|
|
286
|
-
case "outsideMargin": return {
|
|
287
|
-
baseX: geometry.contentWidth,
|
|
288
|
-
bandWidth: geometry.marginRight
|
|
289
|
-
};
|
|
290
|
-
case "character": return {
|
|
291
|
-
baseX: 0,
|
|
292
|
-
bandWidth: 0
|
|
293
|
-
};
|
|
294
|
-
default: return {
|
|
295
|
-
baseX: 0,
|
|
296
|
-
bandWidth: geometry.contentWidth
|
|
297
|
-
};
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
function resolveVerticalBand(relativeTo, fragmentY, geometry) {
|
|
301
|
-
switch (relativeTo) {
|
|
302
|
-
case "page": return {
|
|
303
|
-
baseY: -geometry.marginTop,
|
|
304
|
-
bandHeight: geometry.pageHeight
|
|
305
|
-
};
|
|
306
|
-
case "topMargin": return {
|
|
307
|
-
baseY: -geometry.marginTop,
|
|
308
|
-
bandHeight: geometry.marginTop
|
|
309
|
-
};
|
|
310
|
-
case "bottomMargin": return {
|
|
311
|
-
baseY: geometry.contentHeight,
|
|
312
|
-
bandHeight: geometry.marginBottom
|
|
313
|
-
};
|
|
314
|
-
case "paragraph":
|
|
315
|
-
case "line": return {
|
|
316
|
-
baseY: fragmentY,
|
|
317
|
-
bandHeight: 0
|
|
318
|
-
};
|
|
319
|
-
default: return {
|
|
320
|
-
baseY: 0,
|
|
321
|
-
bandHeight: geometry.contentHeight
|
|
322
|
-
};
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
276
|
/**
|
|
326
277
|
* Resolve the on-page coordinates of an anchored floating image.
|
|
327
278
|
*
|
|
@@ -337,47 +288,7 @@ function resolveVerticalBand(relativeTo, fragmentY, geometry) {
|
|
|
337
288
|
* picked by `relativeFrom`.
|
|
338
289
|
*/
|
|
339
290
|
function resolveAnchoredImagePosition(imgRun, fragmentY, geometry) {
|
|
340
|
-
|
|
341
|
-
const contentWidth = geometry.contentWidth;
|
|
342
|
-
let side = "left";
|
|
343
|
-
let x = 0;
|
|
344
|
-
if (position?.horizontal) {
|
|
345
|
-
const h = position.horizontal;
|
|
346
|
-
const { baseX, bandWidth } = resolveHorizontalBand(h.relativeTo, geometry);
|
|
347
|
-
const horizontalHasBand = h.relativeTo !== "character";
|
|
348
|
-
if (h.align === "right" || h.align === "outside") {
|
|
349
|
-
side = "right";
|
|
350
|
-
x = horizontalHasBand ? baseX + bandWidth - imgRun.width : 0;
|
|
351
|
-
} else if (h.align === "left" || h.align === "inside") {
|
|
352
|
-
side = "left";
|
|
353
|
-
x = baseX;
|
|
354
|
-
} else if (h.align === "center") {
|
|
355
|
-
side = "left";
|
|
356
|
-
x = horizontalHasBand ? baseX + (bandWidth - imgRun.width) / 2 : 0;
|
|
357
|
-
} else if (h.posOffset !== void 0) {
|
|
358
|
-
x = baseX + emuToPixels(h.posOffset);
|
|
359
|
-
side = x > contentWidth / 2 ? "right" : "left";
|
|
360
|
-
} else x = baseX;
|
|
361
|
-
} else if (imgRun.cssFloat === "right") {
|
|
362
|
-
side = "right";
|
|
363
|
-
x = contentWidth - imgRun.width;
|
|
364
|
-
}
|
|
365
|
-
let y;
|
|
366
|
-
if (position?.vertical) {
|
|
367
|
-
const v = position.vertical;
|
|
368
|
-
const { baseY, bandHeight } = resolveVerticalBand(v.relativeTo, fragmentY, geometry);
|
|
369
|
-
const verticalHasBand = v.relativeTo !== "paragraph" && v.relativeTo !== "line";
|
|
370
|
-
if (v.align === "top" || v.align === "inside") y = baseY;
|
|
371
|
-
else if (v.align === "center") y = verticalHasBand ? baseY + (bandHeight - imgRun.height) / 2 : fragmentY;
|
|
372
|
-
else if (v.align === "bottom" || v.align === "outside") y = verticalHasBand ? baseY + bandHeight - imgRun.height : fragmentY;
|
|
373
|
-
else if (v.posOffset !== void 0) y = baseY + emuToPixels(v.posOffset);
|
|
374
|
-
else y = verticalHasBand ? baseY : fragmentY;
|
|
375
|
-
} else y = fragmentY;
|
|
376
|
-
return {
|
|
377
|
-
x,
|
|
378
|
-
y,
|
|
379
|
-
side
|
|
380
|
-
};
|
|
291
|
+
return resolveAnchoredImagePosition$1(imgRun, fragmentY, geometry);
|
|
381
292
|
}
|
|
382
293
|
/**
|
|
383
294
|
* Extract floating images from a paragraph block and determine their page-level positions.
|
|
@@ -1011,7 +922,10 @@ function renderPage(page, context, options = {}) {
|
|
|
1011
922
|
});
|
|
1012
923
|
prevParagraphBorders = paragraphBlock.attrs?.borders;
|
|
1013
924
|
} else if (fragment.kind === "table" && blockData?.block.kind === "table" && blockData.measure.kind === "table") {
|
|
1014
|
-
fragmentEl = renderTableFragment(fragment, blockData.block, blockData.measure, fragmentContext, {
|
|
925
|
+
fragmentEl = renderTableFragment(fragment, blockData.block, blockData.measure, fragmentContext, {
|
|
926
|
+
document: doc,
|
|
927
|
+
pageGeometry
|
|
928
|
+
});
|
|
1015
929
|
prevParagraphBorders = void 0;
|
|
1016
930
|
} else if (fragment.kind === "image" && blockData?.block.kind === "image" && blockData.measure.kind === "image") {
|
|
1017
931
|
fragmentEl = renderImageFragment(fragment, blockData.block, blockData.measure, fragmentContext, { document: doc });
|
|
@@ -1086,7 +1000,6 @@ function renderPage(page, context, options = {}) {
|
|
|
1086
1000
|
headerEl.style.width = `${headerContentWidth}px`;
|
|
1087
1001
|
headerEl.style.height = `${interactiveHeaderHeight}px`;
|
|
1088
1002
|
headerEl.style.minHeight = `${interactiveHeaderHeight}px`;
|
|
1089
|
-
headerEl.style.opacity = "0.62";
|
|
1090
1003
|
let shouldClipHeader = !headerOverflows && headerContentFitsBox;
|
|
1091
1004
|
if (options.headerContent && options.headerContent.blocks.length > 0) {
|
|
1092
1005
|
const headerContentEl = renderHeaderFooterContent(options.headerContent, {
|
|
@@ -1107,7 +1020,8 @@ function renderPage(page, context, options = {}) {
|
|
|
1107
1020
|
}
|
|
1108
1021
|
if (shouldClipHeader) {
|
|
1109
1022
|
headerEl.style.maxHeight = `${availableHeaderHeight}px`;
|
|
1110
|
-
headerEl.style.overflow = "
|
|
1023
|
+
headerEl.style.overflow = "clip";
|
|
1024
|
+
headerEl.style.overflowClipMargin = `${HEADER_FOOTER_RULE_CLIP_MARGIN}px`;
|
|
1111
1025
|
}
|
|
1112
1026
|
pageEl.append(headerEl);
|
|
1113
1027
|
moveBehindHeaderFooterElementsToPage(headerEl, pageEl, headerDistance, page.margins.left);
|
|
@@ -1132,7 +1046,6 @@ function renderPage(page, context, options = {}) {
|
|
|
1132
1046
|
footerEl.style.width = `${footerContentWidth}px`;
|
|
1133
1047
|
footerEl.style.height = `${interactiveFooterHeight}px`;
|
|
1134
1048
|
footerEl.style.minHeight = `${interactiveFooterHeight}px`;
|
|
1135
|
-
footerEl.style.opacity = "0.62";
|
|
1136
1049
|
const footerContentFitsBox = footerVisualBottom - footerVisualTop <= interactiveFooterHeight;
|
|
1137
1050
|
let shouldClipFooter = !footerOverflows && footerContentFitsBox;
|
|
1138
1051
|
if (options.footerContent && options.footerContent.blocks.length > 0) {
|
|
@@ -1154,7 +1067,8 @@ function renderPage(page, context, options = {}) {
|
|
|
1154
1067
|
}
|
|
1155
1068
|
if (shouldClipFooter) {
|
|
1156
1069
|
footerEl.style.maxHeight = `${availableFooterHeight}px`;
|
|
1157
|
-
footerEl.style.overflow = "
|
|
1070
|
+
footerEl.style.overflow = "clip";
|
|
1071
|
+
footerEl.style.overflowClipMargin = `${HEADER_FOOTER_RULE_CLIP_MARGIN}px`;
|
|
1158
1072
|
}
|
|
1159
1073
|
pageEl.append(footerEl);
|
|
1160
1074
|
moveBehindHeaderFooterElementsToPage(footerEl, pageEl, footerNaturalTop, page.margins.left);
|
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import { parseXmlDocument } from "../docx/xmlParser.js";
|
|
2
2
|
import { resolveFontFamily } from "../utils/fontResolver.js";
|
|
3
|
+
import { detectBaseDirection } from "../utils/baseDirection.js";
|
|
4
|
+
import { AUTHOR_COLORS, getAuthorColorIdx } from "../utils/authorColors.js";
|
|
3
5
|
import "../utils/fontWeights.js";
|
|
6
|
+
import { FONT_KERNING_MODE, countCompressibleSpaces, getFontKerningMode, getRunFontKerningMode } from "../layout-engine/measure/textMeasurementPolicy.js";
|
|
7
|
+
import "../layout-engine/measure/measureHelpers.js";
|
|
4
8
|
import { calculateTabWidth } from "../prosemirror/utils/tabCalculator.js";
|
|
5
9
|
import { inlineImageBoundingBox, parseRotationDegrees, rotatedBoundingBox } from "../utils/rotationBoundingBox.js";
|
|
6
10
|
import { hasCjk, segmentByScript } from "../utils/scriptSegments.js";
|
|
7
11
|
import { isFloatingImageRun } from "../layout-engine/types.js";
|
|
8
12
|
import { getListMarkerInlineWidth, getListMarkerVisualOffset } from "../layout-engine/measure/listMarkerWidth.js";
|
|
13
|
+
import { resolveImageLineAlign } from "./renderUtils.js";
|
|
9
14
|
import { applySdtDataAttrs } from "./sdtBoundary.js";
|
|
10
15
|
import { applyImageVisualAttrs, hasImageVisualAttrs, wrapImageWithCrop } from "./renderImage.js";
|
|
11
16
|
import { ommlToMathml } from "../docx/mathToMathml.js";
|
|
12
17
|
import { evaluateFieldInstruction } from "../fields/evaluateField.js";
|
|
13
|
-
import {
|
|
14
|
-
import { detectBaseDirection } from "../utils/baseDirection.js";
|
|
18
|
+
import { borderStrokeToCss, resolveParagraphBorderHorizontalOutsets } from "./borderStroke.js";
|
|
15
19
|
import { getAutomaticTextColorForBackground } from "./documentColors.js";
|
|
16
|
-
import { resolveImageLineAlign } from "./renderUtils.js";
|
|
17
20
|
//#region src/layout-painter/renderParagraph.ts
|
|
18
21
|
/**
|
|
19
22
|
* Paragraph Fragment Renderer
|
|
@@ -128,9 +131,7 @@ function applyRunStyles(element, run) {
|
|
|
128
131
|
element.style.transform = `scaleX(${run.horizontalScale / 100})`;
|
|
129
132
|
element.style.transformOrigin = "left center";
|
|
130
133
|
}
|
|
131
|
-
|
|
132
|
-
if ((run.fontSize ?? 11) >= run.kerningMinPt) element.style.fontKerning = "normal";
|
|
133
|
-
}
|
|
134
|
+
element.style.fontKerning = getRunFontKerningMode(run, 11);
|
|
134
135
|
if (run.emboss) element.style.textShadow = "1px 1px 1px rgba(255,255,255,0.5), -1px -1px 1px rgba(0,0,0,0.3)";
|
|
135
136
|
if (run.imprint) element.style.textShadow = "-1px -1px 1px rgba(255,255,255,0.5), 1px 1px 1px rgba(0,0,0,0.3)";
|
|
136
137
|
if (run.textShadow && !run.emboss && !run.imprint) element.style.textShadow = "1px 1px 2px rgba(0,0,0,0.3)";
|
|
@@ -785,19 +786,14 @@ const startsAfterSoftWrap = (block, line) => {
|
|
|
785
786
|
* must trigger within this slack.
|
|
786
787
|
*/
|
|
787
788
|
const RIGHT_EDGE_EPSILON_PX = .5;
|
|
788
|
-
function countShrinkableSpaces(runs) {
|
|
789
|
+
function countShrinkableSpaces(runs, context) {
|
|
789
790
|
let count = 0;
|
|
790
|
-
for (const run of runs) if (isTextRun(run))
|
|
791
|
-
|
|
792
|
-
} else if (isFieldRun(run)) {
|
|
793
|
-
for (const char of run.fallback ?? "") if (char === " ") count++;
|
|
794
|
-
} else if (isMathRun(run)) {
|
|
795
|
-
for (const char of run.plainText ?? "") if (char === " ") count++;
|
|
796
|
-
}
|
|
791
|
+
for (const run of runs) if (isTextRun(run)) count += countCompressibleSpaces(run.text ?? "");
|
|
792
|
+
else if (isFieldRun(run)) count += countCompressibleSpaces(resolveFieldText(run, context));
|
|
797
793
|
return count;
|
|
798
794
|
}
|
|
799
795
|
/**
|
|
800
|
-
* Build
|
|
796
|
+
* Build the shared measurement style from a paintable text run.
|
|
801
797
|
*/
|
|
802
798
|
function runMeasureStyle(run) {
|
|
803
799
|
return {
|
|
@@ -805,7 +801,8 @@ function runMeasureStyle(run) {
|
|
|
805
801
|
...run.italic !== void 0 ? { italic: run.italic } : {},
|
|
806
802
|
...run.letterSpacing !== void 0 ? { letterSpacing: run.letterSpacing } : {},
|
|
807
803
|
...run.smallCaps !== void 0 ? { smallCaps: run.smallCaps } : {},
|
|
808
|
-
...run.eastAsiaFontFamily !== void 0 ? { eastAsiaFontFamily: run.eastAsiaFontFamily } : {}
|
|
804
|
+
...run.eastAsiaFontFamily !== void 0 ? { eastAsiaFontFamily: run.eastAsiaFontFamily } : {},
|
|
805
|
+
kerning: getRunFontKerningMode(run, 11) === FONT_KERNING_MODE.enabled
|
|
809
806
|
};
|
|
810
807
|
}
|
|
811
808
|
/**
|
|
@@ -910,6 +907,7 @@ function createTextMeasurer(doc) {
|
|
|
910
907
|
const ctx = doc.createElement("canvas").getContext("2d");
|
|
911
908
|
return (text, fontSize = 11, fontFamily = "Calibri", style = {}) => {
|
|
912
909
|
if (!ctx) return applyLetterSpacingToMeasuredWidth(text.length * 7, text, style.letterSpacing);
|
|
910
|
+
ctx.fontKerning = getFontKerningMode(style);
|
|
913
911
|
const cssFallback = resolveFontFamily(fontFamily).cssFallback;
|
|
914
912
|
const fontSizePx = fontSize * 96 / 72;
|
|
915
913
|
const fontPrefixParts = [];
|
|
@@ -996,7 +994,7 @@ function renderLine(block, line, alignment, doc, options) {
|
|
|
996
994
|
const firstLineHangingExpansionPx = hasVisibleListMarker ? Math.min(firstLineHangingPx, Math.max(0, options.leftIndentPx ?? 0)) : firstLineHangingPx;
|
|
997
995
|
const justifyCapacityPx = options.availableWidth + firstLineHangingExpansionPx;
|
|
998
996
|
const overfullPx = line.width - justifyCapacityPx;
|
|
999
|
-
const shrinkableSpaces = countShrinkableSpaces(runsForLine.filter((run) => !isTextRun(run) || !isCollapsedLineEdgeSpaceRun(run)));
|
|
997
|
+
const shrinkableSpaces = countShrinkableSpaces(runsForLine.filter((run) => !isTextRun(run) || !isCollapsedLineEdgeSpaceRun(run)), options.context);
|
|
1000
998
|
if (overfullPx > RIGHT_EDGE_EPSILON_PX && shrinkableSpaces > 0) {
|
|
1001
999
|
lineEl.style.textAlign = "left";
|
|
1002
1000
|
lineEl.style.textAlignLast = "auto";
|
|
@@ -1134,6 +1132,20 @@ function renderLine(block, line, alignment, doc, options) {
|
|
|
1134
1132
|
lineEl.append(runEl);
|
|
1135
1133
|
}
|
|
1136
1134
|
}
|
|
1135
|
+
if (line.discretionaryHyphen) {
|
|
1136
|
+
const sourceRun = block.runs[line.discretionaryHyphen.runIndex];
|
|
1137
|
+
if (sourceRun && isTextRun(sourceRun)) {
|
|
1138
|
+
const hyphenRun = {
|
|
1139
|
+
...sourceRun,
|
|
1140
|
+
text: "-"
|
|
1141
|
+
};
|
|
1142
|
+
Reflect.deleteProperty(hyphenRun, "pmStart");
|
|
1143
|
+
Reflect.deleteProperty(hyphenRun, "pmEnd");
|
|
1144
|
+
const hyphenEl = renderTextRun(hyphenRun, doc);
|
|
1145
|
+
hyphenEl.dataset["discretionaryHyphen"] = "true";
|
|
1146
|
+
lineEl.append(hyphenEl);
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1137
1149
|
const inFlowRuns = runsForLine.filter((run) => !(isImageRun(run) && isFloatingImageRun(run)));
|
|
1138
1150
|
const blankBreakRun = inFlowRuns.length > 0 && inFlowRuns.every(isLineBreakRun) ? inFlowRuns.find(isLineBreakRun) : void 0;
|
|
1139
1151
|
if (blankBreakRun?.pmStart !== void 0) {
|
|
@@ -1239,7 +1251,10 @@ function renderParagraphFragment(fragment, block, measure, context, options = {}
|
|
|
1239
1251
|
}
|
|
1240
1252
|
};
|
|
1241
1253
|
fragmentEl.style.boxSizing = "border-box";
|
|
1242
|
-
const borderToCss = (
|
|
1254
|
+
const borderToCss = (border) => borderStrokeToCss({
|
|
1255
|
+
...border,
|
|
1256
|
+
style: borderStyleToCss(border.style)
|
|
1257
|
+
});
|
|
1243
1258
|
const groupedWithPrev = bordersFormGroup(options.prevBorders, borders);
|
|
1244
1259
|
const groupedWithNext = bordersFormGroup(borders, options.nextBorders);
|
|
1245
1260
|
const renderedTopBorder = groupedWithPrev ? borders.between : borders.top;
|
|
@@ -1249,8 +1264,9 @@ function renderParagraphFragment(fragment, block, measure, context, options = {}
|
|
|
1249
1264
|
borderBox.style.position = "absolute";
|
|
1250
1265
|
borderBox.style.pointerEvents = "none";
|
|
1251
1266
|
borderBox.style.boxSizing = "border-box";
|
|
1252
|
-
|
|
1253
|
-
borderBox.style.
|
|
1267
|
+
const horizontalOutsets = resolveParagraphBorderHorizontalOutsets(borders, renderedTopBorder !== void 0 || renderedBottomBorder !== void 0);
|
|
1268
|
+
borderBox.style.left = `${indentLeft - horizontalOutsets.left}px`;
|
|
1269
|
+
borderBox.style.right = `${indentRight - horizontalOutsets.right}px`;
|
|
1254
1270
|
borderBox.style.top = `${-(renderedTopBorder?.space ?? 0) - (renderedTopBorder?.width ?? 0)}px`;
|
|
1255
1271
|
borderBox.style.bottom = `${-(renderedBottomBorder?.space ?? 0) - (renderedBottomBorder?.width ?? 0)}px`;
|
|
1256
1272
|
if (renderedTopBorder) borderBox.style.borderTop = borderToCss(renderedTopBorder);
|
|
@@ -1342,7 +1358,7 @@ function renderParagraphFragment(fragment, block, measure, context, options = {}
|
|
|
1342
1358
|
lineEl.style.paddingLeft = `${Math.max(0, markerStart)}px`;
|
|
1343
1359
|
lineEl.style.textIndent = "0";
|
|
1344
1360
|
let firstTextRun;
|
|
1345
|
-
if (!block.attrs.listMarkerFontFamily || !block.attrs.listMarkerFontSize) for (let ri = line.fromRun; ri <= line.toRun; ri++) {
|
|
1361
|
+
if (!block.attrs.listMarkerFontFamily || !block.attrs.listMarkerFontSize || block.attrs.listMarkerBold === void 0) for (let ri = line.fromRun; ri <= line.toRun; ri++) {
|
|
1346
1362
|
const r = block.runs[ri];
|
|
1347
1363
|
if (r && r.kind === "text") {
|
|
1348
1364
|
firstTextRun = r;
|
|
@@ -1351,7 +1367,8 @@ function renderParagraphFragment(fragment, block, measure, context, options = {}
|
|
|
1351
1367
|
}
|
|
1352
1368
|
const markerFontFamily = block.attrs.listMarkerFontFamily ?? firstTextRun?.fontFamily ?? block.attrs.defaultFontFamily;
|
|
1353
1369
|
const markerFontSize = block.attrs.listMarkerFontSize ?? firstTextRun?.fontSize ?? block.attrs.defaultFontSize;
|
|
1354
|
-
const
|
|
1370
|
+
const markerBold = block.attrs.listMarkerBold ?? firstTextRun?.bold;
|
|
1371
|
+
const marker = renderListMarker(block.attrs.listMarker, getListMarkerInlineWidth(block), getListMarkerVisualOffset(block), doc, markerFontFamily, markerFontSize, markerBold, block.attrs.listMarkerRevision, block.attrs.listMarkerSecondSlotOffsetTwips);
|
|
1355
1372
|
const markerMarginLeft = markerStart - Math.min(indentLeft, 0);
|
|
1356
1373
|
if (markerMarginLeft < 0) marker.style.marginLeft = `${markerMarginLeft}px`;
|
|
1357
1374
|
lineEl.prepend(marker);
|
|
@@ -1368,12 +1385,13 @@ function renderParagraphFragment(fragment, block, measure, context, options = {}
|
|
|
1368
1385
|
* tab grid. Long markers like "1.1.1." therefore grow to the next stop
|
|
1369
1386
|
* instead of butting against the body text.
|
|
1370
1387
|
*/
|
|
1371
|
-
function renderListMarker(marker, inlineWidth, visualOffset, doc, fontFamily, fontSize, revision, secondSlotOffsetTwips) {
|
|
1388
|
+
function renderListMarker(marker, inlineWidth, visualOffset, doc, fontFamily, fontSize, bold, revision, secondSlotOffsetTwips) {
|
|
1372
1389
|
const span = doc.createElement("span");
|
|
1373
1390
|
span.className = "layout-list-marker";
|
|
1374
1391
|
span.style.display = "inline-block";
|
|
1375
1392
|
if (fontFamily) span.style.fontFamily = resolveFontFamily(fontFamily).cssFallback;
|
|
1376
1393
|
if (fontSize) span.style.fontSize = `${fontSize * 96 / 72}px`;
|
|
1394
|
+
if (bold !== void 0) span.style.fontWeight = bold ? "800" : "normal";
|
|
1377
1395
|
span.style.textAlign = "left";
|
|
1378
1396
|
span.style.textAlignLast = "left";
|
|
1379
1397
|
span.style.boxSizing = "border-box";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { TableBlock, TableFragment, TableMeasure } from "../layout-engine/types.js";
|
|
2
2
|
import { RenderContext } from "./renderUtils.js";
|
|
3
|
+
import { PageGeometry } from "./anchoredImagePosition.js";
|
|
3
4
|
|
|
4
5
|
//#region src/layout-painter/renderTable.d.ts
|
|
5
6
|
/**
|
|
@@ -20,6 +21,7 @@ declare const TABLE_CLASS_NAMES: {
|
|
|
20
21
|
*/
|
|
21
22
|
type RenderTableFragmentOptions = {
|
|
22
23
|
document?: Document;
|
|
24
|
+
pageGeometry?: PageGeometry;
|
|
23
25
|
};
|
|
24
26
|
/**
|
|
25
27
|
* Render a table fragment to DOM
|