Mostly working
Some checks are pending
CI / Test (20) (push) Waiting to run
CI / Test (22) (push) Waiting to run
CI / Test (23) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
Lint / Lint (lts/*) (push) Waiting to run
Types tests / Test (lts/*) (push) Waiting to run
Some checks are pending
CI / Test (20) (push) Waiting to run
CI / Test (22) (push) Waiting to run
CI / Test (23) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
Lint / Lint (lts/*) (push) Waiting to run
Types tests / Test (lts/*) (push) Waiting to run
* ranges passed through * updates possible
This commit is contained in:
parent
1dc874260b
commit
20b6e32907
@ -11,7 +11,7 @@ const STANDARD_FONT_DATA_URL =
|
|||||||
|
|
||||||
// Loading file from file system into typed array.
|
// Loading file from file system into typed array.
|
||||||
const pdfPath =
|
const pdfPath =
|
||||||
process.argv[2] || "../../web/compressed.tracemonkey-pldi-09.pdf";
|
process.argv[2] || "C:\\Users\\kj131\\pdf-forge\\test_pdfs\\ISO_32000-2_2020(en).pdf";
|
||||||
const data = new Uint8Array(fs.readFileSync(pdfPath));
|
const data = new Uint8Array(fs.readFileSync(pdfPath));
|
||||||
|
|
||||||
// Load the PDF file.
|
// Load the PDF file.
|
||||||
@ -21,12 +21,46 @@ const loadingTask = getDocument({
|
|||||||
cMapPacked: CMAP_PACKED,
|
cMapPacked: CMAP_PACKED,
|
||||||
standardFontDataUrl: STANDARD_FONT_DATA_URL,
|
standardFontDataUrl: STANDARD_FONT_DATA_URL,
|
||||||
});
|
});
|
||||||
|
test(loadingTask);
|
||||||
|
async function test(loading) {
|
||||||
try {
|
try {
|
||||||
const pdfDocument = await loadingTask.promise;
|
const pdfDocument = await loading.promise;
|
||||||
console.log("# PDF document loaded.");
|
console.log("# PDF document loaded.");
|
||||||
const page = await pdfDocument.getPage(1);
|
const page = await pdfDocument.getPage(4);
|
||||||
|
printOpList(page);
|
||||||
|
console.time("contents");
|
||||||
|
const contents = await page.getContents();
|
||||||
|
console.timeEnd("contents");
|
||||||
|
console.time("oplist");
|
||||||
const opList = await page.getOperatorList();
|
const opList = await page.getOperatorList();
|
||||||
console.log(opList);
|
console.timeEnd("oplist");
|
||||||
|
// console.log(opList);
|
||||||
|
let newContents = "";
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
const range = opList.rangeArray[i];
|
||||||
|
if (range) {
|
||||||
|
newContents += contents.slice(range[0], range[1]);
|
||||||
|
newContents += "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(newContents);
|
||||||
|
await page.updateContents(newContents);
|
||||||
|
await printOpList(page);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function printOpList(page) {
|
||||||
|
const contents = await page.getContents();
|
||||||
|
const opList = await page.getOperatorList();
|
||||||
|
// console.log(opList);
|
||||||
|
const ops = [];
|
||||||
|
for (let i = 0; i < opList.rangeArray.length; i++) {
|
||||||
|
const range = opList.rangeArray[i];
|
||||||
|
if (range) {
|
||||||
|
ops.push(contents.slice(range[0], range[1]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(ops.slice(0, 100));
|
||||||
|
}
|
||||||
|
|||||||
@ -45,7 +45,7 @@ function bytesToString(bytes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function parse(doc) {
|
async function parse(doc) {
|
||||||
const path = "/Page2/Contents/2";
|
const path = "/Page2/Contents/1";
|
||||||
let [stream] = await getPrimitive(path, doc);
|
let [stream] = await getPrimitive(path, doc);
|
||||||
const lexer = new Lexer(stream);
|
const lexer = new Lexer(stream);
|
||||||
const parser = new Parser({ lexer, xref: doc.xref, trackRanges: true });
|
const parser = new Parser({ lexer, xref: doc.xref, trackRanges: true });
|
||||||
@ -63,12 +63,12 @@ async function parse(doc) {
|
|||||||
const bytes = stream.getBytes();
|
const bytes = stream.getBytes();
|
||||||
const classes = new Set();
|
const classes = new Set();
|
||||||
for (const o of objs) {
|
for (const o of objs) {
|
||||||
console.log(o[0].constructor.name);
|
// console.log(o[0].constructor.name);
|
||||||
classes.add(o[0].constructor.name);
|
classes.add(o[0].constructor.name);
|
||||||
const lexemmeBytes = bytes.slice(o[1], o[2]);
|
const lexemmeBytes = bytes.slice(o[1], o[2]);
|
||||||
console.log(bytesToString(lexemmeBytes));
|
// console.log(bytesToString(lexemmeBytes));
|
||||||
}
|
}
|
||||||
console.log("unique classes", classes);
|
// console.log("unique classes", classes);
|
||||||
[stream] = await getPrimitive(path, doc);
|
[stream] = await getPrimitive(path, doc);
|
||||||
const preprocessor = new EvaluatorPreprocessor(stream, doc.xref);
|
const preprocessor = new EvaluatorPreprocessor(stream, doc.xref);
|
||||||
const operation = {};
|
const operation = {};
|
||||||
@ -78,10 +78,10 @@ async function parse(doc) {
|
|||||||
const fn = operation.fn;
|
const fn = operation.fn;
|
||||||
const range = operation.range;
|
const range = operation.range;
|
||||||
const op = bytesToString(bytes.slice(range[0], range[1]));
|
const op = bytesToString(bytes.slice(range[0], range[1]));
|
||||||
console.log(args, fn);
|
// console.log(args, fn);
|
||||||
console.log(`${range[0]}------------------------------------`);
|
// console.log(`----------------- ${range} -------------------`);
|
||||||
console.log(op);
|
console.log(`${fn}: ${op}`);
|
||||||
console.log(`${range[1]}------------------------------------`);
|
// console.log(`---------------------------------------------`);
|
||||||
}
|
}
|
||||||
// console.time("xref");
|
// console.time("xref");
|
||||||
// let table = await retrieveXref(doc);
|
// let table = await retrieveXref(doc);
|
||||||
|
|||||||
@ -65,7 +65,7 @@ import { Catalog } from "./catalog.js";
|
|||||||
import { clearGlobalCaches } from "./cleanup_helper.js";
|
import { clearGlobalCaches } from "./cleanup_helper.js";
|
||||||
import { DatasetReader } from "./dataset_reader.js";
|
import { DatasetReader } from "./dataset_reader.js";
|
||||||
import { Linearization } from "./parser.js";
|
import { Linearization } from "./parser.js";
|
||||||
import { NullStream } from "./stream.js";
|
import { NullStream, StringStream } from "./stream.js";
|
||||||
import { ObjectLoader } from "./object_loader.js";
|
import { ObjectLoader } from "./object_loader.js";
|
||||||
import { OperatorList } from "./operator_list.js";
|
import { OperatorList } from "./operator_list.js";
|
||||||
import { PartialEvaluator } from "./evaluator.js";
|
import { PartialEvaluator } from "./evaluator.js";
|
||||||
@ -107,6 +107,8 @@ class Page {
|
|||||||
this.resourcesPromise = null;
|
this.resourcesPromise = null;
|
||||||
this.xfaFactory = xfaFactory;
|
this.xfaFactory = xfaFactory;
|
||||||
|
|
||||||
|
this.updatedContents = null;
|
||||||
|
|
||||||
const idCounters = {
|
const idCounters = {
|
||||||
obj: 0,
|
obj: 0,
|
||||||
};
|
};
|
||||||
@ -246,10 +248,19 @@ class Page {
|
|||||||
throw reason;
|
throw reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setContents(newContents) {
|
||||||
|
this.updatedContents = newContents;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {Promise<BaseStream>}
|
* @returns {Promise<BaseStream>}
|
||||||
*/
|
*/
|
||||||
getContentStream() {
|
getContentStream() {
|
||||||
|
if (this.updatedContents !== null) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
resolve(new StringStream(this.updatedContents));
|
||||||
|
});
|
||||||
|
}
|
||||||
return this.pdfManager.ensure(this, "content").then(content => {
|
return this.pdfManager.ensure(this, "content").then(content => {
|
||||||
if (content instanceof BaseStream) {
|
if (content instanceof BaseStream) {
|
||||||
return content;
|
return content;
|
||||||
@ -426,8 +437,11 @@ class Page {
|
|||||||
cacheKey,
|
cacheKey,
|
||||||
annotationStorage = null,
|
annotationStorage = null,
|
||||||
modifiedIds = null,
|
modifiedIds = null,
|
||||||
|
contentOverride = null,
|
||||||
}) {
|
}) {
|
||||||
const contentStreamPromise = this.getContentStream();
|
const contentStreamPromise = contentOverride
|
||||||
|
? new StringStream(contentOverride)
|
||||||
|
: this.getContentStream();
|
||||||
const resourcesPromise = this.loadResources([
|
const resourcesPromise = this.loadResources([
|
||||||
"ColorSpace",
|
"ColorSpace",
|
||||||
"ExtGState",
|
"ExtGState",
|
||||||
|
|||||||
@ -802,6 +802,7 @@ class PartialEvaluator {
|
|||||||
operatorList.addImageOps(
|
operatorList.addImageOps(
|
||||||
OPS.paintImageXObject,
|
OPS.paintImageXObject,
|
||||||
args,
|
args,
|
||||||
|
range,
|
||||||
optionalContent,
|
optionalContent,
|
||||||
hasMask
|
hasMask
|
||||||
);
|
);
|
||||||
@ -1445,15 +1446,20 @@ class PartialEvaluator {
|
|||||||
minMax = [Infinity, Infinity, -Infinity, -Infinity];
|
minMax = [Infinity, Infinity, -Infinity, -Infinity];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
operatorList.addOp(OPS.constructPath, [[fn], args, minMax], range);
|
operatorList.addOp(
|
||||||
|
OPS.constructPath,
|
||||||
|
[[fn], args, minMax, [range[0], range[1]]],
|
||||||
|
range
|
||||||
|
);
|
||||||
|
|
||||||
if (parsingText) {
|
if (parsingText) {
|
||||||
operatorList.addOp(OPS.restore, null, range);
|
operatorList.addOp(OPS.restore, null);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const opArgs = operatorList.argsArray[lastIndex];
|
const opArgs = operatorList.argsArray[lastIndex];
|
||||||
opArgs[0].push(fn);
|
opArgs[0].push(fn);
|
||||||
opArgs[1].push(...args);
|
opArgs[1].push(...args);
|
||||||
|
opArgs[3].push(...range);
|
||||||
const minMax = opArgs[2];
|
const minMax = opArgs[2];
|
||||||
|
|
||||||
const opRange = operatorList.rangeArray[lastIndex];
|
const opRange = operatorList.rangeArray[lastIndex];
|
||||||
@ -5215,7 +5221,7 @@ class EvaluatorPreprocessor {
|
|||||||
|
|
||||||
operation.fn = fn;
|
operation.fn = fn;
|
||||||
operation.args = args;
|
operation.args = args;
|
||||||
const end = this.parser.getPosition();
|
const end = this.parser.getEnd();
|
||||||
operation.range = [start, end];
|
operation.range = [start, end];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -59,12 +59,7 @@ function getInlineImageCacheKey(bytes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Parser {
|
class Parser {
|
||||||
constructor({
|
constructor({ lexer, xref, allowStreams = false, recoveryMode = false }) {
|
||||||
lexer,
|
|
||||||
xref,
|
|
||||||
allowStreams = false,
|
|
||||||
recoveryMode = false,
|
|
||||||
}) {
|
|
||||||
this.lexer = lexer;
|
this.lexer = lexer;
|
||||||
this.xref = xref;
|
this.xref = xref;
|
||||||
this.allowStreams = allowStreams;
|
this.allowStreams = allowStreams;
|
||||||
@ -75,8 +70,8 @@ class Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
refill() {
|
refill() {
|
||||||
const [buf1, start1, end1] = this.lexer.getObj(true);
|
const [buf1, start1, end1] = this.lexer.getObjWithRange();
|
||||||
const [buf2, start2, end2] = this.lexer.getObj(true);
|
const [buf2, start2, end2] = this.lexer.getObjWithRange();
|
||||||
this.buf1 = buf1;
|
this.buf1 = buf1;
|
||||||
this.range1 = [start1, end1];
|
this.range1 = [start1, end1];
|
||||||
this.buf2 = buf2;
|
this.buf2 = buf2;
|
||||||
@ -87,12 +82,14 @@ class Parser {
|
|||||||
if (this.buf2 instanceof Cmd && this.buf2.cmd === "ID") {
|
if (this.buf2 instanceof Cmd && this.buf2.cmd === "ID") {
|
||||||
this.buf1 = this.buf2;
|
this.buf1 = this.buf2;
|
||||||
this.buf2 = null;
|
this.buf2 = null;
|
||||||
|
this.lastEnd = this.range1[1];
|
||||||
this.range1 = this.range2;
|
this.range1 = this.range2;
|
||||||
this.range2 = null;
|
this.range2 = null;
|
||||||
} else {
|
} else {
|
||||||
this.buf1 = this.buf2;
|
this.buf1 = this.buf2;
|
||||||
|
this.lastEnd = this.range1[1];
|
||||||
this.range1 = this.range2;
|
this.range1 = this.range2;
|
||||||
const [buf2, start2, end2] = this.lexer.getObj(true);
|
const [buf2, start2, end2] = this.lexer.getObjWithRange();
|
||||||
this.buf2 = buf2;
|
this.buf2 = buf2;
|
||||||
this.range2 = [start2, end2];
|
this.range2 = [start2, end2];
|
||||||
}
|
}
|
||||||
@ -116,6 +113,10 @@ class Parser {
|
|||||||
return this.range1 ? this.range1[0] : 0;
|
return this.range1 ? this.range1[0] : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getEnd() {
|
||||||
|
return this.lastEnd ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
getObjWithRange(cipherTransform = null) {
|
getObjWithRange(cipherTransform = null) {
|
||||||
const start = this.range1[0];
|
const start = this.range1[0];
|
||||||
const obj = this.getObj(cipherTransform);
|
const obj = this.getObj(cipherTransform);
|
||||||
@ -1229,14 +1230,18 @@ class Lexer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getObjWithRange() {
|
getObjWithRange() {
|
||||||
// at the start of getObj() the stream has stepped beyond currentChar by one
|
const ch = this._skipWhitespaceAndComments();
|
||||||
const start = this.stream.pos - 1;
|
if (ch === EOF) {
|
||||||
|
return [ch, -1, -1];
|
||||||
|
}
|
||||||
|
// currentChar is always at pos - 1
|
||||||
|
const start = Math.max(this.stream.pos - 1, 0);
|
||||||
const obj = this.getObj();
|
const obj = this.getObj();
|
||||||
const end = this.stream.pos;
|
const end = this.stream.pos - 1;
|
||||||
return [obj, start, end];
|
return [obj, start, end];
|
||||||
}
|
}
|
||||||
|
|
||||||
getObj(withRange = false) {
|
_skipWhitespaceAndComments() {
|
||||||
// Skip whitespace and comments.
|
// Skip whitespace and comments.
|
||||||
let comment = false;
|
let comment = false;
|
||||||
let ch = this.currentChar;
|
let ch = this.currentChar;
|
||||||
@ -1255,16 +1260,14 @@ class Lexer {
|
|||||||
}
|
}
|
||||||
ch = this.nextChar();
|
ch = this.nextChar();
|
||||||
}
|
}
|
||||||
const start = this.stream.pos - 1;
|
return ch;
|
||||||
const obj = this.extracted(ch);
|
|
||||||
const end = this.stream.pos - 1;
|
|
||||||
if (withRange) {
|
|
||||||
return [start, obj, end];
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extracted(ch) {
|
getObj() {
|
||||||
|
let ch = this._skipWhitespaceAndComments();
|
||||||
|
if (ch === EOF) {
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
// Start reading a token.
|
// Start reading a token.
|
||||||
switch (ch | 0) {
|
switch (ch | 0) {
|
||||||
case 0x30: // '0'
|
case 0x30: // '0'
|
||||||
|
|||||||
@ -748,6 +748,31 @@ class WorkerMessageHandler {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
handler.on("StreamContents", function(data, sink) {
|
||||||
|
const pageIndex = data.pageIndex;
|
||||||
|
pdfManager.getPage(pageIndex).then(function(page) {
|
||||||
|
page.getContentStream().then(stream => {
|
||||||
|
let byte;
|
||||||
|
let string = "";
|
||||||
|
while ((byte = stream.getByte()) !== -1) {
|
||||||
|
string += String.fromCharCode(byte);
|
||||||
|
}
|
||||||
|
sink.enqueue(string, string.length);
|
||||||
|
sink.close();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
handler.on("UpdateContents", function (data) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
const pageIndex = data.pageIndex;
|
||||||
|
pdfManager.getPage(pageIndex).then(function (page) {
|
||||||
|
page.setContents(data.value);
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
handler.on("GetOperatorList", function (data, sink) {
|
handler.on("GetOperatorList", function (data, sink) {
|
||||||
const pageIndex = data.pageIndex;
|
const pageIndex = data.pageIndex;
|
||||||
pdfManager.getPage(pageIndex).then(function (page) {
|
pdfManager.getPage(pageIndex).then(function (page) {
|
||||||
@ -767,6 +792,7 @@ class WorkerMessageHandler {
|
|||||||
cacheKey: data.cacheKey,
|
cacheKey: data.cacheKey,
|
||||||
annotationStorage: data.annotationStorage,
|
annotationStorage: data.annotationStorage,
|
||||||
modifiedIds: data.modifiedIds,
|
modifiedIds: data.modifiedIds,
|
||||||
|
contentOverride: data.contentOverride,
|
||||||
})
|
})
|
||||||
.then(
|
.then(
|
||||||
function (operatorListInfo) {
|
function (operatorListInfo) {
|
||||||
|
|||||||
@ -35,6 +35,7 @@ import {
|
|||||||
AbortException,
|
AbortException,
|
||||||
AnnotationMode,
|
AnnotationMode,
|
||||||
assert,
|
assert,
|
||||||
|
djb2Hash,
|
||||||
FeatureTest,
|
FeatureTest,
|
||||||
getVerbosityLevel,
|
getVerbosityLevel,
|
||||||
info,
|
info,
|
||||||
@ -1660,6 +1661,37 @@ class PDFPageProxy {
|
|||||||
return renderTask;
|
return renderTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateContents(newContents) {
|
||||||
|
if (!newContents) {
|
||||||
|
throw new Error("Contents may not be null or undefined");
|
||||||
|
}
|
||||||
|
this._intentStates.clear();
|
||||||
|
return this._transport.updateContents(newContents, this._pageIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
getContents() {
|
||||||
|
const readableStream = this._transport.streamContents(this._pageIndex);
|
||||||
|
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
function pump() {
|
||||||
|
reader.read().then(function ({ value, done }) {
|
||||||
|
if (done) {
|
||||||
|
resolve(textContent.text);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
textContent.text += value;
|
||||||
|
pump();
|
||||||
|
}, reject);
|
||||||
|
}
|
||||||
|
|
||||||
|
const reader = readableStream.getReader();
|
||||||
|
const textContent = {
|
||||||
|
text: "",
|
||||||
|
};
|
||||||
|
pump();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {GetOperatorListParameters} params - Page getOperatorList
|
* @param {GetOperatorListParameters} params - Page getOperatorList
|
||||||
* parameters.
|
* parameters.
|
||||||
@ -1671,6 +1703,7 @@ class PDFPageProxy {
|
|||||||
annotationMode = AnnotationMode.ENABLE,
|
annotationMode = AnnotationMode.ENABLE,
|
||||||
printAnnotationStorage = null,
|
printAnnotationStorage = null,
|
||||||
isEditing = false,
|
isEditing = false,
|
||||||
|
contentOverride = null,
|
||||||
} = {}) {
|
} = {}) {
|
||||||
if (typeof PDFJSDev !== "undefined" && !PDFJSDev.test("GENERIC")) {
|
if (typeof PDFJSDev !== "undefined" && !PDFJSDev.test("GENERIC")) {
|
||||||
throw new Error("Not implemented: getOperatorList");
|
throw new Error("Not implemented: getOperatorList");
|
||||||
@ -1688,7 +1721,8 @@ class PDFPageProxy {
|
|||||||
annotationMode,
|
annotationMode,
|
||||||
printAnnotationStorage,
|
printAnnotationStorage,
|
||||||
isEditing,
|
isEditing,
|
||||||
/* isOpList = */ true
|
/* isOpList = */ true,
|
||||||
|
contentOverride
|
||||||
);
|
);
|
||||||
let intentState = this._intentStates.get(intentArgs.cacheKey);
|
let intentState = this._intentStates.get(intentArgs.cacheKey);
|
||||||
if (!intentState) {
|
if (!intentState) {
|
||||||
@ -1910,6 +1944,7 @@ class PDFPageProxy {
|
|||||||
cacheKey,
|
cacheKey,
|
||||||
annotationStorageSerializable,
|
annotationStorageSerializable,
|
||||||
modifiedIds,
|
modifiedIds,
|
||||||
|
contentOverride,
|
||||||
}) {
|
}) {
|
||||||
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
|
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
|
||||||
assert(
|
assert(
|
||||||
@ -1927,6 +1962,7 @@ class PDFPageProxy {
|
|||||||
cacheKey,
|
cacheKey,
|
||||||
annotationStorage: map,
|
annotationStorage: map,
|
||||||
modifiedIds,
|
modifiedIds,
|
||||||
|
contentOverride,
|
||||||
},
|
},
|
||||||
transfer
|
transfer
|
||||||
);
|
);
|
||||||
@ -2528,7 +2564,8 @@ class WorkerTransport {
|
|||||||
annotationMode = AnnotationMode.ENABLE,
|
annotationMode = AnnotationMode.ENABLE,
|
||||||
printAnnotationStorage = null,
|
printAnnotationStorage = null,
|
||||||
isEditing = false,
|
isEditing = false,
|
||||||
isOpList = false
|
isOpList = false,
|
||||||
|
contentOverride = null
|
||||||
) {
|
) {
|
||||||
let renderingIntent = RenderingIntentFlag.DISPLAY; // Default value.
|
let renderingIntent = RenderingIntentFlag.DISPLAY; // Default value.
|
||||||
let annotationStorageSerializable = SerializableEmpty;
|
let annotationStorageSerializable = SerializableEmpty;
|
||||||
@ -2586,11 +2623,16 @@ class WorkerTransport {
|
|||||||
modifiedIdsHash,
|
modifiedIdsHash,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if (contentOverride) {
|
||||||
|
cacheKeyBuf.push(djb2Hash(contentOverride));
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
renderingIntent,
|
renderingIntent,
|
||||||
cacheKey: cacheKeyBuf.join("_"),
|
cacheKey: cacheKeyBuf.join("_"),
|
||||||
annotationStorageSerializable,
|
annotationStorageSerializable,
|
||||||
modifiedIds,
|
modifiedIds,
|
||||||
|
contentOverride,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2974,6 +3016,23 @@ class WorkerTransport {
|
|||||||
return this.messageHandler.sendWithPromise("GetXRefEntries", null);
|
return this.messageHandler.sendWithPromise("GetXRefEntries", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
streamContents(pageIndex) {
|
||||||
|
return this.messageHandler.sendWithStream("StreamContents", {
|
||||||
|
pageIndex,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Promise<void>} A promise that is resolved once the contents
|
||||||
|
* are updated.
|
||||||
|
*/
|
||||||
|
updateContents(newContents, pageIndex) {
|
||||||
|
return this.messageHandler.sendWithPromise("UpdateContents", {
|
||||||
|
value: newContents,
|
||||||
|
pageIndex,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
saveDocument() {
|
saveDocument() {
|
||||||
if (this.annotationStorage.size <= 0) {
|
if (this.annotationStorage.size <= 0) {
|
||||||
warn(
|
warn(
|
||||||
|
|||||||
@ -578,6 +578,16 @@ function objectFromMap(map) {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fast and easy hash
|
||||||
|
function djb2Hash(str) {
|
||||||
|
let hash = 5381;
|
||||||
|
for (let i = 0; i < str.length; i++) {
|
||||||
|
hash = (hash << 5) + hash + str.charCodeAt(i);
|
||||||
|
hash &= hash; // Convert to 32-bit integer
|
||||||
|
}
|
||||||
|
return hash >>> 0; // Convert to unsigned
|
||||||
|
}
|
||||||
|
|
||||||
// Checks the endianness of the platform.
|
// Checks the endianness of the platform.
|
||||||
function isLittleEndian() {
|
function isLittleEndian() {
|
||||||
const buffer8 = new Uint8Array(4);
|
const buffer8 = new Uint8Array(4);
|
||||||
@ -1136,6 +1146,7 @@ export {
|
|||||||
BASELINE_FACTOR,
|
BASELINE_FACTOR,
|
||||||
bytesToString,
|
bytesToString,
|
||||||
createValidAbsoluteUrl,
|
createValidAbsoluteUrl,
|
||||||
|
djb2Hash,
|
||||||
DocumentActionEventType,
|
DocumentActionEventType,
|
||||||
FeatureTest,
|
FeatureTest,
|
||||||
FONT_IDENTITY_MATRIX,
|
FONT_IDENTITY_MATRIX,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user