@syncfusion/ej2-pdf
Version:
Feature-rich JavaScript PDF library with built-in support for loading and manipulating PDF document.
4,425 lines • 187 kB
JavaScript
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
import { _PdfContentStream, _PdfStream } from './base-stream';
import { _PdfCrossReference } from './pdf-cross-reference';
import { _Linearization } from './pdf-parser';
import { _isWhiteSpace, FormatError, _decode, _getNewGuidString, _isNullOrUndefined, _updatePageSettings, _updatePageCount, _convertDateToString, _convertStringToDate, _getCjkEncoding, _getCjkDescendantFont, _resolveStandardFontFamily, _resolveCjkFontFamily, _bytesToHex } from './utils';
import { _PdfCatalog } from './pdf-catalog';
import { _PdfDictionary, _PdfReference, _isName, _PdfName, _clearPrimitiveCaches } from './pdf-primitives';
import { PdfPage } from './pdf-page';
import { Save } from '@syncfusion/ej2-file-utils';
import { DataFormat, PdfPermissionFlag, PdfTextAlignment, PdfPageOrientation, PdfRotationAngle, _PdfWordWrapType, PdfTemplateHorizontalAlignment, PdfTemplateVerticalAlignment, PdfTemplateLayerMode, _PdfDocumentTemplateKey, _TemplateSide, _PdfAlignmentStyle } from './enumerator';
import { PdfForm } from './form/form';
import { _PdfTransformationMatrix, PdfBrush, PdfGraphics } from './graphics/pdf-graphics';
import { _PdfCjkStandardFontMetricsFactory, _PdfStandardFontMetricsFactory, PdfCjkStandardFont, PdfFontFamily, PdfFontStyle, PdfStandardFont, PdfTrueTypeFont } from './fonts/pdf-standard-font';
import { PdfStringFormat, PdfVerticalAlignment } from './fonts/pdf-string-format';
import { _XfdfDocument } from './import-export/xfdf-document';
import { _JsonDocument } from './import-export/json-document';
import { _FdfDocument } from './import-export/fdf-document';
import { PdfBookmarkBase, _PdfNamedDestinationCollection } from './pdf-outline';
import { _XmlDocument } from './import-export/xml-document';
import { PdfFileStructure } from './pdf-file-structure';
import { _PdfMergeHelper } from './pdf-merge';
import { PdfPageImportOptions } from './pdf-page-import-options';
import { PdfLayerCollection } from './layers/layer-collection';
import { PdfSection } from './pdf-section';
import { _UnicodeTrueTypeFont } from './fonts/unicode-true-type-font';
import { _MD5 } from './security/encryptors/messageDigest5';
import { PdfSignature } from './security/digital-signature/signature/pdf-signature';
import { initializeTelemetry, initializeTelemetryFeature, validateLicense } from '@syncfusion/ej2-base';
import { PdfUriAnnotation } from './annotations/annotation';
import { _PdfStringLayouter } from './fonts/string-layouter';
import { PdfXmpMetadata } from './xmp/pdf-xmp-metadata';
import { _XmlReader } from './xmp/xml-reader';
import { _PdfFlateStream } from './flate-stream';
import { PdfCustomMetadata } from './xmp/pdf-custom-metadata';
import { _PdfStreamWriter } from './graphics/pdf-stream-writer';
/**
* Represents a PDF document and can be used to parse an existing PDF document.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data);
* // Access first page
* let page: PdfPage = document.getPage(0);
* // Flatten annotations and form fields
* document.flatten = true;
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
var PdfDocument = /** @class */ (function () {
function PdfDocument(data, password) {
this._headerSignature = new Uint8Array([0x25, 0x50, 0x44, 0x46, 0x2d]);
this._startXrefSignature = new Uint8Array([0x73, 0x74, 0x61, 0x72, 0x74, 0x78, 0x72, 0x65, 0x66]);
this._endObjSignature = new Uint8Array([0x65, 0x6e, 0x64, 0x6f, 0x62, 0x6a]);
this._version = '';
/**
* Effective permission flags for the current document.
*
* @private
*/
this._permissions = PdfPermissionFlag.default;
/**
* Indicates whether the source document is encrypted.
*
* @private
*/
this._isEncrypted = false;
/**
* Indicates whether a user password was used to decrypt the document.
*
* @private
*/
this._isUserPassword = false;
/**
* Indicates whether only a user password is present for the document.
*
* @private
*/
this._hasUserPasswordOnly = false;
/**
* Indicates whether only attachments should be encrypted.
*
* @private
*/
this._encryptOnlyAttachment = false;
/**
* Indicates whether metadata needs to be encrypted.
*
* @private
*/
this._encryptMetaData = false;
/**
* Indicates whether the current operation is an export action (annotations/forms).
*
* @private
*/
this._isExport = false;
this._allowCustomData = false;
/**
* Indicates that the current import operation is duplicating an existing page.
*
* @private
*/
this._isDuplicatePage = false;
/**
* Indicates that the current document is used during a split operation.
*
* @private
*/
this._isSplitDocument = false;
/**
* Optional content configuration dictionary references.
*
* @private
*/
this._optionalContentDictionaries = [];
/**
* Optional content order array of OCG/OCMD references.
*
* @private
*/
this._order = [];
/**
* Optional content groups to be set ON.
*
* @private
*/
this._on = [];
/**
* Optional content groups to be set OFF.
*
* @private
*/
this._off = [];
/**
* Optional content group/intent relationships.
*
* @private
*/
this._as = [];
/**
* Optional content groups to be printed.
*
* @private
*/
this._printLayer = [];
/**
* Indicates whether the document was loaded from an existing byte source.
*
* @private
*/
this._isLoaded = true;
this._isFormImport = false;
/**
* Collection of sections within the document.
*
* @private
*/
this._sections = [];
/**
* Maintains background layer mappings for each page.
*
* @private
*/
this._backgroundLayers = new Map();
/**
* Indicates whether template rendering has started for the document.
*
* @private
*/
this._templateRenderingStarted = false;
initializeTelemetry('PDFLibrary');
this._fontCollection = new Map();
if (data) {
this._stream = new _PdfStream(typeof data === 'string' ? _decode(data) : data);
this._fileStructure = new PdfFileStructure();
this._crossReference = new _PdfCrossReference(this, password);
this._pages = new Map();
this._checkHeader();
this._crossReference._setStartXRef(this._startXRef);
try {
this._parse(false);
}
catch (e) {
if (e.name === 'XRefParseException') {
this._parse(true);
}
else {
throw e;
}
}
this._crossReference._version = this._version;
}
else {
this._isLoaded = false;
this._stream = new _PdfStream([]);
this._version = '1.4';
this._fileStructure = new PdfFileStructure();
this._fileStructure.isIncrementalUpdate = false;
this._crossReference = new _PdfCrossReference(this);
this._crossReference._version = this._version;
this._crossReference._nextReferenceNumber = 1;
var catalogDictionary = new _PdfDictionary(this._crossReference);
catalogDictionary.update('Type', _PdfName.get('Catalog'));
var catalogReference = this._crossReference._getNextReference();
catalogDictionary.objId = catalogReference.objectNumber + ' ' + catalogReference.generationNumber;
this._crossReference._cacheMap.set(catalogReference, catalogDictionary);
var trailerDictionary = new _PdfDictionary();
trailerDictionary.update('Root', catalogReference);
this._crossReference._trailer = trailerDictionary;
this._crossReference._root = catalogDictionary;
var topPagesDictionary = new _PdfDictionary(this._crossReference);
topPagesDictionary.update('Type', _PdfName.get('Pages'));
topPagesDictionary.update('Kids', []);
topPagesDictionary.update('Count', 0);
var topPagesReference = this._crossReference._getNextReference();
this._crossReference._cacheMap.set(topPagesReference, topPagesDictionary);
catalogDictionary.update('Pages', topPagesReference);
this._catalog = new _PdfCatalog(this._crossReference);
this._pages = new Map();
}
}
Object.defineProperty(PdfDocument.prototype, "_allowImportCustomData", {
/**
* Gets whether custom data import is allowed.
*
* @private
* @returns {boolean} `true` if importing custom data is allowed; otherwise, `false`.
*/
get: function () {
return this._allowCustomData;
},
/**
* Sets whether custom data import is allowed.
*
* @private
* @param {boolean} value `true` to allow custom data import; otherwise, `false`.
*/
set: function (value) {
this._allowCustomData = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfDocument.prototype, "_linearization", {
/**
* Gets the parsed linearization information if available.
*
* @private
* @returns {_Linearization} The linearization helper if the document is linearized; otherwise, `undefined`.
*/
get: function () {
if (!this._linear) {
var value = void 0;
try {
value = new _Linearization(this._stream);
}
catch (err) { } // eslint-disable-line
this._linear = value;
}
return this._linear;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfDocument.prototype, "_startXRef", {
/**
* Locates and returns the byte offset of the startxref section.
*
* @private
* @returns {number} The position of the last `startxref` marker; otherwise, 0 if not found.
*/
get: function () {
var stream = this._stream;
var startXRef = 0;
if (this._linearization && this._linearization.isValid) {
stream.reset();
if (this._find(stream, this._endObjSignature)) {
startXRef = stream.position + 6 - stream.start;
}
}
else {
var step = 1024;
var startXRefLength = this._startXrefSignature.length;
var found = false;
var position = stream.end;
while (!found && position > 0) {
position -= step - startXRefLength;
if (position < 0) {
position = 0;
}
stream.position = position;
found = this._find(stream, this._startXrefSignature, step, true);
}
if (found) {
stream.skip(9);
var ch = void 0;
do {
ch = stream.getByte();
} while (_isWhiteSpace(ch));
var str = '';
while (ch >= 0x20 && ch <= 0x39) {
str += String.fromCharCode(ch);
ch = stream.getByte();
}
startXRef = parseInt(str, 10);
if (isNaN(startXRef)) {
startXRef = 0;
}
}
}
return startXRef;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfDocument.prototype, "isEncrypted", {
/**
* Gets a value indicating whether the document is encrypted. (Read Only).
*
* @returns {boolean} A boolean value indicates whether the document is encrypted.
*
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Gets a value indicating whether the document is encrypted.
* let isEncrypted: boolean = document.isEncrypted;
* // Destroy the document
* document.destroy();
* ```
*/
get: function () {
return this._isEncrypted;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfDocument.prototype, "isUserPassword", {
/**
* Gets a value indicating whether the document is decrypted using the user password. (Read only).
*
* @returns {boolean} A boolean value indicates whether the document is decrypted using the user password.
*
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Gets a value indicating whether the document is decrypted using the user password
* let isUserPassword: boolean = document.isUserPassword;
* // Destroy the document
* document.destroy();
* ```
*/
get: function () {
return this._isUserPassword;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfDocument.prototype, "pageCount", {
/**
* Gets the page count (Read only).
*
* @returns {number} Number of pages
*
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Gets the page count
* let count: number = document.pageCount;
* // Destroy the document
* document.destroy();
* ```
*/
get: function () {
if (typeof this._pageCount === 'undefined') {
this._pageCount = 0;
if (this._linearization && this._linearization.isValid) {
this._pageCount = this._linearization.pageCount;
}
else {
this._pageCount = this._catalog.pageCount;
}
}
return this._pageCount;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfDocument.prototype, "form", {
/**
* Gets the PDF form fields included in the document (Read only).
*
* @returns {PdfForm} Form object
*
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Access loaded form
* let form: PdfForm = document.form;
* // Destroy the document
* document.destroy();
* ```
*/
get: function () {
if (typeof this._form === 'undefined') {
this._form = new PdfForm(this._catalog.acroForm, this._crossReference);
}
return this._form;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfDocument.prototype, "flatten", {
/**
* Gets the boolean flag to flatten the annotations and form fields.
*
* @returns {boolean} Flag to flatten
*
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Gets the flatten value applied
* let flatten: boolean = document.flatten;
* // Destroy the document
* document.destroy();
* ```
*/
get: function () {
return this._flatten;
},
/**
* Sets the boolean flag to flatten the annotations and form fields.
*
* @param {boolean} value to flatten
*
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Flatten PDF annotations and form fields
* document.flatten = true;
* // Destroy the document
* document.destroy();
* ```
*/
set: function (value) {
this._flatten = value;
},
enumerable: true,
configurable: true
});
/**
* Decompresses PDF stream bytes if they are compressed with a filter.
*
* @private
* @param {_PdfStream} stream The PDF stream to decompress.
* @returns {Uint8Array} The decompressed bytes, or original bytes if not compressed.
*/
PdfDocument.prototype._getDecompressedStreamBytes = function (stream) {
if (stream instanceof _PdfFlateStream) {
var len = stream.bytes ? stream.bytes.length : (stream.bufferLength || 0); // eslint-disable-line
return stream.getBytes(len);
}
return stream.bytes;
};
/**
* Gets the XMP metadata of the PDF document.
*
* @private
* @returns {PdfXmpMetadata} The XMP metadata object present.
*/
PdfDocument.prototype._getMetadataValue = function () {
if (this._xmpMetadata) {
return this._xmpMetadata;
}
if (this._catalog && this._catalog._catalogDictionary.has('Metadata')) {
var metadataRef = this._catalog._catalogDictionary.getRaw('Metadata'); // eslint-disable-line
var metadataStream = void 0; // eslint-disable-line
if (metadataRef instanceof _PdfReference) {
var obj = this._crossReference._fetch(metadataRef); // eslint-disable-line
if (obj instanceof _PdfStream || obj instanceof _PdfFlateStream) {
metadataStream = obj;
}
}
else if (metadataRef instanceof _PdfStream || metadataRef instanceof _PdfFlateStream) {
metadataStream = metadataRef;
}
if (metadataStream) {
var reader = new _XmlReader();
reader._load(this._getDecompressedStreamBytes(metadataStream));
this._xmpMetadata = reader._parseXmp();
return this._xmpMetadata;
}
}
this._xmpMetadata = new PdfXmpMetadata();
return this._xmpMetadata;
};
Object.defineProperty(PdfDocument.prototype, "permissions", {
/**
* Gets the permission flag of the PDF document (Read only).
*
* @returns {PdfPermissionFlag} permission flag. Default value is PdfPermissionFlag.default.
*
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Gets the permission flag
* let permission: PdfPermissionFlag = document.permissions;
* // Destroy the document
* document.destroy();
* ```
*/
get: function () {
if (this._crossReference) {
var flag = this._crossReference._permissionFlags;
if (typeof flag !== 'undefined') {
this._permissions = (flag & ~-3904);
}
}
return this._permissions;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfDocument.prototype, "bookmarks", {
/**
* Gets the bookmarks (Read only).
*
* @returns {PdfBookmarkBase} Bookmarks.
*
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Get bookmarks
* let bookmarks: PdfBookmarkBase = document.bookmarks;
* // Destroy the document
* document.destroy();
* ```
*/
get: function () {
var catalog = this._catalog;
if (catalog) {
if (catalog._catalogDictionary.has('Outlines')) {
var reference = catalog._catalogDictionary._get('Outlines');
var outlines = catalog._catalogDictionary.get('Outlines');
if (outlines) {
this._bookmarkBase = new PdfBookmarkBase(outlines, this._crossReference);
this._bookmarkBase._reference = reference;
if (outlines.has('First')) {
this._bookmarkBase._reproduceTree();
}
}
}
else {
var outlines = new _PdfDictionary(this._crossReference);
var reference = this._crossReference._getNextReference();
this._crossReference._cacheMap.set(reference, outlines);
catalog._catalogDictionary.update('Outlines', reference);
this._crossReference._allowCatalog = true;
this._bookmarkBase = new PdfBookmarkBase(outlines, this._crossReference);
this._bookmarkBase._reference = reference;
}
}
return this._bookmarkBase;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfDocument.prototype, "fileStructure", {
/**
* Gets the internal structure of the PDF document.
*
* @returns {PdfFileStructure} The internal structure of the PDF document.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Access the internal file structure of the PDF document
* let fileStructure: PdfFileStructure = document.fileStructure;
* // Get the cross reference type
* let type: PdfCrossReferenceType = fileStructure.crossReferenceType;
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
get: function () {
return this._fileStructure;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfDocument.prototype, "layers", {
/**
* Gets the collection of `PdfLayer` from the document.
*
* @returns {PdfLayerCollection} Layer collection.
*
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data);
* // Access the collection of layers in the document
* let layers: PdfLayerCollection = document.layers;
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
get: function () {
if (!this._layers) {
this._layers = new PdfLayerCollection(this);
}
return this._layers;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfDocument.prototype, "template", {
/**
* Gets the template configuration for document-level headers and footers.
*
* ```typescript
* // Create new document
* let document: PdfDocument = new PdfDocument();
* // Initialize the standard font
* const font: PdfStandardFont = new PdfStandardFont(PdfFontFamily.helvetica, 12);
* / Initialize brush
* const brush: PdfBrush = new PdfBrush({ r: 0, g: 0, b: 0 });
* // Create header template
* let headerTemplate: PdfPageTemplateElement = new PdfPageTemplateElement({width: 500, height: 50});
* // Draw content on header
* headerTemplate.graphics.drawString('Document Header', font, {x: 10, y: 10, width: 400, height: 30}, brush);
* // Assign template to document
* document.template.top = {template: headerTemplate };
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*
* @returns {PdfDocumentTemplate} The document template.
*/
get: function () {
if (this._isLoaded) {
return this._template;
}
if (!this._template) {
this._template = {};
}
return this._template;
},
enumerable: true,
configurable: true
});
/**
* Gets an array of revision numbers for the PDF document.
*
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data);
* // Retrieve all revision indexes of the PDF document
* let revisions: number[] = document.getRevisions();
* // Destroy the document
* document.destroy();
* ```
*
* @returns {number[]} - The list of revisions in the document.
*/
PdfDocument.prototype.getRevisions = function () {
var _this = this;
if (!this._isLoaded) {
return undefined;
}
if (this._revisions) {
return this._revisions;
}
var startCrossReferences = this._startXRefParsedCache
? this._startXRefParsedCache.sort(function (a, b) { return a - b; })
: [];
if (startCrossReferences.length === 0) {
return (this._revisions = []);
}
var eofSig = new Uint8Array([0x25, 0x25, 0x45, 0x4F, 0x46]);
var stream = this._stream;
var endOfFileSign = [];
startCrossReferences.forEach(function (entry) {
stream.position = entry;
var remaining = stream.end - stream.position;
if (remaining < eofSig.length || !_this._find(stream, eofSig, remaining, false)) {
return;
}
var j = stream.position + eofSig.length;
stream.position = j;
if (stream.position < stream.end) {
var nextCharacter = stream.getByte();
if (nextCharacter === 0x0d) {
j++;
if (stream.position < stream.end && stream.getByte() === 0x0a) {
j++;
}
}
else if (nextCharacter === 0x0a) {
j++;
}
}
endOfFileSign.push(j);
});
return (this._revisions = endOfFileSign);
};
PdfDocument.prototype.embedFont = function (arg1, arg2, arg3, arg4) {
var key;
var primitive;
if (typeof arg1 === 'string' || arg1 instanceof Uint8Array) {
var fontData = typeof arg1 === 'string' ? _decode(arg1) : arg1;
key = this._computeFontHash(fontData);
var size_1 = arg2;
var options = arg3;
primitive = this._getOrCreateFontPrimitive(key, { type: 'ttf', data: fontData });
this._fontCollection.set(key, primitive);
var style_1 = PdfFontStyle.regular;
if (options && options.shouldUnderline) {
style_1 = PdfFontStyle.underline;
}
if (options && options.shouldStrikeout) {
style_1 = PdfFontStyle.strikeout;
}
var trueTypeFont = new PdfTrueTypeFont(fontData, size_1, style_1, primitive);
trueTypeFont._document = this;
return trueTypeFont;
}
var fontFamily = arg1; // eslint-disable-line
var style = arg3;
var size = arg2;
var isCjk = false;
if (typeof arg4 === 'boolean') {
isCjk = arg4;
}
if (isCjk) {
var cjkFamily = fontFamily;
key = "cjk_" + cjkFamily + "_" + style;
primitive = this._getOrCreateFontPrimitive(key, { type: 'cjk', family: cjkFamily, style: style });
}
else {
var standardFamily = fontFamily;
key = "standard_" + standardFamily + "_" + style;
primitive = this._getOrCreateFontPrimitive(key, { type: 'standard', family: standardFamily, style: style });
}
return this._createFontFromPrimitive(primitive, size, style);
};
/**
* Creates or retrieves a font primitive for the specified key and font data.
*
* @private
* @param {string} key Unique key used to cache the font primitive.
* @param {_FontData} fontData Font descriptor and/or data used to build a font primitive.
* @returns {_PdfFontPrimitive} The created or cached font primitive.
*/
PdfDocument.prototype._getOrCreateFontPrimitive = function (key, fontData) {
if (typeof key === 'string' && this._fontCollection.has(key)) {
return this._fontCollection.get(key);
}
var dictionary = new _PdfDictionary();
var primitive;
switch (fontData.type) {
case 'standard': {
var metrics = _PdfStandardFontMetricsFactory._getMetrics(fontData.family, fontData.style);
dictionary._updated = true;
dictionary.set('Type', _PdfName.get('Font'));
dictionary.set('Subtype', _PdfName.get('Type1'));
dictionary.set('BaseFont', new _PdfName(metrics._postScriptName));
if (fontData.family !== PdfFontFamily.symbol && fontData.family !== PdfFontFamily.zapfDingbats) {
dictionary.set('Encoding', new _PdfName('WinAnsiEncoding'));
}
primitive = { dictionary: dictionary, metrices: metrics };
break;
}
case 'cjk': {
var metrics = _PdfCjkStandardFontMetricsFactory._getMetrics(fontData.family, fontData.style);
dictionary._updated = true;
dictionary.set('Type', _PdfName.get('Font'));
dictionary.set('Subtype', _PdfName.get('Type0'));
dictionary.set('BaseFont', new _PdfName(metrics._postScriptName));
dictionary.set('Encoding', _getCjkEncoding(fontData.family));
dictionary.set('DescendantFonts', _getCjkDescendantFont(fontData.family, fontData.style, metrics));
primitive = { dictionary: dictionary, metrices: metrics };
break;
}
case 'ttf': {
var fontInternal = new _UnicodeTrueTypeFont(fontData.data);
fontInternal._createInternals();
dictionary = fontInternal._getInternals();
fontInternal._metrics._isUnicodeFont = true;
primitive = { dictionary: dictionary, metrices: fontInternal._metrics, fontInternal: fontInternal };
break;
}
default:
throw new Error('Unsupported font type.');
}
this._fontCollection.set(key, primitive);
return primitive;
};
/**
* Creates a concrete `PdfFont` from a font primitive and style/size.
*
* @private
* @param {_PdfFontPrimitive} primitive The source font primitive.
* @param {number} size The font size.
* @param {PdfFontStyle} style The font style.
* @returns {PdfFont} The created font wrapper object.
*/
PdfDocument.prototype._createFontFromPrimitive = function (primitive, size, style) {
var subtype = primitive.dictionary.get('Subtype').name;
var baseFontName = primitive.dictionary.get('BaseFont').name;
var font;
switch (subtype) {
case 'Type1':
font = new PdfStandardFont(_resolveStandardFontFamily(baseFontName), size, style, primitive);
break;
case 'Type0':
font = new PdfCjkStandardFont(_resolveCjkFontFamily(baseFontName), size, style, primitive);
break;
default:
throw new Error("Unsupported font subtype: " + subtype);
}
font.style = style;
font._document = this;
return font;
};
/**
* Computes a stable hash for font data (MD5 hex).
*
* @private
* @param {Uint8Array} fontData Raw font bytes.
* @returns {string} Hex-encoded MD5 hash of the font bytes.
*/
PdfDocument.prototype._computeFontHash = function (fontData) {
var md5 = new _MD5();
var hashBytes = md5.hash(fontData, 0, fontData.length);
return _bytesToHex(hashBytes);
};
/**
* Gets the `PdfPage` at the specified index.
*
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Access first page
* let page: PdfPage = document.getPage(0);
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*
* @param {number} pageIndex Page index.
* @returns {PdfPage} PDF page at the specified index.
*/
PdfDocument.prototype.getPage = function (pageIndex) {
if (pageIndex < 0 || pageIndex >= this.pageCount) {
throw new Error('Invalid page index');
}
var cachedPage = this._pages.get(pageIndex);
if (cachedPage) {
return cachedPage;
}
var _a = this, _catalog = _a._catalog, _linearization = _a._linearization;
var promise;
if (_linearization && _linearization.isValid && _linearization.pageFirst === pageIndex) {
promise = this._getLinearizationPage(pageIndex);
}
else {
promise = _catalog._getPageDictionary(pageIndex);
}
var page = new PdfPage(this._crossReference, pageIndex, promise.dictionary, promise.reference);
this._pages.set(pageIndex, page);
return page;
};
PdfDocument.prototype.addPage = function (arg1, arg2) {
var settings;
var pageIndex;
if (typeof arg2 !== 'undefined') {
settings = arg2;
pageIndex = arg1;
this._checkPageNumber(pageIndex);
}
else if (typeof arg1 === 'undefined') {
settings = new PdfPageSettings();
pageIndex = this.pageCount;
}
else if (arg1 instanceof PdfPageSettings) {
settings = arg1;
pageIndex = this.pageCount;
}
else {
settings = new PdfPageSettings();
pageIndex = arg1;
this._checkPageNumber(pageIndex);
}
var sectionDictionary = new _PdfDictionary(this._crossReference);
sectionDictionary.update('Type', _PdfName.get('Pages'));
sectionDictionary.update('Count', 1);
_updatePageSettings(sectionDictionary, settings);
var sectionReference = this._crossReference._getNextReference();
this._crossReference._cacheMap.set(sectionReference, sectionDictionary);
sectionDictionary.objId = sectionReference.toString();
var pageDictionary = new _PdfDictionary(this._crossReference);
pageDictionary.update('Type', _PdfName.get('Page'));
var pageReference = this._crossReference._getNextReference();
this._crossReference._cacheMap.set(pageReference, pageDictionary);
pageDictionary.objId = pageReference.toString();
pageDictionary.update('Parent', sectionReference);
sectionDictionary.update('Kids', [pageReference]);
if (this.pageCount === 0) {
var parentReference = this._catalog._catalogDictionary._get('Pages');
if (parentReference && this._catalog._topPagesDictionary) {
var isUpdated = false;
if (this._catalog._topPagesDictionary.has('Kids')) {
var kids = this._catalog._topPagesDictionary.get('Kids');
if (kids) {
kids.push(sectionReference);
this._catalog._topPagesDictionary.update('Kids', kids);
isUpdated = true;
}
}
if (!isUpdated) {
this._catalog._topPagesDictionary.update('Kids', [sectionReference]);
}
this._catalog._topPagesDictionary.update('Count', 1);
sectionDictionary.update('Parent', parentReference);
}
else {
this._catalog._catalogDictionary.update('Pages', sectionReference);
}
this._pages = new Map();
this._pageCount = 1;
}
else {
var lastPage_1 = this.getPage(pageIndex === this.pageCount ? (pageIndex - 1) : pageIndex);
if (lastPage_1 && lastPage_1._pageDictionary) {
var parentReference = lastPage_1._pageDictionary._get('Parent');
var parentDictionary = this._crossReference._fetch(parentReference);
if (parentDictionary && parentDictionary.has('Kids')) {
var kids = parentDictionary.get('Kids');
if (kids) {
if (pageIndex === this.pageCount) {
kids.push(sectionReference);
}
else {
var newKids_1 = [];
kids.forEach(function (entry) {
if (entry === lastPage_1._ref) {
newKids_1.push(sectionReference);
}
newKids_1.push(entry);
});
kids = newKids_1;
this._updatePageCache(pageIndex);
}
parentDictionary.update('Kids', kids);
sectionDictionary.update('Parent', parentReference);
_updatePageCount(parentDictionary, 1);
this._pageCount = this.pageCount + 1;
}
}
}
}
var result = new PdfPage(this._crossReference, pageIndex, pageDictionary, pageReference);
result._pageSettings = settings;
result._isNew = true;
this._pages.set(pageIndex, result);
return result;
};
PdfDocument.prototype.addSection = function (settings) {
var result;
if (!this._isLoaded) {
var pageSettings = settings ? settings : new PdfPageSettings();
result = new PdfSection(this, pageSettings);
this._sections.push(result);
}
return result;
};
PdfDocument.prototype.removePage = function (argument) {
var targetPage = (argument instanceof PdfPage) ? argument : this.getPage(argument);
this._removePage(targetPage);
};
/**
* Gets the document information of the PDF.
*
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Gets the document information of the PDF
* let documentProperties: PdfDocumentInformation = document.getDocumentInformation();
* // Gets the title of the PDF document
* let title = documentProperties.title;
* // Gets the author of the PDF document
* let author = documentProperties.author;
* // Gets the subject of the PDF document
* let subject = documentProperties.subject;
* // Gets the keywords of the PDF document
* let keywords = documentProperties.keywords;
* // Gets the creator of the PDF document
* let creator = documentProperties.creator;
* // Gets the producer of the PDF document
* let producer = documentProperties.producer;
* // Gets the language of the PDF document
* let language = documentProperties.language;
* // Gets the creation date of the PDF document
* let creationDate = documentProperties.creationDate;
* // Gets the modification date of the PDF document
* let modificationDate = documentProperties.modificationDate;
* document.destroy();
* ```
*
* @param {boolean} skipMetadata flag value to skip the metadata.
* @returns {PdfDocumentInformation} Document information.
*/
PdfDocument.prototype.getDocumentInformation = function (skipMetadata) {
if (skipMetadata === void 0) { skipMetadata = true; }
var infoDict = this._getInfoDictionary(false);
var catalogDictionary = this._catalog._catalogDictionary;
var result = {};
if (!infoDict) {
if (!skipMetadata) {
result.xmpMetadata = this._getMetadataValue();
}
result.customMetadata = new PdfCustomMetadata();
return result;
}
result.title = this._readInfoString(infoDict, 'Title');
result.author = this._readInfoString(infoDict, 'Author');
result.subject = this._readInfoString(infoDict, 'Subject');
result.keywords = this._readInfoString(infoDict, 'Keywords');
result.creator = this._readInfoString(infoDict, 'Creator');
result.producer = this._readInfoString(infoDict, 'Producer');
result.language = this._readInfoString(catalogDictionary, 'Lang');
var creation = this._readInfoString(infoDict, 'CreationDate');
if (typeof creation === 'string') {
result.creationDate = _convertStringToDate(creation);
}
var mod = this._readInfoString(infoDict, 'ModDate');
if (typeof mod === 'string') {
result.modificationDate = _convertStringToDate(mod);
}
if (!skipMetadata) {
result.xmpMetadata = this._getMetadataValue();
}
var standardKeys = new Set([
'Title', 'Author', 'Subject', 'Keywords',
'Creator', 'Producer', 'CreationDate', 'ModDate', 'Trapped'
]);
var custom = new PdfCustomMetadata();
for (var _i = 0, _a = Object.keys(infoDict._map); _i < _a.length; _i++) {
var key = _a[_i];
if (!standardKeys.has(key)) {
var value = infoDict.get(key); // eslint-disable-line
if (typeof value === 'string') {
custom.set(key, value);
}
}
}
result.customMetadata = custom;
return result;
};
PdfDocument.prototype._readInfoString = function (dict, key) {
if (dict && !dict.has(key)) {
return undefined;
}
var value = dict.get(key); // eslint-disable-line
return typeof value === 'string' ? value : undefined;
};
/**
* Sets the document information of the PDF.
*
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Sets the document information of the PDF
* document.setDocumentInformation({
* author: 'Syncfusion',
* modificationDate: Date.now(),
* creator: 'Essential PDF',
* keywords: 'PDF',
* subject: 'Document information DEMO',
* title: 'Essential PDF Sample',
* producer: 'Syncfusion PDF'
* });
* // Save the document
* document.save('output.pdf);
* // Destroy the document
* document.destroy();
* ```
*
* @param {PdfDocumentInformation} information Fields to set.
* @returns {void} Returns nothing.
*/
PdfDocument.prototype.setDocumentInformation = function (information) {
var _this = this;
var infoDict = this._getInfoDictionary(true);
var catalogDictionary = this._catalog._catalogDictionary;
this._writeInfoString(infoDict, 'Title', information.title);
this._writeInfoString(infoDict, 'Author', information.author);
this._writeInfoString(infoDict, 'Subject', information.subject);
this._writeInfoString(infoDict, 'Keywords', information.keywords);
this._writeInfoString(infoDict, 'Creator', information.creator);
this._writeInfoString(infoDict, 'Producer', information.producer);
this._writeInfoString(catalogDictionary, 'Lang', information.language);
this._writeInfoDate(infoDict, 'CreationDate', information.creationDate);
this._writeInfoDate(infoDict, 'ModDate', information.modificationDate);
if (information.customMetadata) {
var map = information.customMetadata._customData;
var schemaMap_1;
if (this._xmpMetadata) {
schemaMap_1 = this._xmpMetadata.customSchema.customData;
}
map.forEach(function (value, key) {
if (typeof key === 'string' && typeof value === 'string') {
_this._writeInfoString(infoDict, key, value);
}
if (_this._xmpMetadata) {
if (!schemaMap_1.has(key)) {
schemaMap_1.set(key, value);
}
}
});
if (this._xmpMetadata) {
this._xmpMetadata.customSchema.customData = schemaMap_1;
}
}
infoDict._updated = true;
};
/**
* Writes a string value into the document information dictionary.
*
* @private
* @param {_PdfDictionary} dict Target dictionary.
* @param {string} key Info key to update.
* @param {string} [value] String value to write if defined.
* @returns {void} nothing.
*/
PdfDocument.prototype._writeInfoString = function (dict, key, value) {
if (value !== null && typeof value === 'string') {
dict.update(key, value);
}
};
/**
* Writes a date value into the document information dictionary.
*
* @private
* @param {_PdfDictionary} dict Target dictionary.
* @param {string} key Info key to update.
* @param {Date} [value] Date value to write if provided.
* @returns {void} nothing.
*/
PdfDocument.prototype._writeInfoDate = function (dict, key, value) {
if (value && value instanceof Date) {
dict.update(key, _convertDateToString(value));
}
};
PdfDocument.prototype._getInfoDictionary = function (createIfMissing) {
var trailer;
if (this._crossReference && this._crossReference._trailer) {
trailer = this._crossReference._trailer;
}
if (!trailer) {
return undefined;
}
if (trailer.has('Info')) {
var raw = trailer.get('Info'); // eslint-disable-line
if (raw instanceof _PdfReference) {
var dict = this._crossReference._fetch(raw);
return dict;
}
else if (raw instanceof _PdfDictionary) {
return raw;
}
}
if (!createIfMissing) {
return undefined;
}
var info = new _PdfDictionary(this._crossReference);
var infoRef = this._crossReference._getNextReference();
this._crossReference._cacheMap.set(infoRef, info);
info.objId = infoRef.toString();
trailer.update('Info', infoRef);
return info;
};
/**
* Validates a page index against the current page count.
*
* @private
* @param {number} index Zero-based page index to validate.
* @returns {void} nothing.
*/
PdfDocument.prototype._checkPageNumber = function (index) {
if (index < 0 || index > this.pageCount) {
throw new Error('Index out of range');
}
};
/**
* Rebuilds the pages cache after insertion or removal and updates page indices.
*
* @private
* @param {number} index The index at which pages were inserted or removed.
* @param {boolean} [isIncrement=true] Set to `true` when inserting; set to `false` when removing.
* @returns {void} nothing.
*/
PdfDocument.prototype._updatePageCache = function (index, isIncrement) {
if (isIncrement === void 0) { isIncrement = true; }
var updatedData = new Map();
for (var i = this.pageCount - 1; i >= 0; i--) {
var page = this.getPage(i);
if (isIncrement) {
if (i >= index) {
updatedData.set(i + 1, page);
page._pageIndex = i + 1;
}
else {
updatedData.set(i, page);
}
}
else {
if (i > index) {
updatedData.set(i - 1, page);
page._pageIndex = i - 1;
}
else if (i !== index) {
updatedData.set(i, page);
}
}
}
this._pages = updatedData;
if (!isIncrement) {
this._pageCount = this._pages.size;
}
};
/**
* Removes the specified page and updates bookmarks, templates, form fields, and page tree.
*
* @private
* @param {PdfPage} pageToRemove The page to remove from the document.
* @returns {void} nothing.
*/
PdfDocument.prototype._removePage = function (pageToRemove) {
var bookMarkMap = this._parseBookmarkDestination();
if (bookMarkMap && bookMarkMap.has(pageToRemove)) {
var bookmarks = bookMarkMap.get(pageToRemove);
if (bookmarks) {
bookmarks.forEach(function (bookmark) {
if (bookmark && bookmark._dictionary) {
if (bookmark._dictionary) {
if (bookmark._dictionary.has('A')) {
bookmark._dictionary.update('A', null);
}
bookmark._dictionary.update('Dest', null);
}
}
});
}
}
this._removePageTemplates(pageToRemove);
for (var i = this.form.count - 1; i >= 0; --i) {
var field = this.form.fieldAt(i);
if (field && field.page === pageToRemove) {
this.form.removeFieldAt(i);
}
}
this._updatePageCache(pageToRemove._pageIndex, false);
this._removeParent(pageToRemove._ref, pageToRemove._pageDictionary);
if (this._crossReference._cacheMap.has(pageToRemove._ref)) {
pageToRemove._pageDictionary._updated = false;
}
if (this.pageCount === 0) {
this._catalog._topPagesDictionary.update('Kids', []);
}
};
/**
* Removes a page reference from its parents Kids array and updates page counts accordingly.
*
* @private
* @param {_PdfReference} referenceToRemove The page indirect reference to remove.
* @param {_PdfDictionary} dictionary The page dictionary whose parent will be updated.
* @returns {void} nothing.
*/
PdfDocument.prototype._removeParent = function (referenceToRemove, dictionary) {
if (dictionary.has('Parent')) {
var parentReference = dictionary._get('Parent');
var parentDictionary = this._crossReference._fetch(parentReference);
if (parentDictionary && parentDictionary.has('Kids')) {
var kids = parentDictionary.get('Kids');
if (_isNullOrUndefined(kids) && kids.length === 1 && parentDictionary && parentDictionary.get('Type').name === 'Pages') {
this._removeParent(parentReference, parentDictionary);
}
else {
kids = kids.filter(function (item) { return item !== referenceToRemove; });
parentDictionary.update('Kids', kids);
_updatePageCount(parentDictionary, -1);
}
}
}
};
/**
* Builds and returns a map of pages to the bookmarks that reference them.
*
* @private
* @returns {Map<PdfPage, PdfBookmarkBase[]>} A map of pages to associated bookmark nodes.
*/
PdfDocument.prototype._parseBookmarkDestination = function () {
var current = this.bookmarks;
if (typeof this._bookmarkHashTable === 'undefined' && current) {
this._bookmarkHashTable = new Map();
var stack = [];
var nodeInformation = { index: 0, kids: current._bookMarkList };
do {
for (; nodeInformation.index < nodeInformation.kids.length;) {
current = nodeInformation.kids[nodeInformation.index];
var namedDestination = current.namedDestination;
if (namedDestination) {
if (namedDestination.destination) {
var page = namedDestination.destination.page;
var list = this._bookmarkHashTable.get(page);
if (!list) {
list = [];
}
list.push(current);
this._bookmarkHashTable.set(page, list);
}
}
else {
var destination = current.destination;
if (destination) {
var page = destination.page;
var list = this._bookmarkHashTable.get(page);
if (!list) {
list = [];
}
list.push(current);
this._bookmarkHashTable.set(page, list);
}
}
nodeInformation.index += 1;
if (current.count > 0) {
stack.push(nodeInformation);
nodeInformation = { index: 0, kids: current._bookMarkList };
continue;
}
}
if (stack.length > 0) {
nodeInformation = stack.pop();
while (nodeInformation.index === nodeInformation.kids.length && stack.length > 0) {
nodeInformation = stack.pop();
}
}
} while (nodeInformation.index < nodeInformation.kids.length);
}
return this._bookmarkHashTable;
};
/**
* Removes template/name entries associated with the specified page from the names dictionary.
*
* @private
* @param {PdfPage} page The page whose template/name entries should be removed.
* @returns {void} nothing.
*/
PdfDocument.prototype._removePageTemplates = function (page) {
var dictionary;
if (this._catalog._catalogDictionary.has('Names')) {
dictionary = this._catalog._catalogDictionary.get('Names');
if (dictionary) {
this._removeInternalTemplates(dictionary, 'Pages', page);
this._removeInternalTemplates(dictionary, 'Templates', page);
}
}
};
/**
* Removes entries from a particular names tree (by key) that reference the specified page.
*
* @private
* @param {_PdfDictionary} dictionary The root names dictionary.
* @param {string} key The names tree key to update (for example, 'Pages' or 'Templates').
* @param {PdfPage} page The page used to filter out entries.
* @returns {void} nothing.
*/
PdfDocument.prototype._removeInternalTemplates = function (dictionary, key, page) {
if (dictionary.has(key)) {
var namedObject = dictionary.get(key);
if (namedObject && namedObject.has('Names')) {
var nameCollection = namedObject.getArray('Names');
if (nameCollection && nameCollection.length > 0) {
var namedPageCollection = this._getUpdatedPageTemplates(nameCollection, page);
var namedPageDictionary = new _PdfDictionary(this._crossReference);
namedPageDictionary.update('Names', namedPageCollection);
var reference = this._crossReference._getNextReference();
this._crossReference._cacheMap.set(reference, namedPageDictionary);
namedPageDictionary.objId = reference.toString();
dictionary.update(key, reference);
}
}
}
};
/**
* Returns a filtered Names array with entries for the specified page removed.
*
* @private
* @param {_PdfDictionary[]} namedPages The original Names array entries.
* @param {PdfPage} page The page whose entries should be removed.
* @returns {_PdfDictionary[]} The updated Names array without the specified page entries.
*/
PdfDocument.prototype._getUpdatedPageTemplates = function (namedPages, page) {
if (namedPages.length > 0) {
for (var i = 1; i <= namedPages.length; i = i + 2) {
var pageDictionary = namedPages[i];
if (pageDictionary && page._pageDictionary === pageDictionary) {
namedPages.pop();
namedPages.pop();
return namedPages;
}
}
}
return namedPages;
};
/**
* Reorders the pages in the PDF document.
*
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Reorders the pages in the PDF document
* document.reorderPages([3, 2, 1]);
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*
* @param {number[]} orderArray The page sequence to arrange the pages.
* @returns {void} Nothing.
*/
PdfDocument.prototype.reorderPages = function (orderArray) {
var _this = this;
orderArray.forEach(function (pageNumber) {
_this._checkPageNumber(pageNumber);
});
var sortedArray = this._sortedArray(orderArray);
var ascendingOrder = orderArray.slice().sort(function (a, b) { return a - b; });
var inputArray = Array.from({ length: this.pageCount }, function (_, i) { return i; });
var pagesToRemove = inputArray.filter(function (element) { return sortedArray.indexOf(element) === -1; });
for (var i = pagesToRemove.length - 1; i >= 0; i--) {
this.removePage(pagesToRemove[i]);
}
var newkids = [];
var newPages = new Map();
var parentReference = this._catalog._catalogDictionary._get('Pages');
sortedArray.forEach(function (sortedItem, i) {
var indexPage = _this.getPage(ascendingOrder.indexOf(sortedItem));
indexPage._pageIndex = i;
newPages.set(i, indexPage);
var sectionDictionary = new _PdfDictionary(_this._crossReference);
sectionDictionary.update('Type', _PdfName.get('Pages'));
sectionDictionary.update('Count', 1);
sectionDictionary.update('Parent', parentReference);
var sectionReference = _this._crossReference._getNextReference();
sectionDictionary.objId = sectionReference.toString();
sectionDictionary.update('Kids', [indexPage._ref]);
newkids.push(sectionReference);
var parentDictionary = indexPage._pageDictionary.get('Parent');
while (parentDictionary && parentDictionary.get('Type').name === 'Pages') {
parentDictionary.forEach(function (key, value) {
switch (key) {
case 'Parent':
case 'Kids':
case 'Type':
case 'Count':
break;
case 'Resources':
_this._cloneResources(parentDictionary.get('Resources'), sectionDictionary);
break;
default:
if (!sectionDictionary.has(key)) {
sectionDictionary.update(key, value);
}
break;
}
});
if (parentDictionary.has('Parent')) {
parentDictionary = parentDictionary.get('Parent');
}
else {
break;
}
}
_this._crossReference._cacheMap.set(sectionReference, sectionDictionary);
var pageSection = _this._crossReference._fetch(indexPage._ref);
pageSection.update('Parent', sectionReference);
});
this._pages = newPages;
if (this._catalog) {
var parentDictionary = this._catalog._topPagesDictionary;
if (parentDictionary && parentDictionary.has('Kids')) {
var kids = parentDictionary.get('Kids');
kids = newkids;
parentDictionary.update('Kids', kids);
}
}
};
/**
* Returns a distinct array preserving the first occurrence order.
*
* @private
* @param {number[]} order Array of page indexes to deduplicate.
* @returns {number[]} The deduplicated array in original order.
*/
PdfDocument.prototype._sortedArray = function (order) {
var sortedArray = [];
order.forEach(function (num) {
if (sortedArray.indexOf(num) === -1) {
sortedArray.push(num);
}
});
return sortedArray;
};
/**
* Clones resource dictionaries from source to target, merging entries where appropriate.
*
* @private
* @param {_PdfDictionary} source Source resource dictionary.
* @param {_PdfDictionary} target Target page/section dictionary to receive merged resources.
* @returns {void} nothing.
*/
PdfDocument.prototype._cloneResources = function (source, target) {
var _this = this;
if (!target.has('Resources')) {
target.update('Resources', source);
}
else {
var resourceDictionary_1 = target.get('Resources');
source.forEach(function (key, value) {
if (resourceDictionary_1.has(key)) {
_this._cloneInnerResources(key, value, resourceDictionary_1);
}
else {
resourceDictionary_1.update(key, value);
}
});
}
};
/**
* Merges nested resource entries (dictionaries or arrays) into a target resource dictionary.
*
* @private
* @param {string} key Resource key to merge.
* @param {any} value Incoming resource value (dictionary or array).
* @param {_PdfDictionary} resourceDictionary Target resource dictionary to update.
* @returns {void} nothing.
*/
PdfDocument.prototype._cloneInnerResources = function (key, value, resourceDictionary) {
if (value instanceof _PdfDictionary) {
var oldObject_1 = resourceDictionary.get(key);
if (oldObject_1) {
var hasNew_1 = false;
oldObject_1.forEach(function (innerKey, innerValue) {
if (!oldObject_1.has(innerKey)) {
oldObject_1.update(innerKey, innerValue);
hasNew_1 = true;
}
});
if (hasNew_1) {
resourceDictionary._updated = true;
}
}
else {
resourceDictionary.update(key, value);
}
}
else if (Array.isArray(value)) {
var oldArray_1 = resourceDictionary.get(key); // eslint-disable-line
if (oldArray_1) {
var hasNew_2 = false;
value.forEach(function (entry) {
if (oldArray_1.indexOf(entry) === -1) {
oldArray_1.push(entry);
hasNew_2 = true;
}
});
if (hasNew_2) {
resourceDictionary._updated = true;
}
}
else {
resourceDictionary.update(key, value);
}
}
};
PdfDocument.prototype.save = function (filename) {
if (!this._isLoaded && this.pageCount === 0) {
this.addSection().addPage();
}
this._doPostProcess(this._flatten);
if (!validateLicense('pdf')) {
this._addWatermarkText();
}
if (typeof filename === 'string') {
Save.save(filename, new Blob([this._crossReference._save()], { type: 'application/pdf' }));
}
else {
return this._crossReference._save();
}
};
PdfDocument.prototype.saveAsync = function (filename) {
return __awaiter(this, void 0, void 0, function () {
var pdfBytes;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!this._isLoaded && this.pageCount === 0) {
this.addSection().addPage();
}
return [4 /*yield*/, Promise.resolve(this._doPostProcess(this._flatten))];
case 1:
_a.sent();
if (!(typeof filename === 'string')) return [3 /*break*/, 4];
return [4 /*yield*/, this._crossReference._saveAsync()];
case 2:
pdfBytes = _a.sent();
return [4 /*yield*/, Promise.resolve(Save.save(filename, new Blob([pdfBytes], { type: 'application/pdf' })))];
case 3:
_a.sent();
return [3 /*break*/, 6];
case 4: return [4 /*yield*/, this._crossReference._saveAsync()];
case 5: return [2 /*return*/, _a.sent()];
case 6: return [2 /*return*/];
}
});
});
};
/**
* Saves the document to the specified output stream and return the stream as Blob.
*
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data);
* // Save the document
* let data: Promise<{ blobData: Blob }> = document.saveAsBlob();
* // Destroy the document
* document.destroy();
* ```
*
* @returns {Promise<{ blobData: Blob }>} Saved PDF data as `Blob`.
*/
PdfDocument.prototype.saveAsBlob = function () {
var _this = this;
return new Promise(function (resolve) {
var obj = { blobData: new Blob([_this._crossReference._save()], { type: 'application/pdf' }) };
resolve(obj);
});
};
PdfDocument.prototype.exportAnnotations = function (arg1, arg2) {
initializeTelemetryFeature('Annotation', 'PDFLibrary');
this._isExport = true;
this._doPostProcessOnAnnotations();
var helper;
var settings;
if (arg1 && arg1 instanceof PdfAnnotationExportSettings) {
settings = arg1;
}
else if (arg2 && arg2 instanceof PdfAnnotationExportSettings) {
settings = arg2;
}
if (settings) {
if (settings.dataFormat === DataFormat.xfdf) {
helper = new _XfdfDocument();
}
else if (settings.dataFormat === DataFormat.json) {
helper = new _JsonDocument();
}
else if (settings.dataFormat === DataFormat.fdf) {
helper = new _FdfDocument();
}
else {
return undefined;
}
helper.exportAppearance = settings.exportAppearance;
}
else {
helper = new _XfdfDocument();
}
var result = helper._exportAnnotations(this);
if (arg1 && typeof arg1 === 'string') {
Save.save(arg1, new Blob([result], { type: 'text/plain' }));
}
else {
return result;
}
};
PdfDocument.prototype.exportFormData = function (arg1, arg2) {
initializeTelemetryFeature('AcroForm', 'PDFLibrary');
this._doPostProcessOnFormFields();
var helper;
var settings;
if (arg1 && arg1 instanceof PdfFormFieldExportSettings) {
settings = arg1;
}
else if (arg2 && arg2 instanceof PdfFormFieldExportSettings) {
settings = arg2;
}
if (settings) {
if (settings.dataFormat === DataFormat.xfdf) {
helper = new _XfdfDocument(settings.exportName);
}
else if (settings.dataFormat === DataFormat.json) {
helper = new _JsonDocument(settings.exportName);
}
else if (settings.dataFormat === DataFormat.fdf) {
helper = new _FdfDocument(settings.exportName);
}
else if (settings.dataFormat === DataFormat.xml) {
helper = new _XmlDocument(settings.exportName);
}
else {
return undefined;
}
helper._asPerSpecification = settings.asPerSpecification;
}
else {
helper = new _XfdfDocument();
helper._asPerSpecification = false;
}
if (arg1 && typeof arg1 === 'string') {
Save.save(arg1, new Blob([helper._exportFormFields(this)], { type: 'text/plain' }));
}
else {
return helper._exportFormFields(this);
}
};
PdfDocument.prototype.importAnnotations = function (data, dataFormat) {
initializeTelemetryFeature('Annotation', 'PDFLibrary');
if (dataFormat === DataFormat.xfdf) {
var xfdf = new _XfdfDocument();
xfdf._importAnnotations(this, (typeof data === 'string') ? _decode(data) : data);
}
else if (dataFormat === DataFormat.json) {
var json = new _JsonDocument();
json._importAnnotations(this, (typeof data === 'string') ? _decode(data) : data);
}
else if (dataFormat === DataFormat.fdf) {
var fdf = new _FdfDocument();
fdf._importAnnotations(this, (typeof data === 'string') ? _decode(data) : data);
}
};
PdfDocument.prototype.importFormData = function (data, dataFormat) {
initializeTelemetryFeature('AcroForm', 'PDFLibrary');
if (this._form && this._form._requiresPostProcessing) {
this._doPostProcessOnFormFields();
}
this._isFormImport = true;
if (this.form.count > 0) {
if (dataFormat === DataFormat.xfdf) {
var xfdf = new _XfdfDocument();
xfdf._importFormData(this, (typeof data === 'string') ? _decode(data) : data);
}
else if (dataFormat === DataFormat.json) {
var json = new _JsonDocument();
json._importFormData(this, (typeof data === 'string') ? _decode(data) : data);
}
else if (dataFormat === DataFormat.fdf) {
var fdf = new _FdfDocument();
fdf._importFormData(this, (typeof data === 'string') ? _decode(data) : data);
}
else if (dataFormat === DataFormat.xml) {
var xml = new _XmlDocument();
xml._importFormData(this, (typeof data === 'string') ? _decode(data) : data);
}
}
};
/**
* Disposes the current instance of `PdfDocument` class.
*
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data);
* // Destroy the document
* document.destroy();
* ```
*
* @returns {void} Nothing.
*/
PdfDocument.prototype.destroy = function () {
if (this._crossReference) {
this._crossReference._destroy();
this._crossReference = undefined;
}
if (this._xmpMetadata) {
this._xmpMetadata._destroy();
}
if (this._catalog) {
this._catalog._destroy();
this._catalog = undefined;
}
this._endObjSignature = undefined;
this._headerSignature = undefined;
if (this._pages && this._pages.size > 0) {
this._pages.forEach(function (value) {
value._destroy();
});
}
if (this._pages) {
this._pages.clear();
this._pages = undefined;
}
this._startXrefSignature = undefined;
this._stream = undefined;
if (this._form) {
this._form._fontCache = undefined;
this._form = undefined;
}
this._fontCollection.clear();
_clearPrimitiveCaches();
if (this._mergeHelperCache) {
if (this._mergeHelperCache.size > 0) {
this._mergeHelperCache.forEach(function (value) {
if (value) {
value._objectDispose();
}
});
}
this._mergeHelperCache.clear();
this._mergeHelperCache = undefined;
}
};
Object.defineProperty(PdfDocument.prototype, "_destinationCollection", {
/**
* Lazily retrieves the named destination collection from the document catalog.
*
* @private
* @returns {_PdfNamedDestinationCollection} The named destination collection.
*/
get: function () {
if (this._namedDestinationCollection === null || typeof this._namedDestinationCollection === 'undefined') {
if (this._catalog._catalogDictionary.has('Names')) {
var names = this._catalog._catalogDictionary.get('Names');
this._namedDestinationCollection = new _PdfNamedDestinationCollection(names, this._crossReference);
}
else {
this._namedDestinationCollection = new _PdfNamedDestinationCollection();
}
}
return this._namedDestinationCollection;
},
enumerable: true,
configurable: true
});
/**
* Retrieves the linearization page dictionary and reference for the given page index.
*
* @private
* @param {number} pageIndex - The zero-based index of the page to retrieve.
* @returns {{dictionary: _PdfDictionary, reference: _PdfReference}} returns reference .
*/
PdfDocument.prototype._getLinearizationPage = function (pageIndex) {
var _a = this, _catalog = _a._catalog, _linearization = _a._linearization, _crossReference = _a._crossReference;
var ref = _PdfReference.get(_linearization.objectNumberFirst, 0);
try {
var obj = _crossReference._fetch(ref); // eslint-disable-line
if (obj instanceof _PdfDictionary) {
var type = obj.get('Type');
if (_isName(type, 'Page') || (!obj.has('Type') && !obj.has('Kids'))) {
if (!_catalog.pageKidsCountCache.has(ref)) {
_catalog.pageKidsCountCache.put(ref, 1);
}
if (!_catalog.pageIndexCache.has(ref)) {
_catalog.pageIndexCache.put(ref, 0);
}
return { dictionary: obj, reference: ref };
}
}
throw new FormatError('The Linearization dictionary does not point to a valid Page dictionary.');
}
catch (reason) {
return _catalog._getPageDictionary(pageIndex);
}
};
/**
* Validates and reads the document header to determine the PDF version and update file structure.
*
* @private
* @returns {void} nothing.
*/
PdfDocument.prototype._checkHeader = function () {
var stream = this._stream;
stream.reset();
if (!this._find(stream, this._headerSignature)) {
return;
}
stream.moveStart();
var version = '';
var ch = stream.getByte();
while (ch > 0x20) {
if (version.length >= 12) {
break;
}
version += String.fromCharCode(ch);
ch = stream.getByte();
}
if (!this._version) {
this._version = version.substring(5);
// if (this._version === '%PDF-1.3' || this._version === '%PDF-1.0' || this._version === '%PDF-1.1'
// || this._version === '%PDF-1.2') {
// this.fileStructure.isIncrementalUpdate = false;
// }
}
};
/**
* Parses cross-reference sections and builds the catalog.
*
* @private
* @param {boolean} recoveryMode Set `true` to enable fallback parsing strategies.
* @returns {void} nothing.
*/
PdfDocument.prototype._parse = function (recoveryMode) {
this._crossReference._parse(recoveryMode);
this._catalog = new _PdfCatalog(this._crossReference);
if (this._catalog.version) {
this._version = this._catalog.version;
}
};
/**
* Searches the given stream for a signature within a byte limit.
*
* @private
* @param {_PdfStream} stream The stream to scan.
* @param {Uint8Array} signature The byte signature to locate.
* @param {number} [limit=1024] Max number of bytes to scan.
* @param {boolean} [backwards=false] If `true`, scans from the end backwards.
* @returns {boolean} `true` if the signature is found; otherwise, `false`.
*/
PdfDocument.prototype._find = function (stream, signature, limit, backwards) {
if (limit === void 0) { limit = 1024; }
if (backwards === void 0) { backwards = false; }
var signatureLength = signature.length;
var scanBytes = stream.peekBytes(limit);
var scanLength = scanBytes.length - signatureLength;
if (scanLength <= 0) {
return false;
}
if (backwards) {
var signatureEnd = signatureLength - 1;
var position = scanBytes.length - 1;
while (position >= signatureEnd) {
var j = 0;
while (j < signatureLength && scanBytes[position - j] === signature[signatureEnd - j]) {
j++;
}
if (j >= signatureLength) {
stream.position += position - signatureEnd;
return true;
}
position--;
}
}
else {
var position = 0;
while (position <= scanLength) {
var j = 0;
while (j < signatureLength && scanBytes[position + j] === signature[j]) { // eslint-disable-line
j++;
}
if (j >= signatureLength) {
stream.position += position;
return true;
}
position++;
}
}
return false;
};
/**
* Performs post-processing for forms and annotations, optionally flattening them.
*
* @private
* @param {boolean} [isFlatten=false] Set `true` to flatten annotations and form fields.
* @returns {void} nothing.
*/
PdfDocument.prototype._doPostProcess = function (isFlatten) {
if (isFlatten === void 0) { isFlatten = false; }
this._renderDocumentTemplates(PdfTemplateLayerMode.background);
this._renderDocumentTemplates(undefined);
this._doPostProcessOnFormFields(isFlatten);
this._doPostProcessOnAnnotations(isFlatten);
this._addXmpMetadata();
this._renderDocumentTemplates(PdfTemplateLayerMode.foreground);
};
/**
* Adds XMP metadata stream to the PDF document catalog.
*
* @private
* @returns {void} nothing.
*/
PdfDocument.prototype._addXmpMetadata = function () {
if (this._xmpMetadata && !this._xmpMetadata._isUpdated) {
this._xmpMetadata._serializeToStream();
var xmpStream = this._xmpMetadata._xmpStream;
if (xmpStream) {
if (!xmpStream.dictionary) {
var dict = new _PdfDictionary(this._crossReference);
dict._updated = true;
xmpStream.dictionary = dict;
}
xmpStream.dictionary.update('Type', _PdfName.get('Metadata'));
xmpStream.dictionary.update('Subtype', _PdfName.get('XML'));
xmpStream._isCompress = false;
var reference = this._crossReference._getNextReference();
this._crossReference._cacheMap.set(reference, xmpStream);
this._catalog._catalogDictionary.update('Metadata', reference);
this._crossReference._allowCatalog = true;
this._xmpMetadata._isUpdated = true;
}
}
};
/**
* Renders document templates (headers/footers) onto all pages for the specified layer mode.
*
* @private
* @param {PdfTemplateLayerMode} mode The template layer mode to render (background|foreground|undefined for default).
* @returns {void} Nothing.
*/
PdfDocument.prototype._renderDocumentTemplates = function (mode) {
var hasTemplate = typeof this._template !== 'undefined' && this._template !== null;
if (!hasTemplate && this._sections) {
for (var _i = 0, _a = this._sections; _i < _a.length; _i++) {
var section = _a[_i];
if (section.template) {
hasTemplate = true;
break;
}
}
}
if (!hasTemplate) {
return;
}
for (var i = 0; i < this.pageCount; i++) {
var page = this.getPage(i);
var pageNumber = i + 1;
var isOddPage = pageNumber % 2 === 1;
this._renderPageTemplates(page, isOddPage, mode);
}
};
/**
* Renders templates for a specific page based on odd/even precedence.
*
* @private
* @param {PdfPage} page The page to render templates on.
* @param {boolean} isOddPage Whether the page is odd-numbered.
* @param {PdfTemplateLayerMode | undefined} mode The template layer mode to render (background|foreground|undefined for default).
* @returns {void} Nothing.
*/
PdfDocument.prototype._renderPageTemplates = function (page, isOddPage, mode) {
this._templateRenderingStarted = true;
var sectionIndex = page._getSectionIndex();
var sides = [
_TemplateSide.top,
_TemplateSide.bottom,
_TemplateSide.left,
_TemplateSide.right
];
var pageGraphics;
for (var _i = 0, sides_1 = sides; _i < sides_1.length; _i++) {
var side = sides_1[_i];
var templateInserted = false;
var isLateGraphics = typeof page._g !== 'undefined' && page._g !== null && !page._needInitializeGraphics; // eslint-disable-line
var sectionTemplateInfo = (sectionIndex >= 0 && sectionIndex < this._sections.length)
? this._getSectionTemplateForSide(this._sections[sectionIndex], side, isOddPage)
: null;
var documentTemplateInfo = this._getTemplateForSide(side, isOddPage); // eslint-disable-line
var templatesToRender = []; // eslint-disable-line
if (documentTemplateInfo && documentTemplateInfo.template) {
templatesToRender.push(documentTemplateInfo);
}
if (sectionTemplateInfo && sectionTemplateInfo.template) {
templatesToRender.push(sectionTemplateInfo);
}
for (var _a = 0, templatesToRender_1 = templatesToRender; _a < templatesToRender_1.length; _a++) {
var templateInfo = templatesToRender_1[_a];
if (!templateInfo || !templateInfo.template) {
continue;
}
var templateMode = templateInfo.templateLayerMode;
var matchesMode = (typeof templateMode !== 'undefined' && templateMode === mode) ||
(typeof templateMode === 'undefined' && mode === undefined);
if (!matchesMode) {
continue;
}
var position = this._getTemplateAlignmentPosition(page, templateInfo.documentTemplate, templateInfo.alignment, side, isOddPage);
var direction = void 0;
if (typeof templateInfo.alignment === 'undefined') {
direction = this._templateSideToString(side);
}
var fixNeeded = isLateGraphics && page._accessedBeforeTemplate &&
!page._templatesRendered;
if (templateMode === PdfTemplateLayerMode.background) {
var bgLayer = this._backgroundLayers.get(page);
if (!bgLayer) {
bgLayer = this.layers.add('_background');
this.layers.move(0, bgLayer);
this._backgroundLayers.set(page, bgLayer);
}
var bgGraphics = bgLayer.createGraphics(page);
var state = bgGraphics.save();
bgGraphics.setTransparency(0.5);
templateInfo.template._draw(bgGraphics, position.x, position.y, position.width, position.height, direction);
bgGraphics.restore(state);
}
else if (templateMode === PdfTemplateLayerMode.foreground) {
if (!page._contents || page._contents.length === 0) {
page.graphics.save();
page.graphics.restore();
}
this._drawForegroundTemplate(page, templateInfo.template._template, position);
}
else {
if (fixNeeded && !templateInserted) {
page._templatesRendered = true;
templateInserted = true;
page._loadContents();
if (page._contents && page._contents.length > 0) {
var tempStream = new _PdfContentStream([]);
var g = new PdfGraphics(page.size, tempStream, this._crossReference, page);
g._initializeCoordinates();
var margins = page._pageSettings.margins;
var bounds = [margins.left, margins.top,
page.size.width - margins.left - margins.right,
page.size.height - margins.top - margins.bottom
];
g._clipTranslateMargins(bounds);
g.translateTransform({ x: position.x, y: 0 });
templateInfo.template._draw(g, 0, 0, position.width, position.height, direction);
tempStream._bytes = [32, 113, 32, 10].concat(tempStream._bytes, [32, 81, 32, 10]);
var ref = this._crossReference._getNextReference();
this._crossReference._cacheMap.set(ref, tempStream);
var insertIndex = page._contents.length - 1;
page._contents.splice(insertIndex, 0, ref);
page._pageDictionary.set('Contents', page._contents);
page._pageDictionary._updated = true;
}
}
else {
if (!pageGraphics) {
pageGraphics = page.graphics;
}
templateInfo.template._draw(pageGraphics, position.x, position.y, position.width, position.height, direction);
}
}
}
}
};
/**
* Gets the index of the section that contains the specified page reference.
*
* @param {_PdfReference} parentRef - The reference of the page's parent section.
* @returns {number} The zero-based index of the matching section, or -1 if not found.
* @private
*/
PdfDocument.prototype._getSectionIndexByPage = function (parentRef) {
if (!this._sections || this._sections.length === 0) {
return -1;
}
for (var i = 0; i < this._sections.length; i++) {
var section = this._sections[i];
if (section && section._reference === parentRef) {
return i;
}
}
return -1;
};
/**
* Renders a `PdfTemplate` into the page contents as a form XObject (foreground).
* This method creates a content stream that places and scales the template
* to the provided `bounds`, registers the template as an XObject resource,
* and appends the resulting content stream to the page contents.
*
* @private
* @param {PdfPage} page The target page to draw the template onto.
* @param {PdfTemplate} template The template to render as an XObject.
* @param {Rectangle} bounds The bounds on the page where the template should be drawn.
* @returns {void} Nothing.
*/
PdfDocument.prototype._drawForegroundTemplate = function (page, template, bounds) {
var stream = new _PdfContentStream([]);
var sw = new _PdfStreamWriter(stream);
sw._write('q');
var matrix = new _PdfTransformationMatrix();
matrix._translate(bounds.x, -(bounds.y + bounds.height));
matrix._scale(bounds.width / template._size.width, bounds.height / template._size.height);
sw._modifyCtm(matrix);
var pageResources = page._pageDictionary.get('Resources');
if (!pageResources) {
pageResources = new _PdfDictionary(this._crossReference);
page._pageDictionary.set('Resources', pageResources);
}
stream.dictionary.update('Resources', pageResources);
var xObject = pageResources.get('XObject');
if (!xObject) {
xObject = new _PdfDictionary(this._crossReference);
pageResources.set('XObject', xObject);
}
if (!template._key) {
template._key = _getNewGuidString();
}
var key = _PdfName.get(template._key);
var ref = this._crossReference._getNextReference();
this._crossReference._cacheMap.set(ref, template._content);
xObject.set(key.name, ref);
sw._executeObject(key);
sw._write('Q');
page._loadContents();
var cref = this._crossReference._getNextReference();
this._crossReference._cacheMap.set(cref, stream);
page._contents.push(cref);
};
/**
* Gets the appropriate template and alignment for the specified side based on odd or even page.
*
* @private
* @param {_TemplateSide} side The template side (top, bottom, left, or right).
* @param {boolean} isOddPage Whether the current page is odd-numbered.
* @param {number} sectionIndex The section index to resolve section-specific templates or -1 if not applicable.
* @returns {Object} The resolved template information, template layer mode and alignment, or null if none is found.
*/
PdfDocument.prototype._getTemplateForSide = function (side, isOddPage, sectionIndex) {
if (sectionIndex === void 0) { sectionIndex = -1; }
var templateKeyMap = new Map([
[_TemplateSide.top, {
odd: _PdfDocumentTemplateKey.oddTop,
even: _PdfDocumentTemplateKey.evenTop,
base: _PdfDocumentTemplateKey.top
}],
[_TemplateSide.bottom, {
odd: _PdfDocumentTemplateKey.oddBottom,
even: _PdfDocumentTemplateKey.evenBottom,
base: _PdfDocumentTemplateKey.bottom
}],
[_TemplateSide.left, {
odd: _PdfDocumentTemplateKey.oddLeft,
even: _PdfDocumentTemplateKey.evenLeft,
base: _PdfDocumentTemplateKey.left
}],
[_TemplateSide.right, {
odd: _PdfDocumentTemplateKey.oddRight,
even: _PdfDocumentTemplateKey.evenRight,
base: _PdfDocumentTemplateKey.right
}]
]);
var keys = templateKeyMap.get(side); // eslint-disable-line
if (!keys) {
return null;
}
if (sectionIndex >= 0 && sectionIndex < this._sections.length) {
var section = this._sections[sectionIndex];
var sectionTemplateInfo = this._getSectionTemplateForSide(section, side, isOddPage); // eslint-disable-line
if (sectionTemplateInfo) {
return sectionTemplateInfo;
}
}
var templateKeyToCheck = isOddPage ? keys.odd : keys.even; // eslint-disable-line
var templateObj = this._getTemplateByKey(templateKeyToCheck); // eslint-disable-line
if (templateObj && templateObj.template) {
return {
template: templateObj.template,
templateLayerMode: templateObj.templateLayerMode,
alignment: templateObj.alignment,
documentTemplate: this._template
};
}
var baseTemplateObj = this._getTemplateByKey(keys.base); // eslint-disable-line
if (baseTemplateObj && baseTemplateObj.template) {
return {
template: baseTemplateObj.template,
templateLayerMode: baseTemplateObj.templateLayerMode,
alignment: baseTemplateObj.alignment,
documentTemplate: this._template
};
}
return null;
};
/**
* Retrieves template object by template key.
*
* @private
* @param {_PdfDocumentTemplateKey} key The template key.
* @returns {any} The template object or undefined.
*/
PdfDocument.prototype._getTemplateByKey = function (key) {
if (!this._template) {
return;
}
switch (key) {
case _PdfDocumentTemplateKey.top:
return this._template.top;
case _PdfDocumentTemplateKey.bottom:
return this._template.bottom;
case _PdfDocumentTemplateKey.left:
return this._template.left;
case _PdfDocumentTemplateKey.right:
return this._template.right;
case _PdfDocumentTemplateKey.evenTop:
return this._template.evenTop;
case _PdfDocumentTemplateKey.evenBottom:
return this._template.evenBottom;
case _PdfDocumentTemplateKey.evenLeft:
return this._template.evenLeft;
case _PdfDocumentTemplateKey.evenRight:
return this._template.evenRight;
case _PdfDocumentTemplateKey.oddTop:
return this._template.oddTop;
case _PdfDocumentTemplateKey.oddBottom:
return this._template.oddBottom;
case _PdfDocumentTemplateKey.oddLeft:
return this._template.oddLeft;
case _PdfDocumentTemplateKey.oddRight:
return this._template.oddRight;
default:
return undefined;
}
};
/**
* Gets the appropriate template and alignment for a section.
*
* @param {PdfSection} section The section to get the template from.
* @param {_TemplateSide} side The template side.
* @param {boolean} isOddPage Whether the page is odd-numbered.
* @returns {Object} The resolved template info, or null if none is found.
* @private
*/
PdfDocument.prototype._getSectionTemplateForSide = function (section, side, isOddPage) {
var sectionTemplate = section.template; // eslint-disable-line
var templateKeyMap = new Map([
[_TemplateSide.top, 'top'],
[_TemplateSide.bottom, 'bottom'],
[_TemplateSide.left, 'left'],
[_TemplateSide.right, 'right']
]);
var baseKey = templateKeyMap.get(side);
if (!baseKey) {
return null;
}
var cap = baseKey.charAt(0).toUpperCase() + baseKey.slice(1);
var oddKey = 'odd' + cap;
var evenKey = 'even' + cap;
var templateInfo = undefined; // eslint-disable-line
if (isOddPage && sectionTemplate[oddKey]) {
templateInfo = sectionTemplate[oddKey];
}
else if (!isOddPage && sectionTemplate[evenKey]) {
templateInfo = sectionTemplate[evenKey];
}
if (!templateInfo && sectionTemplate[baseKey]) {
templateInfo = sectionTemplate[baseKey];
}
if (templateInfo && templateInfo.template) {
return { template: templateInfo.template,
alignment: templateInfo.alignment,
templateLayerMode: templateInfo.templateLayerMode,
documentTemplate: section.template
};
}
return null;
};
/**
* Gets the alignment position for a template on a page.
*
* @private
* @param {PdfPage} page The target page on which the template will be positioned.
* @param {PdfDocumentTemplate} documentTemplate The document template containing the template elements.
* @param {PdfTemplateHorizontalAlignment | PdfTemplateVerticalAlignment | undefined} alignment Specifies the alignment
* (horizontal or vertical) used to position the template within the page.
* @param {_TemplateSide} side Specifies the side of the page (such as top, bottom, left, or right)
* where the template should be placed.
* @param {boolean} isOddPage Indicates whether the current page is an odd-numbered page,
* which may affect template placement (e.g., for mirrored layouts).
* @returns {{ x: number, y: number, width: number, height: number }} An object representing
* the calculated position (x, y) and dimensions (width, height) of the template.
*/
PdfDocument.prototype._getTemplateAlignmentPosition = function (page, documentTemplate, alignment, side, isOddPage) {
var result;
var baseKey = this._templateSideToString(side);
var cap = baseKey.charAt(0).toUpperCase() + baseKey.slice(1);
var oddKey = ('odd' + cap);
var evenKey = ('even' + cap);
var base = baseKey;
var templateObj; // eslint-disable-line
if (isOddPage && documentTemplate[oddKey]) {
templateObj = documentTemplate[oddKey];
}
else if (!isOddPage && documentTemplate[evenKey]) {
templateObj = documentTemplate[evenKey];
}
else {
templateObj = documentTemplate[base];
}
if (!templateObj) {
return { x: 0, y: 0, width: 0, height: 0 };
}
var template = templateObj.template;
if (typeof alignment !== 'undefined' && alignment !== PdfTemplateVerticalAlignment.none &&
alignment !== PdfTemplateHorizontalAlignment.none) {
result = this._getAlignmentBounds(side, template, page, alignment);
}
else {
var direction = this._templateSideToString(side);
result = this._getTemplateDockBounds(page, template, direction);
}
return result;
};
/**
* Gets alignment bounds for a template.
*
* @private
* @param {_TemplateSide} side The template side.
* @param {PdfPageTemplateElement} template The template element.
* @param {PdfPage} page The page.
* @param {PdfTemplateHorizontalAlignment | PdfTemplateVerticalAlignment | undefined} alignment The alignment.
* @returns {Rectangle} The alignment bounds.
*/
PdfDocument.prototype._getAlignmentBounds = function (side, template, page, alignment) {
var alignStyle = this._mapTemplateAlignmentStyle(side, alignment);
return this._getTemplateAlignmentBounds(template, page, alignStyle, side);
};
/**
* Converts template side enum to string for legacy compatibility.
*
* @private
* @param {_TemplateSide} side The template side enum.
* @returns {string} The side as string ('top', 'bottom', 'left', 'right').
*/
PdfDocument.prototype._templateSideToString = function (side) {
switch (side) {
case _TemplateSide.top:
return 'top';
case _TemplateSide.bottom:
return 'bottom';
case _TemplateSide.left:
return 'left';
case _TemplateSide.right:
return 'right';
default:
return 'top';
}
};
/**
* Normalizes a document template key or template side into its corresponding
* base template side (Top, Bottom, Left, or Right).
*
* @private
* @param {_PdfDocumentTemplateKey | _TemplateSide} key
* The document template key or template side to normalize.
* @returns {_TemplateSide} The normalized base template side.
*/
PdfDocument.prototype._normalizeTemplateSide = function (key) {
if (key === _TemplateSide.top ||
key === _TemplateSide.bottom ||
key === _TemplateSide.left ||
key === _TemplateSide.right) {
return key;
}
switch (key) {
case _PdfDocumentTemplateKey.top:
case _PdfDocumentTemplateKey.evenTop:
case _PdfDocumentTemplateKey.oddTop:
return _TemplateSide.top;
case _PdfDocumentTemplateKey.bottom:
case _PdfDocumentTemplateKey.evenBottom:
case _PdfDocumentTemplateKey.oddBottom:
return _TemplateSide.bottom;
case _PdfDocumentTemplateKey.left:
case _PdfDocumentTemplateKey.evenLeft:
case _PdfDocumentTemplateKey.oddLeft:
return _TemplateSide.left;
case _PdfDocumentTemplateKey.right:
case _PdfDocumentTemplateKey.evenRight:
case _PdfDocumentTemplateKey.oddRight:
default:
return _TemplateSide.right;
}
};
/**
* Resolves the effective template alignment style based on the document template key
* (including odd/even variants) and the specified horizontal or vertical alignment.
*
* @private
* @param {_PdfDocumentTemplateKey | _TemplateSide} templateKey
* The document template key or normalized template side used to determine alignment context.
* @param {PdfTemplateHorizontalAlignment | PdfTemplateVerticalAlignment} alignment
* The alignment value applied to the template.
* @returns {_PdfAlignmentStyle} The resolved alignment style for positioning the template.
*/
PdfDocument.prototype._mapTemplateAlignmentStyle = function (templateKey, alignment) {
var side = this._normalizeTemplateSide(templateKey);
if (typeof alignment === 'undefined' ||
alignment === PdfTemplateHorizontalAlignment.none ||
alignment === PdfTemplateVerticalAlignment.none) {
switch (side) {
case _TemplateSide.top:
case _TemplateSide.left:
return _PdfAlignmentStyle.topLeft;
case _TemplateSide.bottom:
return _PdfAlignmentStyle.bottomLeft;
case _TemplateSide.right:
return _PdfAlignmentStyle.topRight;
}
}
if (side === _TemplateSide.top || side === _TemplateSide.bottom) {
var isTop = side === _TemplateSide.top;
switch (alignment) {
case PdfTemplateHorizontalAlignment.center:
return isTop
? _PdfAlignmentStyle.topCenter
: _PdfAlignmentStyle.bottomCenter;
case PdfTemplateHorizontalAlignment.right:
return isTop
? _PdfAlignmentStyle.topRight
: _PdfAlignmentStyle.bottomRight;
case PdfTemplateHorizontalAlignment.left:
default:
return isTop
? _PdfAlignmentStyle.topLeft
: _PdfAlignmentStyle.bottomLeft;
}
}
if (side === _TemplateSide.left || side === _TemplateSide.right) {
var isLeft = side === _TemplateSide.left;
switch (alignment) {
case PdfTemplateVerticalAlignment.middle:
return isLeft
? _PdfAlignmentStyle.middleLeft
: _PdfAlignmentStyle.middleRight;
case PdfTemplateVerticalAlignment.bottom:
return isLeft
? _PdfAlignmentStyle.bottomLeft
: _PdfAlignmentStyle.bottomRight;
case PdfTemplateVerticalAlignment.top:
default:
return isLeft
? _PdfAlignmentStyle.topLeft
: _PdfAlignmentStyle.topRight;
}
}
return _PdfAlignmentStyle.topLeft;
};
/**
* Gets the template alignment bounds based on alignment style.
*
* @private
* @param {PdfPageTemplateElement} template The template element.
* @param {PdfPage} page The page.
* @param {_PdfAlignmentStyle} alignmentStyle The alignment style enum.
* @param {_TemplateSide} [side] Optional template side for context-specific positioning.
* @returns {Rectangle} The alignment bounds.
*/
PdfDocument.prototype._getTemplateAlignmentBounds = function (template, page, alignmentStyle, side) {
var result = template._bounds;
var actualBounds;
if (page._isNew) {
actualBounds = page._getActualTemplateBounds(page._pageSettings);
}
if (actualBounds && actualBounds.length > 0) {
var x = template._bounds.x;
var y = template._bounds.y;
switch (alignmentStyle) {
case _PdfAlignmentStyle.topLeft:
x = -actualBounds[0];
y = (side === _TemplateSide.top) ? -actualBounds[1] : 0;
break;
case _PdfAlignmentStyle.topCenter:
x = (actualBounds[2] - template._bounds.width) / 2;
y = -actualBounds[1];
break;
case _PdfAlignmentStyle.topRight:
x = actualBounds[2] + this._getRightIndentWidth(page, false) - template._bounds.width;
y = (side === _TemplateSide.top) ? -actualBounds[1] : 0;
break;
case _PdfAlignmentStyle.middleLeft:
x = -actualBounds[0];
y = (actualBounds[3] - template._bounds.height) / 2;
break;
case _PdfAlignmentStyle.middleCenter:
x = (actualBounds[2] - template._bounds.width) / 2;
y = (actualBounds[3] - template._bounds.height) / 2;
break;
case _PdfAlignmentStyle.middleRight:
x = actualBounds[2] + this._getRightIndentWidth(page, false) - template._bounds.width;
y = (actualBounds[3] - template._bounds.height) / 2;
break;
case _PdfAlignmentStyle.bottomLeft:
x = -actualBounds[0];
y = (side === _TemplateSide.bottom)
? actualBounds[3] + this._getBottomIndentHeight(page, false) - template._bounds.height
: actualBounds[3] - template._bounds.height;
break;
case _PdfAlignmentStyle.bottomCenter:
x = (actualBounds[2] - template._bounds.width) / 2;
y = actualBounds[3] + this._getBottomIndentHeight(page, false) - template._bounds.height;
break;
case _PdfAlignmentStyle.bottomRight:
x = actualBounds[2] + this._getRightIndentWidth(page, false) - template._bounds.width;
y = (side === _TemplateSide.bottom)
? actualBounds[3] + this._getBottomIndentHeight(page, false) - template._bounds.height
: actualBounds[3] - template._bounds.height;
break;
}
result.x = x;
result.y = y;
}
return result;
};
/**
* Checks if a template should not reserve space (background or foreground templates).
*
* @param {PdfTemplateLayerMode} templateLayerMode Template layer mode.
* @returns {boolean} True if the template should not reserve space.
* @private
*/
PdfDocument.prototype._isNonReservingTemplate = function (templateLayerMode) {
if (typeof templateLayerMode === 'undefined') {
return false;
}
return templateLayerMode === PdfTemplateLayerMode.background || templateLayerMode === PdfTemplateLayerMode.foreground;
};
/**
* Calculates the left indent width reserved by page templates and optional page margins.
*
* @private
* @param {PdfPage} page The page to compute the left indent for.
* @param {boolean} includeMargins If true, include the page left margin in the returned width.
* @returns {number} The total left indent width (in points).
*/
PdfDocument.prototype._getLeftIndentWidth = function (page, includeMargins) {
var value = 0;
if (includeMargins) {
value += page._pageSettings.margins.left;
}
var templates = page._crossReference._document.template;
if (templates) {
var pageIndex = page._pageIndex ? page._pageIndex : 0;
var isEven = ((pageIndex + 1) % 2) === 0;
var widths = [];
if (templates.left && !this._isNonReservingTemplate(templates.left.templateLayerMode)) {
widths.push(templates.left.template._bounds.width);
}
if (isEven && templates.evenLeft && !this._isNonReservingTemplate(templates.evenLeft.templateLayerMode)) {
widths.push(templates.evenLeft.template._bounds.width);
}
if (!isEven && templates.oddLeft && !this._isNonReservingTemplate(templates.oddLeft.templateLayerMode)) {
widths.push(templates.oddLeft.template._bounds.width);
}
if (widths.length > 0) {
value += Math.max.apply(Math, widths);
}
}
return value;
};
/**
* Calculates the top indent height reserved by page templates and optional page margins.
*
* @private
* @param {PdfPage} page The page to compute the top indent for.
* @param {boolean} includeMargins If true, include the page top margin in the returned height.
* @returns {number} The total top indent height (in points).
*/
PdfDocument.prototype._getTopIndentHeight = function (page, includeMargins) {
var value = 0;
if (includeMargins) {
value += page._pageSettings.margins.top;
}
var templates = page._crossReference._document.template;
if (templates) {
var pageIndex = page._pageIndex ? page._pageIndex : 0;
var isEven = ((pageIndex + 1) % 2) === 0;
var heights = [];
if (templates.top && !this._isNonReservingTemplate(templates.top.templateLayerMode)) {
heights.push(templates.top.template._bounds.height);
}
if (isEven && templates.evenTop && !this._isNonReservingTemplate(templates.evenTop.templateLayerMode)) {
heights.push(templates.evenTop.template._bounds.height);
}
if (!isEven && templates.oddTop && !this._isNonReservingTemplate(templates.oddTop.templateLayerMode)) {
heights.push(templates.oddTop.template._bounds.height);
}
if (heights.length > 0) {
value += Math.max.apply(Math, heights);
}
}
return value;
};
/**
* Calculates the right indent width reserved by page templates and optional page margins.
*
* @private
* @param {PdfPage} page The page to compute the right indent for.
* @param {boolean} includeMargins If true, include the page right margin in the returned width.
* @returns {number} The total right indent width (in points).
*/
PdfDocument.prototype._getRightIndentWidth = function (page, includeMargins) {
var value = 0;
if (includeMargins) {
value += page._pageSettings.margins.right;
}
var templates = page._crossReference._document.template;
if (templates) {
var pageIndex = page._pageIndex ? page._pageIndex : 0;
var isEven = ((pageIndex + 1) % 2) === 0;
var widths = [];
if (templates.right && !this._isNonReservingTemplate(templates.right.templateLayerMode)) {
widths.push(templates.right.template._bounds.width);
}
if (isEven && templates.evenRight && !this._isNonReservingTemplate(templates.evenRight.templateLayerMode)) {
widths.push(templates.evenRight.template._bounds.width);
}
if (!isEven && templates.oddRight && !this._isNonReservingTemplate(templates.oddRight.templateLayerMode)) {
widths.push(templates.oddRight.template._bounds.width);
}
if (widths.length > 0) {
value += Math.max.apply(Math, widths);
}
}
return value;
};
/**
* Calculates the bottom indent height reserved by page templates and optional page margins.
*
* @private
* @param {PdfPage} page The page to compute the bottom indent for.
* @param {boolean} includeMargins If true, include the page bottom margin in the returned height.
* @returns {number} The total bottom indent height (in points).
*/
PdfDocument.prototype._getBottomIndentHeight = function (page, includeMargins) {
var value = 0;
if (includeMargins) {
value += page._pageSettings.margins.bottom;
}
var templates = page._crossReference._document.template;
if (templates) {
var pageIndex = page._pageIndex ? page._pageIndex : 0;
var isEven = ((pageIndex + 1) % 2) === 0;
var heights = [];
if (templates.bottom && !this._isNonReservingTemplate(templates.bottom.templateLayerMode)) {
heights.push(templates.bottom.template._bounds.height);
}
if (isEven && templates.evenBottom && !this._isNonReservingTemplate(templates.evenBottom.templateLayerMode)) {
heights.push(templates.evenBottom.template._bounds.height);
}
if (!isEven && templates.oddBottom && !this._isNonReservingTemplate(templates.oddBottom.templateLayerMode)) {
heights.push(templates.oddBottom.template._bounds.height);
}
if (heights.length > 0) {
value += Math.max.apply(Math, heights);
}
}
return value;
};
/**
* Calculates the docking bounds for a page template based on the specified dock position.
*
* @private
* @param {PdfPage} page The page on which the template is being positioned.
* @param {PdfPageTemplateElement} template The template element to dock.
* @param {string} dock The dock position applied to the template ('left', 'top', 'right', or 'bottom').
* @returns {Rectangle} The calculated bounds of the docked template.
*/
PdfDocument.prototype._getTemplateDockBounds = function (page, template, dock) {
var result = template._bounds;
var actualBounds;
var actualSize;
if (page._isNew) {
actualBounds = page._getActualTemplateBounds(page._pageSettings);
actualSize = page._pageSettings._getActualSize();
}
if (actualBounds && actualBounds.length > 0 && actualSize && actualSize.length > 0) {
var x = template._bounds.x;
var y = template._bounds.y;
var width = template._bounds.width;
var height = template._bounds.height;
var topIndent = this._getTopIndentHeight(page, false);
var bottomIndent = this._getBottomIndentHeight(page, false);
switch (dock) {
case 'left':
x = -actualBounds[0];
y = topIndent > 0 ? topIndent : 0;
width = template._bounds.width;
height = actualBounds[3] - topIndent - bottomIndent;
break;
case 'top':
x = -actualBounds[0];
y = -actualBounds[1];
width = actualSize[0];
height = template._bounds.height;
if (actualBounds[3] < 0) {
y = -actualBounds[1] + actualSize[1];
}
break;
case 'right':
x = actualBounds[2] + this._getRightIndentWidth(page, false) - template._bounds.width;
y = topIndent > 0 ? topIndent : 0;
width = template._bounds.width;
height = actualBounds[3] - topIndent - bottomIndent;
break;
case 'bottom':
x = -actualBounds[0];
y = actualBounds[3] + this._getBottomIndentHeight(page, false) - template._bounds.height;
width = actualSize[0];
height = template._bounds.height;
if (actualBounds[3] < 0) {
y -= actualSize[1];
}
break;
}
result = { x: x, y: y, width: width, height: height };
}
return result;
};
/**
* Finalizes form fields, optionally flattening and updating appearance flags.
*
* @private
* @param {boolean} [isFlatten=false] Set `true` to flatten form fields.
* @returns {void} nothing.
*/
PdfDocument.prototype._doPostProcessOnFormFields = function (isFlatten) {
if (isFlatten === void 0) { isFlatten = false; }
if (this._catalog._catalogDictionary.has('AcroForm')) {
this.form._doPostProcess(isFlatten);
this.form._requiresPostProcessing = false;
if (isFlatten) {
var formObject = this._catalog._catalogDictionary.getRaw('AcroForm');
var dictionary = new _PdfDictionary(this._crossReference);
dictionary._updated = true;
if (formObject instanceof _PdfReference) {
this._crossReference._cacheMap.set(formObject, dictionary);
}
else {
this.form._dictionary = dictionary;
this._crossReference._allowCatalog = true;
}
this.form._clear();
}
if (this.form._isDefaultAppearance) {
this.form._dictionary.update('NeedAppearances', this.form._isDefaultAppearance);
}
else if (!this.form._isDefaultAppearance && this.form._dictionary.has('NeedAppearances') && this.form._isNeedAppearances) {
this.form._dictionary.update('NeedAppearances', false);
}
else if (!this.form._isDefaultAppearance && this.form._dictionary.has('NeedAppearances')) {
this.form._dictionary.update('NeedAppearances', this.form.needAppearances);
}
}
};
/**
* Finalizes annotations for all pages, optionally flattening them.
*
* @private
* @param {boolean} [isFlatten=false] Set `true` to flatten annotations.
* @returns {void} nothing.
*/
PdfDocument.prototype._doPostProcessOnAnnotations = function (isFlatten) {
if (isFlatten === void 0) { isFlatten = false; }
for (var i = 0; i < this.pageCount; i++) {
var page = this.getPage(i);
page.annotations._isExport = this._isExport;
page.annotations._doPostProcess(isFlatten);
if (isFlatten) {
if (page._pageDictionary.has('Annots')) {
delete page._pageDictionary._map.Annots;
page._pageDictionary._updated = true;
}
page.annotations._clear();
}
}
};
/**
* Adds the evaluation watermark text to all pages when license validation fails.
*
* @private
* @returns {void} nothing.
*/
PdfDocument.prototype._addWatermarkText = function () {
for (var i = 0; i < this.pageCount; i++) {
this._addLincenseWaterMark(this.getPage(i), i === 0, i === this.pageCount - 1);
}
};
/**
* Add license watermark on the page.
*
* @private
* @param { PdfPage } page PDF-page.
* @param { boolean } isFirstPage It denotes it is a first page or not.
* @param { boolean } isLastPage It denotes it is a last page or not.
* @returns { void } Returns void
*/
PdfDocument.prototype._addLincenseWaterMark = function (page, isFirstPage, isLastPage) {
var diagonalText = 'Created with a trial version of Syncfusion PDF library.';
var formatCenter = new PdfStringFormat(PdfTextAlignment.center, PdfVerticalAlignment.middle);
var fontSize = 14;
var graphics = page.graphics;
var clientSize = graphics.clientSize;
if (page.size.width < 400) {
fontSize = page.size.width * 0.035;
}
var font = new PdfStandardFont(PdfFontFamily.helvetica, fontSize, PdfFontStyle.regular);
if (isFirstPage) {
this._drawWatermarkOnPage(page, font, graphics, false);
}
else if (isLastPage) {
this._drawWatermarkOnPage(page, font, graphics, true);
}
var textSize = font.measureString(diagonalText, clientSize.width);
var centerX = clientSize.width / 2;
var centerY = clientSize.height / 2;
graphics.save();
if (!page._isNew && (page.rotation === PdfRotationAngle.angle90)) {
graphics.translateTransform({ x: centerY, y: centerX });
}
else {
graphics.translateTransform({ x: centerX, y: centerY });
}
graphics.setTransparency(0.5);
if (page._isNew) {
switch (page.rotation) {
case PdfRotationAngle.angle90:
graphics.rotateTransform(-135);
break;
case PdfRotationAngle.angle180:
graphics.rotateTransform(-225);
break;
case PdfRotationAngle.angle270:
graphics.rotateTransform(-315);
break;
default:
graphics.rotateTransform(-45);
break;
}
}
else {
graphics.rotateTransform(-45);
}
var x = textSize.width / 2;
var y = textSize.height / 2;
var x1 = centerX - x;
graphics.drawString(diagonalText, font, { x: -x, y: -(y / 2), width: clientSize.width - (x1 + x1), height: textSize.height }, new PdfBrush({ r: 255, g: 0, b: 0 }), formatCenter);
graphics.restore();
graphics.restore();
};
/**
* Draw the watermark in the header and footer of the page.
*
* @private
* @param { PdfPage } page PDF-page.
* @param { PdfStandardFont } font It denotes the font for the text added.
* @param { PdfGraphics } graphics It denotes the graphis of the page.
* @param { boolean } isLastPage It denotes it is a last page or not.
* @returns {void} Returns void.
*/
PdfDocument.prototype._drawWatermarkOnPage = function (page, font, graphics, isLastPage) {
var watermarkHeaderText = 'Created with a trial version of Syncfusion PDF library or registered the wrong key in your application. To obtain the valid key, Click';
var watermarkLinkText = 'here';
var xPosition = 40;
var yPostion = 10;
var rotation = page.rotation;
var size = page._isNew && (rotation === PdfRotationAngle.angle270 || rotation === PdfRotationAngle.angle90)
? { width: graphics.clientSize.width, height: graphics.clientSize.height - 70 }
: { width: graphics.clientSize.width - 70, height: graphics.clientSize.height };
if (!page._isNew && (rotation === PdfRotationAngle.angle270 || rotation === PdfRotationAngle.angle90)) {
size = { width: page.size.height - 70, height: page.size.width };
}
var textFormat = new PdfStringFormat();
textFormat._wordWrap = _PdfWordWrapType.word;
var redBrush = new PdfBrush({ r: 255, g: 0, b: 0 });
var blueBrush = new PdfBrush({ r: 0, g: 0, b: 255 });
var headerSize = font.measureString(watermarkHeaderText);
var linkSize = font.measureString(watermarkLinkText);
var lineHeight = headerSize.height;
var availableWidth = (page._isNew && (rotation === PdfRotationAngle.angle270 || rotation === PdfRotationAngle.angle90))
? size.height : size.width;
var currentX = rotation === PdfRotationAngle.angle90 && page._isNew ? xPosition - 70 : xPosition;
var currentY = isLastPage
? (page._isNew && (rotation === PdfRotationAngle.angle270 || rotation === PdfRotationAngle.angle90)
? size.width : size.height) - (page.orientation === PdfPageOrientation.landscape &&
page.size.width === 420 || page.size.height === 420 ? lineHeight * 4 : lineHeight * 3) - yPostion : yPostion;
if (page._isNew) {
if (page.rotation !== PdfRotationAngle.angle0) {
graphics.save();
if (rotation === PdfRotationAngle.angle90) {
graphics.rotateTransform(-90);
}
else if (rotation === PdfRotationAngle.angle180) {
graphics.rotateTransform(-180);
}
else if (rotation === PdfRotationAngle.angle270) {
graphics.rotateTransform(-270);
}
}
}
var adjustBoundsForRotation = function (rect) {
if (page._isNew) {
if (rotation === PdfRotationAngle.angle90) {
return {
x: -(size.height - rect.x),
y: rect.y,
width: rect.height - xPosition,
height: rect.width
};
}
if (rotation === PdfRotationAngle.angle180) {
return {
x: -(graphics.clientSize.width - rect.x),
y: -(size.height - rect.y),
width: rect.width - xPosition,
height: rect.height
};
}
if (rotation === PdfRotationAngle.angle270) {
return {
x: rect.x,
y: -(size.width - rect.y),
width: rect.height - xPosition,
height: rect.width
};
}
}
return rect;
};
var headerBounds = adjustBoundsForRotation({
x: currentX,
y: currentY,
width: size.width,
height: size.height
});
graphics.drawString(watermarkHeaderText, font, headerBounds, redBrush, textFormat);
var layouter = new _PdfStringLayouter();
var headerLayoutResult = layouter._layout(watermarkHeaderText, font, textFormat, [headerBounds.width, headerBounds.height]);
var headerLines = headerLayoutResult._layoutLines;
var lastLine = headerLines[headerLines.length - 1];
currentX += lastLine._width + 5;
if (headerLayoutResult._lineCount >= 2) {
currentY += headerLayoutResult._lineHeight * (headerLayoutResult._lineCount - 1);
}
if (currentX + linkSize.width > availableWidth) {
currentX = xPosition;
currentY += headerLayoutResult._lineHeight;
}
var linkRect = {
x: currentX,
y: currentY,
width: linkSize.width,
height: linkSize.height
};
var rotatedLinkRect = adjustBoundsForRotation(linkRect);
rotatedLinkRect.width += 70;
graphics.drawString(watermarkLinkText, font, rotatedLinkRect, blueBrush, textFormat);
rotatedLinkRect.width -= 70;
var annotationRect;
if (page._isNew) {
switch (rotation) {
case PdfRotationAngle.angle0:
annotationRect = __assign({}, linkRect);
break;
case PdfRotationAngle.angle90:
annotationRect = {
x: linkRect.y,
y: size.height - linkRect.x - linkRect.width,
width: linkRect.height,
height: linkRect.width
};
break;
case PdfRotationAngle.angle180:
annotationRect = {
x: size.width - linkRect.x + 40,
y: size.height - linkRect.y - linkRect.height,
width: linkRect.width,
height: linkRect.height
};
break;
case PdfRotationAngle.angle270:
annotationRect = {
x: size.width - linkRect.y - linkRect.height,
y: linkRect.x,
width: linkRect.height,
height: linkRect.width
};
break;
}
}
else {
switch (rotation) {
case PdfRotationAngle.angle0:
annotationRect = __assign({}, linkRect);
break;
case PdfRotationAngle.angle90:
annotationRect = {
x: linkRect.y,
y: page.size.height - linkRect.x - linkRect.width,
width: linkRect.height,
height: linkRect.width
};
break;
case PdfRotationAngle.angle180:
annotationRect = {
x: page.size.width - linkRect.x - linkRect.width,
y: page.size.height - linkRect.y - linkRect.height,
width: linkRect.width,
height: linkRect.height
};
break;
case PdfRotationAngle.angle270:
annotationRect = {
x: page.size.width - linkRect.y - linkRect.height,
y: linkRect.x,
width: linkRect.height,
height: linkRect.width
};
break;
}
}
var linkAnnotation = new PdfUriAnnotation(annotationRect, 'http://www.syncfusion.com');
linkAnnotation.border.width = 0;
linkAnnotation.border.hRadius = 0;
linkAnnotation.border.vRadius = 0;
page.annotations.add(linkAnnotation);
linkAnnotation._doPostProcess();
if (page.rotation !== PdfRotationAngle.angle0 && page._isNew) {
graphics.restore();
}
else {
graphics.save();
}
};
PdfDocument.prototype.importPageRange = function (sourceDocument, startIndex, endIndex, options) {
if (startIndex > endIndex || startIndex >= sourceDocument.pageCount) {
throw new Error('The start index is greater then the end index, which might indicate the error in the program.');
}
this._importPages(sourceDocument, startIndex, endIndex, options);
};
/**
* Imports pages from the specified source document into this document.
*
* @private
* @param {PdfDocument} sourceDocument - The source PDF document to import pages from.
* @param {number} startIndex - The starting page index in the source document.
* @param {number} endIndex - The ending page index in the source document.
* @param {PdfPageImportOptions} [options] - Optional settings that control import behavior.
* @returns {void} nothing.
*/
PdfDocument.prototype._importPages = function (sourceDocument, startIndex, endIndex, options) {
initializeTelemetryFeature('MergePDF', 'PDFLibrary');
var sourceOCProperties;
var correspondancePagecount = 0;
var ocProperties;
if (typeof options !== 'undefined' && typeof options.targetIndex === 'number') {
if (options.targetIndex > this.pageCount) {
throw new Error('The target index is out of range.');
}
this._targetIndex = options.targetIndex;
}
var pageReference = new Map();
if (!this._isDuplicatePage) {
var start = Math.max(0, startIndex);
var end = Math.min(endIndex, sourceDocument.pageCount - 1);
for (var index = start; index <= end; index++) {
var srcPage = sourceDocument.getPage(index);
pageReference.set(srcPage._pageDictionary, null);
}
}
var helper;
if (!this._mergeHelperCache) {
this._mergeHelperCache = new Map();
}
if (!sourceDocument._uniqueID) {
sourceDocument._uniqueID = _getNewGuidString();
}
if (this._mergeHelperCache.has(sourceDocument._uniqueID)) {
helper = this._mergeHelperCache.get(sourceDocument._uniqueID);
}
else {
helper = new _PdfMergeHelper(this._crossReference, this, sourceDocument, pageReference, options);
this._mergeHelperCache.set(sourceDocument._uniqueID, helper);
}
var isLayersPresent = false;
var hasOCProps = sourceDocument._catalog._catalogDictionary.has('OCProperties');
if (hasOCProps && (!this._isDuplicatePage || (options && !options.optimizeResources))) {
isLayersPresent = true;
sourceOCProperties = sourceDocument._catalog._catalogDictionary.get('OCProperties');
ocProperties = new _PdfDictionary(this._crossReference);
helper._writeObject(sourceDocument, ocProperties, sourceOCProperties, sourceOCProperties, 'OCProperties', null, null);
ocProperties._updated = true;
}
var flattenSource = sourceDocument.flatten;
var isSplitImport = sourceDocument._isSplitDocument;
for (var i = startIndex; i <= endIndex; i++) {
var page = sourceDocument.getPage(i);
sourceDocument.form._doPostProcess(flattenSource, page);
if (page.annotations.count > 0) {
page.annotations._doPostProcess(flattenSource);
if (flattenSource) {
if (page._pageDictionary.has('Annots')) {
delete page._pageDictionary._map.Annots;
page._pageDictionary._updated = true;
}
page.annotations._clear();
}
}
if (isSplitImport) {
helper._importPages(page, this._targetIndex, isLayersPresent, this._isDuplicatePage, options, isSplitImport);
}
else {
helper._importPages(page, this._targetIndex, isLayersPresent, this._isDuplicatePage, options);
}
correspondancePagecount++;
if (typeof this._targetIndex === 'number') {
++this._targetIndex;
}
}
if (!this._isDuplicatePage) {
helper._fixDestinations(sourceDocument);
}
helper._exportBookmarks(sourceDocument, correspondancePagecount);
helper._mergeFormFieldsWithDocument();
if (isLayersPresent && (!this._isDuplicatePage || (options && !options.optimizeResources))) {
helper._importLayers(ocProperties, true);
}
helper._objectDispose();
this._isDuplicatePage = false;
};
PdfDocument.prototype.importPage = function (arg1, arg2, options) {
if (typeof arg1 === 'number') {
this._isDuplicatePage = true;
if (arg2 instanceof PdfPageImportOptions) {
this._importPages(this, arg1, arg1, arg2);
}
else {
this._importPages(this, arg1, arg1);
}
}
else if (arg1 instanceof PdfPage && arg2 instanceof PdfDocument) {
var index = arg1._pageIndex;
this.importPageRange(arg2, index, index, options);
}
};
/**
* Splitting a PDF file into individual pages.
*
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data);
* document.splitEvent = documentSplitEvent;
* // Split PDF document into individual pages
* document.split();
* // Event to invoke while splitting PDF document data
* function documentSplitEvent(sender: PdfDocument, args: PdfDocumentSplitEventArgs): void {
* Save.save('output_' + args.splitIndex + '.pdf', new Blob([args.pdfData], { type: 'application/pdf' }));
* }
* // Destroy the document
* document.destroy();
* ```
*
* @returns {void} Nothing
*/
PdfDocument.prototype.split = function () {
this.splitByFixedNumber(1);
};
/**
* Splits the PDF document into parts, each containing a maximum number of pages specified.
*
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data);
* document.splitEvent = documentSplitEvent;
* // Split PDF document by fixed number of pages
* document.splitByFixedNumber(1);
* // Event to invoke while splitting PDF document data
* function documentSplitEvent(sender: PdfDocument, args: PdfDocumentSplitEventArgs): void {
* Save.save('output_' + args.splitIndex + '.pdf', new Blob([args.pdfData], { type: 'application/pdf' }));
* }
* // Destroy the document
* document.destroy();
* ```
*
* @param {number} fixedNumber specifies the maximum number of pages in each split PDF. The default value is 1.
* @returns {void} Nothing
*/
PdfDocument.prototype.splitByFixedNumber = function (fixedNumber) {
var pageCount = this.pageCount;
if (this.splitEvent && pageCount >= fixedNumber && fixedNumber > 0) {
var splitIndex = 0;
for (var tempValue = 0; tempValue < pageCount; tempValue += fixedNumber) {
var endIndex = Math.min(tempValue + fixedNumber - 1, pageCount - 1);
var pdfData = this._importDocumentPages(tempValue, endIndex);
this._invokeSplitEvent(splitIndex, pdfData);
splitIndex++;
}
}
else {
throw new Error('Invalid split number. Split number should be greater than zero and less than or equal to page count.');
}
};
/**
* Splits the PDF document into multiple parts based on the specified page ranges.
*
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data);
* document.splitEvent = documentSplitEvent;
* // Split PDF document by page ranges specified
* document.splitByPageRanges([[0, 4], [5, 9]]);
* // Event to invoke while splitting PDF document data
* function documentSplitEvent(sender: PdfDocument, args: PdfDocumentSplitEventArgs): void {
* Save.save('output_' + args.splitIndex + '.pdf', new Blob([args.pdfData], { type: 'application/pdf' }));
* }
* // Destroy the document
* document.destroy();
* ```
*
* @param {Array<number[]>} ranges The two dimensional number array specified for start and end page indexes to split PDF documents.
* @returns {void} Nothing
*/
PdfDocument.prototype.splitByPageRanges = function (ranges) {
var _this = this;
var pageCount = this.pageCount;
if (this.splitEvent) {
var splitIndex_1 = 0;
ranges.forEach(function (range) {
if (Array.isArray(range) && range.length < 2) {
throw new Error('Invalid page range. Start and end page indexes should be specified.');
}
var start = range[0];
var end = range[1];
if (start < 0 || end < 0 || start >= pageCount || end >= pageCount || start > end) {
throw new Error("Invalid page range: start (" + start + ") and end (" + end + ").");
}
var pdfData = _this._importDocumentPages(start, end);
_this._invokeSplitEvent(splitIndex_1, pdfData);
splitIndex_1++;
});
}
};
PdfDocument.prototype._importDocumentPages = function (startIndex, endIndex) {
this._isSplitDocument = true;
var document = new PdfDocument();
for (var i = startIndex; i <= endIndex; i++) {
var page = this.getPage(i);
document.importPage(page, this);
}
var result = document.save();
document.destroy();
return result;
};
PdfDocument.prototype._invokeSplitEvent = function (splitIndex, pdfData) {
initializeTelemetryFeature('SplitPDF', 'PDFLibrary');
var args = new PdfDocumentSplitEventArgs(splitIndex, pdfData);
this.splitEvent(this, args);
};
/**
* Retrieves and initializes a PDF signature instance from the given dictionary and field.
*
* @private
* @param {_PdfDictionary} dictionary - The signature dictionary from the PDF.
* @param {any} field - The associated form field containing the signature.
* @returns {PdfSignature} The initialized `PdfSignature` object.
*/
PdfDocument.prototype._getSignature = function (dictionary, field) {
var signature = new PdfSignature();
signature._initializeInternals(dictionary, field);
return signature;
};
/**
* Determines whether the document has any template content (headers/footers) defined.
*
* @private
* @returns {boolean} `true` if the document has template content; otherwise, `false`.
*/
PdfDocument.prototype._hasTemplateContent = function () {
if (!this._template) {
return false;
}
return ((this._template.oddTop !== null && typeof this._template.oddTop !== 'undefined') ||
(this._template.evenTop !== null && typeof this._template.evenTop !== 'undefined') ||
(this._template.oddBottom !== null && typeof this._template.oddBottom !== 'undefined') ||
(this._template.evenBottom !== null && typeof this._template.evenBottom !== 'undefined') ||
(this._template.left !== null && typeof this._template.left !== 'undefined') ||
(this._template.oddLeft !== null && typeof this._template.oddLeft !== 'undefined') ||
(this._template.evenLeft !== null && typeof this._template.evenLeft !== 'undefined') ||
(this._template.right !== null && typeof this._template.right !== 'undefined') ||
(this._template.oddRight !== null && typeof this._template.oddRight !== 'undefined') ||
(this._template.evenRight !== null && typeof this._template.evenRight !== 'undefined') ||
(this._template.top !== null && typeof this._template.top !== 'undefined') ||
(this._template.bottom !== null && typeof this._template.bottom !== 'undefined'));
};
Object.defineProperty(PdfDocument.prototype, "_hasTemplateContentValue", {
/**
* Gets a value indicating whether the document contains any header or footer templates.
*
* @private
* @returns {boolean} `true` if at least one template is defined; otherwise, `false`.
*/
get: function () {
return this._hasTemplateContent();
},
enumerable: true,
configurable: true
});
return PdfDocument;
}());
export { PdfDocument };
/**
* Represents annotation export settings.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Sets export data format as JSON type to annotation export settings
* let settings: PdfAnnotationExportSettings = new PdfAnnotationExportSettings();
* // Set the data format defined in annotation export settings
* settings.dataFormat = DataFormat.json;
* // Export annotations to JSON format
* let json: Uint8Array = document.exportAnnotations(settings);
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
var PdfAnnotationExportSettings = /** @class */ (function () {
function PdfAnnotationExportSettings() {
/**
* @private
*/
this._format = DataFormat.xfdf;
this._exportAppearance = false;
}
Object.defineProperty(PdfAnnotationExportSettings.prototype, "dataFormat", {
/**
* Gets the data format defined in annotation export settings.
*
* @returns {DataFormat} - Returns the data format.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Sets export data format as JSON type to annotation export settings
* let settings: PdfAnnotationExportSettings = new PdfAnnotationExportSettings();
* // Export annotations to JSON format
* let json: Uint8Array = document.exportAnnotations(settings);
* // Get the data format defined in annotation export settings
* let dataFormat: DataFormat = settings.dataFormat;
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
get: function () {
return this._format;
},
/**
* Sets the data format defined in annotation export settings.
*
* @param {DataFormat} format - Specifies the data format.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Sets export data format as JSON type to annotation export settings
* let settings: PdfAnnotationExportSettings = new PdfAnnotationExportSettings();
* // Set the data format defined in annotation export settings
* settings.dataFormat = DataFormat.json;
* // Export annotations to JSON format
* let json: Uint8Array = document.exportAnnotations(settings);
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
set: function (format) {
this._format = format;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfAnnotationExportSettings.prototype, "exportAppearance", {
/**
* Gets the boolean value indicating whether the appearance of a particular object can be exported or not.
*
* @returns {boolean} - Returns the boolean value.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Sets the annotation export settings with enabled export appearance.
* let settings: PdfAnnotationExportSettings = new PdfAnnotationExportSettings();
* // Export annotations to XFDF format
* let xfdf: Uint8Array = document.exportAnnotations(settings);
* // Get the boolean value indicating whether the appearance of a particular object can be exported or not
* let appearance: boolean = settings.exportAppearance;
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
get: function () {
return this._exportAppearance;
},
/**
* Sets the boolean value indicating whether the appearance of a particular object can be exported or not.
*
* @param {boolean} value - The boolean value.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Sets the annotation export settings with enabled export appearance.
* let settings: PdfAnnotationExportSettings = new PdfAnnotationExportSettings();
* // Set the boolean value indicating whether the appearance of a particular object can be exported or not
* settings.exportAppearance = true;
* // Export annotations to XFDF format
* let xfdf: Uint8Array = document.exportAnnotations(settings);
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
set: function (value) {
this._exportAppearance = value;
},
enumerable: true,
configurable: true
});
return PdfAnnotationExportSettings;
}());
export { PdfAnnotationExportSettings };
/**
* Represents form fields export settings.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data);
* // Sets the form field data export settings with output data format.
* let settings: PdfFormFieldExportSettings = new PdfFormFieldExportSettings();
* // Set the data format defined in form field export settings.
* settings.dataFormat = DataFormat.json;
* // Export form field to JSON format
* let json: Uint8Array = document.exportFormData(settings);
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
var PdfFormFieldExportSettings = /** @class */ (function () {
function PdfFormFieldExportSettings() {
/**
* @private
*/
this._format = DataFormat.xfdf;
/**
* @private
*/
this._exportName = '';
/**
* @private
*/
this._asPerSpecification = true;
}
Object.defineProperty(PdfFormFieldExportSettings.prototype, "dataFormat", {
/**
* Gets the data format defined in form field export settings.
*
* @returns {DataFormat} - Returns the data format.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data);
* // Sets the form field data export settings with output data format.
* let settings: PdfFormFieldExportSettings = new PdfFormFieldExportSettings();
* // Export form field to JSON format
* let json: Uint8Array = document.exportFormData(settings);
* // Get the data format defined in form field export settings
* let dataFormat: DataFormat = settings.dataFormat;
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
get: function () {
return this._format;
},
/**
* Sets the data format defined in form field export settings.
*
* @param {DataFormat} format - Specifies the data format.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data);
* // Sets the form field data export settings with output data format.
* let settings: PdfFormFieldExportSettings = new PdfFormFieldExportSettings();
* // Set the data format defined in form field export settings.
* settings.dataFormat = DataFormat.json;
* // Export form field to JSON format
* let json: Uint8Array = document.exportFormData(settings);
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
set: function (format) {
this._format = format;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfFormFieldExportSettings.prototype, "exportName", {
/**
* Gets the export name defined in form field export settings.
*
* @returns {string} - Returns the string value.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data);
* // Sets the form field data export settings with export name.
* let settings: PdfFormFieldExportSettings = new PdfFormFieldExportSettings();
* // Export form field to JSON format
* let json: Uint8Array = document.exportFormData(settings);
* // Get the export name defined in form field export settings
* let name: boolean = settings.exportName;
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
get: function () {
return this._exportName;
},
/**
* Sets the export name defined in form field export settings.
*
* @param {string} name - Specifies the export name of the form.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data);
* // Sets the form field data export settings with export name.
* let settings: PdfFormFieldExportSettings = new PdfFormFieldExportSettings();
* // Set the export name defined in form field export settings.
* settings.exportName = 'JobApplication'.
* // Export form field to JSON format
* let json: Uint8Array = document.exportFormData(settings);
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
set: function (name) {
this._exportName = name;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfFormFieldExportSettings.prototype, "asPerSpecification", {
/**
* Gets the boolean value indicating whether the data in a form field can be exported based on a certain specification.
*
* @returns {boolean} - Returns the boolean value.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data);
* // Sets the boolean value indicating whether the data in a form field can be exported based on a certain specification.
* let settings: PdfFormFieldExportSettings = new PdfFormFieldExportSettings();
* // Export form field to JSON format
* let json: Uint8Array = document.exportFormData(settings);
* // Get the boolean value indicating whether the data in a form field can be exported based on a certain specification.
* let asPerSpecification: boolean = settings.asPerSpecification;
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
get: function () {
return this._asPerSpecification;
},
/**
* Sets the boolean value indicating whether the data in a form field can be exported based on a certain specification.
*
* @param {boolean} value - The boolean value.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data);
* // Sets the boolean value indicating whether the data in a form field can be exported based on a certain specification.
* let settings: PdfFormFieldExportSettings = new PdfFormFieldExportSettings();
* // Set the boolean value indicating whether the data in a form field can be exported based on a certain specification.
* settings.asPerSpecification = true;
* // Export form field to JSON format
* let json: Uint8Array = document.exportFormData(settings);
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
set: function (value) {
this._asPerSpecification = value;
},
enumerable: true,
configurable: true
});
return PdfFormFieldExportSettings;
}());
export { PdfFormFieldExportSettings };
/**
* The class provides various settings related to PDF pages.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Create a new PDF page settings instance
* let pageSettings: PdfPageSettings = new PdfPageSettings();
* // Sets the margins
* pageSettings.margins = new PdfMargins(40);
* // Sets the page size
* pageSettings.size = {width: 595, height: 842};
* // Sets the page orientation
* pageSettings.orientation = PdfPageOrientation.landscape;
* // Add a new PDF page with page settings
* page = document.addPage(pageSettings);
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
var PdfPageSettings = /** @class */ (function () {
/**
* Initializes a new instance of the `PdfPageSettings` class.
*
* @param {object} [options] Optional settings to initialize the page.
* @param {PdfPageOrientation} [options.orientation] Page orientation.
* @param {Size} [options.size] Page size.
* @param {PdfMargins} [options.margins] Page margins.
* @param {PdfRotationAngle} [options.rotation] Page rotation angle.
*
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Create a new PDF page settings with custom options
* let pageSettings = new PdfPageSettings({
* orientation: PdfPageOrientation.landscape,
* size: { width: 842, height: 595 },
* margins: new PdfMargins(40),
* rotation: PdfRotationAngle.angle90
* });
* // Add a new PDF page with page settings
* page = document.addPage(pageSettings);
* // Destroy the document
* document.destroy();
* ```
*/
function PdfPageSettings(options) {
/**
* @private
*/
this._size = { width: 595, height: 842 };
/**
* @private
*/
this._isOrientation = false;
if (options && 'orientation' in options && options.orientation !== null && typeof options.orientation !== 'undefined') {
this.orientation = options.orientation;
}
else {
this._orientation = PdfPageOrientation.portrait;
}
if (options && 'size' in options && options.size !== null && typeof options.size !== 'undefined') {
this.size = options.size;
}
else {
this._size = { width: 595, height: 842 };
}
if (options && 'margins' in options && options.margins !== null && typeof options.margins !== 'undefined') {
this.margins = options.margins;
}
else {
this._margins = new PdfMargins();
}
if (options && 'rotation' in options && options.rotation !== null && typeof options.rotation !== 'undefined') {
this.rotation = options.rotation;
}
else {
this._rotation = PdfRotationAngle.angle0;
}
}
Object.defineProperty(PdfPageSettings.prototype, "orientation", {
/**
* Gets the orientation of the page.
*
* @returns {PdfPageOrientation} The orientation.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Create a new PDF page settings instance
* let pageSettings: PdfPageSettings = new PdfPageSettings();
* // Sets the page size
* pageSettings.size = {width: 842, height: 595};
* // Gets the page orientation
* let orientation: PdfPageOrientation = pageSettings.orientation;
* // Add a new PDF page with page settings
* page = document.addPage(pageSettings);
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
get: function () {
return this._orientation;
},
/**
* Sets the orientation of the page.
*
* @param {PdfPageOrientation} value The orientation.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Create a new PDF page settings instance
* let pageSettings: PdfPageSettings = new PdfPageSettings();
* // Sets the page orientation
* pageSettings.orientation = PdfPageOrientation.landscape;
* // Add a new PDF page with page settings
* page = document.addPage(pageSettings);
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
set: function (value) {
this._isOrientation = true;
if (this._orientation !== value) {
this._orientation = value;
this._updateSize(value);
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfPageSettings.prototype, "size", {
/**
* Gets the size of the page.
*
* @returns {Size} The width and height of the page as number array.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Access the first page
* let page: PdfPage = document.getPage(0);
* // Gets the width and height of the PDF page as number array
* let size: Size = page.size;
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
get: function () {
return this._size;
},
/**
* Sets the width and height of the page.
*
* @param {Size} value The width and height of the page as number array.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Create a new PDF page settings instance
* let pageSettings: PdfPageSettings = new PdfPageSettings();
* // Sets the page size
* pageSettings.size = {width: 595, height: 842};
* // Sets the page orientation
* pageSettings.orientation = PdfPageOrientation.landscape;
* // Add a new PDF page with page settings
* page = document.addPage(pageSettings);
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
set: function (value) {
if (this._isOrientation) {
this._updateSize(value);
}
else {
this._size = value;
this._updateOrientation();
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfPageSettings.prototype, "margins", {
/**
* Gets the margin value of the page.
*
* @returns {PdfMargins} PDF margins
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Create a new PDF page settings instance
* let pageSettings: PdfPageSettings = new PdfPageSettings();
* // Gets the margins
* let margins: PdfMargins = pageSettings.margins;
* // Destroy the document
* document.destroy();
* ```
*/
get: function () {
return this._margins;
},
/**
* Sets the margin value of the page.
*
* @param {PdfMargins} value PDF margins
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Create a new PDF page settings instance
* let pageSettings: PdfPageSettings = new PdfPageSettings();
* // Sets the margins
* pageSettings.margins = new PdfMargins(40);
* // Add a new PDF page with page settings
* page = document.addPage(pageSettings);
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
set: function (value) {
this._margins = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfPageSettings.prototype, "rotation", {
/**
* Gets the rotation angle of the PDF page.
*
* @returns {PdfRotationAngle} PDF rotation angle
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Create a new PDF page settings instance
* let pageSettings: PdfPageSettings = new PdfPageSettings();
* // Gets the rotation angle
* let rotation: PdfRotationAngle = pageSettings.rotation;
* // Destroy the document
* document.destroy();
* ```
*/
get: function () {
return this._rotation;
},
/**
* Sets the rotation angle of the PDF page.
*
* @param {PdfRotationAngle} value PDF rotation angle
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Create a new PDF page settings instance
* let pageSettings: PdfPageSettings = new PdfPageSettings();
* // Sets the rotation angle
* pageSettings.rotation = PdfRotationAngle.angle90;
* // Add a new PDF page with page settings
* page = document.addPage(pageSettings);
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
set: function (value) {
this._rotation = value;
if (value >= 4) {
this._rotation = (value % 4);
}
},
enumerable: true,
configurable: true
});
/**
* Updates the page size using either a `Size` object or a `PdfPageOrientation`, normalizing width/height accordingly.
*
* @private
* @param {Size | PdfPageOrientation} value The target size or orientation.
* @returns {void} nothing.
*/
PdfPageSettings.prototype._updateSize = function (value) {
var pageOrientation;
var pageSize;
if (typeof value !== 'number' && 'width' in value && 'height' in value && typeof value.width !== 'undefined' && typeof value.height !== 'undefined') {
pageOrientation = this.orientation;
pageSize = value;
}
else {
pageOrientation = value;
pageSize = this._size;
}
if (pageOrientation === PdfPageOrientation.portrait) {
this._size = { width: Math.min(pageSize.width, pageSize.height), height: Math.max(pageSize.width, pageSize.height) };
}
else {
this._size = { width: Math.max(pageSize.width, pageSize.height), height: Math.min(pageSize.width, pageSize.height) };
}
};
/**
* Recomputes the page orientation from the current size (portrait if height ≥ width; otherwise landscape).
*
* @private
* @returns {void} nothing.
*/
PdfPageSettings.prototype._updateOrientation = function () {
this._orientation = (this._size.height >= this._size.width) ? PdfPageOrientation.portrait : PdfPageOrientation.landscape;
};
/**
* Computes the drawable content size by subtracting margins from the page size.
*
* @private
* @returns {number[]} A two-element array.
*/
PdfPageSettings.prototype._getActualSize = function () {
var width = this._size.width - (this._margins._left + this._margins._right);
var height = this._size.height - (this._margins._top + this._margins._bottom);
return [width, height];
};
return PdfPageSettings;
}());
export { PdfPageSettings };
/**
* A class representing PDF page margins.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Create a new PDF page settings instance
* let pageSettings: PdfPageSettings = new PdfPageSettings();
* // Sets the margins
* pageSettings.margins = new PdfMargins(40);
* // Sets the page size
* pageSettings.size = {width: 595, height: 842};
* // Sets the page orientation
* pageSettings.orientation = PdfPageOrientation.landscape;
* // Add a new PDF page with page settings
* page = document.addPage(pageSettings);
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
var PdfMargins = /** @class */ (function () {
function PdfMargins(all) {
if (typeof all === 'undefined') {
this._left = this._right = this._top = this._bottom = 40;
}
else {
this._left = this._right = this._top = this._bottom = all;
}
}
Object.defineProperty(PdfMargins.prototype, "left", {
/**
* Gets the left margin value of the page.
*
* @returns {number} Left margin.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Create a new PDF page settings instance
* let pageSettings: PdfPageSettings = new PdfPageSettings();
* // Gets the left margin
* let left: number = pageSettings.margins.left;
* // Destroy the document
* document.destroy();
* ```
*/
get: function () {
return this._left;
},
/**
* Sets the left margin value of the page.
*
* @param {number} value Left margin.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Create a new PDF page settings instance
* let pageSettings: PdfPageSettings = new PdfPageSettings();
* // Sets the margins
* let margins: PdfMargins = new PdfMargins();
* margins.left = 40;
* margins.right = 40;
* margins.top = 20;
* margins.bottom = 20;
* pageSettings.margins = margins;
* // Sets the page size
* pageSettings.size = {width: 595, height: 842};
* // Sets the page orientation
* pageSettings.orientation = PdfPageOrientation.landscape;
* // Add a new PDF page with page settings
* page = document.addPage(pageSettings);
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
set: function (value) {
this._left = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfMargins.prototype, "right", {
/**
* Gets the right margin value of the page.
*
* @returns {number} Right margin.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Create a new PDF page settings instance
* let pageSettings: PdfPageSettings = new PdfPageSettings();
* // Gets the right margin
* let right: number = pageSettings.margins.right;
* // Destroy the document
* document.destroy();
* ```
*/
get: function () {
return this._right;
},
/**
* Sets the right margin value of the page.
*
* @param {number} value - Right margin.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Create a new PDF page settings instance
* let pageSettings: PdfPageSettings = new PdfPageSettings();
* // Sets the margins
* let margins: PdfMargins = new PdfMargins();
* margins.left = 40;
* margins.right = 40;
* margins.top = 20;
* margins.bottom = 20;
* pageSettings.margins = margins;
* // Sets the page size
* pageSettings.size = {width: 595, height: 842};
* // Sets the page orientation
* pageSettings.orientation = PdfPageOrientation.landscape;
* // Add a new PDF page with page settings
* page = document.addPage(pageSettings);
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
set: function (value) {
this._right = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfMargins.prototype, "top", {
/**
* Gets the top margin value of the page.
*
* @returns {number} Top margin.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Create a new PDF page settings instance
* let pageSettings: PdfPageSettings = new PdfPageSettings();
* // Gets the top margin
* let top: number = pageSettings.margins.top;
* // Destroy the document
* document.destroy();
* ```
*/
get: function () {
return this._top;
},
/**
*Sets the top margin value of the page.
*
* @param {number} value Top margin.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Create a new PDF page settings instance
* let pageSettings: PdfPageSettings = new PdfPageSettings();
* // Sets the margins
* let margins: PdfMargins = new PdfMargins();
* margins.left = 40;
* margins.right = 40;
* margins.top = 20;
* margins.bottom = 20;
* pageSettings.margins = margins;
* // Sets the page size
* pageSettings.size = {width: 595, height: 842};
* // Sets the page orientation
* pageSettings.orientation = PdfPageOrientation.landscape;
* // Add a new PDF page with page settings
* page = document.addPage(pageSettings);
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
set: function (value) {
this._top = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfMargins.prototype, "bottom", {
/**
* Get the bottom margin value of the page.
*
* @returns {number} Bottom margin.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Create a new PDF page settings instance
* let pageSettings: PdfPageSettings = new PdfPageSettings();
* // Gets the bottom margin
* let bottom: number = pageSettings.margins.bottom;
* // Destroy the document
* document.destroy();
* ```
*/
get: function () {
return this._bottom;
},
/**
* Sets the bottom margin value of the page.
*
* @param {number} value Bottom margin.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Create a new PDF page settings instance
* let pageSettings: PdfPageSettings = new PdfPageSettings();
* // Sets the margins
* let margins: PdfMargins = new PdfMargins();
* margins.left = 40;
* margins.right = 40;
* margins.top = 20;
* margins.bottom = 20;
* pageSettings.margins = margins;
* // Sets the page size
* pageSettings.size = {width: 595, height: 842};
* // Sets the page orientation
* pageSettings.orientation = PdfPageOrientation.landscape;
* // Add a new PDF page with page settings
* page = document.addPage(pageSettings);
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
set: function (value) {
this._bottom = value;
},
enumerable: true,
configurable: true
});
return PdfMargins;
}());
export { PdfMargins };
/**
* Public class to provide data for the document split event, including the split index and PDF data.
*
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data);
* document.splitEvent = documentSplitEvent;
* // Split PDF document by fixed number of pages
* document.splitByFixedNumber(1);
* // Event to invoke while splitting PDF document data
* function documentSplitEvent(sender: PdfDocument, args: PdfDocumentSplitEventArgs): void {
* Save.save('output_' + args.splitIndex + '.pdf', new Blob([args.pdfData], { type: 'application/pdf' }));
* }
* // Destroy the document
* document.destroy();
*/
var PdfDocumentSplitEventArgs = /** @class */ (function () {
/*
* Initializes a new instance of the `PdfDocumentSplitEventArgs` class.
*
* @param {number} splitIndex The fixed number to split PDF document pages. The default value is 1.
* @param {Uint8Array} pdfData The byte array of the split PDF document data.
*
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data);
* document.splitEvent = documentSplitEvent;
* // Split PDF document by fixed number of pages
* document.splitByFixedNumber(1);
* // Event to invoke while splitting PDF document data
* function documentSplitEvent(sender: PdfDocument, args: PdfDocumentSplitEventArgs): void {
* Save.save('output_' + args.splitIndex + '.pdf', new Blob([args.pdfData], { type: 'application/pdf' }));
* }
* // Destroy the document
* document.destroy();
*/
function PdfDocumentSplitEventArgs(splitIndex, pdfData) {
this._index = splitIndex;
this._pdfData = pdfData;
}
Object.defineProperty(PdfDocumentSplitEventArgs.prototype, "pdfData", {
/*
* Gets the byte array of the PDF document data.
*
* @returns {Uint8Array} The byte array of the PDF document data.
*
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data);
* document.splitEvent = documentSplitEvent;
* // Split PDF document by fixed number of pages
* document.splitByFixedNumber(1);
* // Event to invoke while splitting PDF document data
* function documentSplitEvent(sender: PdfDocument, args: PdfDocumentSplitEventArgs): void {
* Save.save('output_' + args.splitIndex + '.pdf', new Blob([args.pdfData], { type: 'application/pdf' }));
* }
* // Destroy the document
* document.destroy();
*/
get: function () {
return this._pdfData;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfDocumentSplitEventArgs.prototype, "index", {
/*
* Gets the split index of the PDF document.
*
* @returns {Uint8Array} The index that defines the number of event calls during the PDF document split.
*
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data);
* document.splitEvent = documentSplitEvent;
* // Split PDF document by fixed number of pages
* document.splitByFixedNumber(1);
* // Event to invoke while splitting PDF document data
* function documentSplitEvent(sender: PdfDocument, args: PdfDocumentSplitEventArgs): void {
* Save.save('output_' + args.splitIndex + '.pdf', new Blob([args.pdfData], { type: 'application/pdf' }));
* }
* // Destroy the document
* document.destroy();
*/
get: function () {
return this._index;
},
enumerable: true,
configurable: true
});
return PdfDocumentSplitEventArgs;
}());
export { PdfDocumentSplitEventArgs };