summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2023-10-11 08:32:02 +0200
committerMiklos Vajna <vmiklos@collabora.com>2023-10-11 09:47:26 +0200
commit6b9378154f9b504b9e924fe4565df444786e7d73 (patch)
tree3c9d1086d2a7744056034aa835dfbd9d5886cce1 /sw
parent1f9cd62b67d679da078c50b4b48295918657a70a (diff)
sw floattable, crashtesting: fix PDF export of ooo91654-1.doc
Regression from 89a75cd194371002247d0138e759835bc673f7b0 (tdf#126449 sw floattable: DOC import: handle inner floating table, 2023-10-04), the document crashed Writer layout when exporting to PDF, which triggers a layout calculation. The trouble seems to be that in case the split fly is anchored in a table which is in a section, then we assume that we can create a section on the next page and move the follow fly frame there, which will mean the follow anchor won't be in a table anymore. Fix this by not moving the follow anchor explicitly, similar to what the nested floating table (inline or floating outer table) code does. The layout will later figure out that the available space is not enough, split the outer table for us, which will lead to a correct result. Note that the original bugdoc is DOC, but just saving it as-is in Word hides the problem, so it's not easy to minimize the reproducer. Instead create a similar DOCX reproducer from scratch. Change-Id: I769615af467ccaa88057ab322da2865f11d3d2ee Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157803 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
Diffstat (limited to 'sw')
-rw-r--r--sw/qa/core/layout/data/floattable-in-inltbl-in-sect.docxbin0 -> 18625 bytes
-rw-r--r--sw/qa/core/layout/flycnt.cxx26
-rw-r--r--sw/source/core/layout/flycnt.cxx26
3 files changed, 48 insertions, 4 deletions
diff --git a/sw/qa/core/layout/data/floattable-in-inltbl-in-sect.docx b/sw/qa/core/layout/data/floattable-in-inltbl-in-sect.docx
new file mode 100644
index 000000000000..ff329ecb5a5f
--- /dev/null
+++ b/sw/qa/core/layout/data/floattable-in-inltbl-in-sect.docx
Binary files differ
diff --git a/sw/qa/core/layout/flycnt.cxx b/sw/qa/core/layout/flycnt.cxx
index 37b255945d9e..325b0078ecb0 100644
--- a/sw/qa/core/layout/flycnt.cxx
+++ b/sw/qa/core/layout/flycnt.cxx
@@ -1157,6 +1157,32 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitFlyDelEmpty)
// Then make sure that the page count matches Word:
CPPUNIT_ASSERT_EQUAL(7, getPages());
}
+
+CPPUNIT_TEST_FIXTURE(Test, testSplitFlyInTableInSection)
+{
+ // Given a document where page 2 and page 3 has a floating table inside an inline table, inside
+ // a section:
+ // Without the accompanying fix in place, this test would have crashed, we created a follow
+ // anchor which was marked as "in table", but had no table parent.
+ createSwDoc("floattable-in-inltbl-in-sect.docx");
+
+ // Then make sure that the floating table is on page 2 and page 3:
+ SwDoc* pDoc = getSwDoc();
+ SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+ auto pPage1 = pLayout->Lower()->DynCastPageFrame();
+ CPPUNIT_ASSERT(pPage1);
+ CPPUNIT_ASSERT(!pPage1->GetSortedObjs());
+ auto pPage2 = pPage1->GetNext()->DynCastPageFrame();
+ CPPUNIT_ASSERT(pPage2);
+ CPPUNIT_ASSERT(pPage2->GetSortedObjs());
+ SwSortedObjs& rPage2Objs = *pPage2->GetSortedObjs();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPage2Objs.size());
+ auto pPage3 = pPage2->GetNext()->DynCastPageFrame();
+ CPPUNIT_ASSERT(pPage3);
+ CPPUNIT_ASSERT(pPage3->GetSortedObjs());
+ SwSortedObjs& rPage3Objs = *pPage3->GetSortedObjs();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPage3Objs.size());
+}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/flycnt.cxx b/sw/source/core/layout/flycnt.cxx
index 3c0254f929b8..98843c2c0d47 100644
--- a/sw/source/core/layout/flycnt.cxx
+++ b/sw/source/core/layout/flycnt.cxx
@@ -1579,11 +1579,30 @@ SwLayoutFrame *SwFrame::GetNextFlyLeaf( MakePageType eMakePage )
SwLayoutFrame *pLayLeaf = nullptr;
// Look up the first candidate.
SwSectionFrame* pFlyAnchorSection = pFlyAnchor ? pFlyAnchor->FindSctFrame() : nullptr;
+ bool bNesting = false;
if (pFlyAnchorSection)
{
- // We can't just move the split anchor to the next page, that would be outside the section.
- // Rather split that section as well.
- pLayLeaf = pFlyAnchorSection->GetNextSctLeaf(eMakePage);
+ // The anchor is in a section.
+ if (pFlyAnchor)
+ {
+ SwTabFrame* pFlyAnchorTab = pFlyAnchor->FindTabFrame();
+ if (pFlyAnchorTab)
+ {
+ // The anchor is in table as well.
+ if (pFlyAnchorTab->FindSctFrame() == pFlyAnchorSection)
+ {
+ // We're in a table-in-section, no anchor move in this case, because that would
+ // mean we're not in a table anymore.
+ bNesting = true;
+ }
+ }
+ }
+ if (!bNesting)
+ {
+ // We can't just move the split anchor to the next page, that would be outside the section.
+ // Rather split that section as well.
+ pLayLeaf = pFlyAnchorSection->GetNextSctLeaf(eMakePage);
+ }
}
else if (IsTabFrame())
{
@@ -1597,7 +1616,6 @@ SwLayoutFrame *SwFrame::GetNextFlyLeaf( MakePageType eMakePage )
}
SwLayoutFrame* pOldLayLeaf = nullptr;
- bool bNesting = false;
while (true)
{
if (pLayLeaf)