<commit_before>From d78182d3a6451522f239ee1ecbb71863eb053792 Mon Sep 17 00:00:00 2001
From: <NAME> <<EMAIL>>
Date: Mon, 6 May 2013 08:01:01 +0400
Subject: [PATCH] Table page-break improvements

Bump tables to the next page if we cannot fit the caption, thead
and first cell on the current page. Ideally this should be checking
the height of all cells in the first row in the same manner as is
done in the table section render but as this is more of a nice to
have I've done the minimal amount of work for now.

We now only layout section rows once each section has been positioned
within the table, and only supply head and foot reservation heights
to the appropriate sections.

When re-drawing the thead and tfoot only do so if the rect we are
painting is explicitly before/after the "original" thead/tfoot
rather than simply outside of its boundaries. This prevents issues
with re-drawing a redundant head when bumping tables to the next page.

Re-work the table section row layout code so that it's a bit more
streamlined. Additionally, to cater for cells spanning multiple rows
we avoid page breaks in the middle of their content. Note that rows
are always bumped to the next page even if their content doesn't
fit on a full page so as to avoid daft situtations like having the
first 1px on the preceeding page.
---
 .../Source/WebCore/rendering/RenderTable.cpp       |   37 +++++++++++----
 .../WebCore/rendering/RenderTableSection.cpp       |   51 +++++++++++--------
 2 files changed, 57 insertions(+), 31 deletions(-)

diff --git a/src/qt/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp b/src/qt/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp
index 94ca61a..bbc9a1c 100644
--- a/src/qt/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp
+++ b/src/qt/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp
@@ -329,6 +329,28 @@ void RenderTable::layout()
     if (m_caption)
         m_caption->layoutIfNeeded();
 
+    // Bump table to next page if we can't fit the caption, thead and first body cell
+    setPaginationStrut(0);
+    if (view()->layoutState()->pageLogicalHeight()) {
+        LayoutState* layoutState = view()->layoutState();
+        const int pageLogicalHeight = layoutState->m_pageLogicalHeight;
+        const int remainingLogicalHeight = pageLogicalHeight - layoutState->pageLogicalOffset(0) % pageLogicalHeight;
+        if (remainingLogicalHeight > 0) {
+            int requiredHeight = headHeight;
+            if (m_caption && m_caption->style()->captionSide() != CAPBOTTOM) {
+                requiredHeight += m_caption->logicalHeight() + m_caption->marginBefore() + m_caption->marginAfter();
+            }
+            if (m_firstBody) {
+                // FIXME: Calculate maximum required height across all cells in first body row
+                RenderTableCell* firstCell = m_firstBody->primaryCellAt(0, 0);
+                requiredHeight += firstCell->contentLogicalHeight() + firstCell->paddingTop(false) + firstCell->paddingBottom(false) + vBorderSpacing();
+            }
+            if (requiredHeight > remainingLogicalHeight) {
+                setPaginationStrut(remainingLogicalHeight);
+            }
+        }
+    }
+
     // If any table section moved vertically, we will just repaint everything from that
     // section down (it is quite unlikely that any of the following sections
     // did not shift).
@@ -361,12 +383,6 @@ void RenderTable::layout()
         computedLogicalHeight = computePercentageLogicalHeight(logicalHeightLength);
     computedLogicalHeight = max(0, computedLogicalHeight);
 
-    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, headHeight, footHeight);
-    }
-
     if (!m_firstBody && computedLogicalHeight > totalSectionLogicalHeight && !document()->inQuirksMode()) {
         // Completely empty tables (with no sections or anything) should at least honor specified height
         // in strict mode.
@@ -386,6 +402,9 @@ void RenderTable::layout()
         }
         section->setLogicalLocation(sectionLogicalLeft, logicalHeight());
 
+        // FIXME: Distribute extra height between all table body sections instead of giving it all to the first one.
+        section->layoutRows(section == m_firstBody ? max(0, computedLogicalHeight - totalSectionLogicalHeight) : 0, section == m_head ? 0 : headHeight, section == m_foot ? 0 : footHeight);
+
         setLogicalHeight(logicalHeight() + section->logicalHeight());
         section = sectionBelow(section);
     }
