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() );

Reply via email to