summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2023-09-29 09:01:29 +0200
committerXisco Fauli <xiscofauli@libreoffice.org>2023-10-04 11:03:45 +0200
commit328c8083f2e3980252381adbec7f979982c1f8a7 (patch)
treed73feb526c28536946e6ab96b2dc4a2df01a8ecf
parentset libtiff ac_cv_lib_jpeg_jpeg12_read_scanlines cache val to false (diff)
downloadcore-328c8083f2e3980252381adbec7f979982c1f8a7.tar.gz
core-328c8083f2e3980252381adbec7f979982c1f8a7.zip
Related: tdf#126449 sw floattable: fix bad position of in-table follow fly
The reduced bugdoc is of 4 pages, an inner floating table should be on pages 2 -> 4 but was only on 2 -> 3. The reason for this seems to be that we correctly split the inner table twice, but the 3rd fly frame in the chain is positioned on page 3, and once the anchor moves to page 4, we never re-position the fly frame. The fly frame is normally only positioned once, since the position of the anchor and the fly frame depend on each other, so the loop has to be broken, and this is normally done by locking the position of the fly after one positioning. Fix the problem by extending the condition when to unlock the position of anchored fly frames in SwTextFrame::MakePos(): similar to not yet positioned fly frames, do one more cycle in case the anchor and the fly frame are not on the same page. This just fixes a simplified DOCX bugdoc, the full document still needs more fixes. Change-Id: I066c64cf4e12bf31f22218f84f0f2425256ba63e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157393 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157402
-rw-r--r--sw/qa/core/text/data/floattable-bad-fly-pos.docxbin0 -> 18586 bytes
-rw-r--r--sw/qa/core/text/frmform.cxx30
-rw-r--r--sw/source/core/text/frmform.cxx14
3 files changed, 41 insertions, 3 deletions
diff --git a/sw/qa/core/text/data/floattable-bad-fly-pos.docx b/sw/qa/core/text/data/floattable-bad-fly-pos.docx
new file mode 100644
index 000000000000..a0a8bb4dbdb9
--- /dev/null
+++ b/sw/qa/core/text/data/floattable-bad-fly-pos.docx
Binary files differ
diff --git a/sw/qa/core/text/frmform.cxx b/sw/qa/core/text/frmform.cxx
index f2f942bde324..ee791f325729 100644
--- a/sw/qa/core/text/frmform.cxx
+++ b/sw/qa/core/text/frmform.cxx
@@ -116,6 +116,36 @@ CPPUNIT_TEST_FIXTURE(Test, testFloattableAvoidLastManipOfst)
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0),
static_cast<sal_Int32>(pAnchorText->GetOffset()));
}
+
+CPPUNIT_TEST_FIXTURE(Test, testFloattableBadFlyPos)
+{
+ // Given a document with an inner floating table on page 2 -> 4:
+ // When laying out that document:
+ createSwDoc("floattable-bad-fly-pos.docx");
+
+ // Then make sure that pages 2 -> 4 get the 3 fly frames:
+ 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());
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pPage2->GetSortedObjs()->size());
+ auto pPage3 = pPage2->GetNext()->DynCastPageFrame();
+ CPPUNIT_ASSERT(pPage3);
+ CPPUNIT_ASSERT(pPage3->GetSortedObjs());
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 1
+ // - Actual : 2
+ // i.e. the fly on page 4 was still on page 3.
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pPage3->GetSortedObjs()->size());
+ auto pPage4 = pPage3->GetNext()->DynCastPageFrame();
+ CPPUNIT_ASSERT(pPage4);
+ CPPUNIT_ASSERT(pPage4->GetSortedObjs());
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pPage4->GetSortedObjs()->size());
+}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/frmform.cxx b/sw/source/core/text/frmform.cxx
index c3c7f872b88a..495820336fb3 100644
--- a/sw/source/core/text/frmform.cxx
+++ b/sw/source/core/text/frmform.cxx
@@ -365,10 +365,18 @@ void SwTextFrame::MakePos()
// Possibly this fly was positioned relative to us, invalidate its position now that our
// position is changed.
SwPageFrame* pPageFrame = pFly->FindPageFrame();
- if (pPageFrame && pFly->getFrameArea().Pos() == pPageFrame->getFrameArea().Pos())
+ bool bFlyNeedsPositioning = false;
+ bool bFlyPageMismatch = false;
+ if (pPageFrame)
{
- // The position was just adjusted to be be inside the page frame, so not really
- // positioned, unlock the position once to allow a recalc.
+ // Was the position just adjusted to be inside the page frame?
+ bFlyNeedsPositioning = pFly->getFrameArea().Pos() == pPageFrame->getFrameArea().Pos();
+ // Is the fly on a page different than the anchor frame?
+ bFlyPageMismatch = pPageFrame != FindPageFrame();
+ }
+ if (bFlyNeedsPositioning || bFlyPageMismatch)
+ {
+ // Not really positioned, unlock the position once to allow a recalc.
pFly->UnlockPosition();
}
pFly->InvalidatePos();