sw/qa/core/layout/flycnt.cxx | 7 +++++++ sw/source/core/layout/objectformatter.cxx | 7 ++++++- 2 files changed, 13 insertions(+), 1 deletion(-)
New commits: commit facdac2443d50339f81415d09c1869d19dded7bf Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Fri Sep 8 08:26:40 2023 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Fri Sep 8 09:25:19 2023 +0200 sw floattable, nesting: fix PDF export The problem was that the bugdoc rendered fine when opened interactively, but not when converted to PDF via 'soffice --convert-to pdf'. The direct cause was that the interactive case also enabled the navigator that did one more calculation for each fly, and that fixes the layout. The headless export to PDF has no navigator, so that didn't happen. The root of the problem seems to be that: 1) There is a bad left position for the inner follow fly (it's outside the page rectangle). 2) SwTabFrame::Split() for the outer tab normally calls lcl_RecalcSplitLine() which moves flys away + back. 3) Moving away happens in lcl_InvalidateLowerObjs() in the _bMoveObjsOutOfRange case, here we move away both fly 10 and 20 (both inner flys). 4) Moving back happens in SwToContentAnchoredObjectPosition::CalcPosition(), but that's not invoked for the inner follow fly. Fix the problem by extending SwObjectFormatter::FormatObjsAtFrame_() to be more consistent here and move back both flys. This is related to tdf#55160. Change-Id: Ia264a828f36cf2bc1d67986ab3a97d57e9d167a7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156691 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins diff --git a/sw/qa/core/layout/flycnt.cxx b/sw/qa/core/layout/flycnt.cxx index 797d5d8c5691..1c69606c8a24 100644 --- a/sw/qa/core/layout/flycnt.cxx +++ b/sw/qa/core/layout/flycnt.cxx @@ -1068,6 +1068,13 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitFlyNested) // rendered and this way the inner anchor had no fly portion, either. CPPUNIT_ASSERT_GREATER(pPage2->getFrameArea().Top(), pPage2Fly1->getFrameArea().Top()); + // Without the accompanying fix in place, this test would have failed with: + // - Expected less than: 12523 + // - Actual : 15312 + // i.e. the inner follow fly was not "moved back" to its place to have the wanted 4400 position, + // which makes the "Inner A2" text visible. + CPPUNIT_ASSERT_LESS(pPage2->getFrameArea().Right(), pPage2Fly1->getFrameArea().Right()); + auto pPage2Fly2 = rPage2Objs[1]->DynCastFlyFrame()->DynCastFlyAtContentFrame(); CPPUNIT_ASSERT(pPage2Fly2); CPPUNIT_ASSERT(!pPage2Fly2->GetAnchorFrameContainingAnchPos()->IsInFly()); diff --git a/sw/source/core/layout/objectformatter.cxx b/sw/source/core/layout/objectformatter.cxx index 15ca544a2d9c..b99da6a0fe4b 100644 --- a/sw/source/core/layout/objectformatter.cxx +++ b/sw/source/core/layout/objectformatter.cxx @@ -390,7 +390,12 @@ bool SwObjectFormatter::FormatObjsAtFrame_( SwTextFrame* _pMasterTextFrame ) pAnchorCharFrame != pAnchoredObj->GetAnchorFrame() && pAnchorCharFrame->FindBodyFrame() == static_cast<SwTextFrame*>(pAnchoredObj->AnchorFrame())->FindBodyFrame(); - if ( bAnchoredAtFollowInSameBodyAsMaster ) + // Make sure that in case nested split flys are moved "out of range" in + // lcl_InvalidateLowerObjs(), then we moved them back here. + SwFlyFrame* pFly = pAnchoredObj->DynCastFlyFrame(); + bool bSplitFly = pFly && pFly->IsFlySplitAllowed(); + bool bNestedSplitFly = bSplitFly && pAnchorCharFrame && pAnchorCharFrame->IsInFly(); + if (bAnchoredAtFollowInSameBodyAsMaster && !bNestedSplitFly) { continue; }