pdf-lib
Version:
Library for creating and modifying PDF files in JavaScript
268 lines (267 loc) • 13.4 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
}
Object.defineProperty(exports, "__esModule", { value: true });
var isNumber_1 = __importDefault(require("lodash/isNumber"));
var values_1 = __importDefault(require("lodash/values"));
var standard_fonts_1 = require("@pdf-lib/standard-fonts");
var PDFObjectCopier_1 = __importDefault(require("../pdf-document/PDFObjectCopier"));
var PDFObjectIndex_1 = __importDefault(require("../pdf-document/PDFObjectIndex"));
var pdf_objects_1 = require("../pdf-objects");
var pdf_structures_1 = require("../pdf-structures");
var JPEGXObjectFactory_1 = __importDefault(require("../pdf-structures/factories/JPEGXObjectFactory"));
var PDFEmbeddedFontFactory_1 = __importDefault(require("../pdf-structures/factories/PDFEmbeddedFontFactory"));
var PDFFontFactory_1 = __importDefault(require("../pdf-structures/factories/PDFFontFactory"));
var PDFStandardFontFactory_1 = __importDefault(require("../pdf-structures/factories/PDFStandardFontFactory"));
var PNGXObjectFactory_1 = __importDefault(require("../pdf-structures/factories/PNGXObjectFactory"));
var validate_1 = require("../../utils/validate");
var PDFDocument = /** @class */ (function () {
function PDFDocument(catalog, index) {
var _this = this;
/** @hidden */
this.header = pdf_structures_1.PDFHeader.forVersion(1, 7);
/**
* Registers a [[PDFObject]] to the [[PDFDocument]]'s `index`. Returns a
* [[PDFIndirectReference]] that can be used to reference the given `object`
* in other `pdf-lib` methods.
*
* @param object The [[PDFObject]] to be registered.
*
* @returns The [[PDFIndirectReference]] under which the `object` has been
* registered.
*/
this.register = function (object) {
validate_1.validate(object, validate_1.isInstance(pdf_objects_1.PDFObject), 'object must be a PDFObject');
return _this.index.assignNextObjectNumberTo(object);
};
/**
* @returns An array of [[PDFPage]] objects representing the pages of the
* [[PDFDocument]]. The order of the [[PDFPage]] documents in the
* array mirrors the order in which they will be rendered in the
* [[PDFDocument]].
*/
this.getPages = function () {
var pages = [];
_this.catalog.Pages.traverse(function (kid) {
if (kid instanceof pdf_structures_1.PDFPage)
pages.push(kid);
});
return pages;
};
/**
* Creates a new [[PDFPage]] of the given `size`. And optionally, with the
* given `resources` dictionary.
*
* Note that the [[PDFPage]] returned by this method is **not** automatically
* added to the [[PDFDocument]]. You must call the [[addPage]] or [[insertPage]]
* methods for it to be rendered in the document.
*
* @param size A tuple containing the width and height of the page,
* respectively.
* @param resources A resources dictionary for the page.
*
* @returns The newly created [[PDFPage]].
*/
this.createPage = function (size, resources) {
return pdf_structures_1.PDFPage.create(_this.index, size, resources);
};
/**
* Creates a new [[PDFContentStream]] with the given operators.
*
* Note that the [[PDFContentStream]] returned by this method is **not**
* automatically registered to the document or added to any of its pages.
* You must first call the [[register]] method for it to be registered to the
* [[PDFDocument]]. Then, you must call [[PDFPage.addContentStreams]] to add
* the registered [[PDFContentStream]] to the desired page(s).
*
* @param operators One or more [[PDFOperator]]s to be added to the
* [[PDFContentStream]].
*
* @returns The newly created [[PDFContentStream]].
*/
this.createContentStream = function () {
var operators = [];
for (var _i = 0; _i < arguments.length; _i++) {
operators[_i] = arguments[_i];
}
return pdf_structures_1.PDFContentStream.of.apply(pdf_structures_1.PDFContentStream, [pdf_objects_1.PDFDictionary.from({}, _this.index)].concat(operators));
};
/**
* Adds a page to the end of the [[PDFDocument]].
*
* @param page The page to be added.
*/
this.addPage = function (page) {
validate_1.validate(page, validate_1.isInstance(pdf_structures_1.PDFPage), 'page must be a PDFPage');
// If page comes from another document, copy it into this one
if (page.index !== _this.index) {
page = PDFObjectCopier_1.default.for(page.index, _this.index).copy(page);
}
var Pages = _this.catalog.Pages;
var lastPageTree = Pages;
var lastPageTreeRef = _this.catalog.get('Pages');
Pages.traverseRight(function (kid, ref) {
if (kid instanceof pdf_structures_1.PDFPageTree) {
lastPageTree = kid;
lastPageTreeRef = ref;
}
});
page.set('Parent', lastPageTreeRef);
lastPageTree.addPage(_this.register(page));
return _this;
};
// TODO: Clean up unused objects when possible after removing page from tree
// TODO: Make sure "idx" is within required range
/**
* Removes a page from the document.
*
* @param index The index of the page to be removed. The index is zero-based,
* e.g. the first page in the document is index `0`.
*/
this.removePage = function (index) {
validate_1.validate(index, isNumber_1.default, 'idx must be a number');
var pageTreeRef = _this.catalog.get('Pages');
// TODO: Use a "stop" callback to avoid unneccesarily traversing whole page tree...
var treeRef = pageTreeRef;
var pageCount = 0;
var kidNum = 0;
_this.catalog.Pages.traverse(function (kid, ref) {
if (pageCount !== index) {
if (kid instanceof pdf_structures_1.PDFPageTree)
kidNum = 0;
if (kid instanceof pdf_structures_1.PDFPage) {
pageCount += 1;
kidNum += 1;
if (pageCount === index)
treeRef = kid.get('Parent');
}
}
});
var tree = _this.index.lookup(treeRef);
tree.removePage(kidNum);
return _this;
};
// TODO: Make sure "idx" is within required range
/**
* Inserts a page into the document at the specified index. The page that is
* displaced by the insertion will be become the page immediately following
* the inserted page.
*
* @param index The index of the page to be removed. The index is zero-based,
* e.g. the first page in the document is index `0`.
* @param page The page to be inserted.
*/
this.insertPage = function (index, page) {
validate_1.validate(index, isNumber_1.default, 'idx must be a number');
validate_1.validate(page, validate_1.isInstance(pdf_structures_1.PDFPage), 'page must be a PDFPage');
// If page comes from another document, copy it into this one
if (page.index !== _this.index) {
page = PDFObjectCopier_1.default.for(page.index, _this.index).copy(page);
}
var pageTreeRef = _this.catalog.get('Pages');
// TODO: Use a "stop" callback to avoid unneccesarily traversing whole page tree...
var treeRef = pageTreeRef;
var pageCount = 0;
var kidNum = 0;
_this.catalog.Pages.traverse(function (kid, ref) {
if (pageCount !== index) {
if (kid instanceof pdf_structures_1.PDFPageTree)
kidNum = 0;
if (kid instanceof pdf_structures_1.PDFPage) {
pageCount += 1;
kidNum += 1;
if (pageCount === index)
treeRef = kid.get('Parent');
}
}
});
page.set('Parent', treeRef);
var tree = _this.index.lookup(treeRef);
tree.insertPage(kidNum, _this.register(page));
return _this;
};
/**
* Embeds one of the Standard 14 Fonts fonts in the document. This method
* does **not** require a `Uint8Array` containing a font to be passed, because
* the Standard 14 Fonts are automatically available to all PDF documents.
*
* @param fontName Name of the font to be embedded.
*
* @returns A tuple containing the [[PDFIndirectReference]] under which the
* specified font is registered.
*/
this.embedStandardFont = function (fontName) {
validate_1.validate(fontName, validate_1.oneOf.apply(void 0, values_1.default(standard_fonts_1.FontNames)), 'PDFDocument.embedStandardFont: "fontName" must be one of the Standard 14 Fonts: ' +
values_1.default(standard_fonts_1.FontNames).join(', '));
var standardFontFactory = PDFStandardFontFactory_1.default.for(fontName);
return [standardFontFactory.embedFontIn(_this), standardFontFactory];
};
/**
* **Deprecated** - please use [[PDFDocument.embedNonStandardFont]] instead.
*
* Embeds the font contained in the specified `Uint8Array` in the document.
*
* @param fontData A `Uint8Array` containing an OpenType (`.otf`) or TrueType
* (`.ttf`) font.
*
* @returns A tuple containing (1) the [[PDFIndirectReference]] under which the
* specified font is registered, and (2) a [[PDFFontFactory]] object
* containing font metadata properties and methods.
*/
this.embedFont = function (fontData, fontFlags) {
if (fontFlags === void 0) { fontFlags = { Nonsymbolic: true }; }
var fontFactory = PDFFontFactory_1.default.for(fontData, fontFlags);
return [fontFactory.embedFontIn(_this), fontFactory];
};
/**
* Embeds the font contained in the specified `Uint8Array` in the document.
*
* @param fontData A `Uint8Array` containing an OpenType (`.otf`) or TrueType
* (`.ttf`) font.
*
* @returns A tuple containing (1) the [[PDFIndirectReference]] under which the
* specified font is registered, and (2) a [[PDFEmbeddedFontFactory]]
* object containing font metadata properties and methods.
*/
this.embedNonstandardFont = function (fontData) {
var fontFactory = PDFEmbeddedFontFactory_1.default.for(fontData);
return [fontFactory.embedFontIn(_this), fontFactory];
};
/**
* Embeds the PNG image contained in the specified `Uint8Array` in the document.
*
* @param pngData A `Uint8Array` containing a PNG (`.png`) image.
*
* @returns A tuple containing (1) the [[PDFIndirectReference]] under which the
* specified image is registered, and (2) a [[PNGXObjectFactory]]
* object containing the image's width and height.
*/
this.embedPNG = function (pngData) {
var pngFactory = PNGXObjectFactory_1.default.for(pngData);
return [pngFactory.embedImageIn(_this), pngFactory];
};
/**
* Embeds the JPG image contained in the specified `Uint8Array` in the document.
*
* @param jpgData A `Uint8Array` containing a JPG (`.jpg`) image.
*
* @returns A tuple containing (1) the [[PDFIndirectReference]] under which the
* specified image is registered, and (2) a [[JPEGXObjectFactory]]
* object containing the image's width and height.
*/
this.embedJPG = function (jpgData) {
var jpgFactory = JPEGXObjectFactory_1.default.for(jpgData);
return [jpgFactory.embedImageIn(_this), jpgFactory];
};
validate_1.validate(catalog, validate_1.isInstance(pdf_structures_1.PDFCatalog), '"catalog" must be a PDFCatalog object');
validate_1.validate(index, validate_1.isInstance(PDFObjectIndex_1.default), '"index" must be a PDFObjectIndex object');
this.catalog = catalog;
this.index = index;
}
PDFDocument.from = function (catalog, index) {
return new PDFDocument(catalog, index);
};
return PDFDocument;
}());
exports.default = PDFDocument;