@embedpdf/engine-services 3.0.0-next.11 → 3.0.0-next.12

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/index.cjs CHANGED
@@ -1732,7 +1732,8 @@ var PagesReader = class {
1732
1732
  });
1733
1733
  return {
1734
1734
  pageCount: pages.length,
1735
- pages
1735
+ pages,
1736
+ namedPages: readNamedPages(fn, mem, docPtr)
1736
1737
  };
1737
1738
  });
1738
1739
  }
@@ -1797,6 +1798,41 @@ function readUserUnit(fn, mem, docPtr, index, userUnitPtr) {
1797
1798
  function readLabel(fn, mem, docPtr, index) {
1798
1799
  return readUtf16String(mem, (buf, capacity) => fn.FPDF_GetPageLabel(docPtr, index, buf, capacity), null) || null;
1799
1800
  }
1801
+ const NAMED_PAGE_TREES = [0, 1];
1802
+ const NAMED_PAGE_KIND_PAGE = 0;
1803
+ const NAMED_PAGE_KIND_TEMPLATE = 1;
1804
+ /**
1805
+ * The catalog's `/Names /Pages` and `/Names /Templates` registrations, in
1806
+ * tree order, each value classified by the fork (page / template /
1807
+ * dangling). Page-identity data like `label`, so it ships inside the same
1808
+ * snapshot — a registration is only meaningful against the page set that
1809
+ * contains its target.
1810
+ */
1811
+ function readNamedPages(fn, mem, docPtr) {
1812
+ const entries = [];
1813
+ withScratchN(mem, [4, 4], ([objNumPtr, kindPtr]) => {
1814
+ for (const tree of NAMED_PAGE_TREES) {
1815
+ const count = fn.EPDFDoc_GetNamedPageCount(docPtr, tree);
1816
+ for (let index = 0; index < count; index++) {
1817
+ const name = readUtf16String(mem, (buf, capacity) => fn.EPDFDoc_GetNamedPageAt(docPtr, tree, index, buf, capacity, objNumPtr, kindPtr), "");
1818
+ if (name === null) continue;
1819
+ const objectNumber = Number(mem.peek(objNumPtr, "i32")) >>> 0;
1820
+ const kind = Number(mem.peek(kindPtr, "i32"));
1821
+ entries.push({
1822
+ name,
1823
+ target: kind === NAMED_PAGE_KIND_PAGE ? {
1824
+ kind: "page",
1825
+ pageObjectNumber: objectNumber
1826
+ } : kind === NAMED_PAGE_KIND_TEMPLATE ? {
1827
+ kind: "template",
1828
+ objectNumber
1829
+ } : { kind: "dangling" }
1830
+ });
1831
+ }
1832
+ }
1833
+ });
1834
+ return entries;
1835
+ }
1800
1836
  //#endregion
1801
1837
  //#region src/features/pages/PagesMutator.ts
1802
1838
  /**
@@ -1944,6 +1980,38 @@ var PagesMutator = class {
1944
1980
  cache: null
1945
1981
  };
1946
1982
  }
1983
+ /**
1984
+ * Register `name` → page in `/Names /Pages` (create, or replace what the
1985
+ * key points at); with `replace`, drop that other key first — a rename as
1986
+ * one job. Named pages are LAYOUT: page identity and order are untouched
1987
+ * (no registry refresh, no revision bumps) and the fresh snapshot is
1988
+ * returned like `move()`.
1989
+ */
1990
+ setName(input, signal) {
1991
+ throwIfAborted(signal);
1992
+ if (input.name.length === 0) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.InvalidArg, "pages.setName requires a non-empty name");
1993
+ const { fn, mem } = this.runtime;
1994
+ const docPtr = this.session.requireDocPtr();
1995
+ this.session.recordByObjectNumber(input.pageObjectNumber);
1996
+ if (input.replace !== void 0 && input.replace !== input.name && input.replace.length > 0) writeUtf16String(mem, input.replace, (ptr) => fn.EPDFDoc_RemoveNamedPage(docPtr, ptr));
1997
+ if (!writeUtf16String(mem, input.name, (ptr) => fn.EPDFDoc_SetNamedPage(docPtr, ptr, input.pageObjectNumber))) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.Unknown, `EPDFDoc_SetNamedPage rejected '${input.name}' for page ${input.pageObjectNumber}`);
1998
+ return {
1999
+ layout: new PagesReader(this.runtime, this.session).read(signal),
2000
+ cache: null
2001
+ };
2002
+ }
2003
+ /** Remove one `/Names /Pages` registration; the page stays. */
2004
+ removeName(input, signal) {
2005
+ throwIfAborted(signal);
2006
+ if (input.name.length === 0) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.InvalidArg, "pages.removeName requires a non-empty name");
2007
+ const { fn, mem } = this.runtime;
2008
+ const docPtr = this.session.requireDocPtr();
2009
+ if (!writeUtf16String(mem, input.name, (ptr) => fn.EPDFDoc_RemoveNamedPage(docPtr, ptr))) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.NotFound, `pages.removeName: no /Names /Pages registration '${input.name}'`);
2010
+ return {
2011
+ layout: new PagesReader(this.runtime, this.session).read(signal),
2012
+ cache: null
2013
+ };
2014
+ }
1947
2015
  /** Shared input check: non-empty, no duplicate PONs. */
