oasis-editor 0.0.89 → 0.0.91
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/{OasisEditorApp-cKm4OFIF.js → OasisEditorApp-Cwd5XBHr.js} +760 -515
- package/dist/assets/{importDocxWorker-DVDyiqYf.js → importDocxWorker-6DqfSWfq.js} +1 -1
- package/dist/core/model/index.d.ts +3 -3
- package/dist/core/model/types/document.d.ts +2 -0
- package/dist/core/model/types/nodes.d.ts +15 -43
- package/dist/core/model/types/primitives.d.ts +2 -0
- package/dist/core/model/types/styles.d.ts +59 -2
- package/dist/core/tableStyleResolver.d.ts +2 -1
- package/dist/export/docx/docxPackageXml.d.ts +1 -1
- package/dist/export/pdf/OasisPdfWriter.d.ts +6 -102
- package/dist/export/pdf/draw/drawFragment.d.ts +2 -0
- package/dist/export/pdf/writer/PdfContentStream.d.ts +20 -0
- package/dist/export/pdf/writer/PdfDocumentSerializer.d.ts +5 -0
- package/dist/export/pdf/writer/PdfFontTable.d.ts +38 -0
- package/dist/export/pdf/writer/PdfImageTable.d.ts +12 -0
- package/dist/export/pdf/writer/pdfPrimitives.d.ts +20 -0
- package/dist/export/pdf/writer/pdfTypes.d.ts +107 -0
- package/dist/import/docx/settings.d.ts +1 -0
- package/dist/import/docx/tableConditionalFormatting.d.ts +0 -30
- package/dist/import/docx/tableProperties.d.ts +7 -0
- package/dist/import/docx/xmlHelpers.d.ts +5 -0
- package/dist/{index-BICQTKCZ.js → index-C2DlzueH.js} +559 -184
- package/dist/oasis-editor.js +1 -1
- package/dist/oasis-editor.umd.cjs +4 -4
- package/package.json +1 -1
|
@@ -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 { v as visitRun, a as assertNever, c as createSignal, b as createEditorStateFromDocument, d as createInitialEditorState, S as STANDARD_FONT_SIZES_PT, f as fontSizePxToPt, p as probeLocalFontFamilies, e as createEditorParagraphFromRuns, i as isInlineObjectRun, g as createEditorStyledRun, h as getParagraphLength, j as getParagraphText, k as getActiveZone, l as getDocumentSections, m as getActiveSectionIndex, n as getParagraphs, o as normalizeSelection, q as positionToParagraphOffset, r as paragraphOffsetToPosition, s as clampPosition, t as findParagraphIndex, u as createCollapsedSelection, w as isSelectionCollapsed, x as parseFontSizePtToPx, y as formatFontSizePt, z as createEditorParagraph, A as getBlockParagraphs, B as findParagraphTableLocation, C as buildTableCellLayout, P as PT_PER_PX, D as createEditorTableCell, E as createEditorTableRow, F as createEditorTable, G as underlineStyleToCssDecorationStyle, H as resolveImageSrc, I as listKindForTag, J as isParagraphTag, K as collectInlineRuns, L as parseParagraphStyle, M as getRunImage, N as InlineShell, O as BalloonShell, Q as DocumentShell, R as createMemo, T as buildCanvasLayoutSnapshot, U as getCaretRectFromSnapshot, V as getParagraphRectFromSnapshot, W as createComponent, X as CaretOverlay, Y as Show, Z as createRenderEffect, _ as style, $ as setAttribute, a0 as setStyleProperty, a1 as memo, a2 as template, a3 as useI18n, a4 as createEffect, a5 as insert, a6 as use, a7 as addEventListener, a8 as Dialog, a9 as delegateEvents, aa as className, ab as For, ac as UNDERLINE_STYLE_OPTIONS, ad as Tabs, ae as onMount, af as onCleanup, ag as PluginUiHost, ah as OasisEditorEditor, ai as OasisBrandMark, aj as setPreciseFontPreference, ak as setWelcomeSeen, al as enablePreciseFontMode, am as TWIPS_PER_POINT, an as PX_PER_INCH, ao as TWIPS_PER_INCH, ap as resolveEffectiveParagraphStyle, aq as resolveEffectiveTextStyleForParagraph, ar as EMU_PER_PX, as as EMU_PER_PT, at as getRunFootnoteReference, au as getRunEndnoteReference, av as iterateFootnoteReferenceRuns, aw as iterateEndnoteReferenceRuns, ax as imageContentTypeDefaults, ay as getRunFieldChar, az as getRunFieldInstruction, aA as createEditorRun, aB as JSZip, aC as imageExtensionFromMime, aD as pxToPt$1, aE as resolveFloatingObjectRect, aF as getTextBoxFloatingGeometry, aG as getPresetPathSegments, aH as projectBlocksLayout, aI as buildListLabels, aJ as getImageFloatingGeometry, aK as textStyleToFontSizePt, aL as PX_PER_POINT, aM as DEFAULT_FONT_SIZE_PX, aN as isDoubleUnderlineStyle, aO as isWavyUnderlineStyle, aP as underlineStyleLineWidthPx, aQ as underlineStyleDashArray, aR as resolveListLabel, aS as getListLabelInset, aT as getAlignedListLabelInset, aU as getParagraphBorderInsets, aV as buildSegmentTable, aW as buildCanvasTableLayout, aX as resolveCanvasTableWidth, aY as resolveFloatingTableRect, aZ as normalizeFamily, a_ as ROBOTO_FONT_FILES, a$ as loadFontAsset, b0 as OFFICE_COMPAT_FONT_FAMILIES, b1 as buildSfnt, b2 as defaultFontDecoderRegistry, b3 as SfntFontProgram, b4 as collectPdfFontFamilies, b5 as projectDocumentLayout, b6 as getPageContentWidth, b7 as getPageHeaderZoneTop, b8 as getPageBodyTop, b9 as getPageColumnRects, ba as findFootnoteReference, bb as FOOTNOTE_MARKER_GUTTER_PX, bc as resolveImporterForFile, bd as getDocumentSectionsCanonical, be as getDocumentParagraphsCanonical, bf as getDocumentParagraphs, bg as getDocumentPageSettings, bh as getTableCellContentWidthForParagraph, bi as on, bj as debounce, bk as unwrap, bl as perfTimer, bm as getRunTextBox, bn as createEditorDocument, bo as resolveResizedDimensions, bp as resolveTextBoxRenderHeight, bq as getToolbarStyleState, br as getCachedCanvasImage, bs as measureParagraphMinContentWidthPx, bt as getEditableBlocksForZone, bu as findParagraphLocation, bv as createSectionBoundaryParagraph, bw as normalizePageSettings, bx as DEFAULT_EDITOR_PAGE_SETTINGS, by as markStart, bz as markEnd, bA as getParagraphEntries, bB as getParagraphById, bC as createEditorFootnote, bD as createFootnoteReferenceRun, bE as renumberFootnotes, bF as getFootnoteDisplayMarker, bG as getHeadingLevel, bH as preciseFontModeVersion, bI as isPreciseFontModeEnabled, bJ as resolveNamedTextStyle, bK as togglePreciseFontMode, bL as nextFontSizePt, bM as previousFontSizePt, bN as fontSizePtToPx, bO as createDefaultToolbarPreset, bP as MenuRegistry, bQ as createToolbarRegistry, bR as Editor, bS as resolveCommandRef, bT as commandRefName, bU as createOasisEditorClient, bV as createEditorZoom, bW as startLongTaskObserver, bX as installGlobalReport, bY as applyStoredPreciseFontPreference, bZ as getWelcomeSeen, b_ as isLocalFontAccessSupported, b$ as EDITOR_SCROLL_PADDING_PX, c0 as Toolbar, c1 as OasisEditorLoading, c2 as I18nProvider, c3 as createTranslator, c4 as createEditorLogger, c5 as registerDomStatsSurface } from "./index-
|
|
4
|
+
import { v as visitRun, a as assertNever, c as createSignal, b as createEditorStateFromDocument, d as createInitialEditorState, S as STANDARD_FONT_SIZES_PT, f as fontSizePxToPt, p as probeLocalFontFamilies, e as createEditorParagraphFromRuns, i as isInlineObjectRun, g as createEditorStyledRun, h as getParagraphLength, j as getParagraphText, k as getActiveZone, l as getDocumentSections, m as getActiveSectionIndex, n as getParagraphs, o as normalizeSelection, q as positionToParagraphOffset, r as paragraphOffsetToPosition, s as clampPosition, t as findParagraphIndex, u as createCollapsedSelection, w as isSelectionCollapsed, x as parseFontSizePtToPx, y as formatFontSizePt, z as createEditorParagraph, A as getBlockParagraphs, B as findParagraphTableLocation, C as buildTableCellLayout, P as PT_PER_PX, D as createEditorTableCell, E as createEditorTableRow, F as createEditorTable, G as underlineStyleToCssDecorationStyle, H as resolveImageSrc, I as listKindForTag, J as isParagraphTag, K as collectInlineRuns, L as parseParagraphStyle, M as getRunImage, N as InlineShell, O as BalloonShell, Q as DocumentShell, R as createMemo, T as buildCanvasLayoutSnapshot, U as getCaretRectFromSnapshot, V as getParagraphRectFromSnapshot, W as createComponent, X as CaretOverlay, Y as Show, Z as createRenderEffect, _ as style, $ as setAttribute, a0 as setStyleProperty, a1 as memo, a2 as template, a3 as useI18n, a4 as createEffect, a5 as insert, a6 as use, a7 as addEventListener, a8 as Dialog, a9 as delegateEvents, aa as className, ab as For, ac as UNDERLINE_STYLE_OPTIONS, ad as Tabs, ae as onMount, af as onCleanup, ag as PluginUiHost, ah as OasisEditorEditor, ai as OasisBrandMark, aj as setPreciseFontPreference, ak as setWelcomeSeen, al as enablePreciseFontMode, am as TWIPS_PER_POINT, an as PX_PER_INCH, ao as TWIPS_PER_INCH, ap as resolveEffectiveParagraphStyle, aq as resolveEffectiveTextStyleForParagraph, ar as EMU_PER_PX, as as EMU_PER_PT, at as getRunFootnoteReference, au as getRunEndnoteReference, av as iterateFootnoteReferenceRuns, aw as iterateEndnoteReferenceRuns, ax as imageContentTypeDefaults, ay as getRunFieldChar, az as getRunFieldInstruction, aA as createEditorRun, aB as JSZip, aC as imageExtensionFromMime, aD as pxToPt$1, aE as resolveFloatingObjectRect, aF as getTextBoxFloatingGeometry, aG as getPresetPathSegments, aH as projectBlocksLayout, aI as buildListLabels, aJ as getImageFloatingGeometry, aK as textStyleToFontSizePt, aL as PX_PER_POINT, aM as DEFAULT_FONT_SIZE_PX, aN as isDoubleUnderlineStyle, aO as isWavyUnderlineStyle, aP as underlineStyleLineWidthPx, aQ as underlineStyleDashArray, aR as resolveListLabel, aS as getListLabelInset, aT as getAlignedListLabelInset, aU as getParagraphBorderInsets, aV as buildSegmentTable, aW as buildCanvasTableLayout, aX as resolveCanvasTableWidth, aY as resolveFloatingTableRect, aZ as normalizeFamily, a_ as ROBOTO_FONT_FILES, a$ as loadFontAsset, b0 as OFFICE_COMPAT_FONT_FAMILIES, b1 as buildSfnt, b2 as defaultFontDecoderRegistry, b3 as SfntFontProgram, b4 as collectPdfFontFamilies, b5 as projectDocumentLayout, b6 as getPageContentWidth, b7 as getPageHeaderZoneTop, b8 as getPageBodyTop, b9 as getPageColumnRects, ba as findFootnoteReference, bb as FOOTNOTE_MARKER_GUTTER_PX, bc as resolveImporterForFile, bd as getDocumentSectionsCanonical, be as getDocumentParagraphsCanonical, bf as getDocumentParagraphs, bg as getDocumentPageSettings, bh as getTableCellContentWidthForParagraph, bi as on, bj as debounce, bk as unwrap, bl as perfTimer, bm as getRunTextBox, bn as createEditorDocument, bo as resolveResizedDimensions, bp as resolveTextBoxRenderHeight, bq as getToolbarStyleState, br as getCachedCanvasImage, bs as measureParagraphMinContentWidthPx, bt as getEditableBlocksForZone, bu as findParagraphLocation, bv as createSectionBoundaryParagraph, bw as normalizePageSettings, bx as DEFAULT_EDITOR_PAGE_SETTINGS, by as markStart, bz as markEnd, bA as getParagraphEntries, bB as getParagraphById, bC as createEditorFootnote, bD as createFootnoteReferenceRun, bE as renumberFootnotes, bF as getFootnoteDisplayMarker, bG as getHeadingLevel, bH as preciseFontModeVersion, bI as isPreciseFontModeEnabled, bJ as resolveNamedTextStyle, bK as togglePreciseFontMode, bL as nextFontSizePt, bM as previousFontSizePt, bN as fontSizePtToPx, bO as createDefaultToolbarPreset, bP as MenuRegistry, bQ as createToolbarRegistry, bR as Editor, bS as resolveCommandRef, bT as commandRefName, bU as createOasisEditorClient, bV as createEditorZoom, bW as startLongTaskObserver, bX as installGlobalReport, bY as applyStoredPreciseFontPreference, bZ as getWelcomeSeen, b_ as isLocalFontAccessSupported, b$ as EDITOR_SCROLL_PADDING_PX, c0 as Toolbar, c1 as OasisEditorLoading, c2 as I18nProvider, c3 as createTranslator, c4 as createEditorLogger, c5 as registerDomStatsSurface } from "./index-C2DlzueH.js";
|
|
5
5
|
function cloneStyle(style2) {
|
|
6
6
|
return style2 ? { ...style2 } : void 0;
|
|
7
7
|
}
|
|
@@ -30434,7 +30434,11 @@ function createEditorTableContextMenuActions(deps) {
|
|
|
30434
30434
|
};
|
|
30435
30435
|
}
|
|
30436
30436
|
function createEditorChrome(deps) {
|
|
30437
|
-
const {
|
|
30437
|
+
const {
|
|
30438
|
+
computeFontFamilyOptions: computeFontFamilyOptions2,
|
|
30439
|
+
computeFontSizeOptions: computeFontSizeOptions2,
|
|
30440
|
+
loadLocalFontFamilyOptions
|
|
30441
|
+
} = createEditorFontOptions({
|
|
30438
30442
|
state: deps.state,
|
|
30439
30443
|
toolbarStyleState: deps.toolbarStyleState
|
|
30440
30444
|
});
|
|
@@ -33181,6 +33185,10 @@ function serializeParagraphBorders(style2) {
|
|
|
33181
33185
|
const DEFAULT_TABLE_BORDER_COLOR = "6F6F6F";
|
|
33182
33186
|
const DEFAULT_TABLE_BORDER_WIDTH_PT = 0.75;
|
|
33183
33187
|
const DEFAULT_CELL_PADDING_LEFT_RIGHT_PT = 5.4;
|
|
33188
|
+
function serializeExtAttributes(attrs) {
|
|
33189
|
+
if (!attrs) return "";
|
|
33190
|
+
return Object.entries(attrs).map(([name, value]) => ` ${name}="${escapeXml(value)}"`).join("");
|
|
33191
|
+
}
|
|
33184
33192
|
function serializeRevisionAttrs(revision) {
|
|
33185
33193
|
const numericId = /^\d+$/.test(revision.id) ? revision.id : String(
|
|
33186
33194
|
Array.from(revision.id).reduce(
|
|
@@ -33441,10 +33449,11 @@ function serializeTableRowStyleXml(style2) {
|
|
|
33441
33449
|
if (hidden) parts.push(hidden);
|
|
33442
33450
|
const header = serializeOnOffElement("tblHeader", style2.isHeader);
|
|
33443
33451
|
if (header) parts.push(header);
|
|
33452
|
+
if (style2.align) parts.push(`<w:jc w:val="${style2.align}"/>`);
|
|
33444
33453
|
return parts.length > 0 ? `<w:trPr>${parts.join("")}</w:trPr>` : "";
|
|
33445
33454
|
}
|
|
33446
33455
|
function serializeTableRowProperties(row) {
|
|
33447
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
33456
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
33448
33457
|
const parts = [];
|
|
33449
33458
|
const conditional = serializeConditionalFlags(row.conditionalStyle);
|
|
33450
33459
|
if (conditional) parts.push(conditional);
|
|
@@ -33471,13 +33480,14 @@ function serializeTableRowProperties(row) {
|
|
|
33471
33480
|
if (((_g = row.style) == null ? void 0 : _g.isHeader) ?? row.isHeader) parts.push("<w:tblHeader/>");
|
|
33472
33481
|
const hidden = serializeOnOffElement("hidden", (_h = row.style) == null ? void 0 : _h.hidden);
|
|
33473
33482
|
if (hidden) parts.push(hidden);
|
|
33474
|
-
if ((_i = row.style) == null ? void 0 : _i.
|
|
33483
|
+
if ((_i = row.style) == null ? void 0 : _i.align) parts.push(`<w:jc w:val="${row.style.align}"/>`);
|
|
33484
|
+
if ((_j = row.style) == null ? void 0 : _j.propertyRevision) {
|
|
33475
33485
|
const revision = row.style.propertyRevision;
|
|
33476
33486
|
parts.push(
|
|
33477
33487
|
`<w:trPrChange ${serializeRevisionAttrs(revision)}>${serializeTableRowStyleXml(revision.previous)}</w:trPrChange>`
|
|
33478
33488
|
);
|
|
33479
33489
|
}
|
|
33480
|
-
if (((
|
|
33490
|
+
if (((_k = row.style) == null ? void 0 : _k.revision) && row.style.revision.type !== "merge") {
|
|
33481
33491
|
const revision = row.style.revision;
|
|
33482
33492
|
const element = revision.type === "insert" ? "ins" : "del";
|
|
33483
33493
|
parts.push(`<w:${element} ${serializeRevisionAttrs(revision)}/>`);
|
|
@@ -33595,6 +33605,46 @@ function serializeTableProperties(table) {
|
|
|
33595
33605
|
}
|
|
33596
33606
|
return `<w:tblPr>${parts.join("")}</w:tblPr>`;
|
|
33597
33607
|
}
|
|
33608
|
+
function serializeTablePropertyExceptions(exceptions, tblPrExChangeXml) {
|
|
33609
|
+
if (!exceptions && !tblPrExChangeXml) {
|
|
33610
|
+
return "";
|
|
33611
|
+
}
|
|
33612
|
+
const parts = [];
|
|
33613
|
+
if ((exceptions == null ? void 0 : exceptions.width) !== void 0) {
|
|
33614
|
+
parts.push(serializeTableWidth(exceptions.width));
|
|
33615
|
+
}
|
|
33616
|
+
if (exceptions == null ? void 0 : exceptions.align) {
|
|
33617
|
+
parts.push(`<w:jc w:val="${exceptions.align}"/>`);
|
|
33618
|
+
}
|
|
33619
|
+
const cellSpacingXml = serializeDocxWidthElement(
|
|
33620
|
+
"tblCellSpacing",
|
|
33621
|
+
exceptions == null ? void 0 : exceptions.cellSpacing
|
|
33622
|
+
);
|
|
33623
|
+
if (cellSpacingXml) {
|
|
33624
|
+
parts.push(cellSpacingXml);
|
|
33625
|
+
}
|
|
33626
|
+
const indentXml = serializeDocxWidthElement("tblInd", exceptions == null ? void 0 : exceptions.indentLeft);
|
|
33627
|
+
if (indentXml) {
|
|
33628
|
+
parts.push(indentXml);
|
|
33629
|
+
}
|
|
33630
|
+
const bordersXml = exceptions ? serializeTableBorders(exceptions) : "";
|
|
33631
|
+
if (bordersXml) {
|
|
33632
|
+
parts.push(bordersXml);
|
|
33633
|
+
}
|
|
33634
|
+
if (exceptions == null ? void 0 : exceptions.layout) {
|
|
33635
|
+
parts.push(`<w:tblLayout w:type="${exceptions.layout}"/>`);
|
|
33636
|
+
}
|
|
33637
|
+
const marginsXml = serializeTableDefaultCellMargins(
|
|
33638
|
+
exceptions == null ? void 0 : exceptions.defaultCellMargins
|
|
33639
|
+
);
|
|
33640
|
+
if (marginsXml) {
|
|
33641
|
+
parts.push(marginsXml);
|
|
33642
|
+
}
|
|
33643
|
+
if (tblPrExChangeXml) {
|
|
33644
|
+
parts.push(tblPrExChangeXml);
|
|
33645
|
+
}
|
|
33646
|
+
return parts.length > 0 ? `<w:tblPrEx>${parts.join("")}</w:tblPrEx>` : "";
|
|
33647
|
+
}
|
|
33598
33648
|
function serializeTableXml(table, serializeParagraphXml2) {
|
|
33599
33649
|
const tableLayout = buildTableCellLayout(table);
|
|
33600
33650
|
const tableEntriesByKey = new Map(
|
|
@@ -33618,9 +33668,9 @@ function serializeTableXml(table, serializeParagraphXml2) {
|
|
|
33618
33668
|
];
|
|
33619
33669
|
const paragraphsXml = paragraphs.map((paragraph) => serializeParagraphXml2(paragraph, cell)).join("");
|
|
33620
33670
|
const contentXml = cell.vMerge === "continue" ? "<w:p/>" : paragraphsXml;
|
|
33621
|
-
return `<w:tc>${serializeTableCellProperties(cell, fallbackWidthPt)}${contentXml}</w:tc>`;
|
|
33671
|
+
return `<w:tc${serializeExtAttributes(cell.extAttributes)}>${serializeTableCellProperties(cell, fallbackWidthPt)}${contentXml}</w:tc>`;
|
|
33622
33672
|
}).join("");
|
|
33623
|
-
return `<w:tr>${row.
|
|
33673
|
+
return `<w:tr${serializeExtAttributes(row.extAttributes)}>${serializeTablePropertyExceptions(row.propertyExceptions, row.tblPrExChangeXml)}${serializeTableRowProperties(row)}${cellsXml}</w:tr>`;
|
|
33624
33674
|
}).join("");
|
|
33625
33675
|
const gridXml = table.gridCols ? `<w:tblGrid>${table.gridCols.map((width) => `<w:gridCol w:w="${pointsToTwips(width) ?? 0}"/>`).join("")}${table.gridRevision ? `<w:tblGridChange ${serializeRevisionAttrs(table.gridRevision)}><w:tblGrid>${table.gridRevision.previous.map((width) => `<w:gridCol w:w="${pointsToTwips(width) ?? 0}"/>`).join("")}</w:tblGrid></w:tblGridChange>` : ""}</w:tblGrid>` : "";
|
|
33626
33676
|
return `<w:tbl>${serializeTableProperties(table)}${gridXml}${rowsXml}</w:tbl>`;
|
|
@@ -33675,6 +33725,16 @@ function materializeRunStyle(run, paragraphStyleId, styles) {
|
|
|
33675
33725
|
noProof: effective.noProof,
|
|
33676
33726
|
webHidden: effective.webHidden,
|
|
33677
33727
|
specVanish: effective.specVanish,
|
|
33728
|
+
rtl: effective.rtl,
|
|
33729
|
+
complexScript: effective.complexScript,
|
|
33730
|
+
snapToGrid: effective.snapToGrid,
|
|
33731
|
+
fitText: effective.fitText,
|
|
33732
|
+
emphasisMark: effective.emphasisMark,
|
|
33733
|
+
textBorder: effective.textBorder,
|
|
33734
|
+
outline: effective.outline,
|
|
33735
|
+
shadow: effective.shadow,
|
|
33736
|
+
emboss: effective.emboss,
|
|
33737
|
+
imprint: effective.imprint,
|
|
33678
33738
|
textEffect: effective.textEffect,
|
|
33679
33739
|
characterScale: effective.characterScale,
|
|
33680
33740
|
characterSpacing: effective.characterSpacing,
|
|
@@ -33972,15 +34032,23 @@ function serializeRunProperties(styles) {
|
|
|
33972
34032
|
}
|
|
33973
34033
|
if (styles.strike) parts.push("<w:strike/>");
|
|
33974
34034
|
if (styles.doubleStrike) parts.push("<w:dstrike/>");
|
|
34035
|
+
if (styles.outline) parts.push("<w:outline/>");
|
|
34036
|
+
if (styles.shadow) parts.push("<w:shadow/>");
|
|
34037
|
+
if (styles.emboss) parts.push("<w:emboss/>");
|
|
34038
|
+
if (styles.imprint) parts.push("<w:imprint/>");
|
|
33975
34039
|
if (styles.smallCaps) parts.push("<w:smallCaps/>");
|
|
33976
34040
|
if (styles.allCaps) parts.push("<w:caps/>");
|
|
33977
34041
|
if (styles.hidden) parts.push("<w:vanish/>");
|
|
33978
34042
|
if (styles.noProof) parts.push("<w:noProof/>");
|
|
33979
34043
|
if (styles.webHidden) parts.push("<w:webHidden/>");
|
|
33980
34044
|
if (styles.specVanish) parts.push("<w:specVanish/>");
|
|
34045
|
+
if (styles.snapToGrid === false) parts.push('<w:snapToGrid w:val="0"/>');
|
|
33981
34046
|
if (styles.textEffect) {
|
|
33982
34047
|
parts.push(`<w:effect w:val="${escapeXml(styles.textEffect)}"/>`);
|
|
33983
34048
|
}
|
|
34049
|
+
if (styles.textBorder) {
|
|
34050
|
+
parts.push(`<w:bdr ${serializeDocxBorderAttrs(styles.textBorder)}`);
|
|
34051
|
+
}
|
|
33984
34052
|
if (styles.characterScale !== void 0 && styles.characterScale !== null && Number.isFinite(styles.characterScale)) {
|
|
33985
34053
|
parts.push(
|
|
33986
34054
|
`<w:w w:val="${Math.max(1, Math.round(styles.characterScale))}"/>`
|
|
@@ -34048,6 +34116,17 @@ function serializeRunProperties(styles) {
|
|
|
34048
34116
|
`<w:shd w:val="clear" w:color="auto" w:fill="${normalizeDocxColor(styles.shading, "FFFFFF")}"/>`
|
|
34049
34117
|
);
|
|
34050
34118
|
}
|
|
34119
|
+
if (styles.fitText !== void 0 && styles.fitText !== null && Number.isFinite(styles.fitText)) {
|
|
34120
|
+
const twips = pointsToSignedTwips(styles.fitText);
|
|
34121
|
+
if (twips !== null && twips > 0) {
|
|
34122
|
+
parts.push(`<w:fitText w:val="${twips}"/>`);
|
|
34123
|
+
}
|
|
34124
|
+
}
|
|
34125
|
+
if (styles.rtl) parts.push("<w:rtl/>");
|
|
34126
|
+
if (styles.complexScript) parts.push("<w:cs/>");
|
|
34127
|
+
if (styles.emphasisMark) {
|
|
34128
|
+
parts.push(`<w:em w:val="${escapeXml(styles.emphasisMark)}"/>`);
|
|
34129
|
+
}
|
|
34051
34130
|
if (styles.language) {
|
|
34052
34131
|
const attrs = [];
|
|
34053
34132
|
if (styles.language.value) {
|
|
@@ -34777,31 +34856,17 @@ const CONDITIONAL_TYPE_ORDER = [
|
|
|
34777
34856
|
"seCell"
|
|
34778
34857
|
];
|
|
34779
34858
|
function serializeConditionalTcPr(cond) {
|
|
34780
|
-
|
|
34781
|
-
|
|
34782
|
-
|
|
34783
|
-
|
|
34784
|
-
|
|
34785
|
-
|
|
34786
|
-
|
|
34787
|
-
|
|
34788
|
-
|
|
34789
|
-
|
|
34790
|
-
|
|
34791
|
-
];
|
|
34792
|
-
const borderXml = edges.filter(
|
|
34793
|
-
(entry) => entry[1] != null
|
|
34794
|
-
).map(([name, border]) => `<w:${name} ${serializeDocxBorderAttrs(border)}`).join("");
|
|
34795
|
-
if (borderXml) {
|
|
34796
|
-
parts.push(`<w:tcBorders>${borderXml}</w:tcBorders>`);
|
|
34797
|
-
}
|
|
34798
|
-
}
|
|
34799
|
-
if (cond.shading) {
|
|
34800
|
-
parts.push(
|
|
34801
|
-
`<w:shd w:val="clear" w:color="auto" w:fill="${normalizeDocxColor(cond.shading, "FFFFFF")}"/>`
|
|
34802
|
-
);
|
|
34803
|
-
}
|
|
34804
|
-
return parts.length > 0 ? `<w:tcPr>${parts.join("")}</w:tcPr>` : "";
|
|
34859
|
+
const cellStyle = {
|
|
34860
|
+
...cond.borders ? {
|
|
34861
|
+
...cond.borders.borderTop ? { borderTop: cond.borders.borderTop } : {},
|
|
34862
|
+
...cond.borders.borderLeft ? { borderLeft: cond.borders.borderLeft } : {},
|
|
34863
|
+
...cond.borders.borderBottom ? { borderBottom: cond.borders.borderBottom } : {},
|
|
34864
|
+
...cond.borders.borderRight ? { borderRight: cond.borders.borderRight } : {}
|
|
34865
|
+
} : {},
|
|
34866
|
+
...cond.shading ? { shading: cond.shading } : {},
|
|
34867
|
+
...cond.cellStyle
|
|
34868
|
+
};
|
|
34869
|
+
return Object.keys(cellStyle).length > 0 ? serializeTableCellStyleXml(cellStyle) : "";
|
|
34805
34870
|
}
|
|
34806
34871
|
function serializeWidthElement(name, value) {
|
|
34807
34872
|
if (typeof value === "number") {
|
|
@@ -35000,7 +35065,7 @@ function serializeNoteSettings(tagName, settings) {
|
|
|
35000
35065
|
}
|
|
35001
35066
|
return parts.length > 0 ? `<w:${tagName}>${parts.join("")}</w:${tagName}>` : null;
|
|
35002
35067
|
}
|
|
35003
|
-
function buildSettingsXml(hasEvenAndOddHeaders, defaultTabStop, footnoteSettings, endnoteSettings) {
|
|
35068
|
+
function buildSettingsXml(hasEvenAndOddHeaders, defaultTabStop, footnoteSettings, endnoteSettings, allowSpaceOfSameStyleInTable) {
|
|
35004
35069
|
const parts = [];
|
|
35005
35070
|
const defaultTabStopTwips = pointsToTwips(defaultTabStop);
|
|
35006
35071
|
if (defaultTabStopTwips !== null) {
|
|
@@ -35017,6 +35082,11 @@ function buildSettingsXml(hasEvenAndOddHeaders, defaultTabStop, footnoteSettings
|
|
|
35017
35082
|
if (hasEvenAndOddHeaders) {
|
|
35018
35083
|
parts.push("<w:evenAndOddHeaders/>");
|
|
35019
35084
|
}
|
|
35085
|
+
if (allowSpaceOfSameStyleInTable) {
|
|
35086
|
+
parts.push(
|
|
35087
|
+
`<w:compat><w:allowSpaceOfSameStyleInTable/></w:compat>`
|
|
35088
|
+
);
|
|
35089
|
+
}
|
|
35020
35090
|
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><w:settings xmlns:w="${WORD_NS$1}">${parts.join("")}</w:settings>`;
|
|
35021
35091
|
}
|
|
35022
35092
|
function buildPartRelationshipsXml(images, hyperlinks) {
|
|
@@ -35449,7 +35519,7 @@ function buildPartContext(blocks, numberingContext, state, document2) {
|
|
|
35449
35519
|
};
|
|
35450
35520
|
}
|
|
35451
35521
|
async function exportEditorDocumentToDocx(document2) {
|
|
35452
|
-
var _a, _b, _c, _d, _e, _f;
|
|
35522
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
35453
35523
|
document2 = renumberImageCaptionsInDocument(document2);
|
|
35454
35524
|
const zip = new JSZip();
|
|
35455
35525
|
const numberingContext = buildNumberingContext(document2);
|
|
@@ -35534,7 +35604,7 @@ async function exportEditorDocumentToDocx(document2) {
|
|
|
35534
35604
|
return (((_a2 = section.evenPageHeader) == null ? void 0 : _a2.length) ?? 0) > 0 || (((_b2 = section.evenPageFooter) == null ? void 0 : _b2.length) ?? 0) > 0;
|
|
35535
35605
|
}
|
|
35536
35606
|
);
|
|
35537
|
-
const hasDocumentSettings = hasEvenAndOddHeaders || ((_a = document2.settings) == null ? void 0 : _a.defaultTabStop) !== void 0 || ((_b = document2.
|
|
35607
|
+
const hasDocumentSettings = hasEvenAndOddHeaders || ((_a = document2.settings) == null ? void 0 : _a.defaultTabStop) !== void 0 || ((_b = document2.settings) == null ? void 0 : _b.allowSpaceOfSameStyleInTable) !== void 0 || ((_c = document2.footnotes) == null ? void 0 : _c.settings) !== void 0 || ((_d = document2.endnotes) == null ? void 0 : _d.settings) !== void 0;
|
|
35538
35608
|
const allImages = [
|
|
35539
35609
|
...bodyContext.images,
|
|
35540
35610
|
...parts.flatMap((part) => part.context.images)
|
|
@@ -35616,9 +35686,10 @@ async function exportEditorDocumentToDocx(document2) {
|
|
|
35616
35686
|
"word/settings.xml",
|
|
35617
35687
|
buildSettingsXml(
|
|
35618
35688
|
hasEvenAndOddHeaders,
|
|
35619
|
-
(
|
|
35620
|
-
(
|
|
35621
|
-
(
|
|
35689
|
+
(_e = document2.settings) == null ? void 0 : _e.defaultTabStop,
|
|
35690
|
+
(_f = document2.footnotes) == null ? void 0 : _f.settings,
|
|
35691
|
+
(_g = document2.endnotes) == null ? void 0 : _g.settings,
|
|
35692
|
+
(_h = document2.settings) == null ? void 0 : _h.allowSpaceOfSameStyleInTable
|
|
35622
35693
|
)
|
|
35623
35694
|
);
|
|
35624
35695
|
}
|
|
@@ -36130,6 +36201,63 @@ function drawFragmentShading(writer, pageIndex, line, fragment, originX, originY
|
|
|
36130
36201
|
fill: styles.shading
|
|
36131
36202
|
});
|
|
36132
36203
|
}
|
|
36204
|
+
function drawFragmentBorder(writer, pageIndex, line, fragment, originX, originY, styles) {
|
|
36205
|
+
const border = styles.textBorder;
|
|
36206
|
+
if (!border || border.type === "none" || border.width <= 0) {
|
|
36207
|
+
return;
|
|
36208
|
+
}
|
|
36209
|
+
const bounds = resolveFragmentBounds(
|
|
36210
|
+
line,
|
|
36211
|
+
fragment,
|
|
36212
|
+
styles.fontSize ?? DEFAULT_FONT_SIZE_PX
|
|
36213
|
+
);
|
|
36214
|
+
if (!bounds) {
|
|
36215
|
+
return;
|
|
36216
|
+
}
|
|
36217
|
+
writer.drawRect(pageIndex, {
|
|
36218
|
+
x: pxToPt$1(originX + bounds.left),
|
|
36219
|
+
y: pxToPt$1(originY + line.top + 1),
|
|
36220
|
+
width: pxToPt$1(Math.max(0, bounds.right - bounds.left)),
|
|
36221
|
+
height: pxToPt$1(Math.max(2, line.height - 2)),
|
|
36222
|
+
stroke: border.color,
|
|
36223
|
+
lineWidth: pxToPt$1(Math.max(0.5, border.width * PX_PER_POINT))
|
|
36224
|
+
});
|
|
36225
|
+
}
|
|
36226
|
+
const PDF_EMPHASIS_GLYPH = {
|
|
36227
|
+
dot: "•",
|
|
36228
|
+
comma: "‚",
|
|
36229
|
+
circle: "○",
|
|
36230
|
+
underDot: "•"
|
|
36231
|
+
};
|
|
36232
|
+
function drawFragmentEmphasis(writer, pageIndex, line, fragment, originX, originY, styles) {
|
|
36233
|
+
const mark = styles.emphasisMark;
|
|
36234
|
+
if (!mark || mark === "none") {
|
|
36235
|
+
return;
|
|
36236
|
+
}
|
|
36237
|
+
const glyph = PDF_EMPHASIS_GLYPH[mark];
|
|
36238
|
+
if (!glyph) {
|
|
36239
|
+
return;
|
|
36240
|
+
}
|
|
36241
|
+
const slots = resolveFragmentSlots(line, fragment);
|
|
36242
|
+
const below = mark === "underDot";
|
|
36243
|
+
const size = Math.max(4, line.height * 0.35);
|
|
36244
|
+
const y = below ? originY + line.top + line.height + size : originY + line.top + size;
|
|
36245
|
+
for (let i = 0; i < slots.length; i += 1) {
|
|
36246
|
+
const slot = slots[i];
|
|
36247
|
+
if (slot.char === " " || slot.char === " " || slot.char === "\n") {
|
|
36248
|
+
continue;
|
|
36249
|
+
}
|
|
36250
|
+
const next = slots[i + 1];
|
|
36251
|
+
const centerX = next ? (slot.left + next.left) / 2 : slot.left + line.height * 0.25;
|
|
36252
|
+
writer.drawText(pageIndex, {
|
|
36253
|
+
x: pxToPt$1(originX + centerX - size * 0.25),
|
|
36254
|
+
y: pxToPt$1(y),
|
|
36255
|
+
text: glyph,
|
|
36256
|
+
fontSize: pxToPt$1(size),
|
|
36257
|
+
color: styles.color ?? "#000000"
|
|
36258
|
+
});
|
|
36259
|
+
}
|
|
36260
|
+
}
|
|
36133
36261
|
function drawFragmentDecoration(writer, pageIndex, line, fragment, originX, originY, styles, kind) {
|
|
36134
36262
|
const bounds = resolveFragmentBounds(
|
|
36135
36263
|
line,
|
|
@@ -36410,6 +36538,15 @@ async function drawFragmentText(writer, pageIndex, paragraph, line, fragment, do
|
|
|
36410
36538
|
originY,
|
|
36411
36539
|
styles
|
|
36412
36540
|
);
|
|
36541
|
+
drawFragmentBorder(
|
|
36542
|
+
writer,
|
|
36543
|
+
pageIndex,
|
|
36544
|
+
line,
|
|
36545
|
+
fragment,
|
|
36546
|
+
originX,
|
|
36547
|
+
originY,
|
|
36548
|
+
styles
|
|
36549
|
+
);
|
|
36413
36550
|
drawTabLeaders(
|
|
36414
36551
|
writer,
|
|
36415
36552
|
pageIndex,
|
|
@@ -36422,42 +36559,50 @@ async function drawFragmentText(writer, pageIndex, paragraph, line, fragment, do
|
|
|
36422
36559
|
styles.color ?? "#000000"
|
|
36423
36560
|
);
|
|
36424
36561
|
const paragraphAlign = resolveEffectiveParagraphStyle(paragraph.style, document2.styles).align ?? "left";
|
|
36425
|
-
|
|
36426
|
-
|
|
36427
|
-
|
|
36428
|
-
|
|
36429
|
-
|
|
36562
|
+
const baseTextOptions = {
|
|
36563
|
+
fontSize: fontSizePt,
|
|
36564
|
+
bold: styles.bold,
|
|
36565
|
+
italic: styles.italic,
|
|
36566
|
+
fontResourceName: fontFace.writerResourceName,
|
|
36567
|
+
characterSpacing: styles.characterSpacing ?? 0,
|
|
36568
|
+
horizontalScale: styles.characterScale ?? 100
|
|
36569
|
+
};
|
|
36570
|
+
const mainColor = styles.color ?? "#000000";
|
|
36571
|
+
const offsetPt = pxToPt$1(1);
|
|
36572
|
+
const emitChunk = (leftPx, text2) => {
|
|
36573
|
+
if (styles.emboss || styles.imprint) {
|
|
36574
|
+
const dir = styles.imprint ? 1 : -1;
|
|
36430
36575
|
writer.drawText(pageIndex, {
|
|
36431
|
-
|
|
36432
|
-
|
|
36433
|
-
|
|
36434
|
-
|
|
36435
|
-
color:
|
|
36436
|
-
bold: styles.bold,
|
|
36437
|
-
italic: styles.italic,
|
|
36438
|
-
fontResourceName: fontFace.writerResourceName,
|
|
36439
|
-
characterSpacing: styles.characterSpacing ?? 0,
|
|
36440
|
-
horizontalScale: styles.characterScale ?? 100
|
|
36576
|
+
...baseTextOptions,
|
|
36577
|
+
x: pxToPt$1(leftPx) + offsetPt * dir,
|
|
36578
|
+
y: pxToPt$1(baselineY) + offsetPt * dir,
|
|
36579
|
+
text: text2,
|
|
36580
|
+
color: "#BFBFBF"
|
|
36441
36581
|
});
|
|
36442
36582
|
}
|
|
36443
|
-
|
|
36444
|
-
const chunks = groupSlotChunksByOffsetGaps(chars);
|
|
36445
|
-
for (const chunk of chunks) {
|
|
36446
|
-
const chunkText = chunk.map((c) => styles.allCaps ? c.char.toUpperCase() : c.char).join("");
|
|
36447
|
-
if (chunkText.length === 0) continue;
|
|
36583
|
+
if (styles.shadow) {
|
|
36448
36584
|
writer.drawText(pageIndex, {
|
|
36449
|
-
|
|
36450
|
-
|
|
36451
|
-
|
|
36452
|
-
|
|
36453
|
-
color:
|
|
36454
|
-
bold: styles.bold,
|
|
36455
|
-
italic: styles.italic,
|
|
36456
|
-
fontResourceName: fontFace.writerResourceName,
|
|
36457
|
-
characterSpacing: styles.characterSpacing ?? 0,
|
|
36458
|
-
horizontalScale: styles.characterScale ?? 100
|
|
36585
|
+
...baseTextOptions,
|
|
36586
|
+
x: pxToPt$1(leftPx) + offsetPt,
|
|
36587
|
+
y: pxToPt$1(baselineY) + offsetPt,
|
|
36588
|
+
text: text2,
|
|
36589
|
+
color: "#808080"
|
|
36459
36590
|
});
|
|
36460
36591
|
}
|
|
36592
|
+
writer.drawText(pageIndex, {
|
|
36593
|
+
...baseTextOptions,
|
|
36594
|
+
x: pxToPt$1(leftPx),
|
|
36595
|
+
y: pxToPt$1(baselineY),
|
|
36596
|
+
text: text2,
|
|
36597
|
+
color: mainColor,
|
|
36598
|
+
renderMode: styles.outline ? 1 : 0
|
|
36599
|
+
});
|
|
36600
|
+
};
|
|
36601
|
+
const chunks = paragraphAlign === "justify" ? groupSlotChunksByWhitespace(chars) : groupSlotChunksByOffsetGaps(chars);
|
|
36602
|
+
for (const chunk of chunks) {
|
|
36603
|
+
const chunkText = chunk.map((c) => styles.allCaps ? c.char.toUpperCase() : c.char).join("");
|
|
36604
|
+
if (chunkText.length === 0) continue;
|
|
36605
|
+
emitChunk(originX + chunk[0].left, chunkText);
|
|
36461
36606
|
}
|
|
36462
36607
|
if (styles.underline) {
|
|
36463
36608
|
drawFragmentDecoration(
|
|
@@ -36495,6 +36640,17 @@ async function drawFragmentText(writer, pageIndex, paragraph, line, fragment, do
|
|
|
36495
36640
|
"doubleStrike"
|
|
36496
36641
|
);
|
|
36497
36642
|
}
|
|
36643
|
+
if (styles.emphasisMark) {
|
|
36644
|
+
drawFragmentEmphasis(
|
|
36645
|
+
writer,
|
|
36646
|
+
pageIndex,
|
|
36647
|
+
line,
|
|
36648
|
+
fragment,
|
|
36649
|
+
originX,
|
|
36650
|
+
originY,
|
|
36651
|
+
styles
|
|
36652
|
+
);
|
|
36653
|
+
}
|
|
36498
36654
|
}
|
|
36499
36655
|
function getListOrdinals(document2) {
|
|
36500
36656
|
return buildListLabels(document2);
|
|
@@ -37066,227 +37222,6 @@ class PdfFontRegistry {
|
|
|
37066
37222
|
return matchedFamilies;
|
|
37067
37223
|
}
|
|
37068
37224
|
}
|
|
37069
|
-
class SimpleTextLayouter {
|
|
37070
|
-
constructor(font) {
|
|
37071
|
-
this.font = font;
|
|
37072
|
-
}
|
|
37073
|
-
layout(text) {
|
|
37074
|
-
const glyphs = [];
|
|
37075
|
-
const positions = [];
|
|
37076
|
-
let advanceWidth = 0;
|
|
37077
|
-
for (const char of text) {
|
|
37078
|
-
const codePoint = char.codePointAt(0) ?? 65533;
|
|
37079
|
-
const glyphId = this.font.glyphForCodePoint(codePoint);
|
|
37080
|
-
const glyphAdvance = this.font.advanceWidthForGlyph(glyphId);
|
|
37081
|
-
glyphs.push({
|
|
37082
|
-
id: glyphId,
|
|
37083
|
-
codePoints: glyphId === 0 ? [65533] : [codePoint],
|
|
37084
|
-
advanceWidth: glyphAdvance
|
|
37085
|
-
});
|
|
37086
|
-
positions.push({ xAdvance: glyphAdvance });
|
|
37087
|
-
advanceWidth += glyphAdvance;
|
|
37088
|
-
}
|
|
37089
|
-
return { glyphs, positions, advanceWidth };
|
|
37090
|
-
}
|
|
37091
|
-
}
|
|
37092
|
-
function view(bytes) {
|
|
37093
|
-
return new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
37094
|
-
}
|
|
37095
|
-
function u16(bytes, offset) {
|
|
37096
|
-
return view(bytes).getUint16(offset);
|
|
37097
|
-
}
|
|
37098
|
-
function i16(bytes, offset) {
|
|
37099
|
-
return view(bytes).getInt16(offset);
|
|
37100
|
-
}
|
|
37101
|
-
function writeU16(target, offset, value) {
|
|
37102
|
-
view(target).setUint16(offset, value, false);
|
|
37103
|
-
}
|
|
37104
|
-
function writeU32(target, offset, value) {
|
|
37105
|
-
view(target).setUint32(offset, value, false);
|
|
37106
|
-
}
|
|
37107
|
-
function pad4(length) {
|
|
37108
|
-
return length + 3 & -4;
|
|
37109
|
-
}
|
|
37110
|
-
function concat(chunks) {
|
|
37111
|
-
const total = chunks.reduce((sum, chunk) => sum + pad4(chunk.byteLength), 0);
|
|
37112
|
-
const result = new Uint8Array(total);
|
|
37113
|
-
let offset = 0;
|
|
37114
|
-
for (const chunk of chunks) {
|
|
37115
|
-
result.set(chunk, offset);
|
|
37116
|
-
offset += pad4(chunk.byteLength);
|
|
37117
|
-
}
|
|
37118
|
-
return result;
|
|
37119
|
-
}
|
|
37120
|
-
function readLoca(loca, indexToLocFormat) {
|
|
37121
|
-
const offsets = [];
|
|
37122
|
-
const table = view(loca);
|
|
37123
|
-
if (indexToLocFormat === 0) {
|
|
37124
|
-
for (let offset = 0; offset + 1 < loca.byteLength; offset += 2) {
|
|
37125
|
-
offsets.push(table.getUint16(offset) * 2);
|
|
37126
|
-
}
|
|
37127
|
-
} else {
|
|
37128
|
-
for (let offset = 0; offset + 3 < loca.byteLength; offset += 4) {
|
|
37129
|
-
offsets.push(table.getUint32(offset));
|
|
37130
|
-
}
|
|
37131
|
-
}
|
|
37132
|
-
return offsets;
|
|
37133
|
-
}
|
|
37134
|
-
function glyphRange(offsets, glyphId) {
|
|
37135
|
-
const start = offsets[glyphId];
|
|
37136
|
-
const end = offsets[glyphId + 1];
|
|
37137
|
-
return start === void 0 || end === void 0 ? null : { start, end };
|
|
37138
|
-
}
|
|
37139
|
-
function collectCompositeGlyphs(glyph, addGlyph) {
|
|
37140
|
-
if (glyph.byteLength < 10 || i16(glyph, 0) >= 0) {
|
|
37141
|
-
return;
|
|
37142
|
-
}
|
|
37143
|
-
let offset = 10;
|
|
37144
|
-
let flags = 0;
|
|
37145
|
-
do {
|
|
37146
|
-
if (offset + 4 > glyph.byteLength) return;
|
|
37147
|
-
flags = u16(glyph, offset);
|
|
37148
|
-
addGlyph(u16(glyph, offset + 2));
|
|
37149
|
-
offset += 4;
|
|
37150
|
-
offset += flags & 1 ? 4 : 2;
|
|
37151
|
-
if (flags & 8) offset += 2;
|
|
37152
|
-
else if (flags & 64) offset += 4;
|
|
37153
|
-
else if (flags & 128) offset += 8;
|
|
37154
|
-
} while (flags & 32);
|
|
37155
|
-
}
|
|
37156
|
-
function subsetClosure(font, initialGlyphs) {
|
|
37157
|
-
const glyf = font.getRawTableData("glyf");
|
|
37158
|
-
const loca = font.getRawTableData("loca");
|
|
37159
|
-
const head = font.getRawTableData("head");
|
|
37160
|
-
if (!glyf || !loca || !head) {
|
|
37161
|
-
return Array.from(/* @__PURE__ */ new Set([0, ...initialGlyphs])).sort((a, b) => a - b);
|
|
37162
|
-
}
|
|
37163
|
-
const offsets = readLoca(loca, u16(head, 50));
|
|
37164
|
-
const used = /* @__PURE__ */ new Set([0, ...initialGlyphs]);
|
|
37165
|
-
const stack = Array.from(used);
|
|
37166
|
-
while (stack.length > 0) {
|
|
37167
|
-
const glyphId = stack.pop();
|
|
37168
|
-
const range = glyphRange(offsets, glyphId);
|
|
37169
|
-
if (!range || range.end <= range.start || range.end > glyf.byteLength) {
|
|
37170
|
-
continue;
|
|
37171
|
-
}
|
|
37172
|
-
const glyph = glyf.slice(range.start, range.end);
|
|
37173
|
-
collectCompositeGlyphs(glyph, (componentId) => {
|
|
37174
|
-
if (!used.has(componentId)) {
|
|
37175
|
-
used.add(componentId);
|
|
37176
|
-
stack.push(componentId);
|
|
37177
|
-
}
|
|
37178
|
-
});
|
|
37179
|
-
}
|
|
37180
|
-
return Array.from(used).sort((a, b) => a - b);
|
|
37181
|
-
}
|
|
37182
|
-
function buildLoca(offsets) {
|
|
37183
|
-
const loca = new Uint8Array(offsets.length * 4);
|
|
37184
|
-
offsets.forEach((offset, index) => writeU32(loca, index * 4, offset));
|
|
37185
|
-
return loca;
|
|
37186
|
-
}
|
|
37187
|
-
function buildHmtx(font, maxGlyphId) {
|
|
37188
|
-
const hmtx = new Uint8Array((maxGlyphId + 1) * 4);
|
|
37189
|
-
for (let glyphId = 0; glyphId <= maxGlyphId; glyphId += 1) {
|
|
37190
|
-
writeU16(hmtx, glyphId * 4, font.advanceWidthForGlyph(glyphId));
|
|
37191
|
-
writeU16(hmtx, glyphId * 4 + 2, 0);
|
|
37192
|
-
}
|
|
37193
|
-
return hmtx;
|
|
37194
|
-
}
|
|
37195
|
-
function buildSubsetTables(font, glyphIds) {
|
|
37196
|
-
const glyf = font.getRawTableData("glyf");
|
|
37197
|
-
const loca = font.getRawTableData("loca");
|
|
37198
|
-
const head = font.getRawTableData("head");
|
|
37199
|
-
const hhea = font.getRawTableData("hhea");
|
|
37200
|
-
const maxp = font.getRawTableData("maxp");
|
|
37201
|
-
const cmap = font.getRawTableData("cmap");
|
|
37202
|
-
if (!glyf || !loca || !head || !hhea || !maxp || !cmap) {
|
|
37203
|
-
throw new Error("Missing required TrueType tables for subsetting");
|
|
37204
|
-
}
|
|
37205
|
-
const maxGlyphId = Math.max(0, ...glyphIds);
|
|
37206
|
-
const used = new Set(glyphIds);
|
|
37207
|
-
const sourceOffsets = readLoca(loca, u16(head, 50));
|
|
37208
|
-
const locaOffsets = [];
|
|
37209
|
-
const glyfChunks = [];
|
|
37210
|
-
let glyfOffset = 0;
|
|
37211
|
-
for (let glyphId = 0; glyphId <= maxGlyphId; glyphId += 1) {
|
|
37212
|
-
locaOffsets.push(glyfOffset);
|
|
37213
|
-
const range = glyphRange(sourceOffsets, glyphId);
|
|
37214
|
-
if (used.has(glyphId) && range && range.end > range.start) {
|
|
37215
|
-
const glyph = glyf.slice(range.start, range.end);
|
|
37216
|
-
glyfChunks.push(glyph);
|
|
37217
|
-
glyfOffset += pad4(glyph.byteLength);
|
|
37218
|
-
}
|
|
37219
|
-
}
|
|
37220
|
-
locaOffsets.push(glyfOffset);
|
|
37221
|
-
const newHead = head.slice();
|
|
37222
|
-
writeU32(newHead, 8, 0);
|
|
37223
|
-
writeU16(newHead, 50, 1);
|
|
37224
|
-
const newHhea = hhea.slice();
|
|
37225
|
-
writeU16(newHhea, 34, maxGlyphId + 1);
|
|
37226
|
-
const newMaxp = maxp.slice();
|
|
37227
|
-
writeU16(newMaxp, 4, maxGlyphId + 1);
|
|
37228
|
-
const tables = {
|
|
37229
|
-
cmap,
|
|
37230
|
-
head: newHead,
|
|
37231
|
-
hhea: newHhea,
|
|
37232
|
-
hmtx: buildHmtx(font, maxGlyphId),
|
|
37233
|
-
loca: buildLoca(locaOffsets),
|
|
37234
|
-
maxp: newMaxp,
|
|
37235
|
-
glyf: concat(glyfChunks)
|
|
37236
|
-
};
|
|
37237
|
-
for (const tag of ["OS/2", "name", "post"]) {
|
|
37238
|
-
const table = font.getRawTableData(tag);
|
|
37239
|
-
if (table) tables[tag] = table;
|
|
37240
|
-
}
|
|
37241
|
-
return tables;
|
|
37242
|
-
}
|
|
37243
|
-
class TrueTypePdfFontSubsetter {
|
|
37244
|
-
createSubset(font, glyphs) {
|
|
37245
|
-
const unicodeByGlyph = /* @__PURE__ */ new Map();
|
|
37246
|
-
const initialGlyphs = [];
|
|
37247
|
-
for (const glyph of glyphs) {
|
|
37248
|
-
initialGlyphs.push(glyph.id);
|
|
37249
|
-
if (!unicodeByGlyph.has(glyph.id)) {
|
|
37250
|
-
unicodeByGlyph.set(glyph.id, glyph.codePoints);
|
|
37251
|
-
}
|
|
37252
|
-
}
|
|
37253
|
-
const glyphIds = subsetClosure(font, initialGlyphs);
|
|
37254
|
-
const tables = buildSubsetTables(font, glyphIds);
|
|
37255
|
-
const fontFile = buildSfnt(
|
|
37256
|
-
65536,
|
|
37257
|
-
new Map(
|
|
37258
|
-
Object.entries(tables).map(([tag, data]) => [
|
|
37259
|
-
tag.charCodeAt(0) << 24 | tag.charCodeAt(1) << 16 | tag.charCodeAt(2) << 8 | tag.charCodeAt(3),
|
|
37260
|
-
data
|
|
37261
|
-
])
|
|
37262
|
-
)
|
|
37263
|
-
).ttf;
|
|
37264
|
-
const maxGlyphId = Math.max(0, ...glyphIds);
|
|
37265
|
-
const widths = [];
|
|
37266
|
-
const unicode = [];
|
|
37267
|
-
for (let glyphId = 0; glyphId <= maxGlyphId; glyphId += 1) {
|
|
37268
|
-
widths[glyphId] = font.advanceWidthForGlyph(glyphId) / font.unitsPerEm * 1e3;
|
|
37269
|
-
unicode[glyphId] = unicodeByGlyph.get(glyphId) ?? [0];
|
|
37270
|
-
}
|
|
37271
|
-
return {
|
|
37272
|
-
fontFile,
|
|
37273
|
-
widths,
|
|
37274
|
-
unicode,
|
|
37275
|
-
encodeGlyph: (glyphId) => glyphId
|
|
37276
|
-
};
|
|
37277
|
-
}
|
|
37278
|
-
}
|
|
37279
|
-
function parseEmbeddedFontSync(sourceBytes) {
|
|
37280
|
-
const sfntBytes = defaultFontDecoderRegistry.decodeSync(sourceBytes);
|
|
37281
|
-
return SfntFontProgram.parse(sfntBytes);
|
|
37282
|
-
}
|
|
37283
|
-
function createPdfEmbeddableFont(program) {
|
|
37284
|
-
return {
|
|
37285
|
-
program,
|
|
37286
|
-
layouter: new SimpleTextLayouter(program),
|
|
37287
|
-
subsetter: new TrueTypePdfFontSubsetter()
|
|
37288
|
-
};
|
|
37289
|
-
}
|
|
37290
37225
|
const PDF_HEADER = "%PDF-1.4\n% Oasis PDF\n";
|
|
37291
37226
|
const DEFAULT_PDF_FONT_RESOURCES = [
|
|
37292
37227
|
{ kind: "base14", resourceName: "F1", baseFont: "Helvetica" },
|
|
@@ -37480,53 +37415,15 @@ function textMarkerComment(value) {
|
|
|
37480
37415
|
);
|
|
37481
37416
|
return `% OasisText ${encodePdfUtf16Hex(codePoints)}`;
|
|
37482
37417
|
}
|
|
37483
|
-
class
|
|
37484
|
-
constructor(
|
|
37485
|
-
|
|
37486
|
-
|
|
37487
|
-
|
|
37488
|
-
__publicField(this, "usedFontResourceNames", /* @__PURE__ */ new Set());
|
|
37489
|
-
__publicField(this, "imageResources", /* @__PURE__ */ new Map());
|
|
37490
|
-
for (const resource of fontResources) {
|
|
37491
|
-
this.registerFontResource(resource);
|
|
37492
|
-
}
|
|
37493
|
-
}
|
|
37494
|
-
registerFontResource(resource) {
|
|
37495
|
-
this.fontResources.set(resource.resourceName, resource);
|
|
37496
|
-
if (resource.kind === "unicode" && !this.unicodeFontStates.has(resource.resourceName)) {
|
|
37497
|
-
const font = createPdfEmbeddableFont(
|
|
37498
|
-
parseEmbeddedFontSync(resource.fontData)
|
|
37499
|
-
);
|
|
37500
|
-
const scale = 1e3 / font.program.unitsPerEm;
|
|
37501
|
-
const notdef = {
|
|
37502
|
-
id: 0,
|
|
37503
|
-
codePoints: [0],
|
|
37504
|
-
advanceWidth: font.program.advanceWidthForGlyph(0)
|
|
37505
|
-
};
|
|
37506
|
-
this.unicodeFontStates.set(resource.resourceName, {
|
|
37507
|
-
resource,
|
|
37508
|
-
font,
|
|
37509
|
-
usedGlyphs: /* @__PURE__ */ new Map([[0, notdef]]),
|
|
37510
|
-
scale,
|
|
37511
|
-
layoutCache: /* @__PURE__ */ new Map()
|
|
37512
|
-
});
|
|
37513
|
-
}
|
|
37418
|
+
class PdfContentStream {
|
|
37419
|
+
constructor(page, fonts, images) {
|
|
37420
|
+
this.page = page;
|
|
37421
|
+
this.fonts = fonts;
|
|
37422
|
+
this.images = images;
|
|
37514
37423
|
}
|
|
37515
|
-
|
|
37516
|
-
this.
|
|
37517
|
-
|
|
37518
|
-
height: Math.max(1, size.height),
|
|
37519
|
-
commands: [],
|
|
37520
|
-
imageResourceNames: /* @__PURE__ */ new Set()
|
|
37521
|
-
});
|
|
37522
|
-
return this.pages.length - 1;
|
|
37523
|
-
}
|
|
37524
|
-
getPageCount() {
|
|
37525
|
-
return this.pages.length;
|
|
37526
|
-
}
|
|
37527
|
-
drawRect(pageIndex, options) {
|
|
37528
|
-
const page = this.pages[pageIndex];
|
|
37529
|
-
if (!page || options.width <= 0 || options.height <= 0) {
|
|
37424
|
+
drawRect(options) {
|
|
37425
|
+
const page = this.page;
|
|
37426
|
+
if (options.width <= 0 || options.height <= 0) {
|
|
37530
37427
|
return;
|
|
37531
37428
|
}
|
|
37532
37429
|
const commands = ["q"];
|
|
@@ -37556,11 +37453,8 @@ class OasisPdfWriter {
|
|
|
37556
37453
|
commands.push("Q");
|
|
37557
37454
|
page.commands.push(commands.join("\n"));
|
|
37558
37455
|
}
|
|
37559
|
-
drawLine(
|
|
37560
|
-
const page = this.
|
|
37561
|
-
if (!page) {
|
|
37562
|
-
return;
|
|
37563
|
-
}
|
|
37456
|
+
drawLine(options) {
|
|
37457
|
+
const page = this.page;
|
|
37564
37458
|
const dashCommand = options.dashArray && options.dashArray.length > 0 ? `[${options.dashArray.map((value) => formatNumber(value)).join(" ")}] 0 d` : null;
|
|
37565
37459
|
const commands = [
|
|
37566
37460
|
"q",
|
|
@@ -37581,9 +37475,9 @@ class OasisPdfWriter {
|
|
|
37581
37475
|
// Fills/strokes an arbitrary path. Segment coordinates are in points with a
|
|
37582
37476
|
// top-left origin (callers convert px→pt, like drawRect/drawLine); the y axis
|
|
37583
37477
|
// is flipped here to the PDF bottom-left origin.
|
|
37584
|
-
drawPath(
|
|
37585
|
-
const page = this.
|
|
37586
|
-
if (
|
|
37478
|
+
drawPath(options) {
|
|
37479
|
+
const page = this.page;
|
|
37480
|
+
if (options.segments.length === 0) {
|
|
37587
37481
|
return;
|
|
37588
37482
|
}
|
|
37589
37483
|
if (!options.fill && !options.stroke) {
|
|
@@ -37632,24 +37526,18 @@ class OasisPdfWriter {
|
|
|
37632
37526
|
}
|
|
37633
37527
|
// Saves the graphics state (`q`). Pair with restoreGraphicsState. Any draw
|
|
37634
37528
|
// commands emitted in between inherit the current transform/clip.
|
|
37635
|
-
saveGraphicsState(
|
|
37636
|
-
|
|
37637
|
-
if (page) {
|
|
37638
|
-
page.commands.push("q");
|
|
37639
|
-
}
|
|
37529
|
+
saveGraphicsState() {
|
|
37530
|
+
this.page.commands.push("q");
|
|
37640
37531
|
}
|
|
37641
|
-
restoreGraphicsState(
|
|
37642
|
-
|
|
37643
|
-
if (page) {
|
|
37644
|
-
page.commands.push("Q");
|
|
37645
|
-
}
|
|
37532
|
+
restoreGraphicsState() {
|
|
37533
|
+
this.page.commands.push("Q");
|
|
37646
37534
|
}
|
|
37647
37535
|
// Concatenates a clockwise rotation (in degrees, matching the canvas/editor
|
|
37648
37536
|
// convention) about a top-left-origin point onto the current CTM. Must sit
|
|
37649
37537
|
// inside a saveGraphicsState/restoreGraphicsState pair.
|
|
37650
|
-
rotateAbout(
|
|
37651
|
-
const page = this.
|
|
37652
|
-
if (!
|
|
37538
|
+
rotateAbout(centerX, centerY, degrees) {
|
|
37539
|
+
const page = this.page;
|
|
37540
|
+
if (!degrees) {
|
|
37653
37541
|
return;
|
|
37654
37542
|
}
|
|
37655
37543
|
const cyf = page.height - centerY;
|
|
@@ -37664,9 +37552,9 @@ class OasisPdfWriter {
|
|
|
37664
37552
|
}
|
|
37665
37553
|
// Intersects the clip path with a rectangle (top-left origin). Must sit inside
|
|
37666
37554
|
// a saveGraphicsState/restoreGraphicsState pair so the clip can be undone.
|
|
37667
|
-
clipRect(
|
|
37668
|
-
const page = this.
|
|
37669
|
-
if (
|
|
37555
|
+
clipRect(x, y, width, height) {
|
|
37556
|
+
const page = this.page;
|
|
37557
|
+
if (width <= 0 || height <= 0) {
|
|
37670
37558
|
return;
|
|
37671
37559
|
}
|
|
37672
37560
|
page.commands.push(
|
|
@@ -37675,48 +37563,42 @@ class OasisPdfWriter {
|
|
|
37675
37563
|
"n"
|
|
37676
37564
|
);
|
|
37677
37565
|
}
|
|
37678
|
-
drawText(
|
|
37679
|
-
|
|
37680
|
-
if (!page || options.text.length === 0) {
|
|
37566
|
+
drawText(options) {
|
|
37567
|
+
if (options.text.length === 0) {
|
|
37681
37568
|
return;
|
|
37682
37569
|
}
|
|
37683
|
-
const fontResourceName =
|
|
37684
|
-
this.
|
|
37685
|
-
const
|
|
37686
|
-
if (
|
|
37687
|
-
this.drawUnicodeText(page, unicodeFont, options);
|
|
37570
|
+
const fontResourceName = this.fonts.resolveAndMarkFontName(options);
|
|
37571
|
+
const unicodeState = this.fonts.getUnicodeState(fontResourceName);
|
|
37572
|
+
const showCommand = unicodeState ? this.fonts.buildUnicodeShowCommand(unicodeState, options.text) : `<${encodePdfHexString(options.text)}> Tj`;
|
|
37573
|
+
if (showCommand === null) {
|
|
37688
37574
|
return;
|
|
37689
37575
|
}
|
|
37576
|
+
this.emitTextBlock(fontResourceName, showCommand, options);
|
|
37577
|
+
}
|
|
37578
|
+
emitTextBlock(fontResourceName, showCommand, options) {
|
|
37579
|
+
const page = this.page;
|
|
37690
37580
|
page.commands.push(
|
|
37691
37581
|
[
|
|
37692
37582
|
textMarkerComment(options.text),
|
|
37693
37583
|
"BT",
|
|
37694
37584
|
colorCommand(options.color, "rg", [0, 0, 0]),
|
|
37695
37585
|
`/${fontResourceName} ${formatNumber(options.fontSize ?? 12)} Tf`,
|
|
37586
|
+
...options.renderMode && options.renderMode !== 0 ? [
|
|
37587
|
+
colorCommand(options.color, "RG", [0, 0, 0]),
|
|
37588
|
+
`${formatNumber(Math.max(0.3, (options.fontSize ?? 12) * 0.03))} w`,
|
|
37589
|
+
`${options.renderMode} Tr`
|
|
37590
|
+
] : [],
|
|
37696
37591
|
...options.horizontalScale && options.horizontalScale > 0 && options.horizontalScale !== 100 ? [`${formatNumber(options.horizontalScale)} Tz`] : [],
|
|
37697
37592
|
...options.characterSpacing && options.characterSpacing !== 0 ? [`${formatNumber(options.characterSpacing)} Tc`] : [],
|
|
37698
37593
|
`${formatNumber(options.x)} ${formatNumber(page.height - options.y)} Td`,
|
|
37699
|
-
|
|
37594
|
+
showCommand,
|
|
37700
37595
|
"ET"
|
|
37701
37596
|
].join("\n")
|
|
37702
37597
|
);
|
|
37703
37598
|
}
|
|
37704
|
-
|
|
37705
|
-
const
|
|
37706
|
-
if (!this.
|
|
37707
|
-
this.imageResources.set(resourceName, {
|
|
37708
|
-
resourceName,
|
|
37709
|
-
width: Math.max(1, Math.round(resource.width)),
|
|
37710
|
-
height: Math.max(1, Math.round(resource.height)),
|
|
37711
|
-
data: resource.data,
|
|
37712
|
-
filter: resource.filter
|
|
37713
|
-
});
|
|
37714
|
-
}
|
|
37715
|
-
return resourceName;
|
|
37716
|
-
}
|
|
37717
|
-
drawImage(pageIndex, options) {
|
|
37718
|
-
const page = this.pages[pageIndex];
|
|
37719
|
-
if (!page || options.width <= 0 || options.height <= 0 || !this.imageResources.has(options.resourceName)) {
|
|
37599
|
+
drawImage(options) {
|
|
37600
|
+
const page = this.page;
|
|
37601
|
+
if (options.width <= 0 || options.height <= 0 || !this.images.has(options.resourceName)) {
|
|
37720
37602
|
return;
|
|
37721
37603
|
}
|
|
37722
37604
|
page.imageResourceNames.add(options.resourceName);
|
|
@@ -37767,72 +37649,292 @@ class OasisPdfWriter {
|
|
|
37767
37649
|
].join("\n")
|
|
37768
37650
|
);
|
|
37769
37651
|
}
|
|
37770
|
-
|
|
37771
|
-
|
|
37772
|
-
|
|
37773
|
-
|
|
37652
|
+
}
|
|
37653
|
+
class SimpleTextLayouter {
|
|
37654
|
+
constructor(font) {
|
|
37655
|
+
this.font = font;
|
|
37656
|
+
}
|
|
37657
|
+
layout(text) {
|
|
37658
|
+
const glyphs = [];
|
|
37659
|
+
const positions = [];
|
|
37660
|
+
let advanceWidth = 0;
|
|
37661
|
+
for (const char of text) {
|
|
37662
|
+
const codePoint = char.codePointAt(0) ?? 65533;
|
|
37663
|
+
const glyphId = this.font.glyphForCodePoint(codePoint);
|
|
37664
|
+
const glyphAdvance = this.font.advanceWidthForGlyph(glyphId);
|
|
37665
|
+
glyphs.push({
|
|
37666
|
+
id: glyphId,
|
|
37667
|
+
codePoints: glyphId === 0 ? [65533] : [codePoint],
|
|
37668
|
+
advanceWidth: glyphAdvance
|
|
37669
|
+
});
|
|
37670
|
+
positions.push({ xAdvance: glyphAdvance });
|
|
37671
|
+
advanceWidth += glyphAdvance;
|
|
37774
37672
|
}
|
|
37775
|
-
|
|
37776
|
-
state.layoutCache.set(text, run);
|
|
37777
|
-
return run;
|
|
37673
|
+
return { glyphs, positions, advanceWidth };
|
|
37778
37674
|
}
|
|
37779
|
-
|
|
37780
|
-
|
|
37781
|
-
|
|
37782
|
-
|
|
37675
|
+
}
|
|
37676
|
+
function view(bytes) {
|
|
37677
|
+
return new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
37678
|
+
}
|
|
37679
|
+
function u16(bytes, offset) {
|
|
37680
|
+
return view(bytes).getUint16(offset);
|
|
37681
|
+
}
|
|
37682
|
+
function i16(bytes, offset) {
|
|
37683
|
+
return view(bytes).getInt16(offset);
|
|
37684
|
+
}
|
|
37685
|
+
function writeU16(target, offset, value) {
|
|
37686
|
+
view(target).setUint16(offset, value, false);
|
|
37687
|
+
}
|
|
37688
|
+
function writeU32(target, offset, value) {
|
|
37689
|
+
view(target).setUint32(offset, value, false);
|
|
37690
|
+
}
|
|
37691
|
+
function pad4(length) {
|
|
37692
|
+
return length + 3 & -4;
|
|
37693
|
+
}
|
|
37694
|
+
function concat(chunks) {
|
|
37695
|
+
const total = chunks.reduce((sum, chunk) => sum + pad4(chunk.byteLength), 0);
|
|
37696
|
+
const result = new Uint8Array(total);
|
|
37697
|
+
let offset = 0;
|
|
37698
|
+
for (const chunk of chunks) {
|
|
37699
|
+
result.set(chunk, offset);
|
|
37700
|
+
offset += pad4(chunk.byteLength);
|
|
37701
|
+
}
|
|
37702
|
+
return result;
|
|
37703
|
+
}
|
|
37704
|
+
function readLoca(loca, indexToLocFormat) {
|
|
37705
|
+
const offsets = [];
|
|
37706
|
+
const table = view(loca);
|
|
37707
|
+
if (indexToLocFormat === 0) {
|
|
37708
|
+
for (let offset = 0; offset + 1 < loca.byteLength; offset += 2) {
|
|
37709
|
+
offsets.push(table.getUint16(offset) * 2);
|
|
37710
|
+
}
|
|
37711
|
+
} else {
|
|
37712
|
+
for (let offset = 0; offset + 3 < loca.byteLength; offset += 4) {
|
|
37713
|
+
offsets.push(table.getUint32(offset));
|
|
37714
|
+
}
|
|
37715
|
+
}
|
|
37716
|
+
return offsets;
|
|
37717
|
+
}
|
|
37718
|
+
function glyphRange(offsets, glyphId) {
|
|
37719
|
+
const start = offsets[glyphId];
|
|
37720
|
+
const end = offsets[glyphId + 1];
|
|
37721
|
+
return start === void 0 || end === void 0 ? null : { start, end };
|
|
37722
|
+
}
|
|
37723
|
+
function collectCompositeGlyphs(glyph, addGlyph) {
|
|
37724
|
+
if (glyph.byteLength < 10 || i16(glyph, 0) >= 0) {
|
|
37725
|
+
return;
|
|
37726
|
+
}
|
|
37727
|
+
let offset = 10;
|
|
37728
|
+
let flags = 0;
|
|
37729
|
+
do {
|
|
37730
|
+
if (offset + 4 > glyph.byteLength) return;
|
|
37731
|
+
flags = u16(glyph, offset);
|
|
37732
|
+
addGlyph(u16(glyph, offset + 2));
|
|
37733
|
+
offset += 4;
|
|
37734
|
+
offset += flags & 1 ? 4 : 2;
|
|
37735
|
+
if (flags & 8) offset += 2;
|
|
37736
|
+
else if (flags & 64) offset += 4;
|
|
37737
|
+
else if (flags & 128) offset += 8;
|
|
37738
|
+
} while (flags & 32);
|
|
37739
|
+
}
|
|
37740
|
+
function subsetClosure(font, initialGlyphs) {
|
|
37741
|
+
const glyf = font.getRawTableData("glyf");
|
|
37742
|
+
const loca = font.getRawTableData("loca");
|
|
37743
|
+
const head = font.getRawTableData("head");
|
|
37744
|
+
if (!glyf || !loca || !head) {
|
|
37745
|
+
return Array.from(/* @__PURE__ */ new Set([0, ...initialGlyphs])).sort((a, b) => a - b);
|
|
37746
|
+
}
|
|
37747
|
+
const offsets = readLoca(loca, u16(head, 50));
|
|
37748
|
+
const used = /* @__PURE__ */ new Set([0, ...initialGlyphs]);
|
|
37749
|
+
const stack = Array.from(used);
|
|
37750
|
+
while (stack.length > 0) {
|
|
37751
|
+
const glyphId = stack.pop();
|
|
37752
|
+
const range = glyphRange(offsets, glyphId);
|
|
37753
|
+
if (!range || range.end <= range.start || range.end > glyf.byteLength) {
|
|
37754
|
+
continue;
|
|
37755
|
+
}
|
|
37756
|
+
const glyph = glyf.slice(range.start, range.end);
|
|
37757
|
+
collectCompositeGlyphs(glyph, (componentId) => {
|
|
37758
|
+
if (!used.has(componentId)) {
|
|
37759
|
+
used.add(componentId);
|
|
37760
|
+
stack.push(componentId);
|
|
37783
37761
|
}
|
|
37784
|
-
const position = run.positions[index];
|
|
37785
|
-
const nominalWidth = glyph.advanceWidth * state.scale;
|
|
37786
|
-
const desiredAdvance = ((position == null ? void 0 : position.xAdvance) ?? glyph.advanceWidth) * state.scale;
|
|
37787
|
-
return { glyphId: glyph.id, nominalWidth, desiredAdvance };
|
|
37788
37762
|
});
|
|
37789
37763
|
}
|
|
37790
|
-
|
|
37791
|
-
|
|
37764
|
+
return Array.from(used).sort((a, b) => a - b);
|
|
37765
|
+
}
|
|
37766
|
+
function buildLoca(offsets) {
|
|
37767
|
+
const loca = new Uint8Array(offsets.length * 4);
|
|
37768
|
+
offsets.forEach((offset, index) => writeU32(loca, index * 4, offset));
|
|
37769
|
+
return loca;
|
|
37770
|
+
}
|
|
37771
|
+
function buildHmtx(font, maxGlyphId) {
|
|
37772
|
+
const hmtx = new Uint8Array((maxGlyphId + 1) * 4);
|
|
37773
|
+
for (let glyphId = 0; glyphId <= maxGlyphId; glyphId += 1) {
|
|
37774
|
+
writeU16(hmtx, glyphId * 4, font.advanceWidthForGlyph(glyphId));
|
|
37775
|
+
writeU16(hmtx, glyphId * 4 + 2, 0);
|
|
37776
|
+
}
|
|
37777
|
+
return hmtx;
|
|
37778
|
+
}
|
|
37779
|
+
function buildSubsetTables(font, glyphIds) {
|
|
37780
|
+
const glyf = font.getRawTableData("glyf");
|
|
37781
|
+
const loca = font.getRawTableData("loca");
|
|
37782
|
+
const head = font.getRawTableData("head");
|
|
37783
|
+
const hhea = font.getRawTableData("hhea");
|
|
37784
|
+
const maxp = font.getRawTableData("maxp");
|
|
37785
|
+
const cmap = font.getRawTableData("cmap");
|
|
37786
|
+
if (!glyf || !loca || !head || !hhea || !maxp || !cmap) {
|
|
37787
|
+
throw new Error("Missing required TrueType tables for subsetting");
|
|
37788
|
+
}
|
|
37789
|
+
const maxGlyphId = Math.max(0, ...glyphIds);
|
|
37790
|
+
const used = new Set(glyphIds);
|
|
37791
|
+
const sourceOffsets = readLoca(loca, u16(head, 50));
|
|
37792
|
+
const locaOffsets = [];
|
|
37793
|
+
const glyfChunks = [];
|
|
37794
|
+
let glyfOffset = 0;
|
|
37795
|
+
for (let glyphId = 0; glyphId <= maxGlyphId; glyphId += 1) {
|
|
37796
|
+
locaOffsets.push(glyfOffset);
|
|
37797
|
+
const range = glyphRange(sourceOffsets, glyphId);
|
|
37798
|
+
if (used.has(glyphId) && range && range.end > range.start) {
|
|
37799
|
+
const glyph = glyf.slice(range.start, range.end);
|
|
37800
|
+
glyfChunks.push(glyph);
|
|
37801
|
+
glyfOffset += pad4(glyph.byteLength);
|
|
37802
|
+
}
|
|
37803
|
+
}
|
|
37804
|
+
locaOffsets.push(glyfOffset);
|
|
37805
|
+
const newHead = head.slice();
|
|
37806
|
+
writeU32(newHead, 8, 0);
|
|
37807
|
+
writeU16(newHead, 50, 1);
|
|
37808
|
+
const newHhea = hhea.slice();
|
|
37809
|
+
writeU16(newHhea, 34, maxGlyphId + 1);
|
|
37810
|
+
const newMaxp = maxp.slice();
|
|
37811
|
+
writeU16(newMaxp, 4, maxGlyphId + 1);
|
|
37812
|
+
const tables = {
|
|
37813
|
+
cmap,
|
|
37814
|
+
head: newHead,
|
|
37815
|
+
hhea: newHhea,
|
|
37816
|
+
hmtx: buildHmtx(font, maxGlyphId),
|
|
37817
|
+
loca: buildLoca(locaOffsets),
|
|
37818
|
+
maxp: newMaxp,
|
|
37819
|
+
glyf: concat(glyfChunks)
|
|
37820
|
+
};
|
|
37821
|
+
for (const tag of ["OS/2", "name", "post"]) {
|
|
37822
|
+
const table = font.getRawTableData(tag);
|
|
37823
|
+
if (table) tables[tag] = table;
|
|
37824
|
+
}
|
|
37825
|
+
return tables;
|
|
37826
|
+
}
|
|
37827
|
+
class TrueTypePdfFontSubsetter {
|
|
37828
|
+
createSubset(font, glyphs) {
|
|
37829
|
+
const unicodeByGlyph = /* @__PURE__ */ new Map();
|
|
37830
|
+
const initialGlyphs = [];
|
|
37831
|
+
for (const glyph of glyphs) {
|
|
37832
|
+
initialGlyphs.push(glyph.id);
|
|
37833
|
+
if (!unicodeByGlyph.has(glyph.id)) {
|
|
37834
|
+
unicodeByGlyph.set(glyph.id, glyph.codePoints);
|
|
37835
|
+
}
|
|
37836
|
+
}
|
|
37837
|
+
const glyphIds = subsetClosure(font, initialGlyphs);
|
|
37838
|
+
const tables = buildSubsetTables(font, glyphIds);
|
|
37839
|
+
const fontFile = buildSfnt(
|
|
37840
|
+
65536,
|
|
37841
|
+
new Map(
|
|
37842
|
+
Object.entries(tables).map(([tag, data]) => [
|
|
37843
|
+
tag.charCodeAt(0) << 24 | tag.charCodeAt(1) << 16 | tag.charCodeAt(2) << 8 | tag.charCodeAt(3),
|
|
37844
|
+
data
|
|
37845
|
+
])
|
|
37846
|
+
)
|
|
37847
|
+
).ttf;
|
|
37848
|
+
const maxGlyphId = Math.max(0, ...glyphIds);
|
|
37849
|
+
const widths = [];
|
|
37850
|
+
const unicode = [];
|
|
37851
|
+
for (let glyphId = 0; glyphId <= maxGlyphId; glyphId += 1) {
|
|
37852
|
+
widths[glyphId] = font.advanceWidthForGlyph(glyphId) / font.unitsPerEm * 1e3;
|
|
37853
|
+
unicode[glyphId] = unicodeByGlyph.get(glyphId) ?? [0];
|
|
37854
|
+
}
|
|
37855
|
+
return {
|
|
37856
|
+
fontFile,
|
|
37857
|
+
widths,
|
|
37858
|
+
unicode,
|
|
37859
|
+
encodeGlyph: (glyphId) => glyphId
|
|
37860
|
+
};
|
|
37861
|
+
}
|
|
37862
|
+
}
|
|
37863
|
+
function parseEmbeddedFontSync(sourceBytes) {
|
|
37864
|
+
const sfntBytes = defaultFontDecoderRegistry.decodeSync(sourceBytes);
|
|
37865
|
+
return SfntFontProgram.parse(sfntBytes);
|
|
37866
|
+
}
|
|
37867
|
+
function createPdfEmbeddableFont(program) {
|
|
37868
|
+
return {
|
|
37869
|
+
program,
|
|
37870
|
+
layouter: new SimpleTextLayouter(program),
|
|
37871
|
+
subsetter: new TrueTypePdfFontSubsetter()
|
|
37872
|
+
};
|
|
37873
|
+
}
|
|
37874
|
+
class PdfFontTable {
|
|
37875
|
+
constructor(fontResources) {
|
|
37876
|
+
__publicField(this, "fontResources", /* @__PURE__ */ new Map());
|
|
37877
|
+
__publicField(this, "unicodeFontStates", /* @__PURE__ */ new Map());
|
|
37878
|
+
__publicField(this, "usedFontResourceNames", /* @__PURE__ */ new Set());
|
|
37879
|
+
for (const resource of fontResources) {
|
|
37880
|
+
this.registerFontResource(resource);
|
|
37881
|
+
}
|
|
37882
|
+
}
|
|
37883
|
+
registerFontResource(resource) {
|
|
37884
|
+
this.fontResources.set(resource.resourceName, resource);
|
|
37885
|
+
if (resource.kind === "unicode" && !this.unicodeFontStates.has(resource.resourceName)) {
|
|
37886
|
+
const font = createPdfEmbeddableFont(
|
|
37887
|
+
parseEmbeddedFontSync(resource.fontData)
|
|
37888
|
+
);
|
|
37889
|
+
const scale = 1e3 / font.program.unitsPerEm;
|
|
37890
|
+
const notdef = {
|
|
37891
|
+
id: 0,
|
|
37892
|
+
codePoints: [0],
|
|
37893
|
+
advanceWidth: font.program.advanceWidthForGlyph(0)
|
|
37894
|
+
};
|
|
37895
|
+
this.unicodeFontStates.set(resource.resourceName, {
|
|
37896
|
+
resource,
|
|
37897
|
+
font,
|
|
37898
|
+
usedGlyphs: /* @__PURE__ */ new Map([[0, notdef]]),
|
|
37899
|
+
scale,
|
|
37900
|
+
layoutCache: /* @__PURE__ */ new Map()
|
|
37901
|
+
});
|
|
37902
|
+
}
|
|
37903
|
+
}
|
|
37904
|
+
/** Resolves the font resource a run uses and marks it as referenced. */
|
|
37905
|
+
resolveAndMarkFontName(options) {
|
|
37906
|
+
const fontResourceName = resolveFontName(options);
|
|
37907
|
+
this.usedFontResourceNames.add(fontResourceName);
|
|
37908
|
+
return fontResourceName;
|
|
37909
|
+
}
|
|
37910
|
+
getUnicodeState(resourceName) {
|
|
37911
|
+
return this.unicodeFontStates.get(resourceName);
|
|
37912
|
+
}
|
|
37913
|
+
/**
|
|
37914
|
+
* Builds the glyph-show operator (`<...> Tj` or `[...] TJ`) for an embedded
|
|
37915
|
+
* Unicode run, recording the glyphs used for subsetting. Returns `null` when
|
|
37916
|
+
* the run produced no glyphs so the caller can skip emission entirely.
|
|
37917
|
+
*/
|
|
37918
|
+
buildUnicodeShowCommand(state, text) {
|
|
37919
|
+
const run = this.layoutUnicodeText(state, text);
|
|
37792
37920
|
const encoded = this.encodeUnicodeGlyphRun(state, run);
|
|
37793
37921
|
if (encoded.length === 0) {
|
|
37794
|
-
return;
|
|
37922
|
+
return null;
|
|
37795
37923
|
}
|
|
37796
37924
|
const usesAdjustments = encoded.some(
|
|
37797
37925
|
(glyph) => Math.abs(glyph.nominalWidth - glyph.desiredAdvance) > 0.01
|
|
37798
37926
|
);
|
|
37799
|
-
|
|
37927
|
+
return usesAdjustments ? `[${encoded.map((glyph) => {
|
|
37800
37928
|
const adjustment = glyph.nominalWidth - glyph.desiredAdvance;
|
|
37801
37929
|
return adjustment === 0 ? `<${encodeGlyphHex(glyph.glyphId)}>` : `<${encodeGlyphHex(glyph.glyphId)}> ${formatNumber(adjustment)}`;
|
|
37802
37930
|
}).join(" ")}] TJ` : `<${encoded.map((glyph) => encodeGlyphHex(glyph.glyphId)).join("")}> Tj`;
|
|
37803
|
-
page.commands.push(
|
|
37804
|
-
[
|
|
37805
|
-
textMarkerComment(options.text),
|
|
37806
|
-
"BT",
|
|
37807
|
-
colorCommand(options.color, "rg", [0, 0, 0]),
|
|
37808
|
-
`/${state.resource.resourceName} ${formatNumber(options.fontSize ?? 12)} Tf`,
|
|
37809
|
-
...options.horizontalScale && options.horizontalScale > 0 && options.horizontalScale !== 100 ? [`${formatNumber(options.horizontalScale)} Tz`] : [],
|
|
37810
|
-
...options.characterSpacing && options.characterSpacing !== 0 ? [`${formatNumber(options.characterSpacing)} Tc`] : [],
|
|
37811
|
-
`${formatNumber(options.x)} ${formatNumber(page.height - options.y)} Td`,
|
|
37812
|
-
textCommand,
|
|
37813
|
-
"ET"
|
|
37814
|
-
].join("\n")
|
|
37815
|
-
);
|
|
37816
|
-
}
|
|
37817
|
-
toArrayBuffer() {
|
|
37818
|
-
const bytes = this.toUint8Array();
|
|
37819
|
-
return Uint8Array.from(bytes).buffer;
|
|
37820
|
-
}
|
|
37821
|
-
toBlob() {
|
|
37822
|
-
return new Blob([this.toArrayBuffer()], { type: "application/pdf" });
|
|
37823
37931
|
}
|
|
37824
|
-
|
|
37825
|
-
|
|
37826
|
-
|
|
37827
|
-
|
|
37828
|
-
|
|
37829
|
-
|
|
37830
|
-
const id = objects.length + 1;
|
|
37831
|
-
objects.push({ id, body: body2 });
|
|
37832
|
-
return id;
|
|
37833
|
-
};
|
|
37834
|
-
const catalogObjectId = addObject("");
|
|
37835
|
-
const pagesObjectId = addObject("");
|
|
37932
|
+
/**
|
|
37933
|
+
* Emits the font objects (base-14 dictionaries and embedded Unicode font
|
|
37934
|
+
* programs) for every referenced resource and returns the `/Font` resource
|
|
37935
|
+
* dictionary XML for page objects.
|
|
37936
|
+
*/
|
|
37937
|
+
buildFontObjects(addObject) {
|
|
37836
37938
|
const fontResourceEntries = Array.from(this.fontResources.values()).filter(
|
|
37837
37939
|
(resource) => resource.kind === "base14" || this.usedFontResourceNames.has(resource.resourceName)
|
|
37838
37940
|
);
|
|
@@ -37845,86 +37947,28 @@ class OasisPdfWriter {
|
|
|
37845
37947
|
}
|
|
37846
37948
|
return addObject(fontResourceObjectBody(font));
|
|
37847
37949
|
});
|
|
37848
|
-
const
|
|
37849
|
-
|
|
37850
|
-
|
|
37851
|
-
|
|
37852
|
-
|
|
37853
|
-
|
|
37854
|
-
|
|
37855
|
-
}
|
|
37856
|
-
const pageObjectIds = [];
|
|
37857
|
-
for (const page of this.pages) {
|
|
37858
|
-
const stream = `${page.commands.join("\n")}
|
|
37859
|
-
`;
|
|
37860
|
-
const contentObjectId = addObject(
|
|
37861
|
-
`<< /Length ${byteLength(stream)} >>
|
|
37862
|
-
stream
|
|
37863
|
-
${stream}endstream`
|
|
37864
|
-
);
|
|
37865
|
-
const imageResourceXml = Array.from(page.imageResourceNames).map((resourceName) => {
|
|
37866
|
-
const objectId = imageObjectIds.get(resourceName);
|
|
37867
|
-
return objectId ? `/${resourceName} ${objectId} 0 R` : "";
|
|
37868
|
-
}).filter(Boolean).join(" ");
|
|
37869
|
-
const xObjectResourceXml = imageResourceXml ? ` /XObject << ${imageResourceXml} >>` : "";
|
|
37870
|
-
const pageObjectId = addObject(
|
|
37871
|
-
[
|
|
37872
|
-
"<< /Type /Page",
|
|
37873
|
-
`/Parent ${pagesObjectId} 0 R`,
|
|
37874
|
-
`/MediaBox [0 0 ${formatNumber(page.width)} ${formatNumber(page.height)}]`,
|
|
37875
|
-
`/Resources << /Font << ${fontResourceXml} >>${xObjectResourceXml} >>`,
|
|
37876
|
-
`/Contents ${contentObjectId} 0 R`,
|
|
37877
|
-
">>"
|
|
37878
|
-
].join("\n")
|
|
37879
|
-
);
|
|
37880
|
-
pageObjectIds.push(pageObjectId);
|
|
37881
|
-
}
|
|
37882
|
-
objects[catalogObjectId - 1].body = `<< /Type /Catalog /Pages ${pagesObjectId} 0 R >>`;
|
|
37883
|
-
objects[pagesObjectId - 1].body = [
|
|
37884
|
-
"<< /Type /Pages",
|
|
37885
|
-
`/Kids [${pageObjectIds.map((id) => `${id} 0 R`).join(" ")}]`,
|
|
37886
|
-
`/Count ${pageObjectIds.length}`,
|
|
37887
|
-
">>"
|
|
37888
|
-
].join("\n");
|
|
37889
|
-
let body = PDF_HEADER;
|
|
37890
|
-
const offsets = [0];
|
|
37891
|
-
for (const object of objects) {
|
|
37892
|
-
offsets[object.id] = byteLength(body);
|
|
37893
|
-
body += `${object.id} 0 obj
|
|
37894
|
-
${object.body}
|
|
37895
|
-
endobj
|
|
37896
|
-
`;
|
|
37897
|
-
}
|
|
37898
|
-
const xrefOffset = byteLength(body);
|
|
37899
|
-
body += `xref
|
|
37900
|
-
0 ${objects.length + 1}
|
|
37901
|
-
`;
|
|
37902
|
-
body += "0000000000 65535 f \n";
|
|
37903
|
-
for (const object of objects) {
|
|
37904
|
-
body += `${String(offsets[object.id] ?? 0).padStart(10, "0")} 00000 n
|
|
37905
|
-
`;
|
|
37950
|
+
const resourceXml = fontResourceEntries.map((font, index) => `/${font.resourceName} ${fontObjectIds[index]} 0 R`).join(" ");
|
|
37951
|
+
return { resourceXml };
|
|
37952
|
+
}
|
|
37953
|
+
layoutUnicodeText(state, text) {
|
|
37954
|
+
const cached = state.layoutCache.get(text);
|
|
37955
|
+
if (cached) {
|
|
37956
|
+
return cached;
|
|
37906
37957
|
}
|
|
37907
|
-
|
|
37908
|
-
|
|
37909
|
-
|
|
37910
|
-
"startxref",
|
|
37911
|
-
String(xrefOffset),
|
|
37912
|
-
"%%EOF",
|
|
37913
|
-
""
|
|
37914
|
-
].join("\n");
|
|
37915
|
-
return new TextEncoder().encode(body);
|
|
37958
|
+
const run = state.font.layouter.layout(text);
|
|
37959
|
+
state.layoutCache.set(text, run);
|
|
37960
|
+
return run;
|
|
37916
37961
|
}
|
|
37917
|
-
|
|
37918
|
-
return
|
|
37919
|
-
|
|
37920
|
-
|
|
37921
|
-
|
|
37922
|
-
|
|
37923
|
-
|
|
37924
|
-
|
|
37925
|
-
|
|
37926
|
-
|
|
37927
|
-
);
|
|
37962
|
+
encodeUnicodeGlyphRun(state, run) {
|
|
37963
|
+
return run.glyphs.map((glyph, index) => {
|
|
37964
|
+
if (!state.usedGlyphs.has(glyph.id)) {
|
|
37965
|
+
state.usedGlyphs.set(glyph.id, glyph);
|
|
37966
|
+
}
|
|
37967
|
+
const position = run.positions[index];
|
|
37968
|
+
const nominalWidth = glyph.advanceWidth * state.scale;
|
|
37969
|
+
const desiredAdvance = ((position == null ? void 0 : position.xAdvance) ?? glyph.advanceWidth) * state.scale;
|
|
37970
|
+
return { glyphId: glyph.id, nominalWidth, desiredAdvance };
|
|
37971
|
+
});
|
|
37928
37972
|
}
|
|
37929
37973
|
addUnicodeFontObjects(state, addObject) {
|
|
37930
37974
|
const subset = state.font.subsetter.createSubset(
|
|
@@ -38002,6 +38046,200 @@ endobj
|
|
|
38002
38046
|
);
|
|
38003
38047
|
}
|
|
38004
38048
|
}
|
|
38049
|
+
class PdfImageTable {
|
|
38050
|
+
constructor() {
|
|
38051
|
+
__publicField(this, "imageResources", /* @__PURE__ */ new Map());
|
|
38052
|
+
}
|
|
38053
|
+
registerImageResource(resource) {
|
|
38054
|
+
const resourceName = resource.resourceName ?? `Im${this.imageResources.size + 1}`;
|
|
38055
|
+
if (!this.imageResources.has(resourceName)) {
|
|
38056
|
+
this.imageResources.set(resourceName, {
|
|
38057
|
+
resourceName,
|
|
38058
|
+
width: Math.max(1, Math.round(resource.width)),
|
|
38059
|
+
height: Math.max(1, Math.round(resource.height)),
|
|
38060
|
+
data: resource.data,
|
|
38061
|
+
filter: resource.filter
|
|
38062
|
+
});
|
|
38063
|
+
}
|
|
38064
|
+
return resourceName;
|
|
38065
|
+
}
|
|
38066
|
+
has(resourceName) {
|
|
38067
|
+
return this.imageResources.has(resourceName);
|
|
38068
|
+
}
|
|
38069
|
+
/** Emits each registered image object, keyed by resource name for page maps. */
|
|
38070
|
+
buildImageObjects(addObject) {
|
|
38071
|
+
const imageObjectIds = /* @__PURE__ */ new Map();
|
|
38072
|
+
for (const image of this.imageResources.values()) {
|
|
38073
|
+
imageObjectIds.set(
|
|
38074
|
+
image.resourceName,
|
|
38075
|
+
this.addImageObject(image, addObject)
|
|
38076
|
+
);
|
|
38077
|
+
}
|
|
38078
|
+
return imageObjectIds;
|
|
38079
|
+
}
|
|
38080
|
+
addImageObject(resource, addObject) {
|
|
38081
|
+
return addObject(
|
|
38082
|
+
asciiHexImageStreamObjectBody(resource.data, [
|
|
38083
|
+
"/Type /XObject",
|
|
38084
|
+
"/Subtype /Image",
|
|
38085
|
+
`/Width ${resource.width}`,
|
|
38086
|
+
`/Height ${resource.height}`,
|
|
38087
|
+
"/ColorSpace /DeviceRGB",
|
|
38088
|
+
"/BitsPerComponent 8"
|
|
38089
|
+
])
|
|
38090
|
+
);
|
|
38091
|
+
}
|
|
38092
|
+
}
|
|
38093
|
+
function serializePdfDocument(pages, fonts, images) {
|
|
38094
|
+
const objects = [];
|
|
38095
|
+
const addObject = (body2) => {
|
|
38096
|
+
const id = objects.length + 1;
|
|
38097
|
+
objects.push({ id, body: body2 });
|
|
38098
|
+
return id;
|
|
38099
|
+
};
|
|
38100
|
+
const catalogObjectId = addObject("");
|
|
38101
|
+
const pagesObjectId = addObject("");
|
|
38102
|
+
const { resourceXml: fontResourceXml } = fonts.buildFontObjects(addObject);
|
|
38103
|
+
const imageObjectIds = images.buildImageObjects(addObject);
|
|
38104
|
+
const pageObjectIds = [];
|
|
38105
|
+
for (const page of pages) {
|
|
38106
|
+
const stream = `${page.commands.join("\n")}
|
|
38107
|
+
`;
|
|
38108
|
+
const contentObjectId = addObject(
|
|
38109
|
+
`<< /Length ${byteLength(stream)} >>
|
|
38110
|
+
stream
|
|
38111
|
+
${stream}endstream`
|
|
38112
|
+
);
|
|
38113
|
+
const imageResourceXml = Array.from(page.imageResourceNames).map((resourceName) => {
|
|
38114
|
+
const objectId = imageObjectIds.get(resourceName);
|
|
38115
|
+
return objectId ? `/${resourceName} ${objectId} 0 R` : "";
|
|
38116
|
+
}).filter(Boolean).join(" ");
|
|
38117
|
+
const xObjectResourceXml = imageResourceXml ? ` /XObject << ${imageResourceXml} >>` : "";
|
|
38118
|
+
const pageObjectId = addObject(
|
|
38119
|
+
[
|
|
38120
|
+
"<< /Type /Page",
|
|
38121
|
+
`/Parent ${pagesObjectId} 0 R`,
|
|
38122
|
+
`/MediaBox [0 0 ${formatNumber(page.width)} ${formatNumber(page.height)}]`,
|
|
38123
|
+
`/Resources << /Font << ${fontResourceXml} >>${xObjectResourceXml} >>`,
|
|
38124
|
+
`/Contents ${contentObjectId} 0 R`,
|
|
38125
|
+
">>"
|
|
38126
|
+
].join("\n")
|
|
38127
|
+
);
|
|
38128
|
+
pageObjectIds.push(pageObjectId);
|
|
38129
|
+
}
|
|
38130
|
+
objects[catalogObjectId - 1].body = `<< /Type /Catalog /Pages ${pagesObjectId} 0 R >>`;
|
|
38131
|
+
objects[pagesObjectId - 1].body = [
|
|
38132
|
+
"<< /Type /Pages",
|
|
38133
|
+
`/Kids [${pageObjectIds.map((id) => `${id} 0 R`).join(" ")}]`,
|
|
38134
|
+
`/Count ${pageObjectIds.length}`,
|
|
38135
|
+
">>"
|
|
38136
|
+
].join("\n");
|
|
38137
|
+
let body = PDF_HEADER;
|
|
38138
|
+
const offsets = [0];
|
|
38139
|
+
for (const object of objects) {
|
|
38140
|
+
offsets[object.id] = byteLength(body);
|
|
38141
|
+
body += `${object.id} 0 obj
|
|
38142
|
+
${object.body}
|
|
38143
|
+
endobj
|
|
38144
|
+
`;
|
|
38145
|
+
}
|
|
38146
|
+
const xrefOffset = byteLength(body);
|
|
38147
|
+
body += `xref
|
|
38148
|
+
0 ${objects.length + 1}
|
|
38149
|
+
`;
|
|
38150
|
+
body += "0000000000 65535 f \n";
|
|
38151
|
+
for (const object of objects) {
|
|
38152
|
+
body += `${String(offsets[object.id] ?? 0).padStart(10, "0")} 00000 n
|
|
38153
|
+
`;
|
|
38154
|
+
}
|
|
38155
|
+
body += [
|
|
38156
|
+
"trailer",
|
|
38157
|
+
`<< /Size ${objects.length + 1} /Root ${catalogObjectId} 0 R >>`,
|
|
38158
|
+
"startxref",
|
|
38159
|
+
String(xrefOffset),
|
|
38160
|
+
"%%EOF",
|
|
38161
|
+
""
|
|
38162
|
+
].join("\n");
|
|
38163
|
+
return new TextEncoder().encode(body);
|
|
38164
|
+
}
|
|
38165
|
+
class OasisPdfWriter {
|
|
38166
|
+
constructor(fontResources = DEFAULT_PDF_FONT_RESOURCES) {
|
|
38167
|
+
__publicField(this, "pages", []);
|
|
38168
|
+
__publicField(this, "streams", []);
|
|
38169
|
+
__publicField(this, "fonts");
|
|
38170
|
+
__publicField(this, "images", new PdfImageTable());
|
|
38171
|
+
this.fonts = new PdfFontTable(fontResources);
|
|
38172
|
+
}
|
|
38173
|
+
registerFontResource(resource) {
|
|
38174
|
+
this.fonts.registerFontResource(resource);
|
|
38175
|
+
}
|
|
38176
|
+
addPage(size) {
|
|
38177
|
+
const page = {
|
|
38178
|
+
width: Math.max(1, size.width),
|
|
38179
|
+
height: Math.max(1, size.height),
|
|
38180
|
+
commands: [],
|
|
38181
|
+
imageResourceNames: /* @__PURE__ */ new Set()
|
|
38182
|
+
};
|
|
38183
|
+
this.pages.push(page);
|
|
38184
|
+
this.streams.push(new PdfContentStream(page, this.fonts, this.images));
|
|
38185
|
+
return this.pages.length - 1;
|
|
38186
|
+
}
|
|
38187
|
+
getPageCount() {
|
|
38188
|
+
return this.pages.length;
|
|
38189
|
+
}
|
|
38190
|
+
drawRect(pageIndex, options) {
|
|
38191
|
+
var _a;
|
|
38192
|
+
(_a = this.streams[pageIndex]) == null ? void 0 : _a.drawRect(options);
|
|
38193
|
+
}
|
|
38194
|
+
drawLine(pageIndex, options) {
|
|
38195
|
+
var _a;
|
|
38196
|
+
(_a = this.streams[pageIndex]) == null ? void 0 : _a.drawLine(options);
|
|
38197
|
+
}
|
|
38198
|
+
drawPath(pageIndex, options) {
|
|
38199
|
+
var _a;
|
|
38200
|
+
(_a = this.streams[pageIndex]) == null ? void 0 : _a.drawPath(options);
|
|
38201
|
+
}
|
|
38202
|
+
saveGraphicsState(pageIndex) {
|
|
38203
|
+
var _a;
|
|
38204
|
+
(_a = this.streams[pageIndex]) == null ? void 0 : _a.saveGraphicsState();
|
|
38205
|
+
}
|
|
38206
|
+
restoreGraphicsState(pageIndex) {
|
|
38207
|
+
var _a;
|
|
38208
|
+
(_a = this.streams[pageIndex]) == null ? void 0 : _a.restoreGraphicsState();
|
|
38209
|
+
}
|
|
38210
|
+
rotateAbout(pageIndex, centerX, centerY, degrees) {
|
|
38211
|
+
var _a;
|
|
38212
|
+
(_a = this.streams[pageIndex]) == null ? void 0 : _a.rotateAbout(centerX, centerY, degrees);
|
|
38213
|
+
}
|
|
38214
|
+
clipRect(pageIndex, x, y, width, height) {
|
|
38215
|
+
var _a;
|
|
38216
|
+
(_a = this.streams[pageIndex]) == null ? void 0 : _a.clipRect(x, y, width, height);
|
|
38217
|
+
}
|
|
38218
|
+
drawText(pageIndex, options) {
|
|
38219
|
+
var _a;
|
|
38220
|
+
(_a = this.streams[pageIndex]) == null ? void 0 : _a.drawText(options);
|
|
38221
|
+
}
|
|
38222
|
+
registerImageResource(resource) {
|
|
38223
|
+
return this.images.registerImageResource(resource);
|
|
38224
|
+
}
|
|
38225
|
+
drawImage(pageIndex, options) {
|
|
38226
|
+
var _a;
|
|
38227
|
+
(_a = this.streams[pageIndex]) == null ? void 0 : _a.drawImage(options);
|
|
38228
|
+
}
|
|
38229
|
+
toArrayBuffer() {
|
|
38230
|
+
const bytes = this.toUint8Array();
|
|
38231
|
+
return Uint8Array.from(bytes).buffer;
|
|
38232
|
+
}
|
|
38233
|
+
toBlob() {
|
|
38234
|
+
return new Blob([this.toArrayBuffer()], { type: "application/pdf" });
|
|
38235
|
+
}
|
|
38236
|
+
toUint8Array() {
|
|
38237
|
+
if (this.pages.length === 0) {
|
|
38238
|
+
this.addPage({ width: 612, height: 792 });
|
|
38239
|
+
}
|
|
38240
|
+
return serializePdfDocument(this.pages, this.fonts, this.images);
|
|
38241
|
+
}
|
|
38242
|
+
}
|
|
38005
38243
|
const FOOTNOTE_BLOCK_GAP_PX = 2;
|
|
38006
38244
|
async function exportEditorDocumentToPdf(document2) {
|
|
38007
38245
|
document2 = renumberImageCaptionsInDocument(document2);
|
|
@@ -44776,7 +45014,9 @@ function createEditorTextDrag(deps) {
|
|
|
44776
45014
|
current,
|
|
44777
45015
|
(temp) => moveOrCopySelectionToPosition(temp, destination, { copy })
|
|
44778
45016
|
),
|
|
44779
|
-
{
|
|
45017
|
+
{
|
|
45018
|
+
mergeKey: copy ? MERGE_KEYS.copyTextByDrag : MERGE_KEYS.moveTextByDrag
|
|
45019
|
+
}
|
|
44780
45020
|
);
|
|
44781
45021
|
(_b = deps.logger) == null ? void 0 : _b.info("text-drag:apply", {
|
|
44782
45022
|
mode: copy ? "copy" : "move",
|
|
@@ -47150,7 +47390,12 @@ function collectTocHeadings(state, maxLevel = DEFAULT_TOC_MAX_LEVEL) {
|
|
|
47150
47390
|
function makeRun(partial) {
|
|
47151
47391
|
const id = createEditorRun(partial.text).id;
|
|
47152
47392
|
if (partial.fieldChar) {
|
|
47153
|
-
return {
|
|
47393
|
+
return {
|
|
47394
|
+
id,
|
|
47395
|
+
text: partial.text,
|
|
47396
|
+
kind: "fieldChar",
|
|
47397
|
+
fieldChar: partial.fieldChar
|
|
47398
|
+
};
|
|
47154
47399
|
}
|
|
47155
47400
|
if (partial.fieldInstruction !== void 0) {
|
|
47156
47401
|
return {
|