web-doc 0.11.0 → 0.12.1
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/adapters/pdf.js +19 -8
- package/dist/edit/engine.d.ts +2 -1
- package/dist/edit/pdf/engine/document.d.ts +4 -2
- package/dist/edit/pdf/engine/document.js +115 -12
- package/dist/edit/pdf/engine/elements.d.ts +5 -1
- package/dist/edit/pdf/engine/elements.js +88 -6
- package/dist/edit/pdf/engine/existing-text.js +33 -64
- package/dist/edit/pdf/engine/fonts.d.ts +14 -0
- package/dist/edit/pdf/engine/fonts.js +114 -0
- package/dist/edit/pdf/engine/handler.js +2 -0
- package/dist/edit/pdf/engine/layout.js +1 -1
- package/dist/edit/pdf/engine/operations.d.ts +7 -1
- package/dist/edit/pdf/engine/paragraph-edit.d.ts +4 -0
- package/dist/edit/pdf/engine/paragraph-edit.js +331 -0
- package/dist/edit/pdf/engine/paragraph.d.ts +31 -0
- package/dist/edit/pdf/engine/paragraph.js +445 -0
- package/dist/edit/pdf/engine/pdfium.d.ts +4 -0
- package/dist/edit/pdf/engine/text-box.js +16 -3
- package/dist/edit/pdf/engine/text-font.js +2 -19
- package/dist/edit/pdf/engine/transform.js +14 -3
- package/dist/edit/pdf/provider.d.ts +3 -1
- package/dist/edit/pdf/provider.js +3 -0
- package/dist/edit/pdf/range-map.d.ts +2 -1
- package/dist/edit/pdf/range-map.js +38 -8
- package/dist/edit/pdf/schemas.d.ts +2 -0
- package/dist/edit/pdf/schemas.js +37 -0
- package/dist/edit/pdf/session.d.ts +3 -1
- package/dist/edit/pdf/session.js +35 -6
- package/dist/edit/pdf/types.d.ts +38 -8
- package/dist/edit/session.js +5 -0
- package/dist/edit/types.d.ts +13 -0
- package/dist/viewport.js +11 -0
- package/dist/worker-protocol.d.ts +1 -1
- package/dist/workers/pdf-edit-worker.js +2026 -1004
- package/package.json +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { paragraphSetTextStyle, replaceParagraphText, } from "./paragraph-edit.js";
|
|
1
2
|
import { objectBounds, OBJECT_TEXT, textScale } from "./elements.js";
|
|
2
|
-
import {
|
|
3
|
+
import { fontCanRewrite, validateScript } from "./fonts.js";
|
|
3
4
|
import { pageToUser } from "./geometry.js";
|
|
4
5
|
import { parseColor, setText, textBoxReplaceText, textBoxSetTextStyle, textBoxTarget, } from "./text-box.js";
|
|
5
6
|
/*
|
|
@@ -10,6 +11,8 @@ import { parseColor, setText, textBoxReplaceText, textBoxSetTextStyle, textBoxTa
|
|
|
10
11
|
*/
|
|
11
12
|
export const replaceText = {
|
|
12
13
|
validate(operation, context, issue) {
|
|
14
|
+
if (context.paragraph(operation.target)?.paragraph.id === operation.target)
|
|
15
|
+
return replaceParagraphText.validate({ ...operation, op: "replaceParagraphText" }, context, issue);
|
|
13
16
|
const box = textBoxTarget(operation.target, context);
|
|
14
17
|
if (box) {
|
|
15
18
|
const spliced = splice(box.spec.text, operation, issue);
|
|
@@ -42,6 +45,8 @@ export const replaceText = {
|
|
|
42
45
|
issue(problem.path, problem.code, problem.message);
|
|
43
46
|
},
|
|
44
47
|
apply(operation, context) {
|
|
48
|
+
if (context.paragraph(operation.target)?.paragraph.id === operation.target)
|
|
49
|
+
return replaceParagraphText.apply({ ...operation, op: "replaceParagraphText" }, context);
|
|
45
50
|
const box = textBoxTarget(operation.target, context);
|
|
46
51
|
if (box)
|
|
47
52
|
return textBoxReplaceText.apply(wholeTextOperation(operation, splice(box.spec.text, operation)), context);
|
|
@@ -95,6 +100,8 @@ function spanOf(operation, previous) {
|
|
|
95
100
|
}
|
|
96
101
|
export const setTextStyle = {
|
|
97
102
|
validate(operation, context, issue) {
|
|
103
|
+
if (context.paragraph(operation.target)?.paragraph.id === operation.target)
|
|
104
|
+
return paragraphSetTextStyle.validate(operation, context, issue);
|
|
98
105
|
if (textBoxTarget(operation.target, context))
|
|
99
106
|
return textBoxSetTextStyle.validate(operation, context, issue);
|
|
100
107
|
if (!textTarget(operation.target, context, issue))
|
|
@@ -110,6 +117,8 @@ export const setTextStyle = {
|
|
|
110
117
|
issue(`/style/${field}`, "unsupported-style", `Only color and fontSize can change on existing text; ${field} cannot`);
|
|
111
118
|
},
|
|
112
119
|
apply(operation, context) {
|
|
120
|
+
if (context.paragraph(operation.target)?.paragraph.id === operation.target)
|
|
121
|
+
return paragraphSetTextStyle.apply(operation, context);
|
|
113
122
|
if (textBoxTarget(operation.target, context))
|
|
114
123
|
return textBoxSetTextStyle.apply(operation, context);
|
|
115
124
|
const target = textTarget(operation.target, context);
|
|
@@ -139,72 +148,18 @@ function textTarget(target, context, issue = () => { }) {
|
|
|
139
148
|
}
|
|
140
149
|
return { location, element };
|
|
141
150
|
}
|
|
142
|
-
/** Right-to-left scripts need shaping the MVP does not do. */
|
|
143
|
-
function validateScript(text, issue) {
|
|
144
|
-
for (const character of text) {
|
|
145
|
-
const code = character.codePointAt(0);
|
|
146
|
-
if ((code >= 0x0590 && code <= 0x08ff) ||
|
|
147
|
-
(code >= 0xfb1d && code <= 0xfdff) ||
|
|
148
|
-
(code >= 0xfe70 && code <= 0xfeff)) {
|
|
149
|
-
issue("/text", "unsupported-script", `Right-to-left text such as "${character}" cannot be edited yet`);
|
|
150
|
-
return false;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
return true;
|
|
154
|
-
}
|
|
155
151
|
/**
|
|
156
152
|
* Whether the object's own font can draw `text`: a standard font for WinAnsi
|
|
157
|
-
* text, or an embedded TrueType program
|
|
158
|
-
* (which also answers for subsets, since
|
|
159
|
-
* kept).
|
|
153
|
+
* text, or an embedded TrueType or bare CFF program with a glyph for every
|
|
154
|
+
* character (which also answers for subsets, since they hold only what they
|
|
155
|
+
* kept), each with a width in the PDF.
|
|
160
156
|
*/
|
|
161
157
|
function canKeepFont(context, target, text) {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
const object = lib.FPDFPage_GetObject(page, target.location.indexes[0]);
|
|
166
|
-
const font = lib.FPDFTextObj_GetFont(object);
|
|
167
|
-
if (!lib.FPDFFont_GetIsEmbedded(font)) {
|
|
168
|
-
const base = pdfium.readUtf8String((buffer, bytes) => lib.FPDFFont_GetBaseFontName(font, buffer, bytes));
|
|
169
|
-
return (isStandardFamily(base.split(/[-,]/)[0] ?? "") &&
|
|
170
|
-
firstNonWinAnsi(text) === undefined);
|
|
171
|
-
}
|
|
172
|
-
const coverage = fontCoverage(pdfium, font);
|
|
173
|
-
if (!coverage)
|
|
174
|
-
return false;
|
|
175
|
-
for (const character of text) {
|
|
176
|
-
const code = character.codePointAt(0);
|
|
177
|
-
if (code !== 0x0a && code !== 0x20 && !coverage.drawable(code))
|
|
178
|
-
return false;
|
|
179
|
-
}
|
|
180
|
-
return true;
|
|
158
|
+
return context.readPage(target.location.pageIndex, (page) => {
|
|
159
|
+
const object = context.pdfium.lib.FPDFPage_GetObject(page, target.location.indexes[0]);
|
|
160
|
+
return fontCanRewrite(context.pdfium, context.pdfium.lib.FPDFTextObj_GetFont(object), text);
|
|
181
161
|
});
|
|
182
162
|
}
|
|
183
|
-
function fontCoverage(pdfium, font) {
|
|
184
|
-
const { lib } = pdfium;
|
|
185
|
-
const size = pdfium.readNumbers(1, "i32", ([out]) => lib.FPDFFont_GetFontData(font, 0, 0, out))?.[0];
|
|
186
|
-
if (!size)
|
|
187
|
-
return undefined;
|
|
188
|
-
const buffer = pdfium.malloc(size);
|
|
189
|
-
try {
|
|
190
|
-
const out = pdfium.malloc(4);
|
|
191
|
-
try {
|
|
192
|
-
if (!lib.FPDFFont_GetFontData(font, buffer, size, out))
|
|
193
|
-
return undefined;
|
|
194
|
-
}
|
|
195
|
-
finally {
|
|
196
|
-
pdfium.free(out);
|
|
197
|
-
}
|
|
198
|
-
const data = pdfium.readBytes(buffer, size);
|
|
199
|
-
const tag = String.fromCharCode(data[0], data[1], data[2], data[3]);
|
|
200
|
-
const truetype = (data[0] === 0 && data[1] === 1 && data[2] === 0 && data[3] === 0) ||
|
|
201
|
-
tag === "true";
|
|
202
|
-
return truetype ? parseCmap(data) : undefined;
|
|
203
|
-
}
|
|
204
|
-
finally {
|
|
205
|
-
pdfium.free(buffer);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
163
|
/** Sets the text and confirms PDFium reads it back; false means it must be replaced. */
|
|
209
164
|
function replaceInPlace(context, target, text) {
|
|
210
165
|
const { pdfium } = context;
|
|
@@ -214,16 +169,30 @@ function replaceInPlace(context, target, text) {
|
|
|
214
169
|
context.withPage(target.location.pageIndex, (page) => {
|
|
215
170
|
setText(pdfium, lib.FPDFPage_GetObject(page, index), text);
|
|
216
171
|
});
|
|
217
|
-
const
|
|
172
|
+
const faithful = context.withPage(target.location.pageIndex, (page) => {
|
|
218
173
|
const textPage = lib.FPDFText_LoadPage(page);
|
|
219
174
|
try {
|
|
220
|
-
|
|
175
|
+
const object = lib.FPDFPage_GetObject(page, index);
|
|
176
|
+
const readBack = pdfium.readWideString((buffer, bytes) => lib.FPDFTextObj_GetText(object, textPage, buffer, bytes));
|
|
177
|
+
if (readBack === text)
|
|
178
|
+
return true;
|
|
179
|
+
// Reading-order extraction can append a generated gap before the next
|
|
180
|
+
// object. Verify the object's own characters instead, retaining every
|
|
181
|
+
// authored space: trimming would also hide a lost deliberate space.
|
|
182
|
+
let authored = "";
|
|
183
|
+
const count = lib.FPDFText_CountChars(textPage);
|
|
184
|
+
for (let at = 0; at < count; at += 1) {
|
|
185
|
+
if (lib.FPDFText_GetTextObject(textPage, at) === object &&
|
|
186
|
+
lib.FPDFText_IsGenerated(textPage, at) === 0)
|
|
187
|
+
authored += String.fromCodePoint(lib.FPDFText_GetUnicode(textPage, at));
|
|
188
|
+
}
|
|
189
|
+
return authored === text;
|
|
221
190
|
}
|
|
222
191
|
finally {
|
|
223
192
|
lib.FPDFText_ClosePage(textPage);
|
|
224
193
|
}
|
|
225
194
|
});
|
|
226
|
-
if (
|
|
195
|
+
if (faithful)
|
|
227
196
|
return true;
|
|
228
197
|
// Put the old text back so the fallback path starts from a known state.
|
|
229
198
|
context.withPage(target.location.pageIndex, (page) => {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { EditWorkerFont } from "../../../worker-protocol.js";
|
|
2
|
+
import type { Issue } from "./operations.js";
|
|
2
3
|
import type { Pdfium } from "./pdfium.js";
|
|
3
4
|
export declare const FALLBACK_FAMILY = "Noto Sans";
|
|
4
5
|
export declare function isStandardFamily(family: string): boolean;
|
|
@@ -76,3 +77,16 @@ export declare class TextMeasurer {
|
|
|
76
77
|
descent: number;
|
|
77
78
|
};
|
|
78
79
|
}
|
|
80
|
+
/** True only when the original native font is known to encode every character. */
|
|
81
|
+
export declare function fontCanDraw(pdfium: Pdfium, font: number, text: string): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Whether one text object can be rewritten in its own font: what
|
|
84
|
+
* `fontCanDraw` proves, extended to bare CFF subsets, whose glyph names say
|
|
85
|
+
* what they draw, and narrowed to characters the PDF gives an advance, since
|
|
86
|
+
* a subset's widths list only the codes it used. Paragraph reflow keeps to
|
|
87
|
+
* `fontCanDraw`, which also decides which rows join a paragraph.
|
|
88
|
+
*/
|
|
89
|
+
export declare function fontCanRewrite(pdfium: Pdfium, font: number, text: string): boolean;
|
|
90
|
+
export declare function fontBytes(pdfium: Pdfium, font: number): Uint8Array | undefined;
|
|
91
|
+
/** Right-to-left scripts need shaping the MVP does not do. */
|
|
92
|
+
export declare function validateScript(text: string, issue: Issue): boolean;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { glyphUnicode, readCff } from "./cff.js";
|
|
1
2
|
/*
|
|
2
3
|
* Fonts for text web-doc writes into a PDF: the standard 14 fonts for
|
|
3
4
|
* WinAnsi text, host-registered TrueType fonts, and a bundled Noto Sans
|
|
@@ -467,3 +468,116 @@ export class TextMeasurer {
|
|
|
467
468
|
}
|
|
468
469
|
}
|
|
469
470
|
}
|
|
471
|
+
/** True only when the original native font is known to encode every character. */
|
|
472
|
+
export function fontCanDraw(pdfium, font, text) {
|
|
473
|
+
const { lib } = pdfium;
|
|
474
|
+
if (!lib.FPDFFont_GetIsEmbedded(font)) {
|
|
475
|
+
const base = pdfium.readUtf8String((buffer, bytes) => lib.FPDFFont_GetBaseFontName(font, buffer, bytes));
|
|
476
|
+
return (isStandardFamily(base.split(/[-,]/)[0] ?? "") &&
|
|
477
|
+
firstNonWinAnsi(text) === undefined);
|
|
478
|
+
}
|
|
479
|
+
const coverage = fontCoverage(pdfium, font);
|
|
480
|
+
if (!coverage)
|
|
481
|
+
return false;
|
|
482
|
+
return [...text].every((character) => {
|
|
483
|
+
const code = character.codePointAt(0);
|
|
484
|
+
// A space needs an encoding even though a valid space has no outline.
|
|
485
|
+
// Imported subsets can omit its cmap entry and use positioned word gaps.
|
|
486
|
+
if (code === 0x20)
|
|
487
|
+
return (coverage.glyph(code) ?? 0) !== 0;
|
|
488
|
+
return code === 0x0a || coverage.drawable(code);
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Whether one text object can be rewritten in its own font: what
|
|
493
|
+
* `fontCanDraw` proves, extended to bare CFF subsets, whose glyph names say
|
|
494
|
+
* what they draw, and narrowed to characters the PDF gives an advance, since
|
|
495
|
+
* a subset's widths list only the codes it used. Paragraph reflow keeps to
|
|
496
|
+
* `fontCanDraw`, which also decides which rows join a paragraph.
|
|
497
|
+
*/
|
|
498
|
+
export function fontCanRewrite(pdfium, font, text) {
|
|
499
|
+
const characters = [...text].filter((character) => character !== "\n");
|
|
500
|
+
if (!characters.every((character) => advance(pdfium, font, character.codePointAt(0)) > 0))
|
|
501
|
+
return false;
|
|
502
|
+
if (fontCanDraw(pdfium, font, text))
|
|
503
|
+
return true;
|
|
504
|
+
if (!pdfium.lib.FPDFFont_GetIsEmbedded(font))
|
|
505
|
+
return false;
|
|
506
|
+
const data = fontBytes(pdfium, font);
|
|
507
|
+
const coverage = data && cffCoverage(data);
|
|
508
|
+
if (!coverage)
|
|
509
|
+
return false;
|
|
510
|
+
// A space needs a glyph of its own, as in `fontCanDraw`.
|
|
511
|
+
return characters.every((character) => coverage.has(character.codePointAt(0)));
|
|
512
|
+
}
|
|
513
|
+
/** The PDF's width for a character, per 1000 units of size; 0 for one it gives none or PDFium cannot ask about. */
|
|
514
|
+
function advance(pdfium, font, code) {
|
|
515
|
+
// PDFium takes one UTF-16 code unit.
|
|
516
|
+
if (code > 0xffff)
|
|
517
|
+
return 0;
|
|
518
|
+
return (pdfium.readNumbers(1, "float", ([width]) => pdfium.lib.FPDFFont_GetGlyphWidth(font, code, 1000, width))?.[0] ?? 0);
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* A bare CFF program's glyphs by the code points their names stand for, as a
|
|
522
|
+
* simple font draws them: its encoding names the glyph. A CID-keyed program
|
|
523
|
+
* names none, and only its PDF CMap would say what its glyphs draw.
|
|
524
|
+
*/
|
|
525
|
+
function cffCoverage(data) {
|
|
526
|
+
const cff = readCff(data);
|
|
527
|
+
if (!cff || cff.cid)
|
|
528
|
+
return undefined;
|
|
529
|
+
const glyphs = new Map();
|
|
530
|
+
cff.glyphNames.forEach((name, glyph) => {
|
|
531
|
+
const code = glyphUnicode(name);
|
|
532
|
+
if (glyph !== 0 && code !== undefined && !glyphs.has(code))
|
|
533
|
+
glyphs.set(code, glyph);
|
|
534
|
+
});
|
|
535
|
+
return {
|
|
536
|
+
has: (code) => glyphs.has(code),
|
|
537
|
+
glyph: (code) => glyphs.get(code),
|
|
538
|
+
drawable: (code) => glyphs.has(code),
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
function fontCoverage(pdfium, font) {
|
|
542
|
+
const data = fontBytes(pdfium, font);
|
|
543
|
+
if (!data)
|
|
544
|
+
return undefined;
|
|
545
|
+
const tag = String.fromCharCode(...data.slice(0, 4));
|
|
546
|
+
const truetype = (data[0] === 0 && data[1] === 1 && data[2] === 0 && data[3] === 0) ||
|
|
547
|
+
tag === "true";
|
|
548
|
+
return truetype ? parseCmap(data) : undefined;
|
|
549
|
+
}
|
|
550
|
+
export function fontBytes(pdfium, font) {
|
|
551
|
+
const { lib } = pdfium;
|
|
552
|
+
const size = pdfium.readNumbers(1, "i32", ([out]) => lib.FPDFFont_GetFontData(font, 0, 0, out))?.[0];
|
|
553
|
+
if (!size)
|
|
554
|
+
return undefined;
|
|
555
|
+
const buffer = pdfium.malloc(size);
|
|
556
|
+
try {
|
|
557
|
+
const out = pdfium.malloc(4);
|
|
558
|
+
try {
|
|
559
|
+
if (!lib.FPDFFont_GetFontData(font, buffer, size, out))
|
|
560
|
+
return undefined;
|
|
561
|
+
}
|
|
562
|
+
finally {
|
|
563
|
+
pdfium.free(out);
|
|
564
|
+
}
|
|
565
|
+
return pdfium.readBytes(buffer, size);
|
|
566
|
+
}
|
|
567
|
+
finally {
|
|
568
|
+
pdfium.free(buffer);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
/** Right-to-left scripts need shaping the MVP does not do. */
|
|
572
|
+
export function validateScript(text, issue) {
|
|
573
|
+
for (const character of text) {
|
|
574
|
+
const code = character.codePointAt(0);
|
|
575
|
+
if ((code >= 0x0590 && code <= 0x08ff) ||
|
|
576
|
+
(code >= 0xfb1d && code <= 0xfdff) ||
|
|
577
|
+
(code >= 0xfe70 && code <= 0xfeff)) {
|
|
578
|
+
issue("/text", "unsupported-script", `Right-to-left text such as "${character}" cannot be edited yet`);
|
|
579
|
+
return false;
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
return true;
|
|
583
|
+
}
|
|
@@ -84,6 +84,8 @@ export function createPdfEditHandler(host) {
|
|
|
84
84
|
}
|
|
85
85
|
case "edit-text-layout":
|
|
86
86
|
return engine().textLayout(payload.id);
|
|
87
|
+
case "edit-text-paragraph":
|
|
88
|
+
return engine().textParagraph(payload.id);
|
|
87
89
|
case "edit-position-at": {
|
|
88
90
|
const { pageIndex, point } = payload;
|
|
89
91
|
return engine().positionAt(pageIndex, point);
|
|
@@ -2,7 +2,7 @@ import { textStyle } from "./elements.js";
|
|
|
2
2
|
import { pageToUser, rectContains, round, roundRect, unionRects, userRectToPage, userToPage, } from "./geometry.js";
|
|
3
3
|
/** How far a point may be from a glyph for `FPDFText_GetCharIndexAtPos`. */
|
|
4
4
|
const HIT_TOLERANCE = 2;
|
|
5
|
-
const TEXT_KINDS = new Set(["text", "textBox", "table"]);
|
|
5
|
+
const TEXT_KINDS = new Set(["text", "textBox", "table", "paragraph"]);
|
|
6
6
|
/** The layout of one element, or `undefined` when it draws no text. */
|
|
7
7
|
export function layoutOf(pdfium, scan, element) {
|
|
8
8
|
if (!TEXT_KINDS.has(element.kind))
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import type { ResourceLimits, ViewerWarning } from "../../../contracts.js";
|
|
2
2
|
import type { AssetSource } from "../../assets.js";
|
|
3
3
|
import type { ImageCache } from "./images.js";
|
|
4
|
-
import type { OperationIssue } from "../../types.js";
|
|
4
|
+
import type { OperationIssue, TextAnchorMigration } from "../../types.js";
|
|
5
5
|
import type { PdfElement, PdfOperation } from "../types.js";
|
|
6
6
|
import type { PageGeometry } from "./geometry.js";
|
|
7
7
|
import type { ObjectRecord } from "./elements.js";
|
|
8
8
|
import type { Pdfium } from "./pdfium.js";
|
|
9
9
|
import type { FontLibrary, TextMeasurer } from "./fonts.js";
|
|
10
|
+
import type { ParagraphTarget } from "./paragraph.js";
|
|
10
11
|
/** What an operation sees of the document while validating or applying. */
|
|
11
12
|
export interface OperationContext {
|
|
12
13
|
readonly pdfium: Pdfium;
|
|
@@ -24,12 +25,16 @@ export interface OperationContext {
|
|
|
24
25
|
newId(pageIndex: number, suffix?: string): string;
|
|
25
26
|
/** Loads a page for writing; its content is regenerated afterwards. */
|
|
26
27
|
withPage<T>(pageIndex: number, use: (page: number) => T): T;
|
|
28
|
+
/** Reads native resources without regenerating the content stream. */
|
|
29
|
+
readPage<T>(pageIndex: number, use: (page: number) => T): T;
|
|
27
30
|
/** Records objects appended to a page by this operation. */
|
|
28
31
|
appendObjects(pageIndex: number, records: readonly ObjectRecord[]): void;
|
|
29
32
|
/** Where an element's objects sit: their page and their indexes in drawing order. */
|
|
30
33
|
locate(id: string): ElementLocation | undefined;
|
|
31
34
|
/** The element as a query would return it. */
|
|
32
35
|
element(id: string): PdfElement | undefined;
|
|
36
|
+
paragraph(id: string): ParagraphTarget | undefined;
|
|
37
|
+
pageElements(pageIndex: number): readonly PdfElement[];
|
|
33
38
|
/** Ids of every element on a page, for what a page deletion removes. */
|
|
34
39
|
pageElementIds(pageIndex: number): readonly string[];
|
|
35
40
|
/** Displayed size of a page in points. */
|
|
@@ -56,6 +61,7 @@ export interface OperationResult {
|
|
|
56
61
|
readonly createdIds: readonly string[];
|
|
57
62
|
/** Ids the operation made disappear. */
|
|
58
63
|
readonly removedIds?: readonly string[];
|
|
64
|
+
readonly textAnchorMigrations?: readonly Omit<TextAnchorMigration, "operationIndex">[];
|
|
59
65
|
readonly changedPages: readonly number[];
|
|
60
66
|
readonly warnings: readonly ViewerWarning[];
|
|
61
67
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ReplaceParagraphTextOperation, SetTextStyleOperation } from "../types.js";
|
|
2
|
+
import type { OperationHandler } from "./operations.js";
|
|
3
|
+
export declare const replaceParagraphText: OperationHandler<ReplaceParagraphTextOperation>;
|
|
4
|
+
export declare const paragraphSetTextStyle: OperationHandler<SetTextStyleOperation>;
|