diff --git a/qtwebkit/Source/WebCore/page/FrameView.h b/qtwebkit/Source/WebCore/page/FrameView.h index be1512ee6..5ada41450 100644 --- a/qtwebkit/Source/WebCore/page/FrameView.h +++ b/qtwebkit/Source/WebCore/page/FrameView.h @@ -437,6 +437,9 @@ public: void setScrollPinningBehavior(ScrollPinningBehavior); + //Enable or disable repeated thead/tfoot. + bool repeatTableHeader; + bool repeatTableFooter; protected: virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect); virtual void scrollContentsSlowPath(const IntRect& updateRect); diff --git a/qtwebkit/Source/WebCore/page/PrintContext.h b/qtwebkit/Source/WebCore/page/PrintContext.h index aeacb8cf8..0d25bf5b4 100644 --- a/qtwebkit/Source/WebCore/page/PrintContext.h +++ b/qtwebkit/Source/WebCore/page/PrintContext.h @@ -81,10 +81,9 @@ public: // The height of the graphics context should be // (pageSizeInPixels.height() + 1) * number-of-pages - 1 static void spoolAllPagesWithBoundaries(Frame*, GraphicsContext&, const FloatSize& pageSizeInPixels); - + Vector m_pageRects; protected: Frame* m_frame; - Vector m_pageRects; private: void computePageRectsWithPageSizeInternal(const FloatSize& pageSizeInPixels, bool allowHorizontalTiling); diff --git a/qtwebkit/Source/WebCore/rendering/RenderTable.cpp b/qtwebkit/Source/WebCore/rendering/RenderTable.cpp index 336b6c995..c233ee04c 100644 --- a/qtwebkit/Source/WebCore/rendering/RenderTable.cpp +++ b/qtwebkit/Source/WebCore/rendering/RenderTable.cpp @@ -431,7 +431,8 @@ void RenderTable::layout() oldTableLogicalTop += m_captions[i]->logicalHeight() + m_captions[i]->marginBefore() + m_captions[i]->marginAfter(); bool collapsing = collapseBorders(); - + int headHeight = 0; + int footHeight = 0; for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if (child->isTableSection()) { RenderTableSection* section = toRenderTableSection(child); @@ -439,6 +440,14 @@ void RenderTable::layout() section->setChildNeedsLayout(true, MarkOnlyThis); section->layoutIfNeeded(); totalSectionLogicalHeight += section->calcRowLogicalHeight(); + int rowHeight = section->calcRowLogicalHeight(); + if (child == m_head && view()->repeatTableHeader) { + headHeight = rowHeight; + } + else if (child == m_foot && view()->repeatTableFooter) { + footHeight = rowHeight; + } + totalSectionLogicalHeight += rowHeight; if (collapsing) section->recalcOuterBorder(); ASSERT(!section->needsLayout()); @@ -496,7 +505,12 @@ void RenderTable::layout() distributeExtraLogicalHeight(floorToInt(computedLogicalHeight - totalSectionLogicalHeight)); for (RenderTableSection* section = topSection(); section; section = sectionBelow(section)) - section->layoutRows(); + { + LayoutUnit height = computedLogicalHeight - totalSectionLogicalHeight; + LayoutUnit First = 0; + height = max(First, height); + section->layoutRows(section == m_firstBody ? height : 0, headHeight, footHeight); + } if (!topSection() && computedLogicalHeight > totalSectionLogicalHeight && !document()->inQuirksMode()) { // Completely empty tables (with no sections or anything) should at least honor specified height @@ -655,6 +669,10 @@ void RenderTable::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffs PaintInfo info(paintInfo); info.phase = paintPhase; info.updateSubtreePaintRootForChildren(this); + bool repaintedHead = false; + IntPoint repaintedHeadPoint; + bool repaintedFoot = false; + IntPoint repaintedFootPoint; for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && (child->isTableSection() || child->isTableCaption())) { @@ -662,7 +680,64 @@ void RenderTable::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffs child->paint(info, childPoint); } } + if (view()->pageLogicalHeight()) { + // re-paint header/footer if table is split over multiple pages + if (m_head && view()->repeatTableHeader) { + LayoutPoint childPoint = flipForWritingModeForChild(m_head, paintOffset); + 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(m_head)->paint(info, repaintedHeadPoint); + } + } + if (m_foot && view()->repeatTableFooter) { + LayoutPoint childPoint = flipForWritingModeForChild(m_foot, paintOffset); + 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... + LayoutPoint rowPoint = flipForWritingModeForChild(toRenderBox(row), paintOffset); + 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(m_foot)->paint(info, repaintedFootPoint); + + } + + } + + } if (collapseBorders() && paintPhase == PaintPhaseChildBlockBackground && style()->visibility() == VISIBLE) { recalcCollapsedBorders(); // Using our cached sorted styles, we then do individual passes, @@ -673,6 +748,15 @@ void RenderTable::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffs m_currentBorder = &m_collapsedBorders[i]; for (RenderTableSection* section = bottomSection(); section; section = sectionAbove(section)) { LayoutPoint childPoint = flipForWritingModeForChild(section, paintOffset); + // also repaint borders of header/footer if required + if (section == m_head && repaintedHead) { + childPoint = repaintedHeadPoint; + + } + else if (section == m_foot && repaintedFoot) { + childPoint = repaintedFootPoint; + + } section->paint(info, childPoint); } } diff --git a/qtwebkit/Source/WebCore/rendering/RenderTableSection.cpp b/qtwebkit/Source/WebCore/rendering/RenderTableSection.cpp index a415af583..d3c9b05e5 100644 --- a/qtwebkit/Source/WebCore/rendering/RenderTableSection.cpp +++ b/qtwebkit/Source/WebCore/rendering/RenderTableSection.cpp @@ -503,7 +503,7 @@ int RenderTableSection::distributeExtraLogicalHeightToRows(int extraLogicalHeigh return extraLogicalHeight - remainingExtraLogicalHeight; } -void RenderTableSection::layoutRows() +int RenderTableSection::layoutRows(int toAdd, int headHeight, int footHeight) { #ifndef NDEBUG SetLayoutNeededForbiddenScope layoutForbiddenScope(this); @@ -522,12 +522,41 @@ void RenderTableSection::layoutRows() LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasTransform() || style()->isFlippedBlocksWritingMode()); + WTF::Vector logicalHeightsForPrinting; + // make sure that rows do not overlap a page break + if (view()->layoutState()->pageLogicalHeight()) { + logicalHeightsForPrinting.resize(totalRows); + int pageOffset = 0; + for (int r = 0; r < totalRows; ++r) { + const int childLogicalHeight = m_rowPos[r + 1] - m_rowPos[r] - (m_grid[r].rowRenderer ? vspacing : 0); + logicalHeightsForPrinting[r] = childLogicalHeight; + LayoutState* layoutState = view()->layoutState(); + const int pageLogicalHeight = layoutState->m_pageLogicalHeight; + + if (childLogicalHeight < pageLogicalHeight - footHeight) { + const LayoutSize 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 - footHeight< childLogicalHeight) { + pageOffset += remainingLogicalHeight + headHeight; + } + } + m_rowPos[r] += pageOffset; + } + m_rowPos[totalRows] += pageOffset; + } for (unsigned r = 0; r < totalRows; r++) { // Set the row's x/y position and width/height. if (RenderTableRow* rowRenderer = m_grid[r].rowRenderer) { rowRenderer->setLocation(LayoutPoint(0, m_rowPos[r])); rowRenderer->setLogicalWidth(logicalWidth()); + if (view()->layoutState()->pageLogicalHeight()) { + rowRenderer->setLogicalHeight(logicalHeightsForPrinting[r]); + } + else { rowRenderer->setLogicalHeight(m_rowPos[r + 1] - m_rowPos[r] - vspacing); + } rowRenderer->updateLayerTransform(); } @@ -541,8 +570,13 @@ void RenderTableSection::layoutRows() continue; int rowIndex = cell->rowIndex(); - int rHeight = m_rowPos[rowIndex + cell->rowSpan()] - m_rowPos[rowIndex] - vspacing; - + int rHeight; + if (view()->layoutState()->pageLogicalHeight() && cell->rowSpan() == 1) { + rHeight = logicalHeightsForPrinting[rowIndex]; + } + else { + rHeight = m_rowPos[rowIndex + cell->rowSpan()] - m_rowPos[rowIndex] - vspacing; + } // Force percent height children to lay themselves out again. // This will cause these children to grow to fill the cell. // FIXME: There is still more work to do here to fully match WinIE (should @@ -656,6 +690,7 @@ void RenderTableSection::layoutRows() computeOverflowFromCells(totalRows, nEffCols); statePusher.pop(); + return height(); } void RenderTableSection::computeOverflowFromCells() diff --git a/qtwebkit/Source/WebCore/rendering/RenderTableSection.h b/qtwebkit/Source/WebCore/rendering/RenderTableSection.h index 1e14b9a26..335bb5b90 100644 --- a/qtwebkit/Source/WebCore/rendering/RenderTableSection.h +++ b/qtwebkit/Source/WebCore/rendering/RenderTableSection.h @@ -78,7 +78,7 @@ public: void addCell(RenderTableCell*, RenderTableRow* row); int calcRowLogicalHeight(); - void layoutRows(); + int layoutRows(int, int, int); void computeOverflowFromCells(); RenderTable* table() const { return toRenderTable(parent()); } diff --git a/qtwebkit/Source/WebCore/rendering/RenderView.cpp b/qtwebkit/Source/WebCore/rendering/RenderView.cpp index 251659fc1..4383e4309 100644 --- a/qtwebkit/Source/WebCore/rendering/RenderView.cpp +++ b/qtwebkit/Source/WebCore/rendering/RenderView.cpp @@ -136,6 +136,8 @@ bool RenderView::isChildAllowed(RenderObject* child, RenderStyle*) const void RenderView::layoutContent(const LayoutState& state) { + repeatTableHeader = m_frameView->repeatTableHeader; + repeatTableFooter = m_frameView->repeatTableFooter; UNUSED_PARAM(state); ASSERT(needsLayout()); diff --git a/qtwebkit/Source/WebCore/rendering/RenderView.h b/qtwebkit/Source/WebCore/rendering/RenderView.h index 09466dec7..1187bca07 100644 --- a/qtwebkit/Source/WebCore/rendering/RenderView.h +++ b/qtwebkit/Source/WebCore/rendering/RenderView.h @@ -230,6 +230,9 @@ public: IntRect pixelSnappedLayoutOverflowRect() const { return pixelSnappedIntRect(layoutOverflowRect()); } + //Enable or disable repeated thead/tfoot. + bool repeatTableHeader; + bool repeatTableFooter; protected: virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const OVERRIDE; virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE; diff --git a/qtwebkit/Source/WebKit/qt/WebCoreSupport/QWebFrameAdapter.cpp b/qtwebkit/Source/WebKit/qt/WebCoreSupport/QWebFrameAdapter.cpp index 6f7b8fc55..c4e272b11 100644 --- a/qtwebkit/Source/WebKit/qt/WebCoreSupport/QWebFrameAdapter.cpp +++ b/qtwebkit/Source/WebKit/qt/WebCoreSupport/QWebFrameAdapter.cpp @@ -981,6 +981,8 @@ void QWebFrameAdapter::setViewportSize(const QSize& size) ASSERT(view); view->resize(size); view->adjustViewSize(); + view->repeatTableHeader = repeatTableHeader; + view->repeatTableFooter = repeatTableFooter; PrintContext printer(frame); printer.setViewportToPdf(size); diff --git a/qtwebkit/Source/WebKit/qt/WebCoreSupport/QWebFrameAdapter.h b/qtwebkit/Source/WebKit/qt/WebCoreSupport/QWebFrameAdapter.h index 463285324..58c5423c9 100644 --- a/qtwebkit/Source/WebKit/qt/WebCoreSupport/QWebFrameAdapter.h +++ b/qtwebkit/Source/WebKit/qt/WebCoreSupport/QWebFrameAdapter.h @@ -226,6 +226,9 @@ public: QWebPageAdapter* pageAdapter; + bool repeatTableHeader; + bool repeatTableFooter; + // protected: bool allowsScrolling; int marginWidth; diff --git a/qtwebkit/Source/WebKit/qt/WebCoreSupport/QtPrintContext.cpp b/qtwebkit/Source/WebKit/qt/WebCoreSupport/QtPrintContext.cpp index acffaa576..d4b66738a 100644 --- a/qtwebkit/Source/WebKit/qt/WebCoreSupport/QtPrintContext.cpp +++ b/qtwebkit/Source/WebKit/qt/WebCoreSupport/QtPrintContext.cpp @@ -47,19 +47,24 @@ QtPrintContext::QtPrintContext(QPainter* painter, const QRect& pageRect, QWebFra { m_printContext->setElementToDraw(element); renderElement = element; - totalPageLayoutSize = m_printContext->begin(pageRect.width(), pageRect.height()); + float pageHeight = 0; + m_printContext->computePageRects(IntRect(pageRect), /* headerHeight 26*/ 0, /* footerHeight 26*/ 0, /* userScaleFactor */ 1.0, pageHeight); + IntRect tempRect = m_printContext->m_pageRects[0]; + totalPageLayoutSize = m_printContext->begin(tempRect.width(), tempRect.height()); + m_printContext->computePageRects(IntRect(pageRect), /* headerHeight 26*/ 0, /* footerHeight 26*/ 0, /* userScaleFactor */ 1.0, pageHeight); printStatus = true; - float pageHeight = 0; - m_printContext->computePageRects(IntRect(pageRect), /* headerHeight */ 0, /* footerHeight */ 0, /* userScaleFactor */ 1.0, pageHeight); + } QtPrintContext::QtPrintContext(QPainter* painter, const QRect& pageRect, QWebFrameAdapter* frameAdapter, bool status) : m_graphicsContext(new GraphicsContext(painter)) , m_printContext(new PrintContext(frameAdapter->frame)) { - totalPageLayoutSize = m_printContext->begin(pageRect.width(), pageRect.height()); - printStatus = status; float pageHeight = 0; m_printContext->computePageRects(IntRect(pageRect), /* headerHeight */ 0, /* footerHeight */ 0, /* userScaleFactor */ 1.0, pageHeight); + IntRect tempRect = m_printContext->m_pageRects[0]; + totalPageLayoutSize = m_printContext->begin(tempRect.width(), tempRect.height()); + printStatus = status; + m_printContext->computePageRects(IntRect(pageRect), /* headerHeight */0, /* footerHeight */ 0, /* userScaleFactor */ 1.0, pageHeight); } QtPrintContext::QtPrintContext(QPainter* painter, QWebFrameAdapter* frameAdapter) { diff --git a/qtwebkit/Source/WebKit/qt/WidgetApi/qwebpage.cpp b/qtwebkit/Source/WebKit/qt/WidgetApi/qwebpage.cpp index 02bddebda..cffc393a6 100644 --- a/qtwebkit/Source/WebKit/qt/WidgetApi/qwebpage.cpp +++ b/qtwebkit/Source/WebKit/qt/WidgetApi/qwebpage.cpp @@ -1996,6 +1996,15 @@ QSize QWebPage::viewportSize() const \sa QWebFrame::render(), preferredContentsSize */ +void QWebPage::EnableRepeatedHeaderFooter(bool header,bool footer) +{ + QWebFrameAdapter* mainFrame = d->mainFrameAdapter(); + if (!mainFrame->hasView()) + return; + mainFrame->repeatTableHeader = header; + mainFrame->repeatTableFooter = footer; +} + void QWebPage::setViewportSize(const QSize &size) const { d->m_viewportSize = size; diff --git a/qtwebkit/Source/WebKit/qt/WidgetApi/qwebpage.h b/qtwebkit/Source/WebKit/qt/WidgetApi/qwebpage.h index 24fe1383e..ee86c496c 100644 --- a/qtwebkit/Source/WebKit/qt/WidgetApi/qwebpage.h +++ b/qtwebkit/Source/WebKit/qt/WidgetApi/qwebpage.h @@ -306,6 +306,7 @@ public: QSize viewportSize() const; void setViewportSize(const QSize &size) const; + void EnableRepeatedHeaderFooter(bool,bool); ViewportAttributes viewportAttributesForSize(const QSize& availableSize) const; QSize preferredContentsSize() const;