oasis-editor 0.0.10 → 0.0.11

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.
@@ -1,7 +1,7 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- import { n as normalizeSelection, g as getParagraphs, c as createEditorParagraphFromRuns, a as createEditorStyledRun, b as getParagraphLength, d as getParagraphText, e as getActiveZone, f as getDocumentSections, h as getActiveSectionIndex, p as positionToParagraphOffset, i as paragraphOffsetToPosition, j as clampPosition, k as findParagraphIndex, l as createCollapsedSelection, m as isSelectionCollapsed, o as createEditorParagraph, q as getBlockParagraphs, r as findParagraphTableLocation, s as buildTableCellLayout, t as createEditorTableCell, u as createEditorTable, v as createEditorTableRow, w as underlineStyleToCssDecorationStyle, x as resolveImageSrc, y as createEditorFootnote, z as createFootnoteReferenceRun, A as renumberFootnotes, B as iterateFootnoteReferenceRuns, C as getFootnoteDisplayMarker, D as createSignal, E as createEffect, F as onCleanup, G as buildCanvasLayoutSnapshot, H as on, I as onMount, J as debounce, K as unwrap, L as getDocumentParagraphs, M as getDocumentSectionsCanonical, N as createEditorDocument, O as getPageContentWidth, P as getDocumentPageSettings, Q as getTableCellContentWidthForParagraph, R as resolveResizedDimensions, S as resolveTextBoxRenderHeight, T as resolveEffectiveParagraphStyle, U as resolveEffectiveTextStyleForParagraph, V as iterateEndnoteReferenceRuns, W as JSZip, X as imageContentTypeDefaults, Y as imageExtensionFromMime, Z as pxToPt$1, _ as textStyleToFontSizePt, $ as PX_PER_POINT, a0 as DEFAULT_FONT_SIZE_PX, a1 as isDoubleUnderlineStyle, a2 as isWavyUnderlineStyle, a3 as underlineStyleLineWidthPx, a4 as underlineStyleDashArray, a5 as getListLabelInset, a6 as getParagraphBorderInsets, a7 as buildSegmentTable, a8 as buildCanvasTableLayout, a9 as normalizeFamily, aa as ROBOTO_FONT_FILES, ab as loadFontAsset, ac as OFFICE_COMPAT_FONT_FAMILIES, ad as buildSfnt, ae as defaultFontDecoderRegistry, af as SfntFontProgram, ag as collectPdfFontFamilies, ah as projectDocumentLayout, ai as getPageHeaderZoneTop, aj as getPageBodyTop, ak as findFootnoteReference, al as FOOTNOTE_MARKER_GUTTER_PX, am as resolveImporterForFile, an as createEditorStateFromDocument, ao as getDocumentParagraphsCanonical, ap as getToolbarStyleState, aq as STANDARD_FONT_SIZES_PT, ar as fontSizePxToPt, as as probeLocalFontFamilies, at as createInitialEditorState, au as parseFontSizePtToPx, av as formatFontSizePt, aw as listKindForTag, ax as isParagraphTag, ay as collectInlineRuns, az as parseParagraphStyle, aA as t, aB as preciseFontModeVersion, aC as isPreciseFontModeEnabled, aD as togglePreciseFontMode, aE as nextFontSizePt, aF as previousFontSizePt, aG as fontSizePtToPx, aH as createDefaultToolbarPreset, aI as defaultMenuItems, aJ as MenuRegistry, aK as createToolbarRegistry, aL as Editor, aM as resolveCommandRef, aN as commandRefName, aO as InlineShell, aP as BalloonShell, aQ as DocumentShell, aR as createMemo, aS as getCaretRectFromSnapshot, aT as getParagraphRectFromSnapshot, aU as createComponent, aV as CaretOverlay, aW as Show, aX as createRenderEffect, aY as style, aZ as setAttribute, a_ as setStyleProperty, a$ as memo, b0 as template, b1 as insert, b2 as use, b3 as addEventListener, b4 as Dialog, b5 as delegateEvents, b6 as className, b7 as For, b8 as UNDERLINE_STYLE_OPTIONS, b9 as Tabs, ba as measureParagraphMinContentWidthPx, bb as getEditableBlocksForZone, bc as findParagraphLocation, bd as createSectionBoundaryParagraph, be as normalizePageSettings, bf as DEFAULT_EDITOR_PAGE_SETTINGS, bg as markStart, bh as markEnd, bi as getParagraphEntries, bj as getParagraphById, bk as PluginUiHost, bl as OasisEditorEditor, bm as perfTimer, bn as OasisBrandMark, bo as setPreciseFontPreference, bp as setWelcomeSeen, bq as enablePreciseFontMode, br as createOasisEditorClient, bs as setLocale, bt as startLongTaskObserver, bu as installGlobalReport, bv as applyStoredPreciseFontPreference, bw as getWelcomeSeen, bx as isLocalFontAccessSupported, by as EDITOR_SCROLL_PADDING_PX, bz as Toolbar, bA as OasisEditorLoading, bB as createEditorLogger, bC as getCachedCanvasImage, bD as registerDomStatsSurface } from "./index--RsWcVrx.js";
4
+ import { n as normalizeSelection, g as getParagraphs, c as createEditorParagraphFromRuns, a as createEditorStyledRun, b as getParagraphLength, d as getParagraphText, e as getActiveZone, f as getDocumentSections, h as getActiveSectionIndex, p as positionToParagraphOffset, i as paragraphOffsetToPosition, j as clampPosition, k as findParagraphIndex, l as createCollapsedSelection, m as isSelectionCollapsed, o as createEditorParagraph, q as getBlockParagraphs, r as findParagraphTableLocation, s as buildTableCellLayout, t as createEditorTableCell, u as createEditorTable, v as createEditorTableRow, w as underlineStyleToCssDecorationStyle, x as resolveImageSrc, y as createEditorFootnote, z as createFootnoteReferenceRun, A as renumberFootnotes, B as iterateFootnoteReferenceRuns, C as getFootnoteDisplayMarker, D as createSignal, E as createEffect, F as onCleanup, G as buildCanvasLayoutSnapshot, H as on, I as onMount, J as debounce, K as unwrap, L as getDocumentParagraphs, M as getDocumentSectionsCanonical, N as createEditorDocument, O as getPageContentWidth, P as getDocumentPageSettings, Q as getTableCellContentWidthForParagraph, R as resolveResizedDimensions, S as resolveTextBoxRenderHeight, T as resolveEffectiveParagraphStyle, U as resolveEffectiveTextStyleForParagraph, V as iterateEndnoteReferenceRuns, W as JSZip, X as imageContentTypeDefaults, Y as imageExtensionFromMime, Z as pxToPt$1, _ as buildSegmentTable, $ as buildCanvasTableLayout, a0 as resolveFloatingObjectRect, a1 as getTextBoxFloatingGeometry, a2 as getPresetPathSegments, a3 as projectBlocksLayout, a4 as textStyleToFontSizePt, a5 as PX_PER_POINT, a6 as DEFAULT_FONT_SIZE_PX, a7 as isDoubleUnderlineStyle, a8 as isWavyUnderlineStyle, a9 as underlineStyleLineWidthPx, aa as underlineStyleDashArray, ab as getListLabelInset, ac as getParagraphBorderInsets, ad as normalizeFamily, ae as ROBOTO_FONT_FILES, af as loadFontAsset, ag as OFFICE_COMPAT_FONT_FAMILIES, ah as buildSfnt, ai as defaultFontDecoderRegistry, aj as SfntFontProgram, ak as collectPdfFontFamilies, al as projectDocumentLayout, am as getPageHeaderZoneTop, an as getPageBodyTop, ao as findFootnoteReference, ap as FOOTNOTE_MARKER_GUTTER_PX, aq as resolveImporterForFile, ar as createEditorStateFromDocument, as as getDocumentParagraphsCanonical, at as getToolbarStyleState, au as STANDARD_FONT_SIZES_PT, av as fontSizePxToPt, aw as probeLocalFontFamilies, ax as createInitialEditorState, ay as parseFontSizePtToPx, az as formatFontSizePt, aA as listKindForTag, aB as isParagraphTag, aC as collectInlineRuns, aD as parseParagraphStyle, aE as t, aF as preciseFontModeVersion, aG as isPreciseFontModeEnabled, aH as togglePreciseFontMode, aI as nextFontSizePt, aJ as previousFontSizePt, aK as fontSizePtToPx, aL as createDefaultToolbarPreset, aM as defaultMenuItems, aN as MenuRegistry, aO as createToolbarRegistry, aP as Editor, aQ as resolveCommandRef, aR as commandRefName, aS as InlineShell, aT as BalloonShell, aU as DocumentShell, aV as createMemo, aW as getCaretRectFromSnapshot, aX as getParagraphRectFromSnapshot, aY as createComponent, aZ as CaretOverlay, a_ as Show, a$ as createRenderEffect, b0 as style, b1 as setAttribute, b2 as setStyleProperty, b3 as memo, b4 as template, b5 as insert, b6 as use, b7 as addEventListener, b8 as Dialog, b9 as delegateEvents, ba as className, bb as For, bc as UNDERLINE_STYLE_OPTIONS, bd as Tabs, be as measureParagraphMinContentWidthPx, bf as getEditableBlocksForZone, bg as findParagraphLocation, bh as createSectionBoundaryParagraph, bi as normalizePageSettings, bj as DEFAULT_EDITOR_PAGE_SETTINGS, bk as markStart, bl as markEnd, bm as getParagraphEntries, bn as getParagraphById, bo as PluginUiHost, bp as OasisEditorEditor, bq as perfTimer, br as OasisBrandMark, bs as setPreciseFontPreference, bt as setWelcomeSeen, bu as enablePreciseFontMode, bv as createOasisEditorClient, bw as setLocale, bx as startLongTaskObserver, by as installGlobalReport, bz as applyStoredPreciseFontPreference, bA as getWelcomeSeen, bB as isLocalFontAccessSupported, bC as EDITOR_SCROLL_PADDING_PX, bD as Toolbar, bE as OasisEditorLoading, bF as createEditorLogger, bG as getCachedCanvasImage, bH as registerDomStatsSurface } from "./index-L71R0x7D.js";
5
5
  function getSelectedObjectRun(state, predicate) {
6
6
  const normalized = normalizeSelection(state);
7
7
  if (normalized.isCollapsed || normalized.startIndex !== normalized.endIndex || normalized.endParagraphOffset - normalized.startParagraphOffset !== 1) {
@@ -1240,6 +1240,43 @@ function resizeSelectedTextBox(state, width, height, options = {}) {
1240
1240
  )
1241
1241
  );
1242
1242
  }
