Skip to content

Commit

Permalink
Vertical alignment for table cells (bpampuch#74, bpampuch#505).
Browse files Browse the repository at this point in the history
  • Loading branch information
jaka committed May 23, 2016
1 parent 57f0bc0 commit 93263dd
Show file tree
Hide file tree
Showing 8 changed files with 254 additions and 52 deletions.
145 changes: 123 additions & 22 deletions build/pdfmake.js
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,6 @@
}

var pages = builder.layoutDocument(docDefinition.content, this.fontProvider, docDefinition.styles || {}, docDefinition.defaultStyle || { fontSize: 12, font: 'Roboto' }, docDefinition.background, docDefinition.header, docDefinition.footer, docDefinition.images, docDefinition.watermark, docDefinition.pageBreakBefore);

renderPages(pages, this.fontProvider, this.pdfKitDoc);

if(options.autoPrint){
Expand Down Expand Up @@ -480,7 +479,13 @@
break;
case 'endClip':
endClip(pdfKitDoc);
break
break;
case 'beginVerticalAlign':
beginVerticalAlign(item.item, pdfKitDoc);
break;
case 'endVerticalAlign':
endVerticalAlign(item.item, pdfKitDoc);
break;
}
}
if(page.watermark){
Expand All @@ -501,6 +506,28 @@
pdfKitDoc.restore();
}

function beginVerticalAlign(item, pdfKitDoc) {
switch(item.verticalAlign) {
case 'center':
pdfKitDoc.save();
pdfKitDoc.translate(0, -(item.nodeHeight - item.viewHeight) / 2);
break;
case 'bottom':
pdfKitDoc.save();
pdfKitDoc.translate(0, -(item.nodeHeight - item.viewHeight));
break;
}
}

function endVerticalAlign(item, pdfKitDoc) {
switch(item.verticalAlign) {
case 'center':
case 'bottom':
pdfKitDoc.restore();
break;
}
}

function renderLine(line, x, y, pdfKitDoc) {
x = x || 0;
y = y || 0;
Expand Down Expand Up @@ -13251,6 +13278,7 @@
this.tracker = new TraversalTracker();
this.imageMeasure = imageMeasure;
this.tableLayouts = {};
this.verticalAlignItemStack = [];
}

LayoutBuilder.prototype.registerTableLayouts = function (tableLayouts) {
Expand Down Expand Up @@ -13354,6 +13382,7 @@

this.addBackground(background);
this.processNode(docStructure);

this.addHeadersAndFooters(header, footer);
/* jshint eqnull:true */
if(watermark != null)
Expand Down Expand Up @@ -13433,11 +13462,11 @@
if (typeof watermark === 'string') {
watermark = {'text': watermark};
}

if (!watermark.text) { // empty watermark text
return;
}

watermark.font = watermark.font || defaultStyle.font || 'Roboto';
watermark.color = watermark.color || 'black';
watermark.opacity = watermark.opacity || 0.6;
Expand Down Expand Up @@ -13526,7 +13555,12 @@
this.linearNodeList.push(node);
decorateNode(node);

var prevTop = self.writer.context().getCurrentPosition().top;
applyMargins(function() {
if (node.verticalAlign) {
var verticalAlignBegin = self.writer.beginVerticalAlign(node.verticalAlign);
}

var absPosition = node.absolutePosition;
if(absPosition){
self.writer.context().beginDetachedBlock();
Expand Down Expand Up @@ -13558,7 +13592,13 @@
if(absPosition){
self.writer.context().endDetachedBlock();
}

if (node.verticalAlign) {
self.verticalAlignItemStack.push({ begin: verticalAlignBegin, end: self.writer.endVerticalAlign(node.verticalAlign) });
}
});
// TODO: ugly; does not work (at least) when page break in node
node._height = self.writer.context().getCurrentPosition().top - prevTop;

function applyMargins(callback) {
var margin = node._margin;
Expand Down Expand Up @@ -13632,10 +13672,13 @@

self.writer.context().beginColumnGroup();

var verticalAlignCols = {};

for(var i = 0, l = columns.length; i < l; i++) {
var column = columns[i];
var width = widths[i]._calcWidth;
var leftOffset = colLeftOffset(i);
var colI = i;

if (column.colSpan && column.colSpan > 1) {
for(var j = 1; j < column.colSpan; j++) {
Expand All @@ -13646,12 +13689,18 @@
self.writer.context().beginColumn(width, leftOffset, getEndingCell(column, i));
if (!column._span) {
if (height) {
self.writer.beginClip(width, height);
var lastClipItem = self.writer.beginClip(width, height);
}
self.processNode(column);
verticalAlignCols[colI] = self.verticalAlignItemStack.length - 1;
addAll(positions, column.positions);
if (height) {
self.writer.endClip();
if (column._height > height) {
self.writer.endClip();
} else {
// optimize by removing unnecessary clipping; this is ugly
lastClipItem.type = '';
}
}
} else if (column._columnEndingContext) {
// row-span ending
Expand All @@ -13660,6 +13709,16 @@
}

self.writer.context().completeColumnGroup(height);

var rowHeight = self.writer.context().height;
for(var i = 0, l = columns.length; i < l; i++) {
var column = columns[i];
if (!column._span && column.verticalAlign) {
var item = self.verticalAlignItemStack[verticalAlignCols[i]].begin.item;
item.viewHeight = rowHeight;
item.nodeHeight = column._height;
}
}
});

return {pageBreaks: pageBreaks, positions: positions};
Expand Down Expand Up @@ -15906,10 +15965,18 @@

this.endingCell = null;
this.x = saved.x;
this.y = height && (saved.y + height) || saved.bottomMost.y;
this.page = saved.bottomMost.page;
if (height) {
this.y = saved.y + height;
this.page = saved.page;
this.height = height;
this.availableHeight = saved.availableHeight - height;
} else {
this.y = saved.bottomMost.y;
this.page = saved.bottomMost.page;
this.height = saved.bottomMost.y - saved.y;
this.availableHeight = saved.bottomMost.availableHeight;
}
this.availableWidth = saved.availableWidth;
this.availableHeight = saved.bottomMost.availableHeight;
this.lastColumnWidth = saved.lastColumnWidth;
};

Expand Down Expand Up @@ -16145,6 +16212,14 @@
return this.writer.endClip();
};

PageElementWriter.prototype.beginVerticalAlign = function(verticalAlign) {
return this.writer.beginVerticalAlign(verticalAlign);
};

PageElementWriter.prototype.endVerticalAlign = function(verticalAlign) {
return this.writer.endVerticalAlign(verticalAlign);
};

PageElementWriter.prototype.addVector = function(vector, ignoreContextX, ignoreContextY, index) {
return this.writer.addVector(vector, ignoreContextX, ignoreContextY, index);
};
Expand Down Expand Up @@ -16467,14 +16542,16 @@
break;

case 'image':
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);

case 'beginVerticalAlign':
case 'endVerticalAlign':
case 'beginClip':
case 'endClip':
var it = pack(item.item);
it.x = (it.x || 0) + (useBlockXOffset ? (block.xOffset || 0) : ctx.x);
it.y = (it.y || 0) + (useBlockYOffset ? (block.yOffset || 0) : ctx.y);
page.items.push({
type: 'image',
item: img
type: item.type,
item: it
});
break;
}
Expand All @@ -16488,20 +16565,44 @@
ElementWriter.prototype.beginClip = function (width, height) {
var ctx = this.context;
var page = ctx.getCurrentPage();
page.items.push({
var item = {
type: 'beginClip',
item: { x: ctx.x, y: ctx.y, width: width, height: height }
});
return true;
};
page.items.push(item);
return item;
};

