UNPKG

pdf-lib

Version:

Library for creating and modifying PDF files in JavaScript

268 lines (267 loc) 13.4 kB
"use strict"; 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;