1243
+ const SHAPE_DEFAULT_WIDTH = 150;
1244
+ const SHAPE_DEFAULT_HEIGHT = 100;
1245
+ const SHAPE_DEFAULT_FILL = "#4472C4";
1246
+ const SHAPE_DEFAULT_BORDER_COLOR = "#2F528F";
1247
+ const SHAPE_DEFAULT_BORDER_WIDTH_PT = 1;
1248
+ function insertShapeAtSelection(state, preset) {
1249
+ const collapsedState = isSelectionCollapsed(state.selection) ? state : deleteSelectionRange(state);
1250
+ const { paragraph, index, offset } = getFocusParagraph(collapsedState);
1251
+ const textBox = {
1252
+ width: SHAPE_DEFAULT_WIDTH,
1253
+ height: SHAPE_DEFAULT_HEIGHT,
1254
+ blocks: [createEditorParagraph("")],
1255
+ shape: {
1256
+ preset,
1257
+ fill: SHAPE_DEFAULT_FILL,
1258
+ borderColor: SHAPE_DEFAULT_BORDER_COLOR,
1259
+ borderWidthPt: SHAPE_DEFAULT_BORDER_WIDTH_PT
1260
+ },
1261
+ floating: wrapPresetToFloating(void 0, "front")
1262
+ };
1263
+ const insertedRun = createEditorStyledRun(
1264
+ "",
1265
+ getStyleAtOffset(paragraph, offset),
1266
+ void 0,
1267
+ textBox
1268
+ );
1269
+ const nextParagraph = insertRunsAtOffset(paragraph, offset, [insertedRun]);
1270
+ const paragraphs = getParagraphs(collapsedState);
1271
+ const nextParagraphs = paragraphs.map(
1272
+ (candidate, candidateIndex) => candidateIndex === index ? nextParagraph : cloneParagraph(candidate)
1273
+ );
1274
+ return cloneStateWithParagraphs(
1275
+ collapsedState,
1276
+ nextParagraphs,
1277
+ withSelection(paragraphOffsetToPosition(nextParagraph, offset + 1))
1278
+ );
1279
+ }
1243
1280
  function cloneFragmentRuns(runs) {
1244
1281
  return runs.map(cloneRun);
1245
1282
  }