ElementWriter.prototype.endClip = function () {
var ctx = this.context;
var page = ctx.getCurrentPage();
page.items.push({
var item = {
type: 'endClip'
});
return true;
};
page.items.push(item);
return item;
};

ElementWriter.prototype.beginVerticalAlign = function (verticalAlign) {
var ctx = this.context;
var page = ctx.getCurrentPage();
var item = {
type: 'beginVerticalAlign',
item: { verticalAlign: verticalAlign }
};
page.items.push(item);
return item;
};

ElementWriter.prototype.endVerticalAlign = function (verticalAlign) {
var ctx = this.context;
var page = ctx.getCurrentPage();
var item = {
type: 'endVerticalAlign',
item: { verticalAlign: verticalAlign }
};
page.items.push(item);
return item;
};

/**
Expand Down
14 changes: 7 additions & 7 deletions build/pdfmake.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/pdfmake.min.js.map

Large diffs are not rendered by default.

14 changes: 11 additions & 3 deletions src/documentContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,18 @@ DocumentContext.prototype.completeColumnGroup = function(height) {

this.endingCell = null;
this.x = saved.x;
this.y = height && (saved.y + height) || saved.bottomMost.y;
this.page = saved.bottomMost.page;
if (height) {
this.y = saved.y + height;
this.page = saved.page;
this.height = height;
this.availableHeight = saved.availableHeight - height;
} else {
this.y = saved.bottomMost.y;
this.page = saved.bottomMost.page;
this.height = saved.bottomMost.y - saved.y;
this.availableHeight = saved.bottomMost.availableHeight;
}
this.availableWidth = saved.availableWidth;
this.availableHeight = saved.bottomMost.availableHeight;
this.lastColumnWidth = saved.lastColumnWidth;
};

Expand Down
52 changes: 39 additions & 13 deletions src/elementWriter.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,14 +210,16 @@ ElementWriter.prototype.addFragment = function (block, useBlockXOffset, useBlock
break;

case 'image':
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);

case 'beginVerticalAlign':
case 'endVerticalAlign':
case 'beginClip':
case 'endClip':
var it = pack(item.item);
it.x = (it.x || 0) + (useBlockXOffset ? (block.xOffset || 0) : ctx.x);
it.y = (it.y || 0) + (useBlockYOffset ? (block.yOffset || 0) : ctx.y);
page.items.push({
type: 'image',
item: img
type: item.type,
item: it
});
break;
}
Expand All @@ -231,20 +233,44 @@ ElementWriter.prototype.addFragment = function (block, useBlockXOffset, useBlock
ElementWriter.prototype.beginClip = function (width, height) {
var ctx = this.context;
var page = ctx.getCurrentPage();
page.items.push({
var item = {
type: 'beginClip',
item: { x: ctx.x, y: ctx.y, width: width, height: height }
});
return true;
};
page.items.push(item);
return item;
};

ElementWriter.prototype.endClip = function () {
var ctx = this.context;
var page = ctx.getCurrentPage();
page.items.push({
var item = {
type: 'endClip'
});
return true;
};
page.items.push(item);
return item;
};

ElementWriter.prototype.beginVerticalAlign = function (verticalAlign) {
var ctx = this.context;
var page = ctx.getCurrentPage();
var item = {
type: 'beginVerticalAlign',
item: { verticalAlign: verticalAlign }
};
page.items.push(item);
return item;
};

ElementWriter.prototype.endVerticalAlign = function (verticalAlign) {
var ctx = this.context;
var page = ctx.getCurrentPage();
var item = {
type: 'endVerticalAlign',
item: { verticalAlign: verticalAlign }
};
page.items.push(item);
return item;
};

/**
Expand Down
Loading

0 comments on commit 93263dd

Please sign in to comment.