@stll/folio-core 0.29.0 → 0.30.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/dist/controller/folioEditor.d.ts +28 -1
- package/dist/controller/folioEditor.js +37 -26
- package/dist/controller/fontReadiness.js +28 -24
- package/dist/controller/hiddenEditorManager.d.ts +2 -7
- package/dist/controller/layoutPipeline.js +33 -3
- package/dist/controller/noteEditorManager.d.ts +3 -6
- package/dist/docx/metafileSvg.d.ts +12 -0
- package/dist/docx/metafileSvg.js +462 -0
- package/dist/docx/paragraphTextBoxEnrichment.js +55 -4
- package/dist/docx/parser.d.ts +2 -2
- package/dist/docx/parser.js +26 -0
- package/dist/docx/runParser.js +2 -1
- package/dist/docx/serializer/runSerializer.js +14 -2
- package/dist/docx/styleParser.js +2 -1
- package/dist/docx/textBoxParser.js +14 -0
- package/dist/docx/vmlImageParser.js +72 -152
- package/dist/docx/vmlPreview.d.ts +31 -0
- package/dist/docx/vmlPreview.js +535 -0
- package/dist/docx/wrapTypes.d.ts +2 -36
- package/dist/docx/wrapTypes.js +1 -39
- package/dist/fonts/fontAlternates.d.ts +8 -0
- package/dist/fonts/fontAlternates.js +16 -0
- package/dist/layout-bridge/convert/footnoteLayout.d.ts +1 -0
- package/dist/layout-bridge/convert/footnoteLayout.js +34 -3
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -0
- package/dist/layout-bridge/convert/headerFooterLayout.js +5 -0
- package/dist/layout-bridge/convert/toFlowBlocks.d.ts +3 -0
- package/dist/layout-bridge/convert/toFlowBlocks.js +78 -28
- package/dist/layout-bridge/dom/noteStoryDom.d.ts +1 -1
- package/dist/layout-bridge/engine/selectionRects.js +3 -1
- package/dist/layout-engine/index.js +65 -32
- package/dist/layout-engine/justifiedLineFit.d.ts +7 -0
- package/dist/layout-engine/justifiedLineFit.js +6 -0
- package/dist/layout-engine/keep-together.js +15 -10
- package/dist/layout-engine/measure/complexScriptFormatting.d.ts +6 -1
- package/dist/layout-engine/measure/complexScriptFormatting.js +11 -2
- package/dist/layout-engine/measure/floatingTablePosition.d.ts +16 -1
- package/dist/layout-engine/measure/floatingTablePosition.js +29 -6
- package/dist/layout-engine/measure/lineBreakProvider.js +67 -8
- package/dist/layout-engine/measure/listMarkerWidth.d.ts +1 -0
- package/dist/layout-engine/measure/listMarkerWidth.js +23 -10
- package/dist/layout-engine/measure/measureBlocks.d.ts +15 -0
- package/dist/layout-engine/measure/measureBlocks.js +197 -30
- package/dist/layout-engine/measure/measureContainer.js +20 -24
- package/dist/layout-engine/measure/measureHelpers.d.ts +1 -1
- package/dist/layout-engine/measure/measureHelpers.js +14 -8
- package/dist/layout-engine/measure/measureParagraph.js +111 -37
- package/dist/layout-engine/measure/measureTypes.d.ts +3 -0
- package/dist/layout-engine/measure/tabCalculator.d.ts +123 -0
- package/dist/layout-engine/measure/tabCalculator.js +144 -0
- package/dist/layout-engine/measure/tableCellFlow.d.ts +21 -1
- package/dist/layout-engine/measure/tableCellFlow.js +45 -8
- package/dist/layout-engine/measure/tableInlinePlacement.d.ts +10 -2
- package/dist/layout-engine/measure/tableInlinePlacement.js +17 -15
- package/dist/layout-engine/paginator.d.ts +26 -2
- package/dist/layout-engine/paginator.js +76 -14
- package/dist/layout-engine/paragraphSpacing.d.ts +3 -1
- package/dist/layout-engine/paragraphSpacing.js +4 -3
- package/dist/layout-engine/renderedBreakReconciliation.d.ts +14 -3
- package/dist/layout-engine/renderedBreakReconciliation.js +45 -14
- package/dist/layout-engine/section-breaks.d.ts +3 -1
- package/dist/layout-engine/section-breaks.js +6 -2
- package/dist/layout-engine/types.d.ts +18 -1
- package/dist/layout-engine/types.js +1 -1
- package/dist/layout-painter/imageLayout.d.ts +1 -1
- package/dist/layout-painter/renderPage.js +6 -1
- package/dist/layout-painter/renderParagraph.js +169 -82
- package/dist/layout-painter/renderTable.d.ts +1 -1
- package/dist/layout-painter/renderTable.js +18 -7
- package/dist/layout-painter/renderTextBox.d.ts +1 -1
- package/dist/layout-painter/renderTextBox.js +6 -1
- package/dist/model.d.ts +3 -3
- package/dist/model.js +2 -2
- package/dist/paged-layout/sectionBlockWidths.d.ts +14 -0
- package/dist/paged-layout/sectionBlockWidths.js +103 -14
- package/dist/prosemirror/attrs/index.js +12 -1
- package/dist/prosemirror/conversion/fromProseDoc.js +6 -2
- package/dist/prosemirror/conversion/toProseDoc.js +10 -3
- package/dist/prosemirror/extensions/marks/CharacterSpacingExtension.js +9 -5
- package/dist/prosemirror/extensions/nodes/TableExtension.js +2 -0
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +6 -2
- package/dist/prosemirror/schema/nodes.d.ts +4 -0
- package/dist/prosemirror/utils/tabCalculator.d.ts +2 -123
- package/dist/prosemirror/utils/tabCalculator.js +1 -140
- package/dist/render-dom/RemoteSelectionOverlay.d.ts +4 -4
- package/dist/types/documentEnumValues.d.ts +4 -1
- package/dist/types/documentEnumValues.js +12 -1
- package/dist/types/editor-story.d.ts +8 -0
- package/dist/types/editor-story.js +0 -0
- package/dist/types/remote-selection.d.ts +11 -0
- package/dist/types/remote-selection.js +0 -0
- package/dist/types/wrap.d.ts +36 -0
- package/dist/types/wrap.js +40 -0
- package/dist/utils/fontResolver.d.ts +1 -1
- package/dist/utils/fontResolver.js +42 -2
- package/dist/utils/formatToStyle.js +4 -2
- package/dist/utils/horizontalScale.d.ts +28 -0
- package/dist/utils/horizontalScale.js +42 -0
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { measureParagraph } from "../../layout-engine/measure/measureParagraph.js";
|
|
2
2
|
import { layoutTextBoxContent } from "../../layout-engine/measure/textBoxParagraphLayout.js";
|
|
3
|
-
import { DEFAULT_TEXTBOX_MARGINS, FOOTNOTE_ENTRY_MARGIN_BOTTOM, FOOTNOTE_FALLBACK_LINE_HEIGHT, FOOTNOTE_SEPARATOR_HEIGHT } from "../../layout-engine/types.js";
|
|
3
|
+
import { DEFAULT_TEXTBOX_MARGINS, FOOTNOTE_ENTRY_MARGIN_BOTTOM, FOOTNOTE_FALLBACK_LINE_HEIGHT, FOOTNOTE_SEPARATOR_HEIGHT, isFloatingImageRun } from "../../layout-engine/types.js";
|
|
4
4
|
import { footnoteToProseDoc } from "../../prosemirror/conversion/toProseDoc.js";
|
|
5
5
|
import { toFlowBlocks } from "./toFlowBlocks.js";
|
|
6
6
|
//#region src/layout-bridge/convert/footnoteLayout.ts
|
|
@@ -196,6 +196,7 @@ function convertFootnoteToContent(footnote, displayNumber, contentWidth, options
|
|
|
196
196
|
const pmDoc = footnoteToProseDoc(footnote.content, proseOptions);
|
|
197
197
|
const flowOptions = {};
|
|
198
198
|
if (options.theme !== void 0) flowOptions.theme = options.theme;
|
|
199
|
+
if (options.fontAlternates !== void 0) flowOptions.fontAlternates = options.fontAlternates;
|
|
199
200
|
if (options.defaultTabStopTwips !== void 0) flowOptions.defaultTabStopTwips = options.defaultTabStopTwips;
|
|
200
201
|
if (options.lineBreakRules) flowOptions.lineBreakRules = options.lineBreakRules;
|
|
201
202
|
if (options.justificationCompatibility) flowOptions.justificationCompatibility = options.justificationCompatibility;
|
|
@@ -363,18 +364,48 @@ function applyFootnotePresentation(blocks, displayNumber) {
|
|
|
363
364
|
return output;
|
|
364
365
|
}
|
|
365
366
|
function createFootnoteNumberRun(displayNumber, paragraph) {
|
|
366
|
-
const firstTextRun = paragraph.runs.find((run) => run.kind === "text");
|
|
367
367
|
const firstFormattedRun = paragraph.runs.find((run) => run.kind === "text" || run.kind === "tab" || run.kind === "field");
|
|
368
368
|
const numberRun = {
|
|
369
369
|
kind: "text",
|
|
370
|
-
text:
|
|
370
|
+
text: `${displayNumber}${resolveFootnoteNumberSuffix(paragraph.runs) === FOOTNOTE_NUMBER_SUFFIX.SEPARATED ? " " : ""}`,
|
|
371
371
|
fontSize: firstFormattedRun?.fontSize ?? paragraph.attrs?.defaultFontSize ?? FOOTNOTE_FONT_SIZE,
|
|
372
372
|
superscript: true
|
|
373
373
|
};
|
|
374
374
|
const fontFamily = firstFormattedRun?.fontFamily ?? paragraph.attrs?.defaultFontFamily;
|
|
375
375
|
if (fontFamily) numberRun.fontFamily = fontFamily;
|
|
376
|
+
const alternateFontFamily = firstFormattedRun?.fontFamily !== void 0 ? firstFormattedRun.alternateFontFamily : paragraph.attrs?.defaultAlternateFontFamily;
|
|
377
|
+
if (alternateFontFamily) numberRun.alternateFontFamily = alternateFontFamily;
|
|
376
378
|
return numberRun;
|
|
377
379
|
}
|
|
380
|
+
const FOOTNOTE_NUMBER_SUFFIX = {
|
|
381
|
+
ATTACHED: "none",
|
|
382
|
+
SEPARATED: "space"
|
|
383
|
+
};
|
|
384
|
+
const ATTACHED_FOOTNOTE_SUFFIX_PATTERN = /^(?:[\p{Pe}\p{Pf}\p{Sentence_Terminal}]|[,;:\u060c\u061b\u3001\uff0c\uff1a\uff1b])/u;
|
|
385
|
+
const LEADING_WHITESPACE_PATTERN = /^\s/u;
|
|
386
|
+
function resolveTextFootnoteNumberSuffix(text) {
|
|
387
|
+
if (LEADING_WHITESPACE_PATTERN.test(text) || ATTACHED_FOOTNOTE_SUFFIX_PATTERN.test(text)) return FOOTNOTE_NUMBER_SUFFIX.ATTACHED;
|
|
388
|
+
return FOOTNOTE_NUMBER_SUFFIX.SEPARATED;
|
|
389
|
+
}
|
|
390
|
+
function resolveRunFootnoteNumberSuffix(run) {
|
|
391
|
+
switch (run.kind) {
|
|
392
|
+
case "text": return run.text.length === 0 ? void 0 : resolveTextFootnoteNumberSuffix(run.text);
|
|
393
|
+
case "tab":
|
|
394
|
+
case "lineBreak": return FOOTNOTE_NUMBER_SUFFIX.ATTACHED;
|
|
395
|
+
case "field": return resolveTextFootnoteNumberSuffix(run.fallback || "1");
|
|
396
|
+
case "image": return isFloatingImageRun(run) ? void 0 : FOOTNOTE_NUMBER_SUFFIX.SEPARATED;
|
|
397
|
+
case "math": return FOOTNOTE_NUMBER_SUFFIX.SEPARATED;
|
|
398
|
+
case "renderedPageBreak": return;
|
|
399
|
+
default: return run;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
function resolveFootnoteNumberSuffix(runs) {
|
|
403
|
+
for (const run of runs) {
|
|
404
|
+
const suffix = resolveRunFootnoteNumberSuffix(run);
|
|
405
|
+
if (suffix !== void 0) return suffix;
|
|
406
|
+
}
|
|
407
|
+
return FOOTNOTE_NUMBER_SUFFIX.SEPARATED;
|
|
408
|
+
}
|
|
378
409
|
function applyFootnoteBlockPresentation(block) {
|
|
379
410
|
if (block.kind === "paragraph") return applyFootnoteParagraphPresentation(block);
|
|
380
411
|
if (block.kind === "table") return applyFootnoteTablePresentation(block);
|
|
@@ -41,6 +41,7 @@ declare function calculateHeaderFooterBodyTopClearance(blocks: FlowBlock[], flow
|
|
|
41
41
|
type ConvertHeaderFooterOptions = {
|
|
42
42
|
styles?: document_d_exports.StyleDefinitions | null;
|
|
43
43
|
theme?: document_d_exports.Theme | null;
|
|
44
|
+
fontAlternates?: ToFlowBlocksOptions["fontAlternates"];
|
|
44
45
|
measureBlocks: MeasureBlocksFn;
|
|
45
46
|
/** Document-wide `w:defaultTabStop` in twips — forwarded to toFlowBlocks. */
|
|
46
47
|
defaultTabStopTwips?: number;
|
|
@@ -333,6 +333,7 @@ function convertHeaderFooterToContent(headerFooter, contentWidth, metrics, optio
|
|
|
333
333
|
const pmDoc = headerFooterToProseDoc(headerFooter.content, proseDocOptions);
|
|
334
334
|
const flowOptions = {};
|
|
335
335
|
if (options.theme !== void 0) flowOptions.theme = options.theme;
|
|
336
|
+
if (options.fontAlternates !== void 0) flowOptions.fontAlternates = options.fontAlternates;
|
|
336
337
|
if (options.defaultTabStopTwips !== void 0) flowOptions.defaultTabStopTwips = options.defaultTabStopTwips;
|
|
337
338
|
if (options.lineBreakRules) flowOptions.lineBreakRules = options.lineBreakRules;
|
|
338
339
|
if (options.justificationCompatibility) flowOptions.justificationCompatibility = options.justificationCompatibility;
|
|
@@ -354,6 +355,7 @@ function convertHeaderFooterPmDocToContent(pmDoc, contentWidth, metrics, options
|
|
|
354
355
|
if (!pmDoc || pmDoc.content.size === 0) return;
|
|
355
356
|
const flowOptions = {};
|
|
356
357
|
if (options.theme !== void 0) flowOptions.theme = options.theme;
|
|
358
|
+
if (options.fontAlternates !== void 0) flowOptions.fontAlternates = options.fontAlternates;
|
|
357
359
|
if (options.defaultTabStopTwips !== void 0) flowOptions.defaultTabStopTwips = options.defaultTabStopTwips;
|
|
358
360
|
if (options.lineBreakRules) flowOptions.lineBreakRules = options.lineBreakRules;
|
|
359
361
|
if (options.justificationCompatibility) flowOptions.justificationCompatibility = options.justificationCompatibility;
|
|
@@ -495,8 +497,11 @@ function serializeRunFmt(run) {
|
|
|
495
497
|
"highlightColor",
|
|
496
498
|
"fontSize",
|
|
497
499
|
"fontFamily",
|
|
500
|
+
"alternateFontFamily",
|
|
498
501
|
"eastAsiaFontFamily",
|
|
502
|
+
"eastAsiaAlternateFontFamily",
|
|
499
503
|
"complexScriptFontFamily",
|
|
504
|
+
"complexScriptAlternateFontFamily",
|
|
500
505
|
"complexScriptFontSize",
|
|
501
506
|
"complexScriptBold",
|
|
502
507
|
"complexScriptItalic",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { document_d_exports } from "../../types/document.js";
|
|
2
2
|
import { BorderStyle, FlowBlock, ParagraphAttrs } from "../../layout-engine/types.js";
|
|
3
|
+
import { FontAlternates } from "../../fonts/fontAlternates.js";
|
|
3
4
|
import { formatCounter, resolveListTemplate } from "../../prosemirror/listMarker.js";
|
|
4
5
|
import { Node } from "prosemirror-model";
|
|
5
6
|
//#region src/layout-bridge/convert/toFlowBlocks.d.ts
|
|
@@ -13,6 +14,8 @@ type ToFlowBlocksOptions = {
|
|
|
13
14
|
defaultSize?: number;
|
|
14
15
|
/** Theme for resolving theme colors. */
|
|
15
16
|
theme?: document_d_exports.Theme | null;
|
|
17
|
+
/** Document-scoped OOXML primary-font to `w:altName` lookup. */
|
|
18
|
+
fontAlternates?: FontAlternates;
|
|
16
19
|
/** Page content height in pixels (pageHeight - marginTop - marginBottom). Images taller than this are scaled down to fit. */
|
|
17
20
|
pageContentHeight?: number;
|
|
18
21
|
/** Shared list counters for nested containers. */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { convertBulletToUnicode } from "../../docx/bulletMarkers.js";
|
|
2
2
|
import { resolveDocumentGridLinePitch } from "../../docx/documentGrid.js";
|
|
3
|
+
import { getFontAlternate } from "../../fonts/fontAlternates.js";
|
|
3
4
|
import { setHyperlinkInstanceIndex } from "../../layout-engine/measure/hyperlinkInstance.js";
|
|
4
5
|
import { setParagraphFrame } from "../../layout-engine/paragraphFrame.js";
|
|
5
6
|
import { setTextBoxGroupId } from "../../layout-engine/textBoxGroup.js";
|
|
@@ -13,9 +14,11 @@ import { resolveNumberedRefFields } from "../../prosemirror/numberedRefFields.js
|
|
|
13
14
|
import { directionToBidi } from "../../prosemirror/paragraphDirection.js";
|
|
14
15
|
import { cascadeStyleTextFormatting } from "../../prosemirror/styles/styleToggleCascade.js";
|
|
15
16
|
import { assertValidProseMirrorDocument } from "../../prosemirror/validation.js";
|
|
17
|
+
import { normalizeShapeTextAnchor } from "../../types/documentEnumValues.js";
|
|
16
18
|
import { resolveColor, resolveHighlightToCss } from "../../utils/colorResolver.js";
|
|
17
19
|
import { resolveThemeFont } from "../../utils/fontResolver.js";
|
|
18
20
|
import { resolveShadingFill } from "../../utils/formatToStyle.js";
|
|
21
|
+
import { normalizeHorizontalScalePercent } from "../../utils/horizontalScale.js";
|
|
19
22
|
import { decodeOoxmlSymbolCharacter } from "../../utils/ooxmlSymbol.js";
|
|
20
23
|
import { tableOfContentsStyleLevel } from "../../utils/tableOfContentsStyle.js";
|
|
21
24
|
import { AUTO_PARAGRAPH_SPACING_PX, halfPointsToPixels, halfPointsToPoints, pointsToPixels } from "../../utils/units.js";
|
|
@@ -85,7 +88,7 @@ function resetBlockIdCounter() {
|
|
|
85
88
|
/**
|
|
86
89
|
* Extract run formatting from ProseMirror marks.
|
|
87
90
|
*/
|
|
88
|
-
function extractRunFormatting(marks, theme) {
|
|
91
|
+
function extractRunFormatting(marks, theme, fontAlternates) {
|
|
89
92
|
const formatting = {};
|
|
90
93
|
let hasNoteRef = false;
|
|
91
94
|
for (const mark of marks) switch (mark.type.name) {
|
|
@@ -137,11 +140,23 @@ function extractRunFormatting(marks, theme) {
|
|
|
137
140
|
case "fontFamily": {
|
|
138
141
|
const attrs = expectFontFamilyMarkAttrs(mark);
|
|
139
142
|
const font = resolveWesternThemeFont(attrs, theme);
|
|
140
|
-
if (font)
|
|
143
|
+
if (font) {
|
|
144
|
+
formatting.fontFamily = font;
|
|
145
|
+
const alternate = getFontAlternate(font, fontAlternates);
|
|
146
|
+
if (alternate) formatting.alternateFontFamily = alternate;
|
|
147
|
+
}
|
|
141
148
|
const eastAsiaFont = resolveEastAsiaThemeFont(attrs, theme);
|
|
142
|
-
if (eastAsiaFont)
|
|
149
|
+
if (eastAsiaFont) {
|
|
150
|
+
formatting.eastAsiaFontFamily = eastAsiaFont;
|
|
151
|
+
const alternate = getFontAlternate(eastAsiaFont, fontAlternates);
|
|
152
|
+
if (alternate) formatting.eastAsiaAlternateFontFamily = alternate;
|
|
153
|
+
}
|
|
143
154
|
const complexScriptFont = resolveComplexScriptThemeFont(attrs, theme);
|
|
144
|
-
if (complexScriptFont)
|
|
155
|
+
if (complexScriptFont) {
|
|
156
|
+
formatting.complexScriptFontFamily = complexScriptFont;
|
|
157
|
+
const alternate = getFontAlternate(complexScriptFont, fontAlternates);
|
|
158
|
+
if (alternate) formatting.complexScriptAlternateFontFamily = alternate;
|
|
159
|
+
}
|
|
145
160
|
break;
|
|
146
161
|
}
|
|
147
162
|
case "language": {
|
|
@@ -157,7 +172,8 @@ function extractRunFormatting(marks, theme) {
|
|
|
157
172
|
const attrs = expectCharacterSpacingMarkAttrs(mark);
|
|
158
173
|
if (attrs.spacing !== void 0) formatting.letterSpacing = twipsToPixels(attrs.spacing);
|
|
159
174
|
if (attrs.position !== void 0 && attrs.position !== 0) formatting.positionPx = halfPointsToPixels(attrs.position);
|
|
160
|
-
|
|
175
|
+
const horizontalScale = normalizeHorizontalScalePercent(attrs.scale);
|
|
176
|
+
if (horizontalScale !== void 0) formatting.horizontalScale = horizontalScale;
|
|
161
177
|
if (attrs.kerning !== void 0 && attrs.kerning > 0) formatting.kerningMinPt = halfPointsToPoints(attrs.kerning);
|
|
162
178
|
break;
|
|
163
179
|
}
|
|
@@ -280,7 +296,11 @@ function mergeRunFormatting(paraDefaults, formatting) {
|
|
|
280
296
|
...paraDefaults,
|
|
281
297
|
...markDefaultBlackTextColorSource(formatting, paraDefaults)
|
|
282
298
|
};
|
|
299
|
+
if (formatting.fontFamily !== void 0 && formatting.alternateFontFamily === void 0) delete merged.alternateFontFamily;
|
|
300
|
+
if (formatting.eastAsiaFontFamily !== void 0 && formatting.eastAsiaAlternateFontFamily === void 0) delete merged.eastAsiaAlternateFontFamily;
|
|
301
|
+
if (formatting.complexScriptFontFamily !== void 0 && formatting.complexScriptAlternateFontFamily === void 0) delete merged.complexScriptAlternateFontFamily;
|
|
283
302
|
if (merged.letterSpacing === 0) delete merged.letterSpacing;
|
|
303
|
+
if (formatting.horizontalScale === 100 && paraDefaults.horizontalScale === void 0) delete merged.horizontalScale;
|
|
284
304
|
return merged;
|
|
285
305
|
}
|
|
286
306
|
/** Restore character-style toggle values that plain visual marks cannot represent. */
|
|
@@ -332,15 +352,27 @@ function applyRunFormattingOverrides(formatting, attrs) {
|
|
|
332
352
|
if (attrs.fontSizeCs !== void 0) formatting.complexScriptFontSize = attrs.fontSizeCs / 2;
|
|
333
353
|
if (attrs.cs !== void 0) formatting.forceComplexScript = attrs.cs;
|
|
334
354
|
}
|
|
335
|
-
function textFormattingToRunFormatting(defaultTextFormatting, theme) {
|
|
355
|
+
function textFormattingToRunFormatting(defaultTextFormatting, theme, fontAlternates) {
|
|
336
356
|
if (!defaultTextFormatting) return {};
|
|
337
357
|
const result = {};
|
|
338
358
|
const fontFamily = defaultTextFormatting.fontFamily ? resolveWesternThemeFont(defaultTextFormatting.fontFamily, theme) : void 0;
|
|
339
|
-
if (fontFamily)
|
|
359
|
+
if (fontFamily) {
|
|
360
|
+
result.fontFamily = fontFamily;
|
|
361
|
+
const alternate = getFontAlternate(fontFamily, fontAlternates);
|
|
362
|
+
if (alternate) result.alternateFontFamily = alternate;
|
|
363
|
+
}
|
|
340
364
|
const eastAsiaFontFamily = defaultTextFormatting.fontFamily ? resolveEastAsiaThemeFont(defaultTextFormatting.fontFamily, theme) : void 0;
|
|
341
|
-
if (eastAsiaFontFamily)
|
|
365
|
+
if (eastAsiaFontFamily) {
|
|
366
|
+
result.eastAsiaFontFamily = eastAsiaFontFamily;
|
|
367
|
+
const alternate = getFontAlternate(eastAsiaFontFamily, fontAlternates);
|
|
368
|
+
if (alternate) result.eastAsiaAlternateFontFamily = alternate;
|
|
369
|
+
}
|
|
342
370
|
const complexScriptFontFamily = defaultTextFormatting.fontFamily ? resolveComplexScriptThemeFont(defaultTextFormatting.fontFamily, theme) : void 0;
|
|
343
|
-
if (complexScriptFontFamily)
|
|
371
|
+
if (complexScriptFontFamily) {
|
|
372
|
+
result.complexScriptFontFamily = complexScriptFontFamily;
|
|
373
|
+
const alternate = getFontAlternate(complexScriptFontFamily, fontAlternates);
|
|
374
|
+
if (alternate) result.complexScriptAlternateFontFamily = alternate;
|
|
375
|
+
}
|
|
344
376
|
if (defaultTextFormatting.language) result.language = { ...defaultTextFormatting.language };
|
|
345
377
|
if (defaultTextFormatting.fontSize !== void 0) result.fontSize = defaultTextFormatting.fontSize / 2;
|
|
346
378
|
if (defaultTextFormatting.fontSizeCs !== void 0) result.complexScriptFontSize = defaultTextFormatting.fontSizeCs / 2;
|
|
@@ -369,7 +401,8 @@ function textFormattingToRunFormatting(defaultTextFormatting, theme) {
|
|
|
369
401
|
if (defaultTextFormatting.smallCaps !== void 0) result.smallCaps = defaultTextFormatting.smallCaps;
|
|
370
402
|
if (defaultTextFormatting.spacing !== void 0 && defaultTextFormatting.spacing !== 0) result.letterSpacing = twipsToPixels(defaultTextFormatting.spacing);
|
|
371
403
|
if (defaultTextFormatting.position !== void 0 && defaultTextFormatting.position !== 0) result.positionPx = halfPointsToPixels(defaultTextFormatting.position);
|
|
372
|
-
|
|
404
|
+
const horizontalScale = normalizeHorizontalScalePercent(defaultTextFormatting.scale);
|
|
405
|
+
if (horizontalScale !== void 0 && horizontalScale !== 100) result.horizontalScale = horizontalScale;
|
|
373
406
|
if (defaultTextFormatting.kerning !== void 0 && defaultTextFormatting.kerning > 0) result.kerningMinPt = halfPointsToPoints(defaultTextFormatting.kerning);
|
|
374
407
|
if (defaultTextFormatting.emboss !== void 0) result.emboss = defaultTextFormatting.emboss;
|
|
375
408
|
if (defaultTextFormatting.imprint !== void 0) result.imprint = defaultTextFormatting.imprint;
|
|
@@ -378,8 +411,8 @@ function textFormattingToRunFormatting(defaultTextFormatting, theme) {
|
|
|
378
411
|
if (defaultTextFormatting.emphasisMark && defaultTextFormatting.emphasisMark !== "none") result.emphasisMark = defaultTextFormatting.emphasisMark;
|
|
379
412
|
return result;
|
|
380
413
|
}
|
|
381
|
-
function paragraphRunDefaults(pmAttrs, theme) {
|
|
382
|
-
return textFormattingToRunFormatting(pmAttrs.defaultTextFormatting, theme);
|
|
414
|
+
function paragraphRunDefaults(pmAttrs, theme, fontAlternates) {
|
|
415
|
+
return textFormattingToRunFormatting(pmAttrs.defaultTextFormatting, theme, fontAlternates);
|
|
383
416
|
}
|
|
384
417
|
/**
|
|
385
418
|
* Build an ImageRun from ProseMirror node attrs, applying conditional property assignment
|
|
@@ -443,8 +476,9 @@ function paragraphToRuns(node, startPos, _options) {
|
|
|
443
476
|
const runs = [];
|
|
444
477
|
const offset = startPos + 1;
|
|
445
478
|
const theme = _options.theme;
|
|
479
|
+
const fontAlternates = _options.fontAlternates;
|
|
446
480
|
const pmAttrs = expectParagraphAttrs(node);
|
|
447
|
-
const paraDefaults = paragraphRunDefaults(pmAttrs, theme);
|
|
481
|
+
const paraDefaults = paragraphRunDefaults(pmAttrs, theme, fontAlternates);
|
|
448
482
|
const paragraphStyleId = pmAttrs.styleId;
|
|
449
483
|
const inTocParagraph = pmAttrs._tableOfContentsLevel !== void 0 || tableOfContentsStyleLevel({ styleId: paragraphStyleId }) !== void 0;
|
|
450
484
|
let leadingRenderedPageBreakPending = pmAttrs.renderedPageBreakBefore === true;
|
|
@@ -464,7 +498,7 @@ function paragraphToRuns(node, startPos, _options) {
|
|
|
464
498
|
}
|
|
465
499
|
if (child.type.name !== "sdt") leadingRenderedPageBreakPending = false;
|
|
466
500
|
if (child.isText && child.text) {
|
|
467
|
-
const formatting = extractRunFormatting(child.marks, theme);
|
|
501
|
+
const formatting = extractRunFormatting(child.marks, theme, fontAlternates);
|
|
468
502
|
applyCharacterStyleToggleFormatting({
|
|
469
503
|
formatting,
|
|
470
504
|
marks: child.marks,
|
|
@@ -485,18 +519,20 @@ function paragraphToRuns(node, startPos, _options) {
|
|
|
485
519
|
const attrs = expectSymbolAttrs(child);
|
|
486
520
|
const text = decodeOoxmlSymbolCharacter(attrs.char);
|
|
487
521
|
if (text === null) return;
|
|
488
|
-
const formatting = extractRunFormatting(child.marks, theme);
|
|
522
|
+
const formatting = extractRunFormatting(child.marks, theme, fontAlternates);
|
|
489
523
|
applyCharacterStyleToggleFormatting({
|
|
490
524
|
formatting,
|
|
491
525
|
marks: child.marks,
|
|
492
526
|
paraDefaults
|
|
493
527
|
});
|
|
494
528
|
if (inTocParagraph) stripTocHyperlinkStyle(formatting);
|
|
529
|
+
const alternateFontFamily = getFontAlternate(attrs.font, fontAlternates);
|
|
530
|
+
formatting.fontFamily = attrs.font;
|
|
531
|
+
if (alternateFontFamily) formatting.alternateFontFamily = alternateFontFamily;
|
|
495
532
|
runs.push({
|
|
496
533
|
kind: "text",
|
|
497
534
|
text,
|
|
498
535
|
...mergeRunFormatting(paraDefaults, formatting),
|
|
499
|
-
fontFamily: attrs.font,
|
|
500
536
|
pmStart: childPos,
|
|
501
537
|
pmEnd: childPos + child.nodeSize
|
|
502
538
|
});
|
|
@@ -511,7 +547,7 @@ function paragraphToRuns(node, startPos, _options) {
|
|
|
511
547
|
return;
|
|
512
548
|
}
|
|
513
549
|
if (child.type.name === "tab") {
|
|
514
|
-
const formatting = extractRunFormatting(child.marks, theme);
|
|
550
|
+
const formatting = extractRunFormatting(child.marks, theme, fontAlternates);
|
|
515
551
|
applyCharacterStyleToggleFormatting({
|
|
516
552
|
formatting,
|
|
517
553
|
marks: child.marks,
|
|
@@ -530,7 +566,7 @@ function paragraphToRuns(node, startPos, _options) {
|
|
|
530
566
|
const attrs = expectImageAttrs(child);
|
|
531
567
|
if (!attrs.src) return;
|
|
532
568
|
const constrained = constrainImageToPage(attrs.width ?? 100, attrs.height ?? 100, _options.pageContentHeight);
|
|
533
|
-
const trackedFmt = extractRunFormatting(child.marks, theme);
|
|
569
|
+
const trackedFmt = extractRunFormatting(child.marks, theme, fontAlternates);
|
|
534
570
|
const run = buildImageRun(attrs, constrained, childPos, childPos + child.nodeSize, trackedFmt);
|
|
535
571
|
runs.push(run);
|
|
536
572
|
return;
|
|
@@ -543,7 +579,7 @@ function paragraphToRuns(node, startPos, _options) {
|
|
|
543
579
|
else if (ft === "NUMPAGES") mappedType = "NUMPAGES";
|
|
544
580
|
else if (ft === "DATE") mappedType = "DATE";
|
|
545
581
|
else if (ft === "TIME") mappedType = "TIME";
|
|
546
|
-
const extractedFieldFormatting = extractRunFormatting(child.marks, theme);
|
|
582
|
+
const extractedFieldFormatting = extractRunFormatting(child.marks, theme, fontAlternates);
|
|
547
583
|
applyCharacterStyleToggleFormatting({
|
|
548
584
|
formatting: extractedFieldFormatting,
|
|
549
585
|
marks: child.marks,
|
|
@@ -655,7 +691,7 @@ function resolveDeletedListMarker(previousListAttrs, listCounterState) {
|
|
|
655
691
|
if (previousListAttrs.listIsBullet) return "•";
|
|
656
692
|
return null;
|
|
657
693
|
}
|
|
658
|
-
function applyDeletedListMarkerAttrs(attrs, change, listCounterState, theme) {
|
|
694
|
+
function applyDeletedListMarkerAttrs(attrs, change, listCounterState, theme, fontAlternates) {
|
|
659
695
|
const previousListAttrs = toPreviousListAttrs(change.previousFormatting);
|
|
660
696
|
const marker = resolveDeletedListMarker(previousListAttrs, listCounterState);
|
|
661
697
|
if (!marker) return;
|
|
@@ -663,11 +699,11 @@ function applyDeletedListMarkerAttrs(attrs, change, listCounterState, theme) {
|
|
|
663
699
|
attrs.listMarkerRevision = toListMarkerRevision("del", change.info);
|
|
664
700
|
if (previousListAttrs.listIsBullet !== void 0) attrs.listIsBullet = previousListAttrs.listIsBullet;
|
|
665
701
|
if (previousListAttrs.listMarkerHidden !== void 0) attrs.listMarkerHidden = previousListAttrs.listMarkerHidden;
|
|
666
|
-
if (previousListAttrs.listMarkerFormatting) attrs.listMarkerFormatting = textFormattingToRunFormatting(previousListAttrs.listMarkerFormatting, theme);
|
|
702
|
+
if (previousListAttrs.listMarkerFormatting) attrs.listMarkerFormatting = textFormattingToRunFormatting(previousListAttrs.listMarkerFormatting, theme, fontAlternates);
|
|
667
703
|
if (previousListAttrs.listMarkerAlignment) attrs.listMarkerAlignment = previousListAttrs.listMarkerAlignment;
|
|
668
704
|
if (previousListAttrs.listMarkerSuffix) attrs.listMarkerSuffix = previousListAttrs.listMarkerSuffix;
|
|
669
705
|
}
|
|
670
|
-
function convertParagraphAttrs(pmAttrs, { theme, listCounterStreams, defaultTabStopTwips }) {
|
|
706
|
+
function convertParagraphAttrs(pmAttrs, { theme, fontAlternates, listCounterStreams, defaultTabStopTwips }) {
|
|
671
707
|
const attrs = {};
|
|
672
708
|
if (pmAttrs.alignment) {
|
|
673
709
|
const align = pmAttrs.alignment;
|
|
@@ -791,14 +827,14 @@ function convertParagraphAttrs(pmAttrs, { theme, listCounterStreams, defaultTabS
|
|
|
791
827
|
else if (pmAttrs.listMarker) attrs.listMarker = pmAttrs.listIsBullet ? convertBulletToUnicode(pmAttrs.listMarker) : pmAttrs.listMarker;
|
|
792
828
|
if (pmAttrs.listIsBullet !== void 0) attrs.listIsBullet = pmAttrs.listIsBullet;
|
|
793
829
|
if (pmAttrs.listMarkerHidden) attrs.listMarkerHidden = true;
|
|
794
|
-
if (pmAttrs.listMarkerFormatting) attrs.listMarkerFormatting = textFormattingToRunFormatting(pmAttrs.listMarkerFormatting, theme);
|
|
830
|
+
if (pmAttrs.listMarkerFormatting) attrs.listMarkerFormatting = textFormattingToRunFormatting(pmAttrs.listMarkerFormatting, theme, fontAlternates);
|
|
795
831
|
if (pmAttrs.listMarkerAlignment) attrs.listMarkerAlignment = pmAttrs.listMarkerAlignment;
|
|
796
832
|
if (pmAttrs.listMarkerSuffix) attrs.listMarkerSuffix = pmAttrs.listMarkerSuffix;
|
|
797
833
|
if (pmAttrs.listMarkerSecondSlotOffsetTwips !== void 0) attrs.listMarkerSecondSlotOffsetTwips = pmAttrs.listMarkerSecondSlotOffsetTwips;
|
|
798
834
|
if (!pmAttrs.numPr) {
|
|
799
835
|
const numberingRemovedChange = propertyChanges.find(isRemovedNumberingChange);
|
|
800
836
|
if (numberingRemovedChange) {
|
|
801
|
-
applyDeletedListMarkerAttrs(attrs, numberingRemovedChange, void 0, theme);
|
|
837
|
+
applyDeletedListMarkerAttrs(attrs, numberingRemovedChange, void 0, theme, fontAlternates);
|
|
802
838
|
if (resolvedMarker !== null) {
|
|
803
839
|
attrs.listMarker = resolvedMarker;
|
|
804
840
|
attrs.listMarkerRevision = toListMarkerRevision("del", numberingRemovedChange.info);
|
|
@@ -812,7 +848,11 @@ function convertParagraphAttrs(pmAttrs, { theme, listCounterStreams, defaultTabS
|
|
|
812
848
|
if (attrs.listMarker !== void 0 && !attrs.listMarkerHidden && dtf.fontSizeCs !== void 0 && (dtf.fontSize === void 0 || dtf.fontSizeCs > dtf.fontSize)) attrs.listParagraphMarkFontSize = dtf.fontSizeCs / 2;
|
|
813
849
|
if (dtf.fontFamily) {
|
|
814
850
|
const resolvedFamily = resolveWesternThemeFont(dtf.fontFamily, theme);
|
|
815
|
-
if (resolvedFamily)
|
|
851
|
+
if (resolvedFamily) {
|
|
852
|
+
attrs.defaultFontFamily = resolvedFamily;
|
|
853
|
+
const alternate = getFontAlternate(resolvedFamily, fontAlternates);
|
|
854
|
+
if (alternate) attrs.defaultAlternateFontFamily = alternate;
|
|
855
|
+
}
|
|
816
856
|
}
|
|
817
857
|
}
|
|
818
858
|
return attrs;
|
|
@@ -843,6 +883,7 @@ function convertParagraph(node, startPos, options) {
|
|
|
843
883
|
const runs = paragraphToRuns(node, startPos, options);
|
|
844
884
|
const attrs = convertParagraphAttrs(pmAttrs, {
|
|
845
885
|
theme: options.theme,
|
|
886
|
+
fontAlternates: options.fontAlternates,
|
|
846
887
|
listCounterStreams: options.listCounterStreams,
|
|
847
888
|
defaultTabStopTwips: options.defaultTabStopTwips
|
|
848
889
|
});
|
|
@@ -856,7 +897,11 @@ function convertParagraph(node, startPos, options) {
|
|
|
856
897
|
if (paragraphMarkFormatting && Object.values(paragraphMarkFormatting).some((value) => value !== void 0 && value !== null)) attrs.hasDirectParagraphMarkFormatting = true;
|
|
857
898
|
if (paragraphMarkFormatting?.fontSize !== void 0) attrs.defaultFontSize = paragraphMarkFormatting.fontSize / 2;
|
|
858
899
|
const paragraphMarkFontFamily = paragraphMarkFormatting?.fontFamily ? resolveWesternThemeFont(paragraphMarkFormatting.fontFamily, options.theme) : void 0;
|
|
859
|
-
if (paragraphMarkFontFamily)
|
|
900
|
+
if (paragraphMarkFontFamily) {
|
|
901
|
+
attrs.defaultFontFamily = paragraphMarkFontFamily;
|
|
902
|
+
const alternate = getFontAlternate(paragraphMarkFontFamily, options.fontAlternates);
|
|
903
|
+
if (alternate) attrs.defaultAlternateFontFamily = alternate;
|
|
904
|
+
}
|
|
860
905
|
}
|
|
861
906
|
if (runs.length === 0 && defaultTextFormatting?.hidden === true) {
|
|
862
907
|
attrs.suppressEmptyParagraphHeight = true;
|
|
@@ -1076,6 +1121,8 @@ function convertTableRow(node, startPos, options, tableCellMargins) {
|
|
|
1076
1121
|
if (attrs.isHeader) row.isHeader = attrs.isHeader;
|
|
1077
1122
|
if (attrs._originalFormatting?.cantSplit) row.cantSplit = true;
|
|
1078
1123
|
if (attrs.hidden) row.hidden = attrs.hidden;
|
|
1124
|
+
const effectiveJustification = attrs._originalFormatting?.justification ?? attrs._resolvedJustification;
|
|
1125
|
+
if (effectiveJustification) row.justification = effectiveJustification;
|
|
1079
1126
|
return row;
|
|
1080
1127
|
}
|
|
1081
1128
|
/**
|
|
@@ -1097,7 +1144,7 @@ function convertTable(node, startPos, options) {
|
|
|
1097
1144
|
const cellWidths = rows[0].cells.map((cell) => cell.width);
|
|
1098
1145
|
if (cellWidths.every((w) => w !== void 0 && w > 0)) columnWidths = cellWidths;
|
|
1099
1146
|
}
|
|
1100
|
-
const justification = attrs.justification;
|
|
1147
|
+
const justification = attrs.justification ?? attrs._resolvedJustification;
|
|
1101
1148
|
const originalFormatting = attrs._originalFormatting;
|
|
1102
1149
|
const effectiveIndent = attrs._resolvedIndent ?? originalFormatting?.indent;
|
|
1103
1150
|
const indentPx = effectiveIndent?.value !== void 0 && effectiveIndent?.type === "dxa" ? twipsToPixels(effectiveIndent.value) : void 0;
|
|
@@ -1201,6 +1248,8 @@ function convertTextBoxNode(node, startPos, opts) {
|
|
|
1201
1248
|
pmStart: startPos,
|
|
1202
1249
|
pmEnd: startPos + node.nodeSize
|
|
1203
1250
|
};
|
|
1251
|
+
const verticalAlign = normalizeShapeTextAnchor(attrs.verticalAlign);
|
|
1252
|
+
if (verticalAlign !== void 0) textBox.verticalAlign = verticalAlign;
|
|
1204
1253
|
if (attrs.height !== void 0) textBox.height = attrs.height;
|
|
1205
1254
|
if (attrs.autoFit !== void 0) textBox.autoFit = attrs.autoFit;
|
|
1206
1255
|
if (attrs.textWrap !== void 0) textBox.textWrap = attrs.textWrap;
|
|
@@ -1416,7 +1465,8 @@ function toFlowBlocks(doc, options = {}) {
|
|
|
1416
1465
|
...sourceAttrs?.snapToGrid !== void 0 ? { snapToGrid: sourceAttrs.snapToGrid } : {},
|
|
1417
1466
|
...sourceAttrs?.documentGridLinePitch !== void 0 ? { documentGridLinePitch: sourceAttrs.documentGridLinePitch } : {},
|
|
1418
1467
|
...sourceAttrs?.defaultFontSize !== void 0 ? { defaultFontSize: sourceAttrs.defaultFontSize } : {},
|
|
1419
|
-
...sourceAttrs?.defaultFontFamily !== void 0 ? { defaultFontFamily: sourceAttrs.defaultFontFamily } : {}
|
|
1468
|
+
...sourceAttrs?.defaultFontFamily !== void 0 ? { defaultFontFamily: sourceAttrs.defaultFontFamily } : {},
|
|
1469
|
+
...sourceAttrs?.defaultAlternateFontFamily !== void 0 ? { defaultAlternateFontFamily: sourceAttrs.defaultAlternateFontFamily } : {}
|
|
1420
1470
|
};
|
|
1421
1471
|
const carrier = {
|
|
1422
1472
|
kind: "paragraph",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NoteStoryKey } from "../../
|
|
1
|
+
import { NoteStoryKey } from "../../types/editor-story.js";
|
|
2
2
|
//#region src/layout-bridge/dom/noteStoryDom.d.ts
|
|
3
3
|
declare const findNoteStoryForTarget: (target: unknown) => NoteStoryKey | null;
|
|
4
4
|
//#endregion
|
|
@@ -6,6 +6,7 @@ import { measureRun } from "../../layout-engine/measure/measureProvider.js";
|
|
|
6
6
|
import { buildTableCellFloatingZones, getTableCellContentWidth, getTableCellFloatingImages } from "../../layout-engine/measure/tableCellFloating.js";
|
|
7
7
|
import { buildTableCellGrid, buildTableCellPlacements } from "../../layout-engine/measure/tableCellGrid.js";
|
|
8
8
|
import { resolveTableCellPadding } from "../../layout-engine/types.js";
|
|
9
|
+
import { normalizeHorizontalScalePercent } from "../../utils/horizontalScale.js";
|
|
9
10
|
import { resolvePhysicalParagraphInlineLayout } from "../../utils/paragraphInlineLayout.js";
|
|
10
11
|
import { inlineImageBoundingBox } from "../../utils/rotationBoundingBox.js";
|
|
11
12
|
import { getPageTop } from "./hitTest.js";
|
|
@@ -33,13 +34,14 @@ function runToFontStyle(run) {
|
|
|
33
34
|
return buildRunFontStyle(run, "Arial", 12);
|
|
34
35
|
}
|
|
35
36
|
function mathRunToFontStyle(run) {
|
|
37
|
+
const horizontalScale = normalizeHorizontalScalePercent(run.horizontalScale);
|
|
36
38
|
return {
|
|
37
39
|
fontFamily: run.fontFamily ?? "Cambria Math",
|
|
38
40
|
fontSize: run.fontSize ?? 11,
|
|
39
41
|
...run.bold !== void 0 ? { bold: run.bold } : {},
|
|
40
42
|
...run.italic !== void 0 ? { italic: run.italic } : {},
|
|
41
43
|
...run.letterSpacing !== void 0 ? { letterSpacing: run.letterSpacing } : {},
|
|
42
|
-
...
|
|
44
|
+
...horizontalScale !== void 0 ? { horizontalScale } : {}
|
|
43
45
|
};
|
|
44
46
|
}
|
|
45
47
|
/**
|