Show More
Commit Description:
use uuid cookie
Commit Description:
use uuid cookie
References:
File last commit:
Show/Diff file:
Action:
node_modules/pdfmake/src/elementWriter.js
| 322 lines
| 7.8 KiB
| application/javascript
| JavascriptLexer
|
r789 | 'use strict'; | |||
var Line = require('./line'); | ||||
var isNumber = require('./helpers').isNumber; | ||||
var pack = require('./helpers').pack; | ||||
var offsetVector = require('./helpers').offsetVector; | ||||
var DocumentContext = require('./documentContext'); | ||||
/** | ||||
* Creates an instance of ElementWriter - a line/vector writer, which adds | ||||
* elements to current page and sets their positions based on the context | ||||
*/ | ||||
function ElementWriter(context, tracker) { | ||||
this.context = context; | ||||
this.contextStack = []; | ||||
this.tracker = tracker; | ||||
} | ||||
function addPageItem(page, item, index) { | ||||
if (index === null || index === undefined || index < 0 || index > page.items.length) { | ||||
page.items.push(item); | ||||
} else { | ||||
page.items.splice(index, 0, item); | ||||
} | ||||
} | ||||
ElementWriter.prototype.addLine = function (line, dontUpdateContextPosition, index) { | ||||
var height = line.getHeight(); | ||||
var context = this.context; | ||||
var page = context.getCurrentPage(), | ||||
position = this.getCurrentPositionOnPage(); | ||||
if (context.availableHeight < height || !page) { | ||||
return false; | ||||
} | ||||
line.x = context.x + (line.x || 0); | ||||
line.y = context.y + (line.y || 0); | ||||
this.alignLine(line); | ||||
addPageItem(page, { | ||||
type: 'line', | ||||
item: line | ||||
}, index); | ||||
this.tracker.emit('lineAdded', line); | ||||
if (!dontUpdateContextPosition) { | ||||
context.moveDown(height); | ||||
} | ||||
return position; | ||||
}; | ||||
ElementWriter.prototype.alignLine = function (line) { | ||||
var width = this.context.availableWidth; | ||||
var lineWidth = line.getWidth(); | ||||
var alignment = line.inlines && line.inlines.length > 0 && line.inlines[0].alignment; | ||||
var offset = 0; | ||||
switch (alignment) { | ||||
case 'right': | ||||
offset = width - lineWidth; | ||||
break; | ||||
case 'center': | ||||
offset = (width - lineWidth) / 2; | ||||
break; | ||||
} | ||||
if (offset) { | ||||
line.x = (line.x || 0) + offset; | ||||
} | ||||
if (alignment === 'justify' && | ||||
!line.newLineForced && | ||||
!line.lastLineInParagraph && | ||||
line.inlines.length > 1) { | ||||
var additionalSpacing = (width - lineWidth) / (line.inlines.length - 1); | ||||
for (var i = 1, l = line.inlines.length; i < l; i++) { | ||||
offset = i * additionalSpacing; | ||||
line.inlines[i].x += offset; | ||||
line.inlines[i].justifyShift = additionalSpacing; | ||||
} | ||||
} | ||||
}; | ||||
ElementWriter.prototype.addImage = function (image, index, type) { | ||||
var context = this.context; | ||||
var page = context.getCurrentPage(), | ||||
position = this.getCurrentPositionOnPage(); | ||||
if (!page || (image.absolutePosition === undefined && context.availableHeight < image._height && page.items.length > 0)) { | ||||
return false; | ||||
} | ||||
if (image._x === undefined) { | ||||
image._x = image.x || 0; | ||||
} | ||||
image.x = context.x + image._x; | ||||
image.y = context.y; | ||||
this.alignImage(image); | ||||
addPageItem(page, { | ||||
type: type || 'image', | ||||
item: image | ||||
}, index); | ||||
context.moveDown(image._height); | ||||
return position; | ||||
}; | ||||
ElementWriter.prototype.addSVG = function (image, index) { | ||||
return this.addImage(image, index, 'svg') | ||||
}; | ||||
ElementWriter.prototype.addQr = function (qr, index) { | ||||
var context = this.context; | ||||
var page = context.getCurrentPage(), | ||||
position = this.getCurrentPositionOnPage(); | ||||
if (!page || (qr.absolutePosition === undefined && context.availableHeight < qr._height)) { | ||||
return false; | ||||
} | ||||
if (qr._x === undefined) { | ||||
qr._x = qr.x || 0; | ||||
} | ||||
qr.x = context.x + qr._x; | ||||
qr.y = context.y; | ||||
this.alignImage(qr); | ||||
for (var i = 0, l = qr._canvas.length; i < l; i++) { | ||||
var vector = qr._canvas[i]; | ||||
vector.x += qr.x; | ||||
vector.y += qr.y; | ||||
this.addVector(vector, true, true, index); | ||||
} | ||||
context.moveDown(qr._height); | ||||
return position; | ||||
}; | ||||
ElementWriter.prototype.alignImage = function (image) { | ||||
var width = this.context.availableWidth; | ||||
var imageWidth = image._minWidth; | ||||
var offset = 0; | ||||
switch (image._alignment) { | ||||
case 'right': | ||||
offset = width - imageWidth; | ||||
break; | ||||
case 'center': | ||||
offset = (width - imageWidth) / 2; | ||||
break; | ||||
} | ||||
if (offset) { | ||||
image.x = (image.x || 0) + offset; | ||||
} | ||||
}; | ||||
ElementWriter.prototype.alignCanvas = function (node) { | ||||
var width = this.context.availableWidth; | ||||
var canvasWidth = node._minWidth; | ||||
var offset = 0; | ||||
switch (node._alignment) { | ||||
case 'right': | ||||
offset = width - canvasWidth; | ||||
break; | ||||
case 'center': | ||||
offset = (width - canvasWidth) / 2; | ||||
break; | ||||
} | ||||
if (offset) { | ||||
node.canvas.forEach(function (vector) { | ||||
offsetVector(vector, offset, 0); | ||||
}); | ||||
} | ||||
}; | ||||
ElementWriter.prototype.addVector = function (vector, ignoreContextX, ignoreContextY, index) { | ||||
var context = this.context; | ||||
var page = context.getCurrentPage(), | ||||
position = this.getCurrentPositionOnPage(); | ||||
if (page) { | ||||
offsetVector(vector, ignoreContextX ? 0 : context.x, ignoreContextY ? 0 : context.y); | ||||
addPageItem(page, { | ||||
type: 'vector', | ||||
item: vector | ||||
}, index); | ||||
return position; | ||||
} | ||||
}; | ||||
ElementWriter.prototype.beginClip = function (width, height) { | ||||
var ctx = this.context; | ||||
var page = ctx.getCurrentPage(); | ||||
page.items.push({ | ||||
type: 'beginClip', | ||||
item: { x: ctx.x, y: ctx.y, width: width, height: height } | ||||
}); | ||||
return true; | ||||
}; | ||||
ElementWriter.prototype.endClip = function () { | ||||
var ctx = this.context; | ||||
var page = ctx.getCurrentPage(); | ||||
page.items.push({ | ||||
type: 'endClip' | ||||
}); | ||||
return true; | ||||
}; | ||||
function cloneLine(line) { | ||||
var result = new Line(line.maxWidth); | ||||
for (var key in line) { | ||||
if (line.hasOwnProperty(key)) { | ||||
result[key] = line[key]; | ||||
} | ||||
} | ||||
return result; | ||||
} | ||||
ElementWriter.prototype.addFragment = function (block, useBlockXOffset, useBlockYOffset, dontUpdateContextPosition) { | ||||
var ctx = this.context; | ||||
var page = ctx.getCurrentPage(); | ||||
if (!useBlockXOffset && block.height > ctx.availableHeight) { | ||||
return false; | ||||
} | ||||
block.items.forEach(function (item) { | ||||
switch (item.type) { | ||||
case 'line': | ||||
var l = cloneLine(item.item); | ||||
if (l._node) { | ||||
l._node.positions[0].pageNumber = ctx.page + 1; | ||||
} | ||||
l.x = (l.x || 0) + (useBlockXOffset ? (block.xOffset || 0) : ctx.x); | ||||
l.y = (l.y || 0) + (useBlockYOffset ? (block.yOffset || 0) : ctx.y); | ||||
page.items.push({ | ||||
type: 'line', | ||||
item: l | ||||
}); | ||||
break; | ||||
case 'vector': | ||||
var v = pack(item.item); | ||||
offsetVector(v, useBlockXOffset ? (block.xOffset || 0) : ctx.x, useBlockYOffset ? (block.yOffset || 0) : ctx.y); | ||||
page.items.push({ | ||||
type: 'vector', | ||||
item: v | ||||
}); | ||||
break; | ||||
case 'image': | ||||
case 'svg': | ||||
var img = pack(item.item); | ||||
img.x = (img.x || 0) + (useBlockXOffset ? (block.xOffset || 0) : ctx.x); | ||||
img.y = (img.y || 0) + (useBlockYOffset ? (block.yOffset || 0) : ctx.y); | ||||
page.items.push({ | ||||
type: item.type, | ||||
item: img | ||||
}); | ||||
break; | ||||
} | ||||
}); | ||||
if (!dontUpdateContextPosition) { | ||||
ctx.moveDown(block.height); | ||||
} | ||||
return true; | ||||
}; | ||||
/** | ||||
* Pushes the provided context onto the stack or creates a new one | ||||
* | ||||
* pushContext(context) - pushes the provided context and makes it current | ||||
* pushContext(width, height) - creates and pushes a new context with the specified width and height | ||||
* pushContext() - creates a new context for unbreakable blocks (with current availableWidth and full-page-height) | ||||
*/ | ||||
ElementWriter.prototype.pushContext = function (contextOrWidth, height) { | ||||
if (contextOrWidth === undefined) { | ||||
height = this.context.getCurrentPage().height - this.context.pageMargins.top - this.context.pageMargins.bottom; | ||||
contextOrWidth = this.context.availableWidth; | ||||
} | ||||
if (isNumber(contextOrWidth)) { | ||||
contextOrWidth = new DocumentContext({ width: contextOrWidth, height: height }, { left: 0, right: 0, top: 0, bottom: 0 }); | ||||
} | ||||
this.contextStack.push(this.context); | ||||
this.context = contextOrWidth; | ||||
}; | ||||
ElementWriter.prototype.popContext = function () { | ||||
this.context = this.contextStack.pop(); | ||||
}; | ||||
ElementWriter.prototype.getCurrentPositionOnPage = function () { | ||||
return (this.contextStack[0] || this.context).getCurrentPosition(); | ||||
}; | ||||
module.exports = ElementWriter; | ||||