web-doc 0.6.2 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (201) hide show
  1. package/THIRD_PARTY_NOTICES.md +33 -1
  2. package/dist/adapters/docx-images.d.ts +13 -4
  3. package/dist/adapters/docx-images.js +3 -0
  4. package/dist/adapters/docx-paragraphs.d.ts +65 -0
  5. package/dist/adapters/docx-paragraphs.js +165 -0
  6. package/dist/adapters/docx-prepass.d.ts +17 -0
  7. package/dist/adapters/docx-prepass.js +230 -0
  8. package/dist/adapters/office.d.ts +31 -5
  9. package/dist/adapters/office.js +60 -29
  10. package/dist/adapters/pdf.d.ts +9 -0
  11. package/dist/adapters/pdf.js +10 -0
  12. package/dist/assets/pdfium/pdfium.wasm +0 -0
  13. package/dist/contracts.d.ts +53 -2
  14. package/dist/edit/ai/outline.d.ts +47 -0
  15. package/dist/edit/ai/outline.js +338 -0
  16. package/dist/edit/ai/targets.d.ts +16 -0
  17. package/dist/edit/ai/targets.js +309 -0
  18. package/dist/edit/ai/tools.d.ts +28 -0
  19. package/dist/edit/ai/tools.js +605 -0
  20. package/dist/edit/ai/types.d.ts +175 -0
  21. package/dist/edit/ai/types.js +1 -0
  22. package/dist/edit/assets.d.ts +23 -0
  23. package/dist/edit/assets.js +75 -0
  24. package/dist/edit/docx/elements.d.ts +6 -0
  25. package/dist/edit/docx/elements.js +90 -0
  26. package/dist/edit/docx/engine.d.ts +57 -0
  27. package/dist/edit/docx/engine.js +547 -0
  28. package/dist/edit/docx/handlers.d.ts +3 -0
  29. package/dist/edit/docx/handlers.js +15 -0
  30. package/dist/edit/docx/ids.d.ts +45 -0
  31. package/dist/edit/docx/ids.js +101 -0
  32. package/dist/edit/docx/model.d.ts +94 -0
  33. package/dist/edit/docx/model.js +350 -0
  34. package/dist/edit/docx/operations.d.ts +47 -0
  35. package/dist/edit/docx/operations.js +3 -0
  36. package/dist/edit/docx/provider.d.ts +16 -0
  37. package/dist/edit/docx/provider.js +37 -0
  38. package/dist/edit/docx/schemas.d.ts +6 -0
  39. package/dist/edit/docx/schemas.js +192 -0
  40. package/dist/edit/docx/session.d.ts +48 -0
  41. package/dist/edit/docx/session.js +467 -0
  42. package/dist/edit/docx/structure-ops.d.ts +6 -0
  43. package/dist/edit/docx/structure-ops.js +529 -0
  44. package/dist/edit/docx/style.d.ts +45 -0
  45. package/dist/edit/docx/style.js +375 -0
  46. package/dist/edit/docx/table-ops.d.ts +4 -0
  47. package/dist/edit/docx/table-ops.js +241 -0
  48. package/dist/edit/docx/text-ops.d.ts +40 -0
  49. package/dist/edit/docx/text-ops.js +491 -0
  50. package/dist/edit/docx/text.d.ts +34 -0
  51. package/dist/edit/docx/text.js +284 -0
  52. package/dist/edit/docx/tracked.d.ts +52 -0
  53. package/dist/edit/docx/tracked.js +347 -0
  54. package/dist/edit/docx/types.d.ts +206 -0
  55. package/dist/edit/docx/types.js +1 -0
  56. package/dist/edit/docx/write.d.ts +64 -0
  57. package/dist/edit/docx/write.js +375 -0
  58. package/dist/edit/engine.d.ts +128 -0
  59. package/dist/edit/engine.js +1 -0
  60. package/dist/edit/history.d.ts +77 -0
  61. package/dist/edit/history.js +123 -0
  62. package/dist/edit/ooxml/names.d.ts +20 -0
  63. package/dist/edit/ooxml/names.js +61 -0
  64. package/dist/edit/ooxml/opc.d.ts +50 -0
  65. package/dist/edit/ooxml/opc.js +150 -0
  66. package/dist/edit/ooxml/package.d.ts +82 -0
  67. package/dist/edit/ooxml/package.js +233 -0
  68. package/dist/edit/ooxml/patch.d.ts +51 -0
  69. package/dist/edit/ooxml/patch.js +250 -0
  70. package/dist/edit/ooxml/transaction.d.ts +39 -0
  71. package/dist/edit/ooxml/transaction.js +316 -0
  72. package/dist/edit/ooxml/worker.d.ts +8 -0
  73. package/dist/edit/ooxml/worker.js +12 -0
  74. package/dist/edit/ooxml/writer.d.ts +21 -0
  75. package/dist/edit/ooxml/writer.js +187 -0
  76. package/dist/edit/ooxml/xml.d.ts +74 -0
  77. package/dist/edit/ooxml/xml.js +451 -0
  78. package/dist/edit/ooxml/zip.d.ts +54 -0
  79. package/dist/edit/ooxml/zip.js +280 -0
  80. package/dist/edit/operations.d.ts +19 -0
  81. package/dist/edit/operations.js +137 -0
  82. package/dist/edit/pdf/engine/compact.d.ts +6 -0
  83. package/dist/edit/pdf/engine/compact.js +442 -0
  84. package/dist/edit/pdf/engine/document.d.ts +95 -0
  85. package/dist/edit/pdf/engine/document.js +868 -0
  86. package/dist/edit/pdf/engine/elements.d.ts +45 -0
  87. package/dist/edit/pdf/engine/elements.js +313 -0
  88. package/dist/edit/pdf/engine/existing-text.d.ts +4 -0
  89. package/dist/edit/pdf/engine/existing-text.js +424 -0
  90. package/dist/edit/pdf/engine/fonts.d.ts +78 -0
  91. package/dist/edit/pdf/engine/fonts.js +466 -0
  92. package/dist/edit/pdf/engine/geometry.d.ts +36 -0
  93. package/dist/edit/pdf/engine/geometry.js +97 -0
  94. package/dist/edit/pdf/engine/handler.d.ts +21 -0
  95. package/dist/edit/pdf/engine/handler.js +108 -0
  96. package/dist/edit/pdf/engine/images.d.ts +33 -0
  97. package/dist/edit/pdf/engine/images.js +188 -0
  98. package/dist/edit/pdf/engine/layout.d.ts +23 -0
  99. package/dist/edit/pdf/engine/layout.js +177 -0
  100. package/dist/edit/pdf/engine/operations.d.ts +67 -0
  101. package/dist/edit/pdf/engine/operations.js +3 -0
  102. package/dist/edit/pdf/engine/pages.d.ts +6 -0
  103. package/dist/edit/pdf/engine/pages.js +98 -0
  104. package/dist/edit/pdf/engine/pdfium.d.ts +195 -0
  105. package/dist/edit/pdf/engine/pdfium.js +249 -0
  106. package/dist/edit/pdf/engine/shapes.d.ts +4 -0
  107. package/dist/edit/pdf/engine/shapes.js +183 -0
  108. package/dist/edit/pdf/engine/tables.d.ts +44 -0
  109. package/dist/edit/pdf/engine/tables.js +315 -0
  110. package/dist/edit/pdf/engine/text-box.d.ts +71 -0
  111. package/dist/edit/pdf/engine/text-box.js +317 -0
  112. package/dist/edit/pdf/engine/text-layout.d.ts +28 -0
  113. package/dist/edit/pdf/engine/text-layout.js +67 -0
  114. package/dist/edit/pdf/engine/transform.d.ts +5 -0
  115. package/dist/edit/pdf/engine/transform.js +137 -0
  116. package/dist/edit/pdf/provider.d.ts +35 -0
  117. package/dist/edit/pdf/provider.js +92 -0
  118. package/dist/edit/pdf/range-map.d.ts +16 -0
  119. package/dist/edit/pdf/range-map.js +107 -0
  120. package/dist/edit/pdf/schemas.d.ts +11 -0
  121. package/dist/edit/pdf/schemas.js +291 -0
  122. package/dist/edit/pdf/selection.d.ts +5 -0
  123. package/dist/edit/pdf/selection.js +152 -0
  124. package/dist/edit/pdf/session.d.ts +63 -0
  125. package/dist/edit/pdf/session.js +312 -0
  126. package/dist/edit/pdf/types.d.ts +336 -0
  127. package/dist/edit/pdf/types.js +1 -0
  128. package/dist/edit/pptx/elements.d.ts +74 -0
  129. package/dist/edit/pptx/elements.js +301 -0
  130. package/dist/edit/pptx/engine.d.ts +37 -0
  131. package/dist/edit/pptx/engine.js +466 -0
  132. package/dist/edit/pptx/geometry.d.ts +72 -0
  133. package/dist/edit/pptx/geometry.js +193 -0
  134. package/dist/edit/pptx/handler.d.ts +7 -0
  135. package/dist/edit/pptx/handler.js +99 -0
  136. package/dist/edit/pptx/handlers.d.ts +3 -0
  137. package/dist/edit/pptx/handlers.js +21 -0
  138. package/dist/edit/pptx/image-table-ops.d.ts +5 -0
  139. package/dist/edit/pptx/image-table-ops.js +233 -0
  140. package/dist/edit/pptx/model.d.ts +69 -0
  141. package/dist/edit/pptx/model.js +170 -0
  142. package/dist/edit/pptx/operations.d.ts +50 -0
  143. package/dist/edit/pptx/operations.js +11 -0
  144. package/dist/edit/pptx/provider.d.ts +17 -0
  145. package/dist/edit/pptx/provider.js +40 -0
  146. package/dist/edit/pptx/schemas.d.ts +6 -0
  147. package/dist/edit/pptx/schemas.js +220 -0
  148. package/dist/edit/pptx/session.d.ts +54 -0
  149. package/dist/edit/pptx/session.js +145 -0
  150. package/dist/edit/pptx/shape-ops.d.ts +10 -0
  151. package/dist/edit/pptx/shape-ops.js +486 -0
  152. package/dist/edit/pptx/slide-ops.d.ts +6 -0
  153. package/dist/edit/pptx/slide-ops.js +353 -0
  154. package/dist/edit/pptx/style.d.ts +31 -0
  155. package/dist/edit/pptx/style.js +181 -0
  156. package/dist/edit/pptx/text-ops.d.ts +13 -0
  157. package/dist/edit/pptx/text-ops.js +267 -0
  158. package/dist/edit/pptx/text-write.d.ts +67 -0
  159. package/dist/edit/pptx/text-write.js +293 -0
  160. package/dist/edit/pptx/text.d.ts +41 -0
  161. package/dist/edit/pptx/text.js +99 -0
  162. package/dist/edit/pptx/types.d.ts +232 -0
  163. package/dist/edit/pptx/types.js +1 -0
  164. package/dist/edit/schema.d.ts +11 -0
  165. package/dist/edit/schema.js +275 -0
  166. package/dist/edit/session.d.ts +77 -0
  167. package/dist/edit/session.js +943 -0
  168. package/dist/edit/sessions.d.ts +8 -0
  169. package/dist/edit/sessions.js +1 -0
  170. package/dist/edit/types.d.ts +290 -0
  171. package/dist/edit/types.js +1 -0
  172. package/dist/edit/worker-engine.d.ts +31 -0
  173. package/dist/edit/worker-engine.js +91 -0
  174. package/dist/fonts/THIRD_PARTY_NOTICES.md +3 -0
  175. package/dist/fonts/manifest.json +6 -1
  176. package/dist/fonts/noto-sans-latin-cyrillic.ttf +0 -0
  177. package/dist/fonts.d.ts +2 -0
  178. package/dist/fonts.js +4 -0
  179. package/dist/fuzzy-alignment.d.ts +11 -4
  180. package/dist/fuzzy-alignment.js +3 -9
  181. package/dist/headless.d.ts +5 -1
  182. package/dist/headless.js +8 -1
  183. package/dist/index.d.ts +10 -2
  184. package/dist/index.js +16 -2
  185. package/dist/limits.js +6 -0
  186. package/dist/ooxml-edit-worker.d.ts +1 -0
  187. package/dist/ooxml-edit-worker.js +8 -0
  188. package/dist/pdf-edit-worker.d.ts +1 -0
  189. package/dist/pdf-edit-worker.js +35 -0
  190. package/dist/spreadsheet-viewport.d.ts +5 -0
  191. package/dist/spreadsheet-viewport.js +11 -0
  192. package/dist/ui.js +7 -0
  193. package/dist/viewer.d.ts +6 -0
  194. package/dist/viewer.js +293 -19
  195. package/dist/viewport.d.ts +13 -0
  196. package/dist/viewport.js +126 -1
  197. package/dist/worker-protocol.d.ts +39 -2
  198. package/dist/workers/fuzzy-search-worker.js +1 -1
  199. package/dist/workers/ooxml-edit-worker.js +9212 -0
  200. package/dist/workers/pdf-edit-worker.js +10847 -0
  201. package/package.json +3 -3
