UNPKG

pdf-lib

Version:

Create and modify PDF files with JavaScript

184 lines 8.93 kB
import { __extends } from "tslib"; import PDFName from "../objects/PDFName"; import PDFRef from "../objects/PDFRef"; import PDFFlateStream from "./PDFFlateStream"; import { bytesFor, Cache, reverseArray, sizeInBytes, sum } from "../../utils"; export var EntryType; (function (EntryType) { EntryType[EntryType["Deleted"] = 0] = "Deleted"; EntryType[EntryType["Uncompressed"] = 1] = "Uncompressed"; EntryType[EntryType["Compressed"] = 2] = "Compressed"; })(EntryType || (EntryType = {})); /** * Entries should be added using the [[addDeletedEntry]], * [[addUncompressedEntry]], and [[addCompressedEntry]] methods * **in order of ascending object number**. */ var PDFCrossRefStream = /** @class */ (function (_super) { __extends(PDFCrossRefStream, _super); function PDFCrossRefStream(dict, entries, encode) { if (encode === void 0) { encode = true; } var _this = _super.call(this, dict, encode) || this; // Returns an array of integer pairs for each subsection of the cross ref // section, where each integer pair represents: // firstObjectNumber(OfSection), length(OfSection) _this.computeIndex = function () { var subsections = []; var subsectionLength = 0; for (var idx = 0, len = _this.entries.length; idx < len; idx++) { var currEntry = _this.entries[idx]; var prevEntry = _this.entries[idx - 1]; if (idx === 0) { subsections.push(currEntry.ref.objectNumber); } else if (currEntry.ref.objectNumber - prevEntry.ref.objectNumber > 1) { subsections.push(subsectionLength); subsections.push(currEntry.ref.objectNumber); subsectionLength = 0; } subsectionLength += 1; } subsections.push(subsectionLength); return subsections; }; _this.computeEntryTuples = function () { var entryTuples = new Array(_this.entries.length); for (var idx = 0, len = _this.entries.length; idx < len; idx++) { var entry = _this.entries[idx]; if (entry.type === EntryType.Deleted) { var type = entry.type, nextFreeObjectNumber = entry.nextFreeObjectNumber, ref = entry.ref; entryTuples[idx] = [type, nextFreeObjectNumber, ref.generationNumber]; } if (entry.type === EntryType.Uncompressed) { var type = entry.type, offset = entry.offset, ref = entry.ref; entryTuples[idx] = [type, offset, ref.generationNumber]; } if (entry.type === EntryType.Compressed) { var type = entry.type, objectStreamRef = entry.objectStreamRef, index = entry.index; entryTuples[idx] = [type, objectStreamRef.objectNumber, index]; } } return entryTuples; }; _this.computeMaxEntryByteWidths = function () { var entryTuples = _this.entryTuplesCache.access(); var widths = [0, 0, 0]; for (var idx = 0, len = entryTuples.length; idx < len; idx++) { var _a = entryTuples[idx], first = _a[0], second = _a[1], third = _a[2]; var firstSize = sizeInBytes(first); var secondSize = sizeInBytes(second); var thirdSize = sizeInBytes(third); if (firstSize > widths[0]) widths[0] = firstSize; if (secondSize > widths[1]) widths[1] = secondSize; if (thirdSize > widths[2]) widths[2] = thirdSize; } return widths; }; _this.entries = entries || []; _this.entryTuplesCache = Cache.populatedBy(_this.computeEntryTuples); _this.maxByteWidthsCache = Cache.populatedBy(_this.computeMaxEntryByteWidths); _this.indexCache = Cache.populatedBy(_this.computeIndex); dict.set(PDFName.of('Type'), PDFName.of('XRef')); return _this; } PDFCrossRefStream.prototype.addDeletedEntry = function (ref, nextFreeObjectNumber) { var type = EntryType.Deleted; this.entries.push({ type: type, ref: ref, nextFreeObjectNumber: nextFreeObjectNumber }); this.entryTuplesCache.invalidate(); this.maxByteWidthsCache.invalidate(); this.indexCache.invalidate(); this.contentsCache.invalidate(); }; PDFCrossRefStream.prototype.addUncompressedEntry = function (ref, offset) { var type = EntryType.Uncompressed; this.entries.push({ type: type, ref: ref, offset: offset }); this.entryTuplesCache.invalidate(); this.maxByteWidthsCache.invalidate(); this.indexCache.invalidate(); this.contentsCache.invalidate(); }; PDFCrossRefStream.prototype.addCompressedEntry = function (ref, objectStreamRef, index) { var type = EntryType.Compressed; this.entries.push({ type: type, ref: ref, objectStreamRef: objectStreamRef, index: index }); this.entryTuplesCache.invalidate(); this.maxByteWidthsCache.invalidate(); this.indexCache.invalidate(); this.contentsCache.invalidate(); }; PDFCrossRefStream.prototype.clone = function (context) { var _a = this, dict = _a.dict, entries = _a.entries, encode = _a.encode; return PDFCrossRefStream.of(dict.clone(context), entries.slice(), encode); }; PDFCrossRefStream.prototype.getContentsString = function () { var entryTuples = this.entryTuplesCache.access(); var byteWidths = this.maxByteWidthsCache.access(); var value = ''; for (var entryIdx = 0, entriesLen = entryTuples.length; entryIdx < entriesLen; entryIdx++) { var _a = entryTuples[entryIdx], first = _a[0], second = _a[1], third = _a[2]; var firstBytes = reverseArray(bytesFor(first)); var secondBytes = reverseArray(bytesFor(second)); var thirdBytes = reverseArray(bytesFor(third)); for (var idx = byteWidths[0] - 1; idx >= 0; idx--) { value += (firstBytes[idx] || 0).toString(2); } for (var idx = byteWidths[1] - 1; idx >= 0; idx--) { value += (secondBytes[idx] || 0).toString(2); } for (var idx = byteWidths[2] - 1; idx >= 0; idx--) { value += (thirdBytes[idx] || 0).toString(2); } } return value; }; PDFCrossRefStream.prototype.getUnencodedContents = function () { var entryTuples = this.entryTuplesCache.access(); var byteWidths = this.maxByteWidthsCache.access(); var buffer = new Uint8Array(this.getUnencodedContentsSize()); var offset = 0; for (var entryIdx = 0, entriesLen = entryTuples.length; entryIdx < entriesLen; entryIdx++) { var _a = entryTuples[entryIdx], first = _a[0], second = _a[1], third = _a[2]; var firstBytes = reverseArray(bytesFor(first)); var secondBytes = reverseArray(bytesFor(second)); var thirdBytes = reverseArray(bytesFor(third)); for (var idx = byteWidths[0] - 1; idx >= 0; idx--) { buffer[offset++] = firstBytes[idx] || 0; } for (var idx = byteWidths[1] - 1; idx >= 0; idx--) { buffer[offset++] = secondBytes[idx] || 0; } for (var idx = byteWidths[2] - 1; idx >= 0; idx--) { buffer[offset++] = thirdBytes[idx] || 0; } } return buffer; }; PDFCrossRefStream.prototype.getUnencodedContentsSize = function () { var byteWidths = this.maxByteWidthsCache.access(); var entryWidth = sum(byteWidths); return entryWidth * this.entries.length; }; PDFCrossRefStream.prototype.updateDict = function () { _super.prototype.updateDict.call(this); var byteWidths = this.maxByteWidthsCache.access(); var index = this.indexCache.access(); var context = this.dict.context; this.dict.set(PDFName.of('W'), context.obj(byteWidths)); this.dict.set(PDFName.of('Index'), context.obj(index)); }; PDFCrossRefStream.create = function (dict, encode) { if (encode === void 0) { encode = true; } var stream = new PDFCrossRefStream(dict, [], encode); stream.addDeletedEntry(PDFRef.of(0, 65535), 0); return stream; }; PDFCrossRefStream.of = function (dict, entries, encode) { if (encode === void 0) { encode = true; } return new PDFCrossRefStream(dict, entries, encode); }; return PDFCrossRefStream; }(PDFFlateStream)); export default PDFCrossRefStream; //# sourceMappingURL=PDFCrossRefStream.js.map