1948
2016
  requireUniquePons(op, pageObjectNumbers) {
1949
2017
  if (pageObjectNumbers.length === 0) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.InvalidArg, `${op} requires at least one page`);
@@ -1956,7 +2024,7 @@ var PagesMutator = class {
1956
2024
  };
1957
2025
  //#endregion
1958
2026
  //#region src/features/pages/PagesExtractor.ts
1959
- const FPDF_NO_INCREMENTAL$1 = 2;
2027
+ const FPDF_NO_INCREMENTAL$2 = 2;
1960
2028
  /**
1961
2029
  * Export a subset of pages as a standalone PDF. A READ over the session:
1962
2030
  * `FPDF_ImportPagesByIndex` copies pages into a scratch document, so the
@@ -1995,7 +2063,7 @@ var PagesExtractor = class {
1995
2063
  for (let i = 0; i < indices.length; i++) mem.poke(idxPtr, "i32", indices[i], 4 * i);
1996
2064
  if (!fn.FPDF_ImportPagesByIndex(destPtr, srcPtr, idxPtr, indices.length, 0)) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.Unknown, `FPDF_ImportPagesByIndex rejected the request (indices=[${indices.join(",")}])`);
1997
2065
  mem.poke(sizePtr, "i32", 0);
1998
- pdfPtr = fn.EPDF_SaveDocumentToOwnedBuffer(destPtr, FPDF_NO_INCREMENTAL$1, sizePtr);
2066
+ pdfPtr = fn.EPDF_SaveDocumentToOwnedBuffer(destPtr, FPDF_NO_INCREMENTAL$2, sizePtr);
1999
2067
  const size = Number(mem.peek(sizePtr, "i32"));
2000
2068
  if (!pdfPtr || size <= 0) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.DocOpenFailed, "failed to save extracted pages");
2001
2069
  const bytes = mem.readBytes(pdfPtr, size);
@@ -2547,6 +2615,13 @@ function readQuadPoints(fn, mem, annotPtr) {
2547
2615
  return out;
2548
2616
  });
2549
2617
  }
2618
+ /**
2619
+ * `/Name` as text, whatever its value (`EPDFAnnot_GetName`): a standard
2620
+ * icon/stamp name or a custom identifier. `null` when absent.
2621
+ */
2622
+ function readAnnotName(fn, mem, annotPtr) {
2623
+ return readUtf8String(mem, (buf, capacity) => fn.EPDFAnnot_GetName(annotPtr, buf, capacity));
2624
+ }
2550
2625
  //#endregion
2551
2626
  //#region src/features/annotations/internal/read/readAnnotationTransformMetadata.ts