@@ -9634,6 +9671,268 @@ function borderDashArray(type) {
9634
9671
  return void 0;
9635
9672
  }
9636
9673
  }
9674
+ function drawCellEdge(writer, pageIndex, border, x1, y1, x2, y2) {
9675
+ if (border.type === "none" || border.width <= 0) {
9676
+ return;
9677
+ }
9678
+ writer.drawLine(pageIndex, {
9679
+ x1: pxToPt$1(x1),
9680
+ y1: pxToPt$1(y1),
9681
+ x2: pxToPt$1(x2),
9682
+ y2: pxToPt$1(y2),
9683
+ stroke: border.color,
9684
+ lineWidth: pxToPt$1(border.width),
9685
+ dashArray: borderDashArray(border.type)
9686
+ });
9687
+ }
9688
+ function drawCellBorders(writer, pageIndex, cell, originX, originY) {
9689
+ const left = originX + cell.left;
9690
+ const top = originY + cell.top;
9691
+ const right = left + cell.width;
9692
+ const bottom = top + cell.height;
9693
+ drawCellEdge(writer, pageIndex, cell.borders.top, left, top, right, top);
9694
+ drawCellEdge(
9695
+ writer,
9696
+ pageIndex,
9697
+ cell.borders.right,
9698
+ right,
9699
+ top,
9700
+ right,
9701
+ bottom
9702
+ );
9703
+ drawCellEdge(
9704
+ writer,
9705
+ pageIndex,
9706
+ cell.borders.bottom,
9707
+ left,
9708
+ bottom,
9709
+ right,
9710
+ bottom
9711
+ );
9712
+ drawCellEdge(writer, pageIndex, cell.borders.left, left, top, left, bottom);
9713
+ }
9714
+ async function drawTableBlock(writer, pageIndex, block, document2, originX, originY, contentWidth, fontRegistry, listOrdinals) {
9715
+ if (block.sourceBlock.type !== "table") {
9716
+ return;
9717
+ }
9718
+ const sourceTable = block.sourceBlock;
9719
+ const segmentTable = block.tableSegment ? buildSegmentTable(sourceTable, block.tableSegment) : sourceTable;
9720
+ if (segmentTable.rows.length === 0) {
9721
+ return;
9722
+ }
9723
+ const stateStub = { document: document2 };
9724
+ const tableLayout = buildCanvasTableLayout({
9725
+ table: segmentTable,
9726
+ state: stateStub,
9727
+ pageIndex: 0,
9728
+ originX: 0,
9729
+ originY: 0,
9730
+ contentWidth,
9731
+ estimatedHeight: block.estimatedHeight
9732
+ });
9733
+ for (const cell of tableLayout.cells) {
9734
+ if (!cell.shading) continue;
9735
+ writer.drawRect(pageIndex, {
9736
+ x: pxToPt$1(originX + cell.left),
9737
+ y: pxToPt$1(originY + cell.top),
9738
+ width: pxToPt$1(cell.width),
9739
+ height: pxToPt$1(cell.height),
9740
+ fill: cell.shading
9741
+ });
9742
+ }
9743
+ for (const cell of tableLayout.cells) {
9744
+ drawCellBorders(writer, pageIndex, cell, originX, originY);
9745
+ }
9746
+ for (const cell of tableLayout.cells) {
9747
+ for (const paragraphLayout of cell.paragraphs) {
9748
+ await drawParagraph(
9749
+ writer,
9750
+ pageIndex,
9751
+ paragraphLayout.paragraph,
9752
+ paragraphLayout.lines,
9753
+ document2,
9754
+ originX + paragraphLayout.originX,
9755
+ originY + paragraphLayout.originY,
9756
+ fontRegistry,
9757
+ listOrdinals
9758
+ );
9759
+ }
9760
+ }
9761
+ }
9762
+ function getPadding(textBox) {
9763
+ var _a, _b, _c, _d;
9764
+ return {
9765
+ left: ((_a = textBox.body) == null ? void 0 : _a.paddingLeft) ?? 0,
9766
+ top: ((_b = textBox.body) == null ? void 0 : _b.paddingTop) ?? 0,
9767
+ right: ((_c = textBox.body) == null ? void 0 : _c.paddingRight) ?? 0,
9768
+ bottom: ((_d = textBox.body) == null ? void 0 : _d.paddingBottom) ?? 0
9769
+ };
9770
+ }
9771
+ function drawShapeGeometry(writer, pageIndex, textBox, xPx, yPx, widthPx, heightPx) {
9772
+ var _a, _b, _c, _d;
9773
+ const segments = getPresetPathSegments(
9774
+ (_a = textBox.shape) == null ? void 0 : _a.preset,
9775
+ pxToPt$1(xPx),
9776
+ pxToPt$1(yPx),
9777
+ pxToPt$1(widthPx),
9778
+ pxToPt$1(heightPx)
9779
+ );
9780
+ const fill = (_b = textBox.shape) == null ? void 0 : _b.fill;
9781
+ const borderColor = (_c = textBox.shape) == null ? void 0 : _c.borderColor;
9782
+ const borderWidthPt = ((_d = textBox.shape) == null ? void 0 : _d.borderWidthPt) ?? (borderColor ? 0.75 : 0);
9783
+ writer.drawPath(pageIndex, {
9784
+ segments,
9785
+ fill,
9786
+ stroke: borderColor && borderWidthPt > 0 ? borderColor : void 0,
9787
+ lineWidth: borderWidthPt
9788
+ });
9789
+ }
9790
+ async function drawTextBoxContent(writer, textBox, ctx, xPx, yPx, widthPx, heightPx) {
9791
+ var _a;
9792
+ if (textBox.blocks.length === 0) {
9793
+ return;
9794
+ }
9795
+ const padding = getPadding(textBox);
9796
+ const innerX = xPx + padding.left;
9797
+ const innerY = yPx + padding.top;
9798
+ const innerWidth = Math.max(1, widthPx - padding.left - padding.right);
9799
+ const innerHeight = Math.max(1, heightPx - padding.top - padding.bottom);
9800
+ const pages = projectBlocksLayout({
9801
+ blocks: textBox.blocks,
9802
+ pageSettings: {
9803
+ width: innerWidth,
9804
+ height: innerHeight,
9805
+ orientation: "portrait",
9806
+ margins: {
9807
+ top: 0,
9808
+ right: 0,
9809
+ bottom: 0,
9810
+ left: 0,
9811
+ header: 0,
9812
+ footer: 0,
9813
+ gutter: 0
9814
+ }
9815
+ },
9816
+ maxPageHeight: innerHeight,
9817
+ styles: ctx.document.styles,
9818
+ pageOffset: ctx.pageIndex
9819
+ });
9820
+ const blocks = ((_a = pages[0]) == null ? void 0 : _a.blocks) ?? [];
9821
+ if (blocks.length === 0) {
9822
+ return;
9823
+ }
9824
+ const listOrdinals = /* @__PURE__ */ new Map();
9825
+ writer.saveGraphicsState(ctx.pageIndex);
9826
+ writer.clipRect(
9827
+ ctx.pageIndex,
9828
+ pxToPt$1(innerX),
9829
+ pxToPt$1(innerY),
9830
+ pxToPt$1(innerWidth),
9831
+ pxToPt$1(innerHeight)
9832
+ );
9833
+ let cursorY = innerY;
9834
+ for (const block of blocks) {
9835
+ if (block.sourceBlock.type === "paragraph" && block.layout) {
9836
+ await drawParagraph(
9837
+ writer,
9838
+ ctx.pageIndex,
9839
+ block.sourceBlock,
9840
+ block.layout.lines,
9841
+ ctx.document,
9842
+ innerX,
9843
+ cursorY,
9844
+ ctx.fontRegistry,
9845
+ listOrdinals
9846
+ );
9847
+ } else if (block.sourceBlock.type === "table") {
9848
+ await drawTableBlock(
9849
+ writer,
9850
+ ctx.pageIndex,
9851
+ block,
9852
+ ctx.document,
9853
+ innerX,
9854
+ cursorY,
9855
+ innerWidth,
9856
+ ctx.fontRegistry,
9857
+ listOrdinals
9858
+ );
9859
+ }
9860
+ cursorY += Math.max(0, block.estimatedHeight);
9861
+ }
9862
+ writer.restoreGraphicsState(ctx.pageIndex);
9863
+ }
9864
+ async function paintTextBox(writer, textBox, ctx, xPx, yPx, widthPx, heightPx) {
9865
+ const rotation = textBox.rotation;
9866
+ if (rotation) {
9867
+ writer.saveGraphicsState(ctx.pageIndex);
9868
+ writer.rotateAbout(
9869
+ ctx.pageIndex,
9870
+ pxToPt$1(xPx + widthPx / 2),
9871
+ pxToPt$1(yPx + heightPx / 2),
9872
+ rotation
9873
+ );
9874
+ }
9875
+ drawShapeGeometry(
9876
+ writer,
9877
+ ctx.pageIndex,
9878
+ textBox,
9879
+ xPx,
9880
+ yPx,
9881
+ widthPx,
9882
+ heightPx
9883
+ );
9884
+ await drawTextBoxContent(writer, textBox, ctx, xPx, yPx, widthPx, heightPx);
9885
+ if (rotation) {
9886
+ writer.restoreGraphicsState(ctx.pageIndex);
9887
+ }
9888
+ }
9889
+ async function drawFloatingTextBoxesForParagraph(options) {
9890
+ const {
9891
+ writer,
9892
+ document: document2,
9893
+ fontRegistry,
9894
+ pageIndex,
9895
+ lines,
9896
+ pageSettings,
9897
+ contentLeft,
9898
+ contentTop,
9899
+ contentWidth,
9900
+ paragraphTop
9901
+ } = options;
9902
+ for (const line of lines) {
9903
+ const slotByOffset = new Map(
9904
+ line.slots.map((slot) => [slot.offset, slot])
9905
+ );
9906
+ for (const fragment of line.fragments) {
9907
+ const textBox = fragment.textBox;
9908
+ if (!(textBox == null ? void 0 : textBox.floating)) {
9909
+ continue;
9910
+ }
9911
+ const slot = slotByOffset.get(fragment.startOffset);
9912
+ const anchorLeft = contentLeft + ((slot == null ? void 0 : slot.left) ?? 0);
9913
+ const lineTop = paragraphTop + line.top;
9914
+ const rect = resolveFloatingObjectRect({
9915
+ object: getTextBoxFloatingGeometry(textBox),
9916
+ pageSettings,
9917
+ contentLeft,
9918
+ contentTop,
9919
+ contentWidth,
9920
+ paragraphTop,
9921
+ lineTop,
9922
+ anchorLeft
9923
+ });
9924
+ await paintTextBox(
9925
+ writer,
9926
+ textBox,
9927
+ { document: document2, fontRegistry, pageIndex },
9928
+ rect.x,
9929
+ rect.y,
9930
+ rect.width,
9931
+ rect.height
9932
+ );
9933
+ }
9934
+ }
9935
+ }
9637
9936
  const imageResourceCache = /* @__PURE__ */ new WeakMap();
