diff options
author | Michael Stahl <michael.stahl@allotropia.de> | 2021-04-27 20:07:14 +0200 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2021-05-03 12:37:30 +0200 |
commit | 31c95393641bcd798ea068889d4061a8dc445a55 (patch) | |
tree | 896358c49318b8d6486df5eb0f83de9dd7769ab1 | |
parent | ec1c01901bdc22a29a8fc40d08864bf66665771a (diff) |
sw: layout: let nested table move forward
The problem is that a nested table at the bottom of the page doesn't fit
into its cell, but it is split and its first row still remains on the
page where it doesn't fit.
The outer table 3 tries to split with bTryToSplit=true.
In SwTabFrame::MakeAll(), first a split of the nested table 435 with
bTryToSplit=true is attempted; this fails and is partially undone -
the follow flow line is removed, but the last 2 rows remain in follow.
The bTryToSplit=false is skipped because there's only one row now.
Then MoveFwd() is tried, but it fails because the top-level table
doesn't have a previous frame.
Then bTryToSplit=false is tried, and succeeds, again leaving row 436
on page 1 and other 2 in follow.
Now another attempt with bTryToSplit=true is made, failing again, not
effectively changing anything.
During all of this, growing of the outer cell frame 434 and row frame
433 is prevented by the outer table 3 having a follow flow line, see
SwRowFrame::GrowFrame().
The result is that cell 434 has content area height 190 but the table
435 with its single row is all valid with height 406, so it's cut off in
the rendering.
This doesn't happen for SwTextFrame inside table because that one does
the MoveFwd().
Plausibly it's the inner table's responsibility to finish with a valid
state that fits the constraints of the current page; there are some
checks in lcl_RecalcSplitLine() to check for no content frame in the
row but none for the row being too small to contain the content that
was formatted.
So the only valid results for the inner table are that it either moved
forward, or it left behind a row containing no content (such as that
produced by its own failed attempt to split with bTryToSplit=true),
which could be handled by the outer table split code - but the latter
could be insufficient in case the outer table is itself a follow, or at
least would require further changes in lcl_RecalcSplitLine().
So fix this by removing a condition in MoveFwd() that doesn't make any
sense to me - why is it relevant for an inner table during a split of
the outer table whether the outer table itself can move forward?
Change-Id: I1e01ce233383cc70b9aea72d25369b7278eb75f0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114760
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
(cherry picked from commit ca19177728c66d913996a48c91a0ba47d08825d6)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114718
Reviewed-by: Thorsten Behrens <thorsten.behrens@allotropia.de>
-rw-r--r-- | sw/qa/extras/layout/data/tabellen_test_windows_1.odt | bin | 0 -> 11954 bytes | |||
-rw-r--r-- | sw/qa/extras/layout/layout.cxx | 12 | ||||
-rw-r--r-- | sw/source/core/layout/flowfrm.cxx | 3 |
3 files changed, 13 insertions, 2 deletions
diff --git a/sw/qa/extras/layout/data/tabellen_test_windows_1.odt b/sw/qa/extras/layout/data/tabellen_test_windows_1.odt Binary files differnew file mode 100644 index 000000000000..a666fe5fd47d --- /dev/null +++ b/sw/qa/extras/layout/data/tabellen_test_windows_1.odt diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx index 15e33d74d18e..d4450264826a 100644 --- a/sw/qa/extras/layout/layout.cxx +++ b/sw/qa/extras/layout/layout.cxx @@ -492,6 +492,18 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, TestTdf134272) assertXPath(pXmlDoc, "/root/page[1]/header/txt[2]/infos/bounds", "bottom", "2819"); } +CPPUNIT_TEST_FIXTURE(SwLayoutWriter, TestNestedTableMoveFwd) +{ + SwDoc* pDoc = createDoc("tabellen_test_windows_1.odt"); + CPPUNIT_ASSERT(pDoc); + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + // the row with the nested table should not be split but be the first row on page 2 + assertXPath(pXmlDoc, "/root/page[1]/body/tab[1]/row[last()]/cell[1]/txt[1]/Text", "Portion", + "Tabelle 1"); + assertXPath(pXmlDoc, "/root/page[2]/body/tab[1]/row[1]/cell[1]/tab[1]/row[1]/cell[1]/txt/Text", + "Portion", "Tabelle 2"); +} + CPPUNIT_TEST_FIXTURE(SwLayoutWriter, TestTdf136613) { SwDoc* pDoc = createDoc("tdf136613.docx"); diff --git a/sw/source/core/layout/flowfrm.cxx b/sw/source/core/layout/flowfrm.cxx index aeeb9df158cf..6a2c12a5044f 100644 --- a/sw/source/core/layout/flowfrm.cxx +++ b/sw/source/core/layout/flowfrm.cxx @@ -1951,8 +1951,7 @@ bool SwFlowFrame::MoveFwd( bool bMakePage, bool bPageBreak, bool bMoveAlways ) // Allow the MoveFwd even if we do not have an IndPrev in these cases: if ( m_rThis.IsInTab() && ( !m_rThis.IsTabFrame() || - ( m_rThis.GetUpper()->IsInTab() && - m_rThis.GetUpper()->FindTabFrame()->IsFwdMoveAllowed() ) ) && + m_rThis.GetUpper()->IsInTab() ) && nullptr != m_rThis.GetNextCellLeaf() ) { bNoFwd = false; |