2552
2627
  /**
@@ -2796,29 +2871,29 @@ function normalizeChecksum(raw) {
2796
2871
  //#endregion
2797
2872
  //#region src/features/annotations/internal/annotationIcon.ts
2798
2873
  /**
2799
- * `/Name` icon ↔ `FPDF_ANNOT_NAME` enum code mapping for text and
2800
- * file-attachment annotations (`EPDFAnnot_SetName` / `EPDFAnnot_GetName`).
2801
- * Codes mirror the `FPDF_ANNOT_NAME` enum in `public/fpdf_annot.h` —
2802
- * same pattern as `stampName.ts` (whose stamp block starts at 13, right
2803
- * after these) keeping engine-core PDFium-free.
2804
- */
2805
- const NOTE_ICON_TO_CODE = Object.freeze({
2806
- comment: 0,
2807
- key: 1,
2808
- note: 2,
2809
- help: 3,
2810
- "new-paragraph": 4,
2811
- paragraph: 5,
2812
- insert: 6
2874
+ * `/Name` icon vocabulary ↔ PDF name mapping for text and file-attachment
2875
+ * annotations (ISO 32000-2 tables 175 and 184). The wire speaks the
2876
+ * kebab-case ids; `EPDFAnnot_SetName` / `EPDFAnnot_GetName` speak the PDF
2877
+ * names. An unknown PDF name reads as the subtype's default (the reader
2878
+ * draws the default glyph for names it does not know — spec behavior).
2879
+ */
2880
+ const NOTE_ICON_TO_NAME = Object.freeze({
2881
+ comment: "Comment",
2882
+ key: "Key",
2883
+ note: "Note",
2884
+ help: "Help",
2885
+ "new-paragraph": "NewParagraph",
2886
+ paragraph: "Paragraph",
2887
+ insert: "Insert"
2813
2888
  });
2814
- const NOTE_CODE_TO_ICON = Object.freeze(Object.fromEntries(Object.entries(NOTE_ICON_TO_CODE).map(([icon, code]) => [code, icon])));
2815
- const FILE_ICON_TO_CODE = Object.freeze({
2816
- graph: 7,
2817
- "push-pin": 8,
2818
- paperclip: 9,
2819
- tag: 10
2889
+ const NOTE_NAME_TO_ICON = Object.freeze(Object.fromEntries(Object.entries(NOTE_ICON_TO_NAME).map(([icon, name]) => [name, icon])));
2890
+ const FILE_ICON_TO_NAME = Object.freeze({
2891
+ graph: "Graph",
2892
+ "push-pin": "PushPin",
2893
+ paperclip: "Paperclip",
2894
+ tag: "Tag"
2820
2895
  });
2821
- const FILE_CODE_TO_ICON = Object.freeze(Object.fromEntries(Object.entries(FILE_ICON_TO_CODE).map(([icon, code]) => [code, icon])));
2896
+ const FILE_NAME_TO_ICON = Object.freeze(Object.fromEntries(Object.entries(FILE_ICON_TO_NAME).map(([icon, name]) => [name, icon])));
2822
2897
  //#endregion
2823
2898
  //#region src/features/annotations/internal/read/readFileAttachmentAnnotation.ts
2824
2899
  /** Default `/C` — matches the generator's default icon fill and the writer default. */
@@ -2840,7 +2915,7 @@ function readFileAttachment(fn, mem, annotPtr, base) {
2840
2915
  const color = readAnnotColor(fn, mem, annotPtr) ?? { ...DEFAULT_FILE_ATTACHMENT_COLOR$1 };
2841
2916
  const ca = readAnnotOpacity(fn, mem, annotPtr);
2842
2917
  const opacity = ca == null ? 1 : Math.max(0, Math.min(1, ca));
2843
- const icon = FILE_CODE_TO_ICON[fn.EPDFAnnot_GetName(annotPtr)] ?? DEFAULT_FILE_ATTACHMENT_ICON;
2918
+ const icon = FILE_NAME_TO_ICON[readAnnotName(fn, mem, annotPtr) ?? ""] ?? DEFAULT_FILE_ATTACHMENT_ICON;
2844
2919
  const attachmentPtr = fn.FPDFAnnot_GetFileAttachment(annotPtr);
2845
2920
  const file = attachmentPtr ? readAttachmentFileInfo(fn, mem, attachmentPtr) : { name: "" };
2846
2921
  return {
@@ -3309,45 +3384,10 @@ function readSquare(fn, mem, annotPtr, base) {
3309
3384
  };
3310
3385
  }
3311
3386
  //#endregion
3312
- //#region src/features/annotations/internal/stampName.ts
3313
- /**
3314
- * Stamp `/Name` label ↔ `FPDF_ANNOT_NAME` enum code mapping for the
3315
- * `EPDFAnnot_SetName` / `EPDFAnnot_GetName` fork helpers. Labels are the
3316
- * PDF spec / Adobe literal name values (ISO 32000 §12.5.6.12 table 181
3317
- * plus the Adobe SB/SH extended set the fork supports). Codes mirror the
3318
- * `FPDF_ANNOT_NAME` enum in `public/fpdf_annot.h` — same pattern as
3319
- * `lineEnding.ts` keeping engine-core PDFium-free.
3320
- */
3321
- const STAMP_NAME_TO_CODE = Object.freeze({
3322
- Approved: 13,
3323
- Experimental: 14,
3324
- NotApproved: 15,
3325
- AsIs: 16,
3326
- Expired: 17,
3327
- NotForPublicRelease: 18,
3328
- Confidential: 19,
3329
- Final: 20,
3330
- Sold: 21,
3331
- Departmental: 22,
3332
- ForComment: 23,
3333
- TopSecret: 24,
3334
- Draft: 25,
3335
- ForPublicRelease: 26,
3336
- Completed: 27,
3337
- Void: 28,
3338
- PreliminaryResults: 29,
3339
- InformationOnly: 30,
3340
- Rejected: 31,
3341
- Witness: 32,
3342
- InitialHere: 33,
3343
- SignHere: 34,
3344
- Accepted: 35
3345
- });
3346
- const STAMP_CODE_TO_NAME = Object.freeze(Object.fromEntries(Object.entries(STAMP_NAME_TO_CODE).map(([name, code]) => [code, name])));
3347
- //#endregion
3348
3387
  //#region src/features/annotations/internal/read/readStampAnnotation.ts
3349
3388
  /**
3350
- * Stamp DTO: base + `/Name` label + transform metadata. The visual content
3389
+ * Stamp DTO: base + `/Name` (standard or custom identifier, verbatim) +
3390
+ * transform metadata. The visual content
3351
3391
  * stays in the `/AP` stream — rendered via `renderAppearanceImages()`,
3352
3392
  * never surfaced as DTO data.
3353
3393
  */
@@ -3357,16 +3397,11 @@ function readStamp(fn, mem, annotPtr, base) {
3357
3397
  return {
3358
3398
  ...base,
3359
3399
  subtype: "stamp",
3360
- name: readStampName(fn, mem, annotPtr),
3400
+ name: readAnnotName(fn, mem, annotPtr),
3361
3401
  ...rotation != null ? { rotation } : {},
3362
3402
  ...unrotatedRect != null ? { unrotatedRect } : {}
3363
3403
  };
3364
3404
  }
3365
- function readStampName(fn, mem, annotPtr) {
3366
- const known = STAMP_CODE_TO_NAME[fn.EPDFAnnot_GetName(annotPtr)];
3367
- if (known !== void 0) return known;
3368
- return readAnnotString(fn, mem, annotPtr, "Name");
3369
- }
3370
3405
  //#endregion
3371
3406
  //#region src/features/annotations/internal/annotationState.ts
3372
3407
  /**
@@ -3422,7 +3457,7 @@ function readText(fn, mem, annotPtr, base) {
3422
3457
  const color = readAnnotColor(fn, mem, annotPtr) ?? { ...DEFAULT_NOTE_COLOR$1 };
3423
3458
  const ca = readAnnotOpacity(fn, mem, annotPtr);
3424
3459
  const opacity = ca == null ? 1 : Math.max(0, Math.min(1, ca));
3425
- const icon = NOTE_CODE_TO_ICON[fn.EPDFAnnot_GetName(annotPtr)] ?? DEFAULT_NOTE_ICON;
3460
+ const icon = NOTE_NAME_TO_ICON[readAnnotName(fn, mem, annotPtr) ?? ""] ?? DEFAULT_NOTE_ICON;
3426
3461
  const stateRaw = readAnnotString(fn, mem, annotPtr, "State");
3427
3462
  const stateModelRaw = readAnnotString(fn, mem, annotPtr, "StateModel");
3428
3463
  return {
@@ -5444,7 +5479,7 @@ function isFileAttachmentSubtype(subtype) {
5444
5479
  return subtype === "file-attachment";
5445
5480
  }
5446
5481
  function setFileAttachmentIcon(fn, annotPtr, icon) {
5447
- if (!fn.EPDFAnnot_SetName(annotPtr, FILE_ICON_TO_CODE[icon])) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.Unknown, "EPDFAnnot_SetName returned false");
5482
+ if (!fn.EPDFAnnot_SetName(annotPtr, FILE_ICON_TO_NAME[icon])) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.Unknown, "EPDFAnnot_SetName returned false");
5448
5483
  }
5449
5484
  function requireFileResource(file, ctx) {
5450
5485
  const resource = ctx?.resources?.[file.resource];
@@ -6106,12 +6141,12 @@ const STAMP_FIT_TO_CODE = {
6106
6141
  * creating an annotation or strengthening a weak annotation id.
6107
6142
  */
6108
6143
  function preflightStampDraft(draft, ctx) {
6109
- if (draft.name !== void 0) requireStampNameCode(draft.name);
6144
+ if (draft.name !== void 0) requireStampName(draft.name);
6110
6145
  requireStampFit(draft.fit ?? "contain");
6111
6146
  requireStampContent(draft.source, ctx);
6112
6147
  }
6113
6148
  function preflightStampPatch(patch, ctx) {
6114
- if (patch.name !== void 0) requireStampNameCode(patch.name);
6149
+ if (patch.name !== void 0 && patch.name !== null) requireStampName(patch.name);
6115
6150
  requireStampFit(patch.fit ?? "contain");
6116
6151
  if (patch.source !== void 0) requireStampContent(patch.source, ctx);
6117
6152
  }
@@ -6137,7 +6172,8 @@ function applyStampDraft(fn, mem, annotPtr, draft, ctx) {
6137
6172
  }
6138
6173
  function applyStampPatch(fn, mem, annotPtr, patch, ctx) {
6139
6174
  applyAnnotationBasePatch(fn, mem, annotPtr, patch);
6140
- if (patch.name !== void 0) setStampName(fn, annotPtr, patch.name);
6175
+ if (patch.name === null) fn.EPDFAnnot_RemoveKey(annotPtr, "Name");
6176
+ else if (patch.name !== void 0) setStampName(fn, annotPtr, patch.name);
6141
6177
  if (patch.source !== void 0) {
6142
6178
  const rect = patch.rect ?? readAnnotRect(fn, mem, annotPtr);
6143
6179
  authorStampAppearance(fn, mem, annotPtr, patch.source, patch.fit ?? "contain", {
@@ -6157,15 +6193,14 @@ function applyStampPatch(fn, mem, annotPtr, patch, ctx) {
6157
6193
  function isStampSubtype(subtype) {
6158
6194
  return subtype === "stamp";
6159
6195
  }
6196
+ /** Any non-empty name: standard ('Approved') or custom ('#LBGiYhk8V…') —
6197
+ * the fork writes a name object and escapes it; predefined sets are a
6198
+ * reader concern (ISO 32000-2 table 187 allows additional names). */
6160
6199
  function setStampName(fn, annotPtr, name) {
6161
- const code = STAMP_NAME_TO_CODE[name];
6162
- if (code === void 0) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.Unknown, "stamp name preflight invariant broken");
6163
- if (!fn.EPDFAnnot_SetName(annotPtr, code)) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.Unknown, "EPDFAnnot_SetName returned false");
6200
+ if (!fn.EPDFAnnot_SetName(annotPtr, name)) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.Unknown, "EPDFAnnot_SetName returned false");
6164
6201
  }
6165
- function requireStampNameCode(name) {
6166
- const code = STAMP_NAME_TO_CODE[name];
6167
- if (code === void 0) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.InvalidArg, `unknown stamp name '${name}'; supported names: ${Object.keys(STAMP_NAME_TO_CODE).join(", ")}`);
6168
- return code;
6202
+ function requireStampName(name) {
6203
+ if (name.length === 0) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.InvalidArg, "stamp name must be non-empty");
6169
6204
  }
6170
6205
  function requireStampFit(fit) {
6171
6206
  if (STAMP_FIT_TO_CODE[fit] === void 0) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.InvalidArg, `unknown stamp fit '${String(fit)}'; expected contain, cover, or fill`);
@@ -6353,7 +6388,7 @@ function isTextSubtype(subtype) {
6353
6388
  return subtype === "text";
6354
6389
  }
6355
6390
  function setNoteIcon(fn, annotPtr, icon) {
6356
- if (!fn.EPDFAnnot_SetName(annotPtr, NOTE_ICON_TO_CODE[icon])) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.Unknown, "EPDFAnnot_SetName returned false");
6391
+ if (!fn.EPDFAnnot_SetName(annotPtr, NOTE_ICON_TO_NAME[icon])) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.Unknown, "EPDFAnnot_SetName returned false");
6357
6392
  }
6358
6393
  //#endregion
6359
6394
  //#region src/features/annotations/internal/write/writeVertexAnnotation.ts
@@ -7080,6 +7115,141 @@ var AnnotationMutator = class {
7080
7115
  }
7081
7116
  };
7082
7117
  //#endregion
7118
+ //#region src/features/annotations/AnnotationFlattener.ts
7119
+ const FLATTEN_FAIL$1 = 0;
7120
+ const FLATTEN_SUCCESS$1 = 1;
7121
+ const FLATTEN_NOTHING_TO_DO$1 = 2;
7122
+ const STATUS_APPLIED = 0;
7123
+ const STATUS_NOT_ON_PAGE = 2;
7124
+ const FPDF_NO_INCREMENTAL$1 = 2;
7125
+ /**
7126
+ * The annotation-plane flatten verbs — `pages.flatten` for a chosen set:
7127
+ * in place (`flatten`) or into a new single-page document
7128
+ * (`exportAppearance`). Both resolve refs to native handles on the page,
7129
+ * hand the SET to the fork (one candidate plan, one placement writer — the
7130
+ * same code whole-page flatten runs), and release every handle afterwards.
7131
+ */
7132
+ var AnnotationFlattener = class {
7133
+ constructor(runtime, session) {
7134
+ this.runtime = runtime;
7135
+ this.session = session;
7136
+ }
7137
+ flatten(pageObjectNumber, refs, usage, signal) {
7138
+ throwIfAborted(signal);
7139
+ this.requireRefs("annotations.flatten", pageObjectNumber, refs);
7140
+ const { fn, mem } = this.runtime;
7141
+ const pool = this.session.pagePool();
7142
+ const pagePtr = pool.acquire(pageObjectNumber);
7143
+ try {
7144
+ const annotPtrs = this.resolveAll(pagePtr, refs);
7145
+ let code;
7146
+ let statuses;
7147
+ try {
7148
+ [code, statuses] = this.withHandleArray(annotPtrs, (arrayPtr) => withScratch(mem, 4 * refs.length, (statusPtr) => {
7149
+ const rc = fn.EPDFPage_FlattenAnnotations(pagePtr, arrayPtr, refs.length, usage === "print" ? 1 : 0, statusPtr);
7150
+ const out = [];
7151
+ for (let i = 0; i < refs.length; i++) out.push(Number(mem.peek(statusPtr, "i32", 4 * i)));
7152
+ return [rc, out];
7153
+ }));
7154
+ } finally {
7155
+ for (const annotPtr of annotPtrs) fn.FPDFPage_CloseAnnot(annotPtr);
7156
+ }
7157
+ if (code === FLATTEN_FAIL$1) {
7158
+ const foreign = statuses.findIndex((status) => status === STATUS_NOT_ON_PAGE);
7159
+ throw new _embedpdf_engine_core_runtime.EngineError(foreign >= 0 ? _embedpdf_engine_core_runtime.EngineErrorCode.InvalidArg : _embedpdf_engine_core_runtime.EngineErrorCode.Unknown, foreign >= 0 ? `annotations.flatten: ref ${foreign} is not an annotation of page ${pageObjectNumber}` : "native annotation flatten failed after preflight");
7160
+ }
7161
+ const results = refs.map((ref, i) => ({
7162
+ ref,
7163
+ status: statuses[i] === STATUS_APPLIED ? "applied" : "skipped"
7164
+ }));
7165
+ if (code === FLATTEN_NOTHING_TO_DO$1 || code !== FLATTEN_SUCCESS$1) return {
7166
+ pageObjectNumber,
7167
+ usage,
7168
+ results,
7169
+ meta: null
7170
+ };
7171
+ this.session.noteMutation();
7172
+ this.session.bumpRevision(pageObjectNumber);
7173
+ try {
7174
+ new AnnotationReader(this.runtime, this.session).list(pageObjectNumber, signal);
7175
+ } catch {}
7176
+ return {
7177
+ pageObjectNumber,
7178
+ usage,
7179
+ results,
7180
+ meta: {
7181
+ affectedPages: [this.session.pageState(pageObjectNumber)],
7182
+ cacheDelta: null
7183
+ }
7184
+ };
7185
+ } finally {
7186
+ pool.release(pageObjectNumber);
7187
+ }
7188
+ }
7189
+ exportAppearance(pageObjectNumber, refs, signal) {
7190
+ throwIfAborted(signal);
7191
+ this.requireRefs("annotations.exportAppearance", pageObjectNumber, refs);
7192
+ const { fn, mem } = this.runtime;
7193
+ const pool = this.session.pagePool();
7194
+ const pagePtr = pool.acquire(pageObjectNumber);
7195
+ let exportedPtr = null;
7196
+ let pdfPtr = null;
7197
+ try {
7198
+ const annotPtrs = this.resolveAll(pagePtr, refs);
7199
+ try {
7200
+ exportedPtr = this.withHandleArray(annotPtrs, (arrayPtr) => fn.EPDFPage_ExportAnnotationsAsDocument(pagePtr, arrayPtr, refs.length));
7201
+ } finally {
7202
+ for (const annotPtr of annotPtrs) fn.FPDFPage_CloseAnnot(annotPtr);
7203
+ }
7204
+ if (!exportedPtr) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.InvalidArg, "annotations.exportAppearance: every ref must be a visible annotation of this page with a normal appearance");
7205
+ return withScratch(mem, 4, (sizePtr) => {
7206
+ mem.poke(sizePtr, "i32", 0);
7207
+ pdfPtr = fn.EPDF_SaveDocumentToOwnedBuffer(exportedPtr, FPDF_NO_INCREMENTAL$1, sizePtr);
7208
+ const size = Number(mem.peek(sizePtr, "i32"));
7209
+ if (!pdfPtr || size <= 0) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.DocOpenFailed, "failed to save exported appearances");
7210
+ const bytes = mem.readBytes(pdfPtr, size);
7211
+ const buffer = new ArrayBuffer(bytes.byteLength);
7212
+ new Uint8Array(buffer).set(bytes);
7213
+ return {
7214
+ bytes: buffer,
7215
+ size
7216
+ };
7217
+ });
7218
+ } finally {
7219
+ if (pdfPtr) fn.EPDF_FreeBuffer(pdfPtr);
7220
+ if (exportedPtr) fn.FPDF_CloseDocument(exportedPtr);
7221
+ pool.release(pageObjectNumber);
7222
+ }
7223
+ }
7224
+ /** Resolve every ref on `pagePtr` (NotFound / InvalidReference from the
7225
+ * resolver on caller error); on any failure, close what was opened. */
7226
+ resolveAll(pagePtr, refs) {
7227
+ const { fn } = this.runtime;
7228
+ const annotPtrs = [];
7229
+ try {
7230
+ for (const ref of refs) annotPtrs.push(resolveAnnotPtr(this.runtime, this.session, pagePtr, ref));
7231
+ return annotPtrs;
7232
+ } catch (error) {
7233
+ for (const annotPtr of annotPtrs) fn.FPDFPage_CloseAnnot(annotPtr);
7234
+ throw error;
7235
+ }
7236
+ }
7237
+ /** Marshal an `FPDF_ANNOTATION*` array for the call's duration. */
7238
+ withHandleArray(annotPtrs, body) {
7239
+ const { mem } = this.runtime;
7240
+ const isWasm = this.runtime.kind === "wasm";
7241
+ const ptrSize = isWasm ? 4 : 8;
7242
+ return withScratch(mem, Math.max(1, annotPtrs.length * ptrSize), (arrayPtr) => {
7243
+ annotPtrs.forEach((ptr, i) => isWasm ? mem.poke(arrayPtr, "i32", Number(ptr), i * 4) : mem.poke(arrayPtr, "i64", ptr, i * 8));
7244
+ return body(arrayPtr);
7245
+ });
7246
+ }
7247
+ requireRefs(op, pageObjectNumber, refs) {
7248
+ if (refs.length === 0) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.InvalidArg, `${op} requires at least one ref`);
7249
+ for (const ref of refs) if (ref.pageObjectNumber !== pageObjectNumber) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.InvalidArg, `${op} refs must all target page ${pageObjectNumber}; got ref on page ${ref.pageObjectNumber}`);
7250
+ }
7251
+ };
7252
+ //#endregion
7083
7253
  //#region src/features/pages/PagesFlattener.ts