@@ -521,7 +540,7 @@ void RenderTable::paintObject(PaintInfo& paintInfo, int tx, int ty)
         // 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())) {
+            if (info.rect.y() > 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());
@@ -529,7 +548,7 @@ void RenderTable::paintObject(PaintInfo& paintInfo, int tx, int ty)
         }
         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())) {
+            if (info.rect.y() + info.rect.height() < 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();
@@ -1291,4 +1310,4 @@ bool RenderTable::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
     return false;
 }
 
-}
+}
\ No newline at end of file
diff --git a/src/qt/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp b/src/qt/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp
index 1e90ac6..b41db29 100644
--- a/src/qt/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp
+++ b/src/qt/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp
@@ -496,23 +496,34 @@ int RenderTableSection::layoutRows(int toAdd, int headHeight, int footHeight)
 
     LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), style()->isFlippedBlocksWritingMode());
 
-    WTF::Vector<int> logicalHeightsForPrinting;
-    // make sure that rows do not overlap a page break
+    // Calculate logical row heights
+    Vector<int> logicalRowHeights;
+    logicalRowHeights.resize(totalRows);
+    for (int r = 0; r < totalRows; r++) {
+        logicalRowHeights[r] = m_rowPos[r + 1] - m_rowPos[r] - vspacing;
+    }
+
+    // Make sure that cell contents do not overlap a page break
     if (view()->layoutState()->pageLogicalHeight()) {
-        logicalHeightsForPrinting.resize(totalRows);
+        LayoutState* layoutState = view()->layoutState();
+        int pageLogicalHeight = layoutState->m_pageLogicalHeight;
         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 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 - footHeight < childLogicalHeight) {
+
+        for (int r = 0; r < totalRows; ++r) {
+            int rowLogicalOffset = m_rowPos[r] + pageOffset;
+            int remainingLogicalHeight = pageLogicalHeight - layoutState->pageLogicalOffset(rowLogicalOffset) % pageLogicalHeight;
+
+            for (int c = 0; c < nEffCols; c++) {
+                CellStruct& cs = cellAt(r, c);
+                RenderTableCell* cell = cs.primaryCell();
+
+                if (!cell || cs.inColSpan || cell->row() != r)
+                    continue;
+
+                int cellRequiredHeight = cell->contentLogicalHeight() + cell->paddingTop(false) + cell->paddingBottom(false);
+                if (max(logicalRowHeights[r], cellRequiredHeight) > remainingLogicalHeight - footHeight - vspacing) {
                     pageOffset += remainingLogicalHeight + headHeight;
+                    break;
                 }
             }
             m_rowPos[r] += pageOffset;
@@ -525,11 +536,7 @@ int RenderTableSection::layoutRows(int toAdd, int headHeight, int footHeight)
         if (RenderTableRow* rowRenderer = m_grid[r].rowRenderer) {
             rowRenderer->setLocation(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->setLogicalHeight(logicalRowHeights[r]);
             rowRenderer->updateLayerTransform();
         }
 
@@ -541,8 +548,8 @@ int RenderTableSection::layoutRows(int toAdd, int headHeight, int footHeight)
                 continue;
 
             rindx = cell->row();
-            if (view()->layoutState()->pageLogicalHeight() && cell->rowSpan() == 1) {
-                rHeight = logicalHeightsForPrinting[rindx];
+            if (cell->rowSpan() == 1) {
+                rHeight = logicalRowHeights[rindx];
             } else {
                 rHeight = m_rowPos[rindx + cell->rowSpan()] - m_rowPos[rindx] - vspacing;
             }
@@ -1253,4 +1260,4 @@ bool RenderTableSection::nodeAtPoint(const HitTestRequest& request, HitTestResul
 
 }
 
-} // namespace WebCore
+} // namespace WebCore
\ No newline at end of file
-- 
1.7.6.1
<commit_msg>Update table page break improvements patch<commit_after>From ae97d8d765a925e62b5397ecc6524b3e8cc5d9ac Mon Sep 17 00:00:00 2001
From: <NAME> <<EMAIL>>
Date: Thu, 18 Jul 2013 12:46:20 +0100
Subject: [PATCH] Table page break improvements

Bump tables to the next page if we cannot fit the caption, thead
and first cell on the current page. Ideally this should be checking
the height of all cells in the first row in the same manner as is
done in the table section render but as this is more of a nice to
have I've done the minimal amount of work for now.

We now only layout section rows once each section has been positioned
within the table, and only supply head and foot reservation heights
to the appropriate sections.

When re-drawing the thead and tfoot only do so if the rect we are
painting is explicitly before/after the "original" thead/tfoot
rather than simply outside of its boundaries. This prevents issues
with re-drawing a redundant head when bumping tables to the next page.

Re-work the table section row layout code so that it's a bit more
streamlined. Additionally, to cater for cells spanning multiple rows
we avoid page breaks in the middle of their content. Note that rows
are always bumped to the next page even if their content doesn't
fit on a full page so as to avoid daft situtations like having the
first 1px on the preceeding page.
---
 .../Source/WebCore/rendering/RenderTable.cpp       |   39 +++++++++++---
 .../WebCore/rendering/RenderTableSection.cpp       |   55 ++++++++++++--------
 2 files changed, 64 insertions(+), 30 deletions(-)

diff --git a/src/qt/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp b/src/qt/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp
index 94ca61a..d26c612 100644
--- a/src/qt/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp
+++ b/src/qt/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp
@@ -329,6 +329,32 @@ void RenderTable::layout()
     if (m_caption)
         m_caption->layoutIfNeeded();
 
+    // Bump table to next page if we can't fit the caption, thead and first body cell
+    setPaginationStrut(0);
+    if (view()->layoutState()->pageLogicalHeight()) {
+        LayoutState* layoutState = view()->layoutState();
+        const int pageLogicalHeight = layoutState->m_pageLogicalHeight;
+        const int remainingLogicalHeight = pageLogicalHeight - layoutState->pageLogicalOffset(0) % pageLogicalHeight;
+        if (remainingLogicalHeight > 0) {
+            int requiredHeight = headHeight;
+            if (m_caption && m_caption->style()->captionSide() != CAPBOTTOM) {
+                requiredHeight += m_caption->logicalHeight() + m_caption->marginBefore() + m_caption->marginAfter();
+            }
+            if (m_firstBody) {
+                // FIXME: Calculate maximum required height across all cells in first body row
+                if (m_firstBody->numRows() > 0 && m_firstBody->numColumns() > 0) {
+                    RenderTableCell* firstCell = m_firstBody->primaryCellAt(0, 0);
+                    if (firstCell) {
+                        requiredHeight += firstCell->contentLogicalHeight() + firstCell->paddingTop(false) + firstCell->paddingBottom(false) + vBorderSpacing();
+                    }
+                }
+            }
+            if (requiredHeight > remainingLogicalHeight) {
+                setPaginationStrut(remainingLogicalHeight);
+            }
+        }
+    }
+
     // If any table section moved vertically, we will just repaint everything from that
     // section down (it is quite unlikely that any of the following sections
     // did not shift).
@@ -361,12 +387,6 @@ void RenderTable::layout()
         computedLogicalHeight = computePercentageLogicalHeight(logicalHeightLength);
     computedLogicalHeight = max(0, computedLogicalHeight);
 
-    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, headHeight, footHeight);
-    }
-
     if (!m_firstBody && computedLogicalHeight > totalSectionLogicalHeight && !document()->inQuirksMode()) {
         // Completely empty tables (with no sections or anything) should at least honor specified height
         // in strict mode.
@@ -386,6 +406,9 @@ void RenderTable::layout()
         }
         section->setLogicalLocation(sectionLogicalLeft, logicalHeight());
 
