sw/CppunitTest_sw_core_layout.mk                    |    1 
 sw/qa/core/layout/anchoredobject.cxx                |   59 ++++++++++++++++++++
 sw/qa/core/layout/data/textbox-fly-page-capture.odt |binary
 sw/source/core/layout/anchoredobject.cxx            |    6 +-
 4 files changed, 65 insertions(+), 1 deletion(-)

New commits:
commit 664b8252e705a2daec9f2a6bb30424e08fcdd3d2
Author:     Miklos Vajna <[email protected]>
AuthorDate: Wed Oct 16 08:13:07 2024 +0200
Commit:     Adolfo Jayme Barrientos <[email protected]>
CommitDate: Thu Oct 17 07:28:48 2024 +0200

    tdf#138711 sw textbox: capture fly when its draw object is captured
    
    Load the bugdoc, notice that the only shape in the document has a
    captured (inside the page frame) draw shape, but its inner fly frame is
    not captured inside the page frame, so a small top margin is paired with
    a larger right margin, which is unexpected.
    
    This is nominally a regression from commit
    9835a5823e0f559aabbc0e15ea126c82229c4bc7 (sw textboxes: reimplement ODF
    import/export, 2014-10-04), because previously the ODF markup for Writer
    TextBoxes were ignored, so we had correct position of the shape text at
    the price of losing complex content.
    
    Fix the problem similar to what commit
    a0b6587c4acb1d74e1b00904147821640c98b323 (tdf#161199 sw
    DoNotCaptureDrawObjsOnPage: capture wrap=none draw objects, 2024-06-13)
    did: if we detect that the fly frame is part of a TextBox, then work
    with the wrap type of the draw format, since these inner fly frames
    always have their wrap type set to "through".
    
    This fixes the unexpected position of the fly frame and keeps the import
    of complex content working.
    
    Change-Id: Ib0d861af0fac74d93a09178c10bc19a1b45e3ce7
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/174987
    Reviewed-by: Miklos Vajna <[email protected]>
    Tested-by: Jenkins
    (cherry picked from commit c8549fa3204802daec8597ba0f9f4f7ef23d5cd2)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/174952
    Reviewed-by: Adolfo Jayme Barrientos <[email protected]>

diff --git a/sw/CppunitTest_sw_core_layout.mk b/sw/CppunitTest_sw_core_layout.mk
index d64a43f7d3fb..4617f8c07234 100644
--- a/sw/CppunitTest_sw_core_layout.mk
+++ b/sw/CppunitTest_sw_core_layout.mk
@@ -14,6 +14,7 @@ $(eval $(call gb_CppunitTest_CppunitTest,sw_core_layout))
 $(eval $(call gb_CppunitTest_use_common_precompiled_header,sw_core_layout))
 
 $(eval $(call gb_CppunitTest_add_exception_objects,sw_core_layout, \
+    sw/qa/core/layout/anchoredobject \
     sw/qa/core/layout/calcmove \
     sw/qa/core/layout/fly \
     sw/qa/core/layout/flycnt \
diff --git a/sw/qa/core/layout/anchoredobject.cxx 
b/sw/qa/core/layout/anchoredobject.cxx
new file mode 100644
index 000000000000..c317298813a0
--- /dev/null
+++ b/sw/qa/core/layout/anchoredobject.cxx
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <swmodeltestbase.hxx>
+
+#include <IDocumentLayoutAccess.hxx>
+#include <docsh.hxx>
+#include <pagefrm.hxx>
+#include <rootfrm.hxx>
+#include <sortedobjs.hxx>
+#include <anchoredobject.hxx>
+
+namespace
+{
+/// Covers sw/source/core/layout/anchoredobject.cxx fixes.
+class Test : public SwModelTestBase
+{
+public:
+    Test()
+        : SwModelTestBase(u"/sw/qa/core/layout/data/"_ustr)
+    {
+    }
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testTextBoxFlyPageCapture)
+{
+    // Given a document with a draw shape with complex content, positioned to 
be outside the page
+    // frame, but capture to page frame is enabled:
+    // When loading that document:
+    createSwDoc("textbox-fly-page-capture.odt");
+
+    // Then make sure the right edge of the inner fly frame is the same as the 
right edge of the
+    // draw frame:
+    SwDoc* pDoc = getSwDocShell()->GetDoc();
+    SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+    auto pPage = pLayout->GetLower()->DynCastPageFrame();
+    CPPUNIT_ASSERT(pPage->GetSortedObjs());
+    const SwSortedObjs& rPageObjs = *pPage->GetSortedObjs();
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), rPageObjs.size());
+    SwAnchoredObject* pDraw = rPageObjs[0];
+    SwTwips nDrawRight = pDraw->GetObjRect().Right();
+    SwAnchoredObject* pFly = rPageObjs[1];
+    SwTwips nFlyRight = pFly->GetObjRect().Right();
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 5081
+    // - Actual  : 4798
+    // i.e. the position of the draw shape was corrected to be inside the page 
frame, but this
+    // didn't happen for the inner fly frame.
+    CPPUNIT_ASSERT_EQUAL(nDrawRight, nFlyRight);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/core/layout/data/textbox-fly-page-capture.odt 
b/sw/qa/core/layout/data/textbox-fly-page-capture.odt
new file mode 100644
index 000000000000..48244049af8a
Binary files /dev/null and 
b/sw/qa/core/layout/data/textbox-fly-page-capture.odt differ
diff --git a/sw/source/core/layout/anchoredobject.cxx 
b/sw/source/core/layout/anchoredobject.cxx
index 36d6caa37404..59ebbcbe27de 100644
--- a/sw/source/core/layout/anchoredobject.cxx
+++ b/sw/source/core/layout/anchoredobject.cxx
@@ -781,7 +781,11 @@ bool SwAnchoredObject::IsDraggingOffPageAllowed(const 
SwFrameFormat* pFrameForma
 {
     assert(pFrameFormat);
     const bool bDisablePositioning = 
pFrameFormat->getIDocumentSettingAccess().get(DocumentSettingId::DISABLE_OFF_PAGE_POSITIONING);
-    const bool bIsWrapThrough = pFrameFormat->GetSurround().GetSurround() == 
text::WrapTextMode::WrapTextMode_THROUGH;
+    // If this fly is paired with a draw format, then take the wrap text mode 
from the outer draw
+    // format, since the fly format is always wrap through.
+    SwFrameFormat* pDrawFormat = 
SwTextBoxHelper::getOtherTextBoxFormat(pFrameFormat, RES_FLYFRMFMT);
+    const SwFrameFormat* pFormat = pDrawFormat ? pDrawFormat : pFrameFormat;
+    const bool bIsWrapThrough = pFormat->GetSurround().GetSurround() == 
text::WrapTextMode::WrapTextMode_THROUGH;
 
     return bDisablePositioning && bIsWrapThrough;
 }

Reply via email to