7084
7254
  const FLATTEN_FAIL = 0;
7085
7255
  const FLATTEN_SUCCESS = 1;
@@ -9686,6 +9856,18 @@ var WorkerHost = class {
9686
9856
  case "pages.delete":
9687
9857
  resultPack = this.handlePagesDelete(msg, ctrl.signal);
9688
9858
  break;
9859
+ case "pages.setName":
9860
+ resultPack = this.handlePagesSetName(msg, ctrl.signal);
9861
+ break;
9862
+ case "annotations.flatten":
9863
+ resultPack = this.handleAnnotationsFlatten(msg, ctrl.signal);
9864
+ break;
9865
+ case "annotations.exportAppearance":
9866
+ resultPack = this.handleAnnotationsExportAppearance(msg, ctrl.signal);
9867
+ break;
9868
+ case "pages.removeName":
9869
+ resultPack = this.handlePagesRemoveName(msg, ctrl.signal);
9870
+ break;
9689
9871
  case "pages.flatten":
9690
9872
  resultPack = this.handlePagesFlatten(msg, ctrl.signal);
9691
9873
  break;
@@ -9913,6 +10095,27 @@ var WorkerHost = class {
9913
10095
  result
9914
10096
  }, req.artifactPath);
9915
10097
  }
10098
+ handleAnnotationsFlatten(req, signal) {
10099
+ const session = this.requireSession(req);
10100
+ const result = new AnnotationFlattener(this.runtime, session).flatten(req.pageObjectNumber, req.refs, req.usage, signal);
10101
+ if (result.meta === null) return (0, _embedpdf_engine_core_runtime.wirePack)({
10102
+ tag: "annotations.flatten",
10103
+ result
10104
+ });
10105
+ return this.finishMutation(session, {
10106
+ tag: "annotations.flatten",
10107
+ result
10108
+ }, req.artifactPath);
10109
+ }
10110
+ handleAnnotationsExportAppearance(req, signal) {
10111
+ const session = this.requireSession(req);
10112
+ const exported = new AnnotationFlattener(this.runtime, session).exportAppearance(req.pageObjectNumber, req.refs, signal);
10113
+ return (0, _embedpdf_engine_core_runtime.wirePack)({
10114
+ tag: "annotations.exportAppearance",
10115
+ bytes: exported.bytes,
10116
+ size: exported.size
10117
+ }, [exported.bytes]);
10118
+ }
9916
10119
  handleAnnotationsMove(req, signal) {
9917
10120
  const session = this.requireSession(req);
9918
10121
  const result = new AnnotationMutator(this.runtime, session).move(req.pageObjectNumber, req.refs, req.toIndex, signal);
@@ -9952,6 +10155,26 @@ var WorkerHost = class {
9952
10155
  result
9953
10156
  }, req.artifactPath);
