summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2023-05-23 15:04:22 +0200
committerMiklos Vajna <vmiklos@collabora.com>2023-05-23 16:45:43 +0200
commit807ad65661c122a33fccb4fd3453ef92c0e9129d (patch)
treeb7de733466182e2cf50e934afcd5c534a463773f /sw
parente1819dfeb0f1436d8b957183758df0a3133c02c1 (diff)
tdf#155002 sw floattable, split but not yet moved follow: fix GetNextFlyLeaf()
Trying to open the bugdoc resulted in a layout loop since commit b47401e12d9c45386899df0aa26653bd26c9abd4 (sw floattable: fix assert fail when object formatter gets the wrong anchor, 2023-05-22), previously could not open due to an assertion failure. What happened is that the anchor hosted a fly frame with a table, but the anchor was inside a section. Instead of splitting the fly and moving part of it to a next page, we constantly created and deleted new pages, without moving anything, which is a layout loop. In fact crating a new page in SwFrame::GetNextFlyLeaf() is not correct: we should realize that we're inside a section and let GetNextSctLeaf() handle the page (and section) creation. Once the anchor code is improved to detect that we're in a section, GetNextSctLeaf() creates the follow section, and later in GetNextFlyLeaf() the call to GetNextLayoutLeaf() will find the new follow section. Which means we have a place for the follow anchor and don't create any new page, fixing the loop. The import result of the bugdoc is still not perfect, but at least we don't crash or hang while opening the document. Change-Id: Ic0717dddbcd0949df7d4ae766f3cc0dbbbcff27a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152163 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
Diffstat (limited to 'sw')
-rw-r--r--sw/qa/core/layout/data/floattable-next-leaf-in-section.docxbin0 -> 24632 bytes
-rw-r--r--sw/qa/core/layout/flycnt.cxx11
-rw-r--r--sw/source/core/layout/flycnt.cxx14
3 files changed, 25 insertions, 0 deletions
diff --git a/sw/qa/core/layout/data/floattable-next-leaf-in-section.docx b/sw/qa/core/layout/data/floattable-next-leaf-in-section.docx
new file mode 100644
index 000000000000..3a315d51c984
--- /dev/null
+++ b/sw/qa/core/layout/data/floattable-next-leaf-in-section.docx
Binary files differ
diff --git a/sw/qa/core/layout/flycnt.cxx b/sw/qa/core/layout/flycnt.cxx
index f849fa330ac4..efc29670c244 100644
--- a/sw/qa/core/layout/flycnt.cxx
+++ b/sw/qa/core/layout/flycnt.cxx
@@ -910,6 +910,17 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitFlyObjectFormatter)
CPPUNIT_ASSERT(pPage3);
CPPUNIT_ASSERT(!pPage3->GetSortedObjs());
}
+
+CPPUNIT_TEST_FIXTURE(Test, testSplitFlyNextLeafInSection)
+{
+ // Given a document with 4 pages: page 1 had a floating table, page 2 & 3 had a second floating
+ // table and finally page 4 is empty:
+ createSwDoc("floattable-next-leaf-in-section.docx");
+
+ // When calculating the layout:
+ // Then this never returned, the loop in SwFrame::GetNextFlyLeaf() never finished.
+ calcLayout();
+}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/flycnt.cxx b/sw/source/core/layout/flycnt.cxx
index 8277ab1c68cb..25e3f45c0bfa 100644
--- a/sw/source/core/layout/flycnt.cxx
+++ b/sw/source/core/layout/flycnt.cxx
@@ -1555,6 +1555,20 @@ SwLayoutFrame *SwFrame::GetNextFlyLeaf( MakePageType eMakePage )
assert(pFly->IsFlySplitAllowed() && "GetNextFlyLeaf: fly split not allowed");
SwTextFrame* pFlyAnchor = pFly->FindAnchorCharFrame();
+
+ if (!pFlyAnchor)
+ {
+ // In case our fly frame is split already, but not yet moved, then FindAnchorCharFrame()
+ // won't find the anchor, since it wants a follow anchor, but there is no follow anchor yet.
+ // In this case work with a plain anchor, so FindSctFrame() works to find out we're in a
+ // section.
+ auto pAnchorFrame = const_cast<SwFrame*>(pFly->GetAnchorFrame());
+ if (pAnchorFrame && pAnchorFrame->IsTextFrame())
+ {
+ pFlyAnchor = static_cast<SwTextFrame*>(pAnchorFrame);
+ }
+ }
+
bool bBody = pFlyAnchor && pFlyAnchor->IsInDocBody();
SwLayoutFrame *pLayLeaf = nullptr;
// Look up the first candidate.