sw/qa/core/objectpositioning/data/floattable-nested-overlap.docx |binary sw/qa/core/objectpositioning/objectpositioning.cxx | 27 ++++++++++ sw/source/core/objectpositioning/tocntntanchoredobjectposition.cxx | 10 +++ 3 files changed, 37 insertions(+)
New commits: commit e2b2ecad7a0ffdf1e0c34ec70c1987698971cbad Author: Miklos Vajna <[email protected]> AuthorDate: Wed Oct 15 08:36:44 2025 +0200 Commit: Adolfo Jayme Barrientos <[email protected]> CommitDate: Mon Oct 20 17:33:58 2025 +0200 tdf#165615 sw floattable, no overlap: avoid check against an own follow Load the bugdoc, the layuot loop control kicks in: warn:sw.layout:20117:20117:sw/source/core/layout/tabfrm.cxx:1853: LoopControl in SwContentFrame::CalcLowers and then the content is laid out on 3 pages, while it fits 2 pages in Word. What happens is that the document has an inline table, then a floating table inside that. The inner floating table has tblOverlap set to 'never', and then things go wrong in SwToContentAnchoredObjectPosition::CalcOverlap(). Fix the problem by checking if the two overlapping fly frames are actually next to each other in a split fly chain: if we're the precede of the other fly, then no need to worry about the overlap, that follow fly will move to the next page anyway. In theory this would be also interesting for toplevel floating tables, too -- but in practice CppunitTest_sw_core_layout's testSplitFlyHeader shows doing this in general would need more work, so just do this for floating tables which are inside tables. Change-Id: I4d0f1bd5229f8fbc3bb49af57f88fd6ef911cbfe Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192433 Reviewed-by: Miklos Vajna <[email protected]> Tested-by: Jenkins (cherry picked from commit 72e79a4d75cbbc8615fe9815bbbe9a38780ff856) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192717 Reviewed-by: Adolfo Jayme Barrientos <[email protected]> diff --git a/sw/qa/core/objectpositioning/data/floattable-nested-overlap.docx b/sw/qa/core/objectpositioning/data/floattable-nested-overlap.docx new file mode 100644 index 000000000000..a852d9c1e7ba Binary files /dev/null and b/sw/qa/core/objectpositioning/data/floattable-nested-overlap.docx differ diff --git a/sw/qa/core/objectpositioning/objectpositioning.cxx b/sw/qa/core/objectpositioning/objectpositioning.cxx index 7e1104df9db9..cf2d93837792 100644 --- a/sw/qa/core/objectpositioning/objectpositioning.cxx +++ b/sw/qa/core/objectpositioning/objectpositioning.cxx @@ -540,6 +540,33 @@ CPPUNIT_TEST_FIXTURE(Test, testDoNotCaptureDrawObjsDrawObjNoCapture) // i.e. the draw object was captured inside the page frame, but it was not in Word. CPPUNIT_ASSERT_GREATER(nDrawObjLeft, nPageLeft); } + +CPPUNIT_TEST_FIXTURE(Test, testFloattableNestedOverlap) +{ + // Given a document with an outer inline table, an inner floating table, the floating table's + // overlap is set to 'never': + createSwDoc("floattable-nested-overlap.docx"); + + // When laying out that document: + calcLayout(); + + // Then make sure the content fits two pages and the floating table is split: + SwDoc* pDoc = getSwDoc(); + SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout(); + SwPageFrame* pPage1 = pLayout->Lower()->DynCastPageFrame(); + CPPUNIT_ASSERT(pPage1); + CPPUNIT_ASSERT(pPage1->GetSortedObjs()); + const SwSortedObjs& rPage1Objs = *pPage1->GetSortedObjs(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPage1Objs.size()); + SwPageFrame* pPage2 = pPage1->GetNext()->DynCastPageFrame(); + CPPUNIT_ASSERT(pPage2); + CPPUNIT_ASSERT(pPage2->GetSortedObjs()); + const SwSortedObjs& rPage2Objs = *pPage2->GetSortedObjs(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPage2Objs.size()); + // Without the accompanying fix in place, this test would have failed, the content was laid out + // on 3 pages in Writer. + CPPUNIT_ASSERT(!pPage2->GetNext()); +} } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/core/objectpositioning/tocntntanchoredobjectposition.cxx b/sw/source/core/objectpositioning/tocntntanchoredobjectposition.cxx index 9ffb25400fd7..48aed01d206e 100644 --- a/sw/source/core/objectpositioning/tocntntanchoredobjectposition.cxx +++ b/sw/source/core/objectpositioning/tocntntanchoredobjectposition.cxx @@ -1290,6 +1290,16 @@ void SwToContentAnchoredObjectPosition::CalcOverlap(const SwTextFrame* pAnchorFr // A fly overlapping with a fly from another upper is fine. continue; } + + bool bAnchoredObjFlyAnchorInTable + = pAnchoredObjFlyAnchor && pAnchoredObjFlyAnchor->IsInTab(); + SwFlyAtContentFrame* pAnchoredObjSplitFly = pAnchoredObjFly->DynCastFlyAtContentFrame(); + if (pAnchoredObjSplitFly && pAnchoredObjSplitFly->GetPrecede() == pFlyFrame + && bAnchoredObjFlyAnchorInTable) + { + // A follow fly will move to the next page anyway, ignore. + continue; + } } css::text::WrapTextMode eWrap = pAnchoredObj->GetFrameFormat()->GetSurround().GetSurround();
