Skip to content

Commit

Permalink
Repeat thead and tfoot when table contains page breaks.
Browse files Browse the repository at this point in the history
This was already done in ariya#211
but somehow got lost when the Qt source tree was imported.

Note that I even improved this patch a bit to also properly repaint
the borders of cells in thead/tfoot.

http://code.google.com/p/phantomjs/issues/detail?id=615
  • Loading branch information
milianw committed Nov 22, 2012
1 parent 5c87852 commit 2d778f6
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -302,11 +302,20 @@ void RenderTable::layout()

bool collapsing = collapseBorders();

// repeat header and footer on each page
int headHeight = 0;
int footHeight = 0;
for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
if (child->isTableSection()) {
child->layoutIfNeeded();
RenderTableSection* section = toRenderTableSection(child);
totalSectionLogicalHeight += section->calcRowLogicalHeight();
int rowHeight = section->calcRowLogicalHeight();
if (child == m_head) {
headHeight = rowHeight;
} else if (child == m_foot) {
footHeight = rowHeight;
}
totalSectionLogicalHeight += rowHeight;
if (collapsing)
section->recalcOuterBorder();
ASSERT(!section->needsLayout());
Expand Down Expand Up @@ -355,7 +364,7 @@ void RenderTable::layout()
for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
if (child->isTableSection())
// FIXME: Distribute extra height between all table body sections instead of giving it all to the first one.
toRenderTableSection(child)->layoutRows(child == m_firstBody ? max(0, computedLogicalHeight - totalSectionLogicalHeight) : 0);
toRenderTableSection(child)->layoutRows(child == m_firstBody ? max(0, computedLogicalHeight - totalSectionLogicalHeight) : 0, headHeight, footHeight);
}

if (!m_firstBody && computedLogicalHeight > totalSectionLogicalHeight && !document()->inQuirksMode()) {
Expand Down Expand Up @@ -503,7 +512,59 @@ void RenderTable::paintObject(PaintInfo& paintInfo, int tx, int ty)
child->paint(info, childPoint.x(), childPoint.y());
}
}


bool repaintedHead = false;
IntPoint repaintedHeadPoint;
bool repaintedFoot = false;
IntPoint repaintedFootPoint;
if (view()->pageLogicalHeight()) {
// re-paint header/footer if table is split over multiple pages
if (m_head) {
IntPoint childPoint = flipForWritingMode(m_head, IntPoint(tx, ty), ParentToChildFlippingAdjustment);
if (!info.rect.contains(childPoint.x() + m_head->x(), childPoint.y() + m_head->y())) {
repaintedHeadPoint = IntPoint(childPoint.x(), info.rect.y() - m_head->y());
repaintedHead = true;
dynamic_cast<RenderObject*>(m_head)->paint(info, repaintedHeadPoint.x(), repaintedHeadPoint.y());
}
}
if (m_foot) {
IntPoint childPoint = flipForWritingMode(m_foot, IntPoint(tx, ty), ParentToChildFlippingAdjustment);
if (!info.rect.contains(childPoint.x() + m_foot->x(), childPoint.y() + m_foot->y())) {
// find actual end of table on current page
int dy = 0;
const int max_dy = info.rect.y() + info.rect.height();
const int vspace = vBorderSpacing();
for (RenderObject* section = firstChild(); section; section = section->nextSibling()) {
if (section->isTableSection()) {
if (toRenderBox(section)->y() > max_dy) {
continue;
}
int i = 0;
for(RenderObject* row = section->firstChild(); row; row = row->nextSibling()) {
if (!row->isTableRow()) {
continue;
}
// get actual bottom-y position of this row - pretty complicated, how could this be simplified?
// note how we have to take the rowPoint and section's y-offset into account, see e.g.
// RenderTableSection::paint where this is also done...
IntPoint rowPoint = flipForWritingMode(toRenderBox(row), IntPoint(tx, ty), ParentToChildFlippingAdjustment);
int row_dy = rowPoint.y() + toRenderBox(row)->y() + toRenderBox(row)->logicalHeight() + toRenderBox(section)->y();
if (row_dy < max_dy && row_dy > dy) {
dy = row_dy;
} else if (row_dy > max_dy) {
break;
}
i++;
}
}
}
repaintedFoot = true;
repaintedFootPoint = IntPoint(childPoint.x(), dy - m_foot->y());
dynamic_cast<RenderObject*>(m_foot)->paint(info, repaintedFootPoint.x(), repaintedFootPoint.y());
}
}
}

if (collapseBorders() && paintPhase == PaintPhaseChildBlockBackground && style()->visibility() == VISIBLE) {
// Collect all the unique border styles that we want to paint in a sorted list. Once we
// have all the styles sorted, we then do individual passes, painting each style of border
Expand All @@ -522,6 +583,12 @@ void RenderTable::paintObject(PaintInfo& paintInfo, int tx, int ty)
for (RenderObject* child = firstChild(); child; child = child->nextSibling())
if (child->isTableSection()) {
IntPoint childPoint = flipForWritingMode(toRenderTableSection(child), IntPoint(tx, ty), ParentToChildFlippingAdjustment);
// also repaint borders of header/footer if required
if (child == m_head && repaintedHead) {
childPoint = repaintedHeadPoint;
} else if (child == m_foot && repaintedFoot) {
childPoint = repaintedFootPoint;
}
child->paint(info, childPoint.x(), childPoint.y());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ void RenderTableSection::layout()
setNeedsLayout(false);
}

int RenderTableSection::layoutRows(int toAdd)
int RenderTableSection::layoutRows(int toAdd, int headHeight, int footHeight)
{
#ifndef NDEBUG
setNeedsLayoutIsForbidden(true);
Expand Down Expand Up @@ -506,13 +506,13 @@ int RenderTableSection::layoutRows(int toAdd)
logicalHeightsForPrinting[r] = childLogicalHeight;
LayoutState* layoutState = view()->layoutState();
const int pageLogicalHeight = layoutState->m_pageLogicalHeight;
if (childLogicalHeight < pageLogicalHeight) {
if (childLogicalHeight < pageLogicalHeight - footHeight) {
const IntSize delta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
const int logicalOffset = m_rowPos[r] + pageOffset;
const int offset = isHorizontalWritingMode() ? delta.height() : delta.width();
const int remainingLogicalHeight = (pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight) % pageLogicalHeight;
if (remainingLogicalHeight < childLogicalHeight) {
pageOffset += remainingLogicalHeight;
if (remainingLogicalHeight - footHeight < childLogicalHeight) {
pageOffset += remainingLogicalHeight + headHeight;
}
}
m_rowPos[r] += pageOffset;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class RenderTableSection : public RenderBox {

void setCellLogicalWidths();
int calcRowLogicalHeight();
int layoutRows(int logicalHeight);
int layoutRows(int logicalHeight, int headHeight, int footHeight);

RenderTable* table() const { return toRenderTable(parent()); }

Expand Down

0 comments on commit 2d778f6

Please sign in to comment.