@@ -0,0 +1,98 @@
1
+ /*
2
+ * Page structure. The model's page records move with the pages, so element
3
+ * ids keep pointing at the same content whatever happens to page order.
4
+ */
5
+ export const insertPage = {
6
+ validate(operation, context, issue) {
7
+ if (operation.index > context.pageCount)
8
+ issue("/index", "range", `The index must be at most the page count (${context.pageCount})`);
9
+ },
10
+ apply(operation, context) {
11
+ const { lib } = context.pdfium;
12
+ const size = operation.size ?? neighbourSize(operation.index, context);
13
+ const page = lib.FPDFPage_New(context.document, operation.index, size.width, size.height);
14
+ lib.FPDFPage_GenerateContent(page);
15
+ lib.FPDF_ClosePage(page);
16
+ context.insertPageRecord(operation.index);
17
+ return {
18
+ createdIds: [],
19
+ changedPages: fromIndex(operation.index, context.pageCount + 1),
20
+ warnings: [],
21
+ };
22
+ },
23
+ };
24
+ export const deletePage = {
25
+ validate(operation, context, issue) {
26
+ if (operation.pageIndex >= context.pageCount)
27
+ issue("/pageIndex", "unknown-target", `No page ${operation.pageIndex}`);
28
+ else if (context.pageCount === 1)
29
+ issue("/pageIndex", "last-page", "The last page cannot be deleted");
30
+ },
31
+ apply(operation, context) {
32
+ const removedIds = context.pageElementIds(operation.pageIndex);
33
+ context.pdfium.lib.FPDFPage_Delete(context.document, operation.pageIndex);
34
+ context.removePageRecord(operation.pageIndex);
35
+ return {
36
+ createdIds: [],
37
+ removedIds,
38
+ changedPages: fromIndex(operation.pageIndex, context.pageCount - 1),
39
+ warnings: [],
40
+ };
41
+ },
42
+ };
43
+ export const movePage = {
44
+ validate(operation, context, issue) {
45
+ if (operation.from >= context.pageCount)
46
+ issue("/from", "unknown-target", `No page ${operation.from}`);
47
+ if (operation.to >= context.pageCount)
48
+ issue("/to", "range", `The index must be below the page count (${context.pageCount})`);
49
+ },
50
+ apply(operation, context) {
51
+ const { pdfium } = context;
52
+ if (operation.from !== operation.to) {
53
+ const indexes = pdfium.writeInt32Array([operation.from]);
54
+ try {
55
+ // PDFium takes the page out first, so the destination is the index
56
+ // the page will have afterwards.
57
+ pdfium.lib.FPDF_MovePages(context.document, indexes, 1, operation.to);
58
+ }
59
+ finally {
60
+ pdfium.free(indexes);
61
+ }
62
+ context.movePageRecord(operation.from, operation.to);
63
+ }
64
+ const low = Math.min(operation.from, operation.to);
65
+ const high = Math.max(operation.from, operation.to);
66
+ return {
67
+ createdIds: [],
68
+ changedPages: Array.from({ length: high - low + 1 }, (_, i) => low + i),
69
+ warnings: [],
70
+ };
71
+ },
72
+ };
73
+ export const rotatePage = {
74
+ validate(operation, context, issue) {
75
+ if (operation.pageIndex >= context.pageCount)
76
+ issue("/pageIndex", "unknown-target", `No page ${operation.pageIndex}`);
77
+ },
78
+ apply(operation, context) {
79
+ const { lib } = context.pdfium;
80
+ context.withPage(operation.pageIndex, (page) => {
81
+ lib.FPDFPage_SetRotation(page, operation.rotation / 90);
82
+ });
83
+ context.invalidatePage(operation.pageIndex);
84
+ return {
85
+ createdIds: [],
86
+ changedPages: [operation.pageIndex],
87
+ warnings: [],
88
+ };
89
+ },
90
+ };
91
+ function neighbourSize(index, context) {
92
+ if (context.pageCount === 0)
93
+ return { width: 612, height: 792 };
94
+ return context.pageSize(index > 0 ? index - 1 : 0);
95
+ }
96
+ function fromIndex(start, pageCount) {
97
+ return Array.from({ length: Math.max(0, pageCount - start) }, (_, i) => start + i);
98
+ }
@@ -0,0 +1,195 @@
1
+ /**
2
+ * The PDFium entry points the PDF edit engine calls, typed from
3
+ * `@embedpdf/pdfium`'s `functions` table. Pointers and handles are plain
4
+ * numbers in the WASM address space.
5
+ */
6
+ export interface PdfiumFunctions {
7
+ PDFiumExt_Init(): void;
8
+ PDFiumExt_OpenFileWriter(): number;
9
+ PDFiumExt_GetFileWriterSize(writer: number): number;
10
+ PDFiumExt_GetFileWriterData(writer: number, buffer: number, size: number): number;
11
+ PDFiumExt_CloseFileWriter(writer: number): void;
12
+ FPDF_GetLastError(): number;
13
+ FPDF_CreateNewDocument(): number;
14
+ FPDF_LoadMemDocument(data: number, size: number, password: string): number;
15
+ FPDF_CloseDocument(document: number): void;
16
+ FPDF_SaveAsCopy(document: number, writer: number, flags: number): boolean;
17
+ FPDF_GetPageCount(document: number): number;
18
+ FPDF_GetSignatureCount(document: number): number;
19
+ FPDF_StructTree_GetForPage(page: number): number;
20
+ FPDF_StructTree_CountChildren(tree: number): number;
21
+ FPDF_StructTree_Close(tree: number): void;
22
+ FPDF_LoadPage(document: number, pageIndex: number): number;
23
+ FPDF_ClosePage(page: number): void;
24
+ FPDF_GetPageWidthF(page: number): number;
25
+ FPDF_GetPageHeightF(page: number): number;
26
+ /** Media box ∩ crop box in user space, as an FS_RECTF {left, top, right, bottom}. */
27
+ FPDF_GetPageBoundingBox(page: number, rect: number): boolean;
28
+ FPDF_PageToDevice(page: number, startX: number, startY: number, sizeX: number, sizeY: number, rotate: number, pageX: number, pageY: number, deviceX: number, deviceY: number): boolean;
29
+ FPDFPage_SetCropBox(page: number, left: number, bottom: number, right: number, top: number): void;
30
+ FPDF_MovePages(document: number, pageIndices: number, count: number, destination: number): boolean;
31
+ FPDFPage_New(document: number, pageIndex: number, width: number, height: number): number;
32
+ FPDFPage_Delete(document: number, pageIndex: number): void;
33
+ FPDFPage_GetRotation(page: number): number;
34
+ FPDFPage_SetRotation(page: number, rotation: number): void;
35
+ FPDFPage_CountObjects(page: number): number;
36
+ FPDFPage_GetObject(page: number, index: number): number;
37
+ FPDFPage_InsertObject(page: number, object: number): void;
38
+ FPDFPage_InsertObjectAtIndex(page: number, object: number, index: number): boolean;
39
+ FPDFPage_GenerateContent(page: number): boolean;
40
+ FPDFPageObj_GetType(object: number): number;
41
+ /** Four floats: left, bottom, right, top in user space. */
42
+ FPDFPageObj_GetBounds(object: number, left: number, bottom: number, right: number, top: number): boolean;
43
+ /** Six floats a, b, c, d, e, f. */
44
+ FPDFPageObj_GetMatrix(object: number, matrix: number): boolean;
45
+ FPDFPageObj_GetFillColor(object: number, r: number, g: number, b: number, a: number): boolean;
46
+ FPDFPageObj_GetStrokeColor(object: number, r: number, g: number, b: number, a: number): boolean;
47
+ FPDFPageObj_GetStrokeWidth(object: number, width: number): boolean;
48
+ FPDFPageObj_SetFillColor(object: number, r: number, g: number, b: number, a: number): boolean;
49
+ FPDFPageObj_SetStrokeColor(object: number, r: number, g: number, b: number, a: number): boolean;
50
+ FPDFPageObj_SetStrokeWidth(object: number, width: number): boolean;
51
+ FPDFPageObj_CreateNewRect(x: number, y: number, width: number, height: number): number;
52
+ FPDFPath_GetDrawMode(path: number, fillMode: number, stroke: number): boolean;
53
+ FPDFPageObj_CreateNewPath(x: number, y: number): number;
54
+ FPDFPath_MoveTo(path: number, x: number, y: number): boolean;
55
+ FPDFPath_LineTo(path: number, x: number, y: number): boolean;
56
+ FPDFPath_BezierTo(path: number, x1: number, y1: number, x2: number, y2: number, x3: number, y3: number): boolean;
57
+ FPDFPath_Close(path: number): boolean;
58
+ FPDFPageObj_SetLineJoin(object: number, join: number): boolean;
59
+ FPDFPath_SetDrawMode(path: number, fillMode: number, stroke: boolean): boolean;
60
+ FPDFTextObj_GetText(textObject: number, textPage: number, buffer: number, bytes: number): number;
61
+ FPDFTextObj_GetFontSize(textObject: number, size: number): boolean;
62
+ FPDFTextObj_GetFont(textObject: number): number;
63
+ FPDFFont_GetFamilyName(font: number, buffer: number, bytes: number): number;
64
+ FPDFFont_GetBaseFontName(font: number, buffer: number, bytes: number): number;
65
+ FPDFFont_GetFlags(font: number): number;
66
+ FPDFFont_GetIsEmbedded(font: number): number;
67
+ FPDFFont_GetAscent(font: number, fontSize: number, ascent: number): boolean;
68
+ FPDFFont_GetDescent(font: number, fontSize: number, descent: number): boolean;
69
+ FPDFPageObj_Destroy(object: number): void;
70
+ FPDFPage_RemoveObject(page: number, object: number): boolean;
71
+ FPDFFont_GetWeight(font: number): number;
72
+ FPDFText_GetCharBox(textPage: number, index: number, left: number, right: number, bottom: number, top: number): boolean;
73
+ FPDFText_GetTextObject(textPage: number, index: number): number;
74
+ FPDFText_GetUnicode(textPage: number, index: number): number;
75
+ FPDFText_GetCharIndexFromTextIndex(textPage: number, textIndex: number): number;
76
+ /** Advance box of a character as an FS_RECTF {left, top, right, bottom} of floats. */
77
+ FPDFText_GetLooseCharBox(textPage: number, index: number, rect: number): boolean;
78
+ /** Two doubles: the glyph origin in user space. */
79
+ FPDFText_GetCharOrigin(textPage: number, index: number, x: number, y: number): boolean;
80
+ /** Char index at a user-space point within the tolerances, -1 for none, -3 on error. */
81
+ FPDFText_GetCharIndexAtPos(textPage: number, x: number, y: number, xTolerance: number, yTolerance: number): number;
82
+ FPDFPageObjMark_CountParams(mark: number): number;
83
+ FPDFPageObj_Transform(object: number, a: number, b: number, c: number, d: number, e: number, f: number): void;
84
+ FPDFPageObj_CreateTextObj(document: number, font: number, fontSize: number): number;
85
+ FPDFPageObj_NewImageObj(document: number): number;
86
+ FPDFPageObj_AddMark(object: number, name: string): number;
87
+ FPDFPageObj_CountMarks(object: number): number;
88
+ FPDFPageObj_GetMark(object: number, index: number): number;
89
+ FPDFPageObjMark_GetName(mark: number, buffer: number, bufferBytes: number, outBytes: number): boolean;
90
+ FPDFPageObjMark_SetStringParam(document: number, object: number, mark: number, key: string, value: string): boolean;
91
+ FPDFPageObjMark_GetParamStringValue(mark: number, key: string, buffer: number, bufferBytes: number, outBytes: number): boolean;
92
+ FPDFImageObj_LoadJpegFileInline(pages: number, count: number, image: number, fileAccess: number): boolean;
93
+ FPDFImageObj_SetBitmap(pages: number, count: number, image: number, bitmap: number): boolean;
94
+ FPDFBitmap_CreateEx(width: number, height: number, format: number, buffer: number, stride: number): number;
95
+ FPDFBitmap_Destroy(bitmap: number): void;
96
+ FPDFBitmap_FillRect(bitmap: number, left: number, top: number, width: number, height: number, color: number): boolean;
97
+ FPDFBitmap_GetBuffer(bitmap: number): number;
98
+ /** Draws the page into the bitmap at the given device rectangle; `rotate` adds quarter turns. */
99
+ FPDF_RenderPageBitmap(bitmap: number, page: number, startX: number, startY: number, sizeX: number, sizeY: number, rotate: number, flags: number): void;
100
+ /** Whether an object takes part in rendering and content generation; out param is an int. */
101
+ FPDFPageObj_GetIsActive(object: number, active: number): boolean;
102
+ FPDFPageObj_SetIsActive(object: number, active: boolean): boolean;
103
+ FPDFImageObj_GetImagePixelSize(image: number, width: number, height: number): boolean;
104
+ FPDFImageObj_SetMatrix(image: number, a: number, b: number, c: number, d: number, e: number, f: number): boolean;
105
+ FPDFText_LoadStandardFont(document: number, name: string): number;
106
+ FPDFText_LoadFont(document: number, data: number, size: number, fontType: number, cid: boolean): number;
107
+ FPDFFont_Close(font: number): void;
108
+ /** Copies the embedded font program; reports the size needed through `outBytes`. */
109
+ FPDFFont_GetFontData(font: number, buffer: number, bytes: number, outBytes: number): boolean;
110
+ FPDFText_SetText(textObject: number, text: number): boolean;
111
+ FPDFText_LoadPage(page: number): number;
112
+ FPDFText_ClosePage(textPage: number): void;
113
+ FPDFText_CountChars(textPage: number): number;
114
+ FPDFText_GetText(textPage: number, start: number, count: number, buffer: number): number;
115
+ }
116
+ /** The Emscripten runtime helpers `@embedpdf/pdfium` re-exports. */
117
+ export interface PdfiumRuntime {
118
+ readonly HEAPU8: Uint8Array;
119
+ readonly wasmExports: {
120
+ malloc(size: number): number;
121
+ free(pointer: number): void;
122
+ };
123
+ UTF16ToString(pointer: number, maxBytesToRead?: number): string;
124
+ stringToUTF16(text: string, pointer: number, maxBytesToWrite?: number): number;
125
+ addFunction(callback: (...args: number[]) => number, signature: string): number;
126
+ removeFunction(pointer: number): void;
127
+ getValue(pointer: number, type: "i32" | "float" | "double"): number;
128
+ setValue(pointer: number, value: number, type: "i32" | "float" | "double"): void;
129
+ }
130
+ export type PdfiumLibrary = PdfiumFunctions & {
131
+ readonly pdfium: PdfiumRuntime;
132
+ };
133
+ /** `FPDF_SaveAsCopy` flags. */
134
+ export declare const SAVE_INCREMENTAL = 1;
135
+ export declare const SAVE_FULL = 2;
136
+ /**
137
+ * Owns one PDFium WASM instance and the memory traffic across its boundary.
138
+ * PDFium keeps global heap state, so an instance must be used by one caller at
139
+ * a time; the edit worker serializes calls.
140
+ */
141
+ export declare class Pdfium {
142
+ #private;
143
+ readonly lib: PdfiumLibrary;
144
+ private constructor();
145
+ /**
146
+ * Instantiates PDFium from WASM bytes. The bytes are always supplied by the
147
+ * caller: the package's default would fetch the module from a public CDN.
148
+ */
149
+ static load(wasmBinary: ArrayBuffer | Uint8Array): Promise<Pdfium>;
150
+ malloc(size: number): number;
151
+ free(pointer: number): void;
152
+ /** Copies bytes into the WASM heap; the caller frees the pointer. */
153
+ writeBytes(bytes: Uint8Array): number;
154
+ readBytes(pointer: number, length: number): Uint8Array;
155
+ /** Writes a NUL-terminated UTF-16LE string; the caller frees the pointer. */
156
+ writeWideString(text: string): number;
157
+ /** Reads a NUL-terminated UTF-16LE string of at most `bytes` bytes. */
158
+ readWideStringAt(pointer: number, bytes: number): string;
159
+ /**
160
+ * Reads a UTF-16LE string from an API that returns the byte size it needs
161
+ * when called with an empty buffer.
162
+ */
163
+ readWideString(read: (buffer: number, bytes: number) => number): string;
164
+ /**
165
+ * Reads a UTF-16LE string from an API that reports the byte size it needs
166
+ * through an `out_buflen` pointer.
167
+ */
168
+ readWideStringOut(read: (buffer: number, bytes: number, outBytes: number) => boolean): string;
169
+ /** Reads a NUL-terminated UTF-8 string from an API that returns the byte size it needs. */
170
+ readUtf8String(read: (buffer: number, bytes: number) => number): string;
171
+ /**
172
+ * Calls `read` with a scratch buffer of `count` numbers of `type` and
173
+ * returns what was written. Used for the many PDFium out-parameters.
174
+ */
175
+ readNumbers(count: number, type: "i32" | "float" | "double", read: (pointers: number[]) => boolean): number[] | undefined;
176
+ /** Writes 32-bit integers into a fresh array; the caller frees it. */
177
+ writeInt32Array(values: readonly number[]): number;
178
+ /**
179
+ * Runs `use` with an `FPDF_FILEACCESS` that serves `bytes` to PDFium through
180
+ * a WASM table callback. Only for APIs that read the data before returning,
181
+ * such as the inline JPEG loader.
182
+ */
183
+ withFileAccess<T>(bytes: Uint8Array, use: (fileAccess: number) => T): T;
184
+ /** Opens a document from bytes; PDFium reads them lazily, so they stay in the heap. */
185
+ openDocument(bytes: Uint8Array): PdfiumDocument;
186
+ createDocument(): PdfiumDocument;
187
+ }
188
+ export declare class PdfiumDocument {
189
+ #private;
190
+ constructor(pdfium: Pdfium, handle: number, data: number);
191
+ get handle(): number;
192
+ /** Serializes the document; `incremental` appends to the bytes it was opened from. */
193
+ save(mode: "incremental" | "full"): Uint8Array;
194
+ close(): void;
195
+ }
@@ -0,0 +1,249 @@
1
+ import { ViewerError } from "../../../errors.js";
2
+ /** `FPDF_SaveAsCopy` flags. */
3
+ export const SAVE_INCREMENTAL = 1;
4
+ export const SAVE_FULL = 2;
5
+ /** `FPDF_GetLastError` value for a missing or wrong password. */
6
+ const PASSWORD_ERROR = 4;
7
+ /** Size of `FPDF_FILEACCESS` in wasm32: file length, callback, parameter. */
8
+ const FILE_ACCESS_BYTES = 12;
9
+ /**
10
+ * Owns one PDFium WASM instance and the memory traffic across its boundary.
11
+ * PDFium keeps global heap state, so an instance must be used by one caller at
12
+ * a time; the edit worker serializes calls.
13
+ */
14
+ export class Pdfium {
15
+ lib;
16
+ #runtime;
17
+ constructor(lib) {
18
+ this.lib = lib;
19
+ this.#runtime = lib.pdfium;
20
+ }
21
+ /**
22
+ * Instantiates PDFium from WASM bytes. The bytes are always supplied by the
23
+ * caller: the package's default would fetch the module from a public CDN.
24
+ */
25
+ static async load(wasmBinary) {
26
+ const { init } = (await import("@embedpdf/pdfium"));
27
+ const lib = await init({ wasmBinary: exactArrayBuffer(wasmBinary) });
28
+ lib.PDFiumExt_Init();
29
+ return new Pdfium(lib);
30
+ }
31
+ malloc(size) {
32
+ const pointer = this.#runtime.wasmExports.malloc(Math.max(1, size));
33
+ if (!pointer)
34
+ throw new ViewerError("resource-limit", "PDFium is out of memory", {
35
+ details: { bytes: size },
36
+ });
37
+ return pointer;
38
+ }
39
+ free(pointer) {
40
+ if (pointer)
41
+ this.#runtime.wasmExports.free(pointer);
42
+ }
43
+ /** Copies bytes into the WASM heap; the caller frees the pointer. */
44
+ writeBytes(bytes) {
45
+ const pointer = this.malloc(bytes.byteLength);
46
+ this.#runtime.HEAPU8.set(bytes, pointer);
47
+ return pointer;
48
+ }
49
+ readBytes(pointer, length) {
50
+ // The heap view is replaced when memory grows, so it is read on each call.
51
+ return this.#runtime.HEAPU8.slice(pointer, pointer + length);
52
+ }
53
+ /** Writes a NUL-terminated UTF-16LE string; the caller frees the pointer. */
54
+ writeWideString(text) {
55
+ const bytes = (text.length + 1) * 2;
56
+ const pointer = this.malloc(bytes);
57
+ this.#runtime.stringToUTF16(text, pointer, bytes);
58
+ return pointer;
59
+ }
60
+ /** Reads a NUL-terminated UTF-16LE string of at most `bytes` bytes. */
61
+ readWideStringAt(pointer, bytes) {
62
+ return this.#runtime.UTF16ToString(pointer, bytes);
63
+ }
64
+ /**
65
+ * Reads a UTF-16LE string from an API that returns the byte size it needs
66
+ * when called with an empty buffer.
67
+ */
68
+ readWideString(read) {
69
+ const bytes = read(0, 0);
70
+ if (bytes <= 2)
71
+ return "";
72
+ const pointer = this.malloc(bytes);
73
+ try {
74
+ read(pointer, bytes);
75
+ return this.#runtime.UTF16ToString(pointer, bytes);
76
+ }
77
+ finally {
78
+ this.free(pointer);
79
+ }
80
+ }
81
+ /**
82
+ * Reads a UTF-16LE string from an API that reports the byte size it needs
83
+ * through an `out_buflen` pointer.
84
+ */
85
+ readWideStringOut(read) {
86
+ const outBytes = this.malloc(4);
87
+ try {
88
+ if (!read(0, 0, outBytes))
89
+ return "";
90
+ const bytes = this.#runtime.getValue(outBytes, "i32");
91
+ if (bytes <= 2)
92
+ return "";
93
+ const pointer = this.malloc(bytes);
94
+ try {
95
+ if (!read(pointer, bytes, outBytes))
96
+ return "";
97
+ return this.#runtime.UTF16ToString(pointer, bytes);
98
+ }
99
+ finally {
100
+ this.free(pointer);
101
+ }
102
+ }
103
+ finally {
104
+ this.free(outBytes);
105
+ }
106
+ }
107
+ /** Reads a NUL-terminated UTF-8 string from an API that returns the byte size it needs. */
108
+ readUtf8String(read) {
109
+ const bytes = read(0, 0);
110
+ if (bytes <= 1)
111
+ return "";
112
+ const pointer = this.malloc(bytes);
113
+ try {
114
+ read(pointer, bytes);
115
+ const raw = this.readBytes(pointer, bytes);
116
+ const end = raw.indexOf(0);
117
+ return new TextDecoder().decode(end < 0 ? raw : raw.subarray(0, end));
118
+ }
119
+ finally {
120
+ this.free(pointer);
121
+ }
122
+ }
123
+ /**
124
+ * Calls `read` with a scratch buffer of `count` numbers of `type` and
125
+ * returns what was written. Used for the many PDFium out-parameters.
126
+ */
127
+ readNumbers(count, type, read) {
128
+ const size = type === "double" ? 8 : 4;
129
+ const base = this.malloc(count * size);
130
+ try {
131
+ const pointers = Array.from({ length: count }, (_, i) => base + i * size);
132
+ if (!read(pointers))
133
+ return undefined;
134
+ return pointers.map((pointer) => this.#runtime.getValue(pointer, type));
135
+ }
136
+ finally {
137
+ this.free(base);
138
+ }
139
+ }
140
+ /** Writes 32-bit integers into a fresh array; the caller frees it. */
141
+ writeInt32Array(values) {
142
+ const pointer = this.malloc(values.length * 4);
143
+ values.forEach((value, index) => this.#runtime.setValue(pointer + index * 4, value, "i32"));
144
+ return pointer;
145
+ }
146
+ /**
147
+ * Runs `use` with an `FPDF_FILEACCESS` that serves `bytes` to PDFium through
148
+ * a WASM table callback. Only for APIs that read the data before returning,
149
+ * such as the inline JPEG loader.
150
+ */
151
+ withFileAccess(bytes, use) {
152
+ const runtime = this.#runtime;
153
+ const callback = runtime.addFunction((_parameter, position, buffer, size) => {
154
+ if (position < 0 || size < 0 || position + size > bytes.byteLength)
155
+ return 0;
156
+ runtime.HEAPU8.set(bytes.subarray(position, position + size), buffer);
157
+ return 1;
158
+ }, "iiiii");
159
+ const fileAccess = this.malloc(FILE_ACCESS_BYTES);
160
+ try {
161
+ runtime.setValue(fileAccess, bytes.byteLength, "i32");
162
+ runtime.setValue(fileAccess + 4, callback, "i32");
163
+ runtime.setValue(fileAccess + 8, 0, "i32");
164
+ return use(fileAccess);
165
+ }
166
+ finally {
167
+ this.free(fileAccess);
168
+ runtime.removeFunction(callback);
169
+ }
170
+ }
171
+ /** Opens a document from bytes; PDFium reads them lazily, so they stay in the heap. */
172
+ openDocument(bytes) {
173
+ const data = this.writeBytes(bytes);
174
+ const handle = this.lib.FPDF_LoadMemDocument(data, bytes.byteLength, "");
175
+ if (!handle) {
176
+ const error = this.lib.FPDF_GetLastError();
177
+ this.free(data);
178
+ throw error === PASSWORD_ERROR
179
+ ? new ViewerError("encrypted-document", "Password-protected PDF documents are not supported")
180
+ : new ViewerError("invalid-file", "PDFium could not open the PDF", {
181
+ details: { pdfiumError: error },
182
+ });
183
+ }
184
+ return new PdfiumDocument(this, handle, data);
185
+ }
186
+ createDocument() {
187
+ const handle = this.lib.FPDF_CreateNewDocument();
188
+ if (!handle)
189
+ throw new ViewerError("internal", "PDFium could not create a document");
190
+ return new PdfiumDocument(this, handle, 0);
191
+ }
192
+ }
193
+ export class PdfiumDocument {
194
+ #pdfium;
195
+ #data;
196
+ #handle;
197
+ constructor(pdfium, handle, data) {
198
+ this.#pdfium = pdfium;
199
+ this.#handle = handle;
200
+ this.#data = data;
201
+ }
202
+ get handle() {
203
+ if (!this.#handle)
204
+ throw new ViewerError("lifecycle-error", "The PDF document is closed");
205
+ return this.#handle;
206
+ }
207
+ /** Serializes the document; `incremental` appends to the bytes it was opened from. */
208
+ save(mode) {
209
+ const { lib } = this.#pdfium;
210
+ const writer = lib.PDFiumExt_OpenFileWriter();
211
+ if (!writer)
212
+ throw new ViewerError("internal", "PDFium could not open a file writer");
213
+ try {
214
+ const flags = mode === "incremental" ? SAVE_INCREMENTAL : SAVE_FULL;
215
+ if (!lib.FPDF_SaveAsCopy(this.handle, writer, flags))
216
+ throw new ViewerError("internal", "PDFium could not save the PDF", {
217
+ details: { mode, pdfiumError: lib.FPDF_GetLastError() },
218
+ });
219
+ const size = lib.PDFiumExt_GetFileWriterSize(writer);
220
+ const buffer = this.#pdfium.malloc(size);
221
+ try {
222
+ lib.PDFiumExt_GetFileWriterData(writer, buffer, size);
223
+ return this.#pdfium.readBytes(buffer, size);
224
+ }
225
+ finally {
226
+ this.#pdfium.free(buffer);
227
+ }
228
+ }
229
+ finally {
230
+ lib.PDFiumExt_CloseFileWriter(writer);
231
+ }
232
+ }
233
+ close() {
234
+ if (!this.#handle)
235
+ return;
236
+ this.#pdfium.lib.FPDF_CloseDocument(this.#handle);
237
+ this.#handle = 0;
238
+ this.#pdfium.free(this.#data);
239
+ }
240
+ }
241
+ function exactArrayBuffer(bytes) {
242
+ if (bytes instanceof ArrayBuffer)
243
+ return bytes;
244
+ return bytes.buffer instanceof ArrayBuffer &&
245
+ bytes.byteOffset === 0 &&
246
+ bytes.byteLength === bytes.buffer.byteLength
247
+ ? bytes.buffer
248
+ : bytes.slice().buffer;
249
+ }
@@ -0,0 +1,4 @@
1
+ import type { InsertShapeOperation, SetShapeStyleOperation } from "../types.js";
2
+ import type { OperationHandler } from "./operations.js";
3
+ export declare const insertShape: OperationHandler<InsertShapeOperation>;
4
+ export declare const setShapeStyle: OperationHandler<SetShapeStyleOperation>;