diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2023-09-29 09:01:29 +0200 |
---|---|---|
committer | Xisco Fauli <xiscofauli@libreoffice.org> | 2023-10-04 11:03:45 +0200 |
commit | 328c8083f2e3980252381adbec7f979982c1f8a7 (patch) | |
tree | d73feb526c28536946e6ab96b2dc4a2df01a8ecf | |
parent | set libtiff ac_cv_lib_jpeg_jpeg12_read_scanlines cache val to false (diff) | |
download | core-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.docx | bin | 0 -> 18586 bytes | |||
-rw-r--r-- | sw/qa/core/text/frmform.cxx | 30 | ||||
-rw-r--r-- | sw/source/core/text/frmform.cxx | 14 |
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 Binary files differnew file mode 100644 index 000000000000..a0a8bb4dbdb9 --- /dev/null +++ b/sw/qa/core/text/data/floattable-bad-fly-pos.docx 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(); |