mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-22 16:18:08 +02:00
Correctly update the xref table when an annotation is deleted
This commit is contained in:
parent
aaa55d2b38
commit
901d995a7e
4 changed files with 131 additions and 18 deletions
|
@ -46,7 +46,15 @@ import {
|
|||
XRefEntryException,
|
||||
XRefParseException,
|
||||
} from "./core_utils.js";
|
||||
import { Dict, isName, isRefsEqual, Name, Ref, RefSet } from "./primitives.js";
|
||||
import {
|
||||
Dict,
|
||||
isName,
|
||||
isRefsEqual,
|
||||
Name,
|
||||
Ref,
|
||||
RefSet,
|
||||
RefSetCache,
|
||||
} from "./primitives.js";
|
||||
import { getXfaFontDict, getXfaFontName } from "./xfa_fonts.js";
|
||||
import { BaseStream } from "./base_stream.js";
|
||||
import { calculateMD5 } from "./crypto.js";
|
||||
|
@ -272,7 +280,7 @@ class Page {
|
|||
continue;
|
||||
}
|
||||
if (annotation.deleted) {
|
||||
deletedAnnotations.put(ref);
|
||||
deletedAnnotations.put(ref, ref);
|
||||
continue;
|
||||
}
|
||||
existingAnnotations?.put(ref);
|
||||
|
@ -300,7 +308,7 @@ class Page {
|
|||
options: this.evaluatorOptions,
|
||||
});
|
||||
|
||||
const deletedAnnotations = new RefSet();
|
||||
const deletedAnnotations = new RefSetCache();
|
||||
const existingAnnotations = new RefSet();
|
||||
this.#replaceIdByRef(annotations, deletedAnnotations, existingAnnotations);
|
||||
|
||||
|
@ -335,6 +343,9 @@ class Page {
|
|||
{ ref: this.ref, data: buffer.join("") },
|
||||
...newData.annotations
|
||||
);
|
||||
for (const deletedRef of deletedAnnotations) {
|
||||
objects.push({ ref: deletedRef, data: null });
|
||||
}
|
||||
|
||||
return objects;
|
||||
}
|
||||
|
|
|
@ -293,10 +293,18 @@ async function getXRefTable(xrefInfo, baseOffset, newRefs, newXref, buffer) {
|
|||
}
|
||||
// The EOL is \r\n to make sure that every entry is exactly 20 bytes long.
|
||||
// (see 7.5.4 - Cross-Reference Table).
|
||||
buffer.push(
|
||||
`${baseOffset.toString().padStart(10, "0")} ${Math.min(ref.gen, 0xffff).toString().padStart(5, "0")} n\r\n`
|
||||
);
|
||||
baseOffset += data.length;
|
||||
if (data !== null) {
|
||||
buffer.push(
|
||||
`${baseOffset.toString().padStart(10, "0")} ${Math.min(ref.gen, 0xffff).toString().padStart(5, "0")} n\r\n`
|
||||
);
|
||||
baseOffset += data.length;
|
||||
} else {
|
||||
buffer.push(
|
||||
`0000000000 ${Math.min(ref.gen + 1, 0xffff)
|
||||
.toString()
|
||||
.padStart(5, "0")} f\r\n`
|
||||
);
|
||||
}
|
||||
}
|
||||
computeIDs(baseOffset, xrefInfo, newXref);
|
||||
buffer.push("trailer\n");
|
||||
|
@ -327,11 +335,17 @@ async function getXRefStreamTable(
|
|||
let maxOffset = 0;
|
||||
let maxGen = 0;
|
||||
for (const { ref, data } of newRefs) {
|
||||
let gen;
|
||||
maxOffset = Math.max(maxOffset, baseOffset);
|
||||
const gen = Math.min(ref.gen, 0xffff);
|
||||
if (data !== null) {
|
||||
gen = Math.min(ref.gen, 0xffff);
|
||||
xrefTableData.push([1, baseOffset, gen]);
|
||||
baseOffset += data.length;
|
||||
} else {
|
||||
gen = Math.min(ref.gen + 1, 0xffff);
|
||||
xrefTableData.push([0, 0, gen]);
|
||||
}
|
||||
maxGen = Math.max(maxGen, gen);
|
||||
xrefTableData.push([1, baseOffset, gen]);
|
||||
baseOffset += data.length;
|
||||
}
|
||||
newXref.set("Index", getIndexes(newRefs));
|
||||
const offsetSize = getSizeInBytes(maxOffset);
|
||||
|
@ -420,15 +434,13 @@ async function incrementalUpdate({
|
|||
});
|
||||
}
|
||||
|
||||
let buffer, baseOffset;
|
||||
const buffer = [];
|
||||
let baseOffset = originalData.length;
|
||||
const lastByte = originalData.at(-1);
|
||||
if (lastByte === /* \n */ 0x0a || lastByte === /* \r */ 0x0d) {
|
||||
buffer = [];
|
||||
baseOffset = originalData.length;
|
||||
} else {
|
||||
if (lastByte !== /* \n */ 0x0a && lastByte !== /* \r */ 0x0d) {
|
||||
// Avoid to concatenate %%EOF with an object definition
|
||||
buffer = ["\n"];
|
||||
baseOffset = originalData.length + 1;
|
||||
buffer.push("\n");
|
||||
baseOffset += 1;
|
||||
}
|
||||
|
||||
const newXref = getTrailerDict(xrefInfo, newRefs, useXrefStream);
|
||||
|
@ -436,7 +448,9 @@ async function incrementalUpdate({
|
|||
(a, b) => /* compare the refs */ a.ref.num - b.ref.num
|
||||
);
|
||||
for (const { data } of newRefs) {
|
||||
buffer.push(data);
|
||||
if (data !== null) {
|
||||
buffer.push(data);
|
||||
}
|
||||
}
|
||||
|
||||
await (useXrefStream
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue