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 44b4ff646ea21df75f9e35b885d76d1aa0d61682
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed Mar 26 09:54:35 2025 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed Mar 26 12:49:21 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/+/183339
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

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 744e9631e409..1ea04c000d72 100644
--- a/sw/source/core/layout/fly.cxx
+++ b/sw/source/core/layout/fly.cxx
@@ -2086,12 +2086,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)

Reply via email to