9954
10157
  }
10158
+ handlePagesSetName(req, signal) {
10159
+ const session = this.requireSession(req);
10160
+ const result = new PagesMutator(this.runtime, session).setName({
10161
+ name: req.name,
10162
+ pageObjectNumber: req.pageObjectNumber,
10163
+ ...req.replace !== void 0 ? { replace: req.replace } : {}
10164
+ }, signal);
10165
+ return this.finishMutation(session, {
10166
+ tag: "pages.setName",
10167
+ result
10168
+ }, req.artifactPath);
10169
+ }
10170
+ handlePagesRemoveName(req, signal) {
10171
+ const session = this.requireSession(req);
10172
+ const result = new PagesMutator(this.runtime, session).removeName({ name: req.name }, signal);
10173
+ return this.finishMutation(session, {
10174
+ tag: "pages.removeName",
10175
+ result
10176
+ }, req.artifactPath);
10177
+ }
9955
10178
  handlePagesFlatten(req, signal) {
9956
10179
  const session = this.requireSession(req);
9957
10180
  const result = new PagesFlattener(this.runtime, session).flatten(req.pageObjectNumbers, req.usage, signal);
@@ -10529,6 +10752,7 @@ function passwordRequiredProbe() {
10529
10752
  exports.ALL_STANDARD_SECURITY_PERMISSIONS = ALL_STANDARD_SECURITY_PERMISSIONS;
10530
10753
  exports.ActionReadBudgetTracker = ActionReadBudgetTracker;
10531
10754
  exports.AnnotationAppearanceReader = AnnotationAppearanceReader;
10755
+ exports.AnnotationFlattener = AnnotationFlattener;
10532
10756
  exports.AnnotationMutator = AnnotationMutator;
10533
10757
  exports.AnnotationReader = AnnotationReader;
10534
10758
  exports.AttachmentMutator = AttachmentMutator;