sw/qa/core/layout/data/shape-left-padding-off-page.docx |binary sw/qa/core/layout/fly.cxx | 30 ++++++++++++++++ sw/source/core/layout/fly.cxx | 22 +++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-)
New commits: commit 61692b82ae4ff62662509b5979a7aabc7d380678 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Wed Jun 19 10:05:57 2024 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Wed Jun 19 11:22:25 2024 +0200 tdf#161635 sw DoNotCaptureDrawObjsOnPage: fix handling of left padding Open the bugdoc, the shape has an 5cm left padding for its text, but only 4cm of that is visible in Writer. Checking the shape, part of that is outside the page frame, so the first 1cm of the left padding is not visible, visually resulting in a 4cm left padding in Writer, but not in Word. Fix the problem by extending SwFlyFrame::MakePrtArea(), so in case the shape is partially outside the page frame, then we make sure to increase the left padding enough that the nominal (5cm) left padding is inside the page frame. With this, the text on the title page of the document is visually centered also in Writer, even if not using an explicit paragraph alignment. Change-Id: I5dcbcf407ed7f12f0bc13820fa39621a76e23fe7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169186 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/sw/qa/core/layout/data/shape-left-padding-off-page.docx b/sw/qa/core/layout/data/shape-left-padding-off-page.docx new file mode 100644 index 000000000000..92e143616016 Binary files /dev/null and b/sw/qa/core/layout/data/shape-left-padding-off-page.docx differ diff --git a/sw/qa/core/layout/fly.cxx b/sw/qa/core/layout/fly.cxx index 075ffe54bc5d..de227280bc55 100644 --- a/sw/qa/core/layout/fly.cxx +++ b/sw/qa/core/layout/fly.cxx @@ -17,6 +17,8 @@ #include <sortedobjs.hxx> #include <docsh.hxx> #include <wrtsh.hxx> +#include <bodyfrm.hxx> +#include <txtfrm.hxx> namespace { @@ -111,6 +113,34 @@ CPPUNIT_TEST_FIXTURE(Test, testFlyRelWithRounding) // i.e. 5714.88 was truncated, not rounded. CPPUNIT_ASSERT_EQUAL(static_cast<tools::Long>(5715), nFlyWidth); } + +CPPUNIT_TEST_FIXTURE(Test, testShapeLeftPaddingOffPage) +{ + // Given a document with a shape that is 1cm off the page: + createSwDoc("shape-left-padding-off-page.docx"); + + // When laying out that document: + SwDoc* pDoc = getSwDoc(); + SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout(); + + // Then make sure that the 2.5cm page margin + 2.5cm para margin and the 5cm shape left padding + // line up (with 1px tolerance): + auto pPage = pLayout->GetLower()->DynCastPageFrame(); + auto pBody = static_cast<SwBodyFrame*>(pPage->GetLower()); + auto pTextFrame = pBody->GetLower()->DynCastTextFrame(); + SwTwips nBodyLeft = pTextFrame->getFrameArea().Left() + pTextFrame->getFramePrintArea().Left(); + CPPUNIT_ASSERT(pPage->GetSortedObjs()); + SwSortedObjs& rPageObjs = *pPage->GetSortedObjs(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), rPageObjs.size()); + auto pFly = rPageObjs[1]->DynCastFlyFrame()->DynCastFlyAtContentFrame(); + CPPUNIT_ASSERT(pFly); + SwTwips nFlyLeft = pFly->getFrameArea().Left() + pFly->getFramePrintArea().Left(); + // Without the accompanying fix in place, this test would have failed with: + // - Expected greater or equal than: 3119 + // - Actual : 2574 + // i.e. the shape text had ~4cm left padding (visually) instead of 5cm. + CPPUNIT_ASSERT_GREATEREQUAL(nBodyLeft - MINFLY, nFlyLeft); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx index 9722a741b2f8..313f047ece98 100644 --- a/sw/source/core/layout/fly.cxx +++ b/sw/source/core/layout/fly.cxx @@ -1986,7 +1986,27 @@ void SwFlyFrame::MakePrtArea( const SwBorderAttrs &rAttrs ) // consider vertical layout SwRectFnSet aRectFnSet(this); - aRectFnSet.SetXMargins( *this, rAttrs.CalcLeftLine(), + SwTwips nLeftLine = rAttrs.CalcLeftLine(); + + // 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(); + bool bDoNotCaptureDrawObjsOnPage = rIDSA.get(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE); + bool bLRTB = pFormat->GetFrameDir().GetValue() == SvxFrameDirection::Horizontal_LR_TB; + SwTwips nFlyLeft = getFrameArea().Left(); + SwTwips nPageLeft = pPageFrame->getFrameArea().Left(); + if (bDoNotCaptureDrawObjsOnPage && bLRTB && nFlyLeft < nPageLeft) + { + // It is outside: only start the left padding of the text inside the page frame, + // when we're in Word compatibility mode. + nLeftLine += (nPageLeft - nFlyLeft); + } + } + + aRectFnSet.SetXMargins( *this, nLeftLine, rAttrs.CalcRightLine() ); aRectFnSet.SetYMargins( *this, rAttrs.CalcTopLine(), rAttrs.CalcBottomLine() );