summaryrefslogtreecommitdiff
path: root/sw/qa/extras
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2016-12-08 23:01:03 +0300
committerAndras Timar <andras.timar@collabora.com>2016-12-12 20:23:04 +0000
commit4a43b3092731daaabb7a97be530ccb2edc0ffc3a (patch)
tree47f3e7a7897ff8a423f73699e0c7c0bb8436f088 /sw/qa/extras
parentbc72923f02685ad0bccea6fab9524214afa901fe (diff)
tdf#104425 sw: split rows w/large min height (fix layout loop)
This solves the problem of rows with too big minimal height causing layout failure (the table just goes out of page, does not flow to next page). It does so with three steps: 1. Currently, a row with a minimum height that flows to next page repeats whole min height on that (and possibly following) pages. If this behaviour continued, then that would cause layout loop: the row min height would be too high for the page, so it would keep flowing to next pages (actually just go beyond the botom because of layout failure). To mitigate this, the patch changes the behaviour to measure total height of all frames of the row: the function lcl_calcHeightOfRowBeforeThisFrame calculates the total height of previous row frames for the same row, then in places where we need to get min height, this value is subtracted from row min total height. On following pages the min height of frames will get less each time. 2. When the row is split, the possibility to split depends on if the minimum height of the row fits into the vertical space left. The minimum height is found as maxinum of two values: minimal contents of the row (e.g., height of first line of text, or an object, or lower table cell), and the minimum height setting. As the minimum height setting should not prevent the cell to flow, (it only should ensure that total height is no less), we should not consider the setting when the split is performed (we should be able to keep on first page as little as required). To allow this, a new bool member introduced in SwRowFrame: m_bIsInSplit, with its setter and getter. When it is true, the routines that calculate min height ignore the min height setting. It is set in lcl_RecalcSplitLine around lcl_RecalcRow and SwRowFrame::Calc that decide if it's possible to keep part of row's content on first page, and update table's height to fit the rest of space. 3. It turns out, that if contents of the splitted cell has less height than the min height setting, then following happens. In SwTabFrame::Split, all rows below splitted one are moved to follow flow table; then table frame's Shrink method used to shrink the freed height. At this moment, still, the height of splitted row is too high, and total height of table is too high. Then, lcl_RecalcSplitLine is called, where row is first shrunk, and then lcl_RecalcRow and SwRowFrame::Calc try to move contents and resize the splitted row. They get the minimum height of content (we already don't consider the min height setting), but then "last row will fill the space in its upper" (see SwRowFrame::Format). Row returns its previous size, table does not resize, it doesn't fit to page, and split fails. To try to fix that, I call SwTabFrame::Shrink in lcl_RecalcSplitLine after lcl_ShrinkCellsAndAllContent before lcl_RecalcRow. Unit test included. Change-Id: I37a6b3589abf287dd5efc991a6336fc378410df9 Reviewed-on: https://gerrit.libreoffice.org/31774 Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com> Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk> Reviewed-on: https://gerrit.libreoffice.org/31915 Reviewed-by: Andras Timar <andras.timar@collabora.com> Tested-by: Andras Timar <andras.timar@collabora.com>
Diffstat (limited to 'sw/qa/extras')
-rw-r--r--sw/qa/extras/uiwriter/data/tdf104425.odtbin0 -> 9459 bytes
-rw-r--r--sw/qa/extras/uiwriter/uiwriter.cxx17
2 files changed, 17 insertions, 0 deletions
diff --git a/sw/qa/extras/uiwriter/data/tdf104425.odt b/sw/qa/extras/uiwriter/data/tdf104425.odt
new file mode 100644
index 000000000000..8bbf265499ef
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/tdf104425.odt
Binary files differ
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index d7827ae6b734..b3f4d63568ff 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -200,6 +200,7 @@ public:
void testLandscape();
void testTdf95699();
void testTdf104440();
+ void testTdf104425();
CPPUNIT_TEST_SUITE(SwUiWriterTest);
CPPUNIT_TEST(testReplaceForward);
@@ -301,6 +302,7 @@ public:
CPPUNIT_TEST(testLandscape);
CPPUNIT_TEST(testTdf95699);
CPPUNIT_TEST(testTdf104440);
+ CPPUNIT_TEST(testTdf104425);
CPPUNIT_TEST_SUITE_END();
private:
@@ -3499,6 +3501,21 @@ void SwUiWriterTest::testTdf104440()
xmlXPathFreeObject(pXmlObj);
}
+void SwUiWriterTest::testTdf104425()
+{
+ createDoc("tdf104425.odt");
+ xmlDocPtr pXmlDoc = parseLayoutDump();
+ // The document contains one top-level 1-cell table with minimum row height set to 70 cm,
+ // and the cell contents does not exceed the minimum row height.
+ // It should span over 3 pages.
+ assertXPath(pXmlDoc, "//page", 3);
+ sal_Int32 nHeight1 = getXPath(pXmlDoc, "//page[1]/body/tab/row/infos/bounds", "height").toInt32();
+ sal_Int32 nHeight2 = getXPath(pXmlDoc, "//page[2]/body/tab/row/infos/bounds", "height").toInt32();
+ sal_Int32 nHeight3 = getXPath(pXmlDoc, "//page[3]/body/tab/row/infos/bounds", "height").toInt32();
+ double fSumHeight_mm = (nHeight1 + nHeight2 + nHeight3) * 25.4 / 1440.0;
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(700.0, fSumHeight_mm, 0.05);
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest);
CPPUNIT_PLUGIN_IMPLEMENT();