@pdfme/pdf-lib
Version:
Create and modify PDF files with JavaScript
133 lines • 6.01 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const PDFCrossRefSection_1 = __importDefault(require("../document/PDFCrossRefSection"));
const PDFHeader_1 = __importDefault(require("../document/PDFHeader"));
const PDFTrailer_1 = __importDefault(require("../document/PDFTrailer"));
const PDFTrailerDict_1 = __importDefault(require("../document/PDFTrailerDict"));
const PDFObjectStream_1 = __importDefault(require("../structures/PDFObjectStream"));
const CharCodes_1 = __importDefault(require("../syntax/CharCodes"));
const utils_1 = require("../../utils");
class PDFWriter {
constructor(context, objectsPerTick) {
Object.defineProperty(this, "context", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "objectsPerTick", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "parsedObjects", {
enumerable: true,
configurable: true,
writable: true,
value: 0
});
Object.defineProperty(this, "shouldWaitForTick", {
enumerable: true,
configurable: true,
writable: true,
value: (n) => {
this.parsedObjects += n;
return this.parsedObjects % this.objectsPerTick === 0;
}
});
this.context = context;
this.objectsPerTick = objectsPerTick;
}
async serializeToBuffer() {
const { size, header, indirectObjects, xref, trailerDict, trailer } = await this.computeBufferSize();
let offset = 0;
const buffer = new Uint8Array(size);
offset += header.copyBytesInto(buffer, offset);
buffer[offset++] = CharCodes_1.default.Newline;
buffer[offset++] = CharCodes_1.default.Newline;
for (let idx = 0, len = indirectObjects.length; idx < len; idx++) {
const [ref, object] = indirectObjects[idx];
const objectNumber = String(ref.objectNumber);
offset += (0, utils_1.copyStringIntoBuffer)(objectNumber, buffer, offset);
buffer[offset++] = CharCodes_1.default.Space;
const generationNumber = String(ref.generationNumber);
offset += (0, utils_1.copyStringIntoBuffer)(generationNumber, buffer, offset);
buffer[offset++] = CharCodes_1.default.Space;
buffer[offset++] = CharCodes_1.default.o;
buffer[offset++] = CharCodes_1.default.b;
buffer[offset++] = CharCodes_1.default.j;
buffer[offset++] = CharCodes_1.default.Newline;
offset += object.copyBytesInto(buffer, offset);
buffer[offset++] = CharCodes_1.default.Newline;
buffer[offset++] = CharCodes_1.default.e;
buffer[offset++] = CharCodes_1.default.n;
buffer[offset++] = CharCodes_1.default.d;
buffer[offset++] = CharCodes_1.default.o;
buffer[offset++] = CharCodes_1.default.b;
buffer[offset++] = CharCodes_1.default.j;
buffer[offset++] = CharCodes_1.default.Newline;
buffer[offset++] = CharCodes_1.default.Newline;
const n = object instanceof PDFObjectStream_1.default ? object.getObjectsCount() : 1;
if (this.shouldWaitForTick(n))
await (0, utils_1.waitForTick)();
}
if (xref) {
offset += xref.copyBytesInto(buffer, offset);
buffer[offset++] = CharCodes_1.default.Newline;
}
if (trailerDict) {
offset += trailerDict.copyBytesInto(buffer, offset);
buffer[offset++] = CharCodes_1.default.Newline;
buffer[offset++] = CharCodes_1.default.Newline;
}
offset += trailer.copyBytesInto(buffer, offset);
return buffer;
}
computeIndirectObjectSize([ref, object]) {
const refSize = ref.sizeInBytes() + 3; // 'R' -> 'obj\n'
const objectSize = object.sizeInBytes() + 9; // '\nendobj\n\n'
return refSize + objectSize;
}
createTrailerDict() {
return this.context.obj({
Size: this.context.largestObjectNumber + 1,
Root: this.context.trailerInfo.Root,
Encrypt: this.context.trailerInfo.Encrypt,
Info: this.context.trailerInfo.Info,
ID: this.context.trailerInfo.ID,
});
}
async computeBufferSize() {
const header = PDFHeader_1.default.forVersion(1, 7);
let size = header.sizeInBytes() + 2;
const xref = PDFCrossRefSection_1.default.create();
const indirectObjects = this.context.enumerateIndirectObjects();
for (let idx = 0, len = indirectObjects.length; idx < len; idx++) {
const indirectObject = indirectObjects[idx];
const [ref] = indirectObject;
xref.addEntry(ref, size);
size += this.computeIndirectObjectSize(indirectObject);
if (this.shouldWaitForTick(1))
await (0, utils_1.waitForTick)();
}
const xrefOffset = size;
size += xref.sizeInBytes() + 1; // '\n'
const trailerDict = PDFTrailerDict_1.default.of(this.createTrailerDict());
size += trailerDict.sizeInBytes() + 2; // '\n\n'
const trailer = PDFTrailer_1.default.forLastCrossRefSectionOffset(xrefOffset);
size += trailer.sizeInBytes();
return { size, header, indirectObjects, xref, trailerDict, trailer };
}
}
Object.defineProperty(PDFWriter, "forContext", {
enumerable: true,
configurable: true,
writable: true,
value: (context, objectsPerTick) => new PDFWriter(context, objectsPerTick)
});
exports.default = PDFWriter;
//# sourceMappingURL=PDFWriter.js.map