9638
9937
  function parseDataUrl(src) {
9639
9938
  const match = /^data:([^;,]+)(;base64)?,(.*)$/i.exec(src);
@@ -10013,6 +10312,25 @@ function drawTabLeaders(writer, pageIndex, paragraph, line, fragment, document2,
10013
10312
  });
10014
10313
  }
10015
10314
  }
10315
+ async function drawInlineTextBoxFragment(writer, pageIndex, line, fragment, document2, originX, originY, fontRegistry) {
10316
+ const textBox = fragment.textBox;
10317
+ if (!textBox || textBox.floating) {
10318
+ return;
10319
+ }
10320
+ const slot = line.slots.find((candidate) => candidate.offset === fragment.startOffset) ?? line.slots.find((candidate) => candidate.offset >= fragment.startOffset);
10321
+ if (!slot) {
10322
+ return;
10323
+ }
10324
+ await paintTextBox(
10325
+ writer,
10326
+ textBox,
10327
+ { document: document2, fontRegistry, pageIndex },
10328
+ originX + slot.left,
10329
+ originY + line.top + line.height - textBox.height,
10330
+ textBox.width,
10331
+ textBox.height
10332
+ );
10333
+ }
10016
10334
  async function drawFragmentText(writer, pageIndex, paragraph, line, fragment, document2, originX, originY, fontRegistry) {
10017
10335
  var _a;
10018
10336
  if (fragment.image) {
@@ -10040,6 +10358,19 @@ async function drawFragmentText(writer, pageIndex, paragraph, line, fragment, do
10040
10358
  });
10041
10359
  return;
10042
10360
  }
