sw/qa/core/layout/data/shape-left-padding-wrap-through-off-page.docx |binary sw/qa/core/layout/fly.cxx | 28 ++++++++++ sw/source/core/layout/fly.cxx | 14 +++-- 3 files changed, 37 insertions(+), 5 deletions(-)
New commits: commit c8a15106e4ee85b613ee73d5879e292e24094f5d Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Wed Mar 26 09:54:35 2025 +0100 Commit: Caolán McNamara <caolan.mcnam...@collabora.com> CommitDate: Wed Mar 26 10:29:52 2025 +0100 tdf#165020 sw DoNotCaptureDrawObjsOnPage: fix left padding for wrap through Open the bugdoc, the left shapre is partially outside the page frame, but is not captured. This is fine, but the text should be clipped in a way that only the right half is visible, and instead the left half is visible. This went wrong in commit 61692b82ae4ff62662509b5979a7aabc7d380678 (tdf#161635 sw DoNotCaptureDrawObjsOnPage: fix handling of left padding, 2024-06-19), where I assumed that in case the left paddig is increased in Word for these partially off-page shapes, then that happens unconditionally. Fix the new use-case by only doing this for non-wrap-through shapes: this restores the lack of increased left padding for the new use-case and keeps the old one fixed. Special-casing the 'wrap mode == through' case for off-page positioning is not new, SwAnchoredObject::IsDraggingOffPageAllowed() and SwAnchoredObjectPosition::GetInfoAboutObj() also takes it into account. Change-Id: I07dec72e860c810a753c2c356f8f32cc2178b012 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183322 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> diff --git a/sw/qa/core/layout/data/shape-left-padding-wrap-through-off-page.docx b/sw/qa/core/layout/data/shape-left-padding-wrap-through-off-page.docx new file mode 100644 index 000000000000..0b84082d6996 Binary files /dev/null and b/sw/qa/core/layout/data/shape-left-padding-wrap-through-off-page.docx differ diff --git a/sw/qa/core/layout/fly.cxx b/sw/qa/core/layout/fly.cxx index de227280bc55..8276f442a8b3 100644 --- a/sw/qa/core/layout/fly.cxx +++ b/sw/qa/core/layout/fly.cxx @@ -141,6 +141,34 @@ CPPUNIT_TEST_FIXTURE(Test, testShapeLeftPaddingOffPage) // i.e. the shape text had ~4cm left padding (visually) instead of 5cm. CPPUNIT_ASSERT_GREATEREQUAL(nBodyLeft - MINFLY, nFlyLeft); } + +CPPUNIT_TEST_FIXTURE(Test, testShapeLeftPaddingWrapThroughOffPage) +{ + // Given a document with a shape that is off the page (partially clipped on the left): + createSwDoc("shape-left-padding-wrap-through-off-page.docx"); + + // When laying out that document: + SwDoc* pDoc = getSwDoc(); + SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout(); + + // Then make sure that the text is also clipped on the left, left margin is only the + // lIns="91440" (in EMUs) from the file: + auto pPage = pLayout->GetLower()->DynCastPageFrame(); + SwSortedObjs& rPageObjs = *pPage->GetSortedObjs(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), rPageObjs.size()); + auto it = std::find_if(rPageObjs.begin(), rPageObjs.end(), [](SwAnchoredObject* pObj) -> bool { + return pObj->DynCastFlyFrame() != nullptr; + }); + CPPUNIT_ASSERT(it != rPageObjs.end()); + auto pFly = (*it)->DynCastFlyFrame(); + CPPUNIT_ASSERT(pFly); + SwTwips nFlyLeftMargin = pFly->getFramePrintArea().Left(); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 144 + // - Actual : 3031 + // i.e. there was a large left margin, the text was clipped on the right. + CPPUNIT_ASSERT_EQUAL(static_cast<SwTwips>(144), nFlyLeftMargin); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx index f174143288e7..1a7caee5969d 100644 --- a/sw/source/core/layout/fly.cxx +++ b/sw/source/core/layout/fly.cxx @@ -2071,12 +2071,16 @@ void SwFlyFrame::MakePrtArea( const SwBorderAttrs &rAttrs ) // The fly frame may be partially outside the page, check for this case. SwPageFrame* pPageFrame = FindPageFrame(); - SwFrameFormat* pFormat = GetFormat(); - if (pPageFrame && pFormat) - { - const IDocumentSettingAccess& rIDSA = pFormat->getIDocumentSettingAccess(); + SwFrameFormat* pFlyFormat = GetFormat(); + SwFrameFormat* pDrawFormat = SwTextBoxHelper::getOtherTextBoxFormat(pFlyFormat, RES_FLYFRMFMT); + const SwFrameFormat* pFormat = pDrawFormat ? pDrawFormat : pFlyFormat; + // Don't increase the left padding if the wrap mode is through. + bool bIsWrapThrough = pFormat && pFormat->GetSurround().GetSurround() == text::WrapTextMode::WrapTextMode_THROUGH; + if (pPageFrame && pFlyFormat && !bIsWrapThrough) + { + const IDocumentSettingAccess& rIDSA = pFlyFormat->getIDocumentSettingAccess(); bool bDoNotCaptureDrawObjsOnPage = rIDSA.get(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE); - bool bLRTB = pFormat->GetFrameDir().GetValue() == SvxFrameDirection::Horizontal_LR_TB; + bool bLRTB = pFlyFormat->GetFrameDir().GetValue() == SvxFrameDirection::Horizontal_LR_TB; SwTwips nFlyLeft = getFrameArea().Left(); SwTwips nPageLeft = pPageFrame->getFrameArea().Left(); if (bDoNotCaptureDrawObjsOnPage && bLRTB && nFlyLeft < nPageLeft)