Current File : /home/tradevaly/www/node_modules/pdfmake/src/documentContext.js |
'use strict';
var TraversalTracker = require('./traversalTracker');
var isString = require('./helpers').isString;
/**
* Creates an instance of DocumentContext - a store for current x, y positions and available width/height.
* It facilitates column divisions and vertical sync
*/
function DocumentContext(pageSize, pageMargins) {
this.pages = [];
this.pageMargins = pageMargins;
this.x = pageMargins.left;
this.availableWidth = pageSize.width - pageMargins.left - pageMargins.right;
this.availableHeight = 0;
this.page = -1;
this.snapshots = [];
this.endingCell = null;
this.tracker = new TraversalTracker();
this.backgroundLength = [];
this.addPage(pageSize);
}
DocumentContext.prototype.beginColumnGroup = function () {
this.snapshots.push({
x: this.x,
y: this.y,
availableHeight: this.availableHeight,
availableWidth: this.availableWidth,
page: this.page,
bottomMost: {
x: this.x,
y: this.y,
availableHeight: this.availableHeight,
availableWidth: this.availableWidth,
page: this.page
},
endingCell: this.endingCell,
lastColumnWidth: this.lastColumnWidth
});
this.lastColumnWidth = 0;
};
DocumentContext.prototype.beginColumn = function (width, offset, endingCell) {
var saved = this.snapshots[this.snapshots.length - 1];
this.calculateBottomMost(saved);
this.endingCell = endingCell;
this.page = saved.page;
this.x = this.x + this.lastColumnWidth + (offset || 0);
this.y = saved.y;
this.availableWidth = width; //saved.availableWidth - offset;
this.availableHeight = saved.availableHeight;
this.lastColumnWidth = width;
};
DocumentContext.prototype.calculateBottomMost = function (destContext) {
if (this.endingCell) {
this.saveContextInEndingCell(this.endingCell);
this.endingCell = null;
} else {
destContext.bottomMost = bottomMostContext(this, destContext.bottomMost);
}
};
DocumentContext.prototype.markEnding = function (endingCell) {
this.page = endingCell._columnEndingContext.page;
this.x = endingCell._columnEndingContext.x;
this.y = endingCell._columnEndingContext.y;
this.availableWidth = endingCell._columnEndingContext.availableWidth;
this.availableHeight = endingCell._columnEndingContext.availableHeight;
this.lastColumnWidth = endingCell._columnEndingContext.lastColumnWidth;
};
DocumentContext.prototype.saveContextInEndingCell = function (endingCell) {
endingCell._columnEndingContext = {
page: this.page,
x: this.x,
y: this.y,
availableHeight: this.availableHeight,
availableWidth: this.availableWidth,
lastColumnWidth: this.lastColumnWidth
};
};
DocumentContext.prototype.completeColumnGroup = function (height) {
var saved = this.snapshots.pop();
this.calculateBottomMost(saved);
this.endingCell = null;
this.x = saved.x;
var y = saved.bottomMost.y;
if (height) {
if (saved.page === saved.bottomMost.page) {
if ((saved.y + height) > y) {
y = saved.y + height;
}
} else {
y += height;
}
}
this.y = y;
this.page = saved.bottomMost.page;
this.availableWidth = saved.availableWidth;
this.availableHeight = saved.bottomMost.availableHeight;
if (height) {
this.availableHeight -= (y - saved.bottomMost.y);
}
this.lastColumnWidth = saved.lastColumnWidth;
};
DocumentContext.prototype.addMargin = function (left, right) {
this.x += left;
this.availableWidth -= left + (right || 0);
};
DocumentContext.prototype.moveDown = function (offset) {
this.y += offset;
this.availableHeight -= offset;
return this.availableHeight > 0;
};
DocumentContext.prototype.initializePage = function () {
this.y = this.pageMargins.top;
this.availableHeight = this.getCurrentPage().pageSize.height - this.pageMargins.top - this.pageMargins.bottom;
this.pageSnapshot().availableWidth = this.getCurrentPage().pageSize.width - this.pageMargins.left - this.pageMargins.right;
};
DocumentContext.prototype.pageSnapshot = function () {
if (this.snapshots[0]) {
return this.snapshots[0];
} else {
return this;
}
};
DocumentContext.prototype.moveTo = function (x, y) {
if (x !== undefined && x !== null) {
this.x = x;
this.availableWidth = this.getCurrentPage().pageSize.width - this.x - this.pageMargins.right;
}
if (y !== undefined && y !== null) {
this.y = y;
this.availableHeight = this.getCurrentPage().pageSize.height - this.y - this.pageMargins.bottom;
}
};
DocumentContext.prototype.moveToRelative = function (x, y) {
if (x !== undefined && x !== null) {
this.x = this.x + x;
}
if (y !== undefined && y !== null) {
this.y = this.y + y;
}
};
DocumentContext.prototype.beginDetachedBlock = function () {
this.snapshots.push({
x: this.x,
y: this.y,
availableHeight: this.availableHeight,
availableWidth: this.availableWidth,
page: this.page,
endingCell: this.endingCell,
lastColumnWidth: this.lastColumnWidth
});
};
DocumentContext.prototype.endDetachedBlock = function () {
var saved = this.snapshots.pop();
this.x = saved.x;
this.y = saved.y;
this.availableWidth = saved.availableWidth;
this.availableHeight = saved.availableHeight;
this.page = saved.page;
this.endingCell = saved.endingCell;
this.lastColumnWidth = saved.lastColumnWidth;
};
function pageOrientation(pageOrientationString, currentPageOrientation) {
if (pageOrientationString === undefined) {
return currentPageOrientation;
} else if (isString(pageOrientationString) && (pageOrientationString.toLowerCase() === 'landscape')) {
return 'landscape';
} else {
return 'portrait';
}
}
var getPageSize = function (currentPage, newPageOrientation) {
newPageOrientation = pageOrientation(newPageOrientation, currentPage.pageSize.orientation);
if (newPageOrientation !== currentPage.pageSize.orientation) {
return {
orientation: newPageOrientation,
width: currentPage.pageSize.height,
height: currentPage.pageSize.width
};
} else {
return {
orientation: currentPage.pageSize.orientation,
width: currentPage.pageSize.width,
height: currentPage.pageSize.height
};
}
};
DocumentContext.prototype.moveToNextPage = function (pageOrientation) {
var nextPageIndex = this.page + 1;
var prevPage = this.page;
var prevY = this.y;
var createNewPage = nextPageIndex >= this.pages.length;
if (createNewPage) {
var currentAvailableWidth = this.availableWidth;
var currentPageOrientation = this.getCurrentPage().pageSize.orientation;
var pageSize = getPageSize(this.getCurrentPage(), pageOrientation);
this.addPage(pageSize);
if (currentPageOrientation === pageSize.orientation) {
this.availableWidth = currentAvailableWidth;
}
} else {
this.page = nextPageIndex;
this.initializePage();
}
return {
newPageCreated: createNewPage,
prevPage: prevPage,
prevY: prevY,
y: this.y
};
};
DocumentContext.prototype.addPage = function (pageSize) {
var page = { items: [], pageSize: pageSize };
this.pages.push(page);
this.backgroundLength.push(0);
this.page = this.pages.length - 1;
this.initializePage();
this.tracker.emit('pageAdded');
return page;
};
DocumentContext.prototype.getCurrentPage = function () {
if (this.page < 0 || this.page >= this.pages.length) {
return null;
}
return this.pages[this.page];
};
DocumentContext.prototype.getCurrentPosition = function () {
var pageSize = this.getCurrentPage().pageSize;
var innerHeight = pageSize.height - this.pageMargins.top - this.pageMargins.bottom;
var innerWidth = pageSize.width - this.pageMargins.left - this.pageMargins.right;
return {
pageNumber: this.page + 1,
pageOrientation: pageSize.orientation,
pageInnerHeight: innerHeight,
pageInnerWidth: innerWidth,
left: this.x,
top: this.y,
verticalRatio: ((this.y - this.pageMargins.top) / innerHeight),
horizontalRatio: ((this.x - this.pageMargins.left) / innerWidth)
};
};
function bottomMostContext(c1, c2) {
var r;
if (c1.page > c2.page) {
r = c1;
} else if (c2.page > c1.page) {
r = c2;
} else {
r = (c1.y > c2.y) ? c1 : c2;
}
return {
page: r.page,
x: r.x,
y: r.y,
availableHeight: r.availableHeight,
availableWidth: r.availableWidth
};
}
module.exports = DocumentContext;