10361
+ if (fragment.textBox) {
10362
+ await drawInlineTextBoxFragment(
10363
+ writer,
10364
+ pageIndex,
10365
+ line,
10366
+ fragment,
10367
+ document2,
10368
+ originX,
10369
+ originY,
10370
+ fontRegistry
10371
+ );
10372
+ return;
10373
+ }
10043
10374
  const styles = resolveEffectiveTextStyleForParagraph(
10044
10375
  fragment.styles,
10045
10376
  (_a = paragraph.style) == null ? void 0 : _a.styleId,
@@ -10385,98 +10716,11 @@ async function drawParagraph(writer, pageIndex, paragraph, lines, document2, ori
10385
10716
  }
10386
10717
  }
10387
10718
  }
10388
- function drawCellEdge(writer, pageIndex, border, x1, y1, x2, y2) {
10389
- if (border.type === "none" || border.width <= 0) {
10390
- return;
10391
- }
10392
- writer.drawLine(pageIndex, {
10393
- x1: pxToPt$1(x1),
10394
- y1: pxToPt$1(y1),
10395
- x2: pxToPt$1(x2),
10396
- y2: pxToPt$1(y2),
10397
- stroke: border.color,
10398
- lineWidth: pxToPt$1(border.width),
10399
- dashArray: borderDashArray(border.type)
10400
- });
10401
- }
10402
- function drawCellBorders(writer, pageIndex, cell, originX, originY) {
10403
- const left = originX + cell.left;
10404
- const top = originY + cell.top;
10405
- const right = left + cell.width;
10406
- const bottom = top + cell.height;
10407
- drawCellEdge(writer, pageIndex, cell.borders.top, left, top, right, top);
10408
- drawCellEdge(
10409
- writer,
10410
- pageIndex,
10411
- cell.borders.right,
10412
- right,
10413
- top,
10414
- right,
10415
- bottom
10416
- );
10417
- drawCellEdge(
10418
- writer,
10419
- pageIndex,
10420
- cell.borders.bottom,
10421
- left,
10422
- bottom,
10423
- right,
10424
- bottom
10425
- );
10426
- drawCellEdge(writer, pageIndex, cell.borders.left, left, top, left, bottom);
10427
- }
10428
- async function drawTableBlock(writer, pageIndex, block, document2, originX, originY, contentWidth, fontRegistry, listOrdinals) {
10429
- if (block.sourceBlock.type !== "table") {
10430
- return;
10431
- }
10432
- const sourceTable = block.sourceBlock;
10433
- const segmentTable = block.tableSegment ? buildSegmentTable(sourceTable, block.tableSegment) : sourceTable;
10434
- if (segmentTable.rows.length === 0) {
10435
- return;
10436
- }
10437
- const stateStub = { document: document2 };
10438
- const tableLayout = buildCanvasTableLayout({
10439
- table: segmentTable,
10440
- state: stateStub,
10441
- pageIndex: 0,
10442
- originX: 0,
10443
- originY: 0,
10444
- contentWidth,
10445
- estimatedHeight: block.estimatedHeight
10446
- });
10447
- for (const cell of tableLayout.cells) {
10448
- if (!cell.shading) continue;
10449
- writer.drawRect(pageIndex, {
10450
- x: pxToPt$1(originX + cell.left),
10451
- y: pxToPt$1(originY + cell.top),
10452
- width: pxToPt$1(cell.width),
10453
- height: pxToPt$1(cell.height),
10454
- fill: cell.shading
10455
- });
10456
- }
10457
- for (const cell of tableLayout.cells) {
10458
- drawCellBorders(writer, pageIndex, cell, originX, originY);
10459
- }
10460
- for (const cell of tableLayout.cells) {
10461
- for (const paragraphLayout of cell.paragraphs) {
10462
- await drawParagraph(
10463
- writer,
10464
- pageIndex,
10465
- paragraphLayout.paragraph,
10466
- paragraphLayout.lines,
10467
- document2,
10468
- originX + paragraphLayout.originX,
10469
- originY + paragraphLayout.originY,
10470
- fontRegistry,
10471
- listOrdinals
10472
- );
10473
- }
10474
- }
10475
- }
10476
- async function drawBlockList(writer, pageIndex, blocks, document2, originX, originY, contentWidth, fontRegistry, listOrdinals) {
10719
+ async function drawBlockList(writer, pageIndex, blocks, document2, originX, originY, contentWidth, fontRegistry, listOrdinals, pageSettings) {
10477
10720
  if (!blocks || blocks.length === 0) {
10478
10721
  return;
10479
10722
  }
10723
+ const contentTop = originY;
10480
10724
  let cursorY = originY;
10481
10725
  for (const block of blocks) {
10482
10726
  if (block.sourceBlock.type === "paragraph" && block.layout) {
@@ -10507,6 +10751,20 @@ async function drawBlockList(writer, pageIndex, blocks, document2, originX, orig
10507
10751
  fontRegistry,
10508
10752
  listOrdinals
10509
10753
  );
10754
+ if (pageSettings) {
10755
+ await drawFloatingTextBoxesForParagraph({
10756
+ writer,
10757
+ document: document2,
10758
+ fontRegistry,
10759
+ pageIndex,
10760
+ lines: block.layout.lines,
10761
+ pageSettings,
10762
+ contentLeft: originX,
10763
+ contentTop,
10764
+ contentWidth,
10765
+ paragraphTop: boxTop
10766
+ });
10767
+ }
10510
10768
  } else if (block.sourceBlock.type === "table") {
10511
10769
  await drawTableBlock(
10512
10770
  writer,
@@ -11207,6 +11465,103 @@ class OasisPdfWriter {
11207
11465
  );
11208
11466
  page.commands.push(commands.join("\n"));
11209
11467
  }
11468
+ // Fills/strokes an arbitrary path. Segment coordinates are in points with a
11469
+ // top-left origin (callers convert px→pt, like drawRect/drawLine); the y axis
11470
+ // is flipped here to the PDF bottom-left origin.
11471
+ drawPath(pageIndex, options) {
11472
+ const page = this.pages[pageIndex];
11473
+ if (!page || options.segments.length === 0) {
11474
+ return;
11475
+ }
11476
+ if (!options.fill && !options.stroke) {
11477
+ return;
11478
+ }
11479
+ const flip = (yy) => page.height - yy;
11480
+ const commands = ["q"];
11481
+ if (options.fill) {
11482
+ commands.push(colorCommand(options.fill, "rg", [1, 1, 1]));
11483
+ }
11484
+ if (options.stroke) {
11485
+ commands.push(colorCommand(options.stroke, "RG", [0, 0, 0]));
11486
+ commands.push(`${formatNumber(options.lineWidth ?? 1)} w`);
11487
+ }
11488
+ for (const segment of options.segments) {
11489
+ switch (segment.type) {
11490
+ case "move":
11491
+ commands.push(
11492
+ `${formatNumber(segment.x)} ${formatNumber(flip(segment.y))} m`
11493
+ );
11494
+ break;
11495
+ case "line":
11496
+ commands.push(
11497
+ `${formatNumber(segment.x)} ${formatNumber(flip(segment.y))} l`
11498
+ );
11499
+ break;
11500
+ case "cubic":
11501
+ commands.push(
11502
+ `${formatNumber(segment.x1)} ${formatNumber(flip(segment.y1))} ${formatNumber(segment.x2)} ${formatNumber(flip(segment.y2))} ${formatNumber(segment.x)} ${formatNumber(flip(segment.y))} c`
11503
+ );
11504
+ break;
11505
+ case "close":
11506
+ commands.push("h");
11507
+ break;
11508
+ }
11509
+ }
11510
+ if (options.fill && options.stroke) {
11511
+ commands.push("B");
11512
+ } else if (options.fill) {
11513
+ commands.push("f");
11514
+ } else {
11515
+ commands.push("S");
11516
+ }
11517
+ commands.push("Q");
11518
+ page.commands.push(commands.join("\n"));
11519
+ }
11520
+ // Saves the graphics state (`q`). Pair with restoreGraphicsState. Any draw
11521
+ // commands emitted in between inherit the current transform/clip.
11522
+ saveGraphicsState(pageIndex) {
11523
+ const page = this.pages[pageIndex];
11524
+ if (page) {
11525
+ page.commands.push("q");
11526
+ }
11527
+ }
11528
+ restoreGraphicsState(pageIndex) {
11529
+ const page = this.pages[pageIndex];
11530
+ if (page) {
11531
+ page.commands.push("Q");
11532
+ }
11533
+ }
11534
+ // Concatenates a clockwise rotation (in degrees, matching the canvas/editor
11535
+ // convention) about a top-left-origin point onto the current CTM. Must sit
11536
+ // inside a saveGraphicsState/restoreGraphicsState pair.
11537
+ rotateAbout(pageIndex, centerX, centerY, degrees) {
11538
+ const page = this.pages[pageIndex];
11539
+ if (!page || !degrees) {
11540
+ return;
11541
+ }
11542
+ const cyf = page.height - centerY;
11543
+ const radians = -degrees * Math.PI / 180;
11544
+ const cos = Math.cos(radians);
11545
+ const sin = Math.sin(radians);
11546
+ const e = centerX - centerX * cos + cyf * sin;
11547
+ const f = cyf - centerX * sin - cyf * cos;
11548
+ page.commands.push(
11549
+ `${formatNumber(cos)} ${formatNumber(sin)} ${formatNumber(-sin)} ${formatNumber(cos)} ${formatNumber(e)} ${formatNumber(f)} cm`
11550
+ );
11551
+ }
11552
+ // Intersects the clip path with a rectangle (top-left origin). Must sit inside
11553
+ // a saveGraphicsState/restoreGraphicsState pair so the clip can be undone.
11554
+ clipRect(pageIndex, x, y, width, height) {
11555
+ const page = this.pages[pageIndex];
11556
+ if (!page || width <= 0 || height <= 0) {
11557
+ return;
11558
+ }
11559
+ page.commands.push(
11560
+ `${formatNumber(x)} ${formatNumber(page.height - y - height)} ${formatNumber(width)} ${formatNumber(height)} re`,
11561
+ "W",
11562
+ "n"
11563
+ );
11564
+ }
11210
11565
  drawText(pageIndex, options) {
11211
11566
  const page = this.pages[pageIndex];
11212
11567
  if (!page || options.text.length === 0) {
@@ -11559,7 +11914,8 @@ async function exportEditorDocumentToPdf(document2) {
11559
11914
  page.headerTop ?? getPageHeaderZoneTop(page.pageSettings),
11560
11915
  contentWidth,
11561
11916
  fontRegistry,
11562
- listOrdinals
11917
+ listOrdinals,
11918
+ page.pageSettings
11563
11919
  );
11564
11920
  await drawBlockList(
11565
11921
  writer,
@@ -11570,7 +11926,8 @@ async function exportEditorDocumentToPdf(document2) {
11570
11926
  page.bodyTop ?? getPageBodyTop(page.pageSettings),
11571
11927
  contentWidth,
11572
11928
  fontRegistry,
11573
- listOrdinals
11929
+ listOrdinals,
11930
+ page.pageSettings
11574
11931
  );
11575
11932
  await drawBlockList(
11576
11933
  writer,
@@ -11581,7 +11938,8 @@ async function exportEditorDocumentToPdf(document2) {
11581
11938
  page.footerTop ?? page.bodyBottom ?? page.pageSettings.height,
11582
11939
  contentWidth,
11583
11940
  fontRegistry,
11584
- listOrdinals
11941
+ listOrdinals,
11942
+ page.pageSettings
11585
11943
  );
11586
11944
  if (page.footnoteBlocks && page.footnoteBlocks.length > 0 && page.footnoteTop !== void 0) {
11587
11945
  if (page.footnoteSeparatorTop !== void 0) {
@@ -40257,6 +40615,10 @@ function buildDocumentAndBrowserCommands({
40257
40615
  () => document2.importDocument()
40258
40616
  ),
40259
40617
  insertImage: actionCommand("insertImage", () => document2.insertImage()),
40618
+ insertShape: actionCommand(
40619
+ "insertShape",
40620
+ (p) => document2.insertShape(String(p))
40621
+ ),
40260
40622
  unlink: actionCommand(
40261
40623
  "unlink",
40262
40624
  () => link.remove(),
@@ -40663,7 +41025,10 @@ function createEditorEssentialsRuntimePlugin(options) {
40663
41025
  insertImage: () => {
40664
41026
  var _a;
40665
41027
  return (_a = options.imageInputRef()) == null ? void 0 : _a.click();
40666
- }
41028
+ },
41029
+ insertShape: (preset) => options.applyTransactionalState(
41030
+ (current) => insertShapeAtSelection(current, preset)
41031
+ )
40667
41032
  };
40668
41033
  const essentialsLink = {
40669
41034
  prompt: () => options.commandsController.promptForLink(),
@@ -0,0 +1,9 @@
1
+ import { EditorState } from '../../../model.js';
2
+
3
+ /**
4
+ * Inserts a basic shape (`wps:wsp` with preset geometry) at the current
5
+ * selection. Modeled as an inline run carrying an {@link EditorTextBoxData}
6
+ * with an empty paragraph body, floating "in front of text" by default — the
7
+ * same anchoring Word applies to a freshly inserted shape.
8
+ */
9
+ export declare function insertShapeAtSelection(state: EditorState, preset: string): EditorState;
@@ -3,6 +3,7 @@
3
3
  */
4
4
  export * from '../commands/image.js';
5
5
  export * from '../commands/textBox.js';
6
+ export * from '../commands/shape.js';
6
7
  export * from '../commands/floatingLayout.js';
7
8
  export * from '../commands/text.js';
8
9
  export * from '../commands/block.js';