+        // FIXME: Distribute extra height between all table body sections instead of giving it all to the first one.
+        section->layoutRows(section == m_firstBody ? max(0, computedLogicalHeight - totalSectionLogicalHeight) : 0, section == m_head ? 0 : headHeight, section == m_foot ? 0 : footHeight);
+
         setLogicalHeight(logicalHeight() + section->logicalHeight());
         section = sectionBelow(section);
     }
@@ -521,7 +544,7 @@ void RenderTable::paintObject(PaintInfo& paintInfo, int tx, int ty)
         // 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())) {
+            if (info.rect.y() > 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());
@@ -529,7 +552,7 @@ void RenderTable::paintObject(PaintInfo& paintInfo, int tx, int ty)
         }
         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())) {
+            if (info.rect.y() + info.rect.height() < 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();
diff --git a/src/qt/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp b/src/qt/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp
index 1e90ac6..611d209 100644
--- a/src/qt/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp
+++ b/src/qt/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp
@@ -496,26 +496,41 @@ int RenderTableSection::layoutRows(int toAdd, int headHeight, int footHeight)
 
     LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), style()->isFlippedBlocksWritingMode());
 
-    WTF::Vector<int> logicalHeightsForPrinting;
-    // make sure that rows do not overlap a page break
+    // Calculate logical row heights
+    Vector<int> logicalRowHeights;
+    logicalRowHeights.resize(totalRows);
+    for (int r = 0; r < totalRows; r++) {
+        logicalRowHeights[r] = m_rowPos[r + 1] - m_rowPos[r] - vspacing;
+    }
+
+    // Make sure that cell contents do not overlap a page break
     if (view()->layoutState()->pageLogicalHeight()) {
-        logicalHeightsForPrinting.resize(totalRows);
+        LayoutState* layoutState = view()->layoutState();
+        int pageLogicalHeight = layoutState->m_pageLogicalHeight;
         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 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 - footHeight < childLogicalHeight) {
+
+        for (int r = 0; r < totalRows; ++r) {
+            m_rowPos[r] += pageOffset;
+            int remainingLogicalHeight = pageLogicalHeight - layoutState->pageLogicalOffset(m_rowPos[r]) % pageLogicalHeight;
+            int availableHeight = remainingLogicalHeight - footHeight - vspacing;
+
+            for (int c = 0; c < nEffCols; c++) {
+                CellStruct& cs = cellAt(r, c);
+                RenderTableCell* cell = cs.primaryCell();
+
+                if (!cell || cs.inColSpan || cell->row() != r)
+                    continue;
+
+                int cellRequiredHeight = cell->contentLogicalHeight() + cell->paddingTop(false) + cell->paddingBottom(false);
+                int requiredHeight = max(logicalRowHeights[r], cellRequiredHeight);
+                if (requiredHeight >= availableHeight) {
                     pageOffset += remainingLogicalHeight + headHeight;
+                    if (requiredHeight > availableHeight) {
+                        m_rowPos[r] += remainingLogicalHeight + headHeight;
+                    }
+                    break;
                 }
             }
-            m_rowPos[r] += pageOffset;
         }
         m_rowPos[totalRows] += pageOffset;
     }
@@ -525,11 +540,7 @@ int RenderTableSection::layoutRows(int toAdd, int headHeight, int footHeight)
         if (RenderTableRow* rowRenderer = m_grid[r].rowRenderer) {
             rowRenderer->setLocation(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->setLogicalHeight(logicalRowHeights[r]);
             rowRenderer->updateLayerTransform();
         }
 
@@ -541,8 +552,8 @@ int RenderTableSection::layoutRows(int toAdd, int headHeight, int footHeight)
                 continue;
 
             rindx = cell->row();
-            if (view()->layoutState()->pageLogicalHeight() && cell->rowSpan() == 1) {
-                rHeight = logicalHeightsForPrinting[rindx];
+            if (cell->rowSpan() == 1) {
+                rHeight = logicalRowHeights[rindx];
             } else {
                 rHeight = m_rowPos[rindx + cell->rowSpan()] - m_rowPos[rindx] - vspacing;
             }
-- 
1.7.10

{'fraction_non_alphanumeric': 0.11873132613192369, 'fraction_numerical': 0.01916800735463112, 'mean_word_length': 2.814165497896213, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 146, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 1, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5925377', 'n_tokens_mistral': 6634, 'n_tokens_neox': 6257, 'n_words': 1640}