sw/qa/core/text/data/para-upper-margin-fly-intersect.docx |binary
 sw/qa/core/text/text.cxx                                  |   30 ++++++++++++++
 sw/qa/extras/layout/layout.cxx                            |   20 ++++-----
 sw/source/core/inc/ftnboss.hxx                            |    2 
 sw/source/core/text/itrform2.cxx                          |    6 ++
 5 files changed, 46 insertions(+), 12 deletions(-)

New commits:
commit bd32306c15ae6773c58d1d66d1d17845b93dc854
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Thu Jun 15 08:24:23 2023 +0200
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Fri Jun 16 12:34:20 2023 +0200

    sw floattable: fix handling of upper margin of anchor for fly intersect
    
    The bugdoc has 2 paragraphs and a shape between them. Word has a small
    amount of space between the shape and the 2nd paragraph, Writer has a
    large amount of space between the shape and the 2nd paragraph.
    
    It seems what happens is that Writer puts both the text node's own
    upper spacing and the previous text node's lower spacing into the upper
    spacing of the text frame, so the check added in commit
    d07fc485d46f431405a3f6a002f951a08c559677 (tdf#116486 Consider upper
    margin in paragraph positioning with flys, 2018-04-10) is not entirely
    correct, as it deal with both upper and lower margins, but its intention
    was just the upper margins.
    
    Fix the problem by (indirectly) using
    GetUpperSpaceAmountConsideredForPrevFrame(), which allows doing the
    intersection for the original text node upper spacing but not for the
    text node lower spacing. This keeps the original bugdoc working, but
    fixes the unexpected vertical space for the new bugdoc.
    
    This is part of the effort so that the original bnc#816603 bugdoc's DOCX
    version moves an overlapping floating table from page 4 back to page 3,
    like Word does. testTdf122878 is modified to just make sure no overlap
    happens, manual testing of the bugdoc shows that our layout still
    matches Word.
    
    (cherry picked from commit 737d90b7b7cb03bb6128b74a32906b0391868830)
    
    Conflicts:
            sw/qa/core/text/text.cxx
            sw/qa/extras/layout/layout3.cxx
    
    Change-Id: I4622fb77dc8a52493766e50688ec92065eac65bc
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153168
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/sw/qa/core/text/data/para-upper-margin-fly-intersect.docx 
b/sw/qa/core/text/data/para-upper-margin-fly-intersect.docx
new file mode 100644
index 000000000000..e8e767fb3897
Binary files /dev/null and 
b/sw/qa/core/text/data/para-upper-margin-fly-intersect.docx differ
diff --git a/sw/qa/core/text/text.cxx b/sw/qa/core/text/text.cxx
index 544a17d3b8c0..138db21fdc35 100644
--- a/sw/qa/core/text/text.cxx
+++ b/sw/qa/core/text/text.cxx
@@ -964,6 +964,36 @@ CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testFloattableOverlap)
     CPPUNIT_ASSERT(!rRect1.Overlaps(rRect2));
 }
 
+CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testParaUpperMarginFlyIntersect)
+{
+    // Given a document with 2 paragraphs, the paragraphs have both upper and 
lower spacing of 567
+    // twips:
+    createSwDoc("para-upper-margin-fly-intersect.docx");
+
+    // When laying out that document:
+    calcLayout();
+
+    // Then make sure that we shift down the text in the second paragraph only 
based on the 2nd para
+    // upper margin, not based on the 1st para lower margin:
+    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+    int nFlyCount
+        = getXPathContent(pXmlDoc,
+                          
"count(//SwParaPortion/SwLineLayout/child::*[@type='PortionType::Fly'])")
+              .toInt32();
+    int nHeight = 0;
+    for (int i = 1; i <= nFlyCount; ++i)
+    {
+        OString xPath = 
"(//SwParaPortion/SwLineLayout/child::*[@type='PortionType::Fly'])["
+                        + OString::number(i) + "]";
+        nHeight += getXPath(pXmlDoc, xPath, "height").toInt32();
+    }
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 521 (~500)
+    // - Actual  : 857 (~1000)
+    // I.e. both upper and lower margin was taken into account.
+    CPPUNIT_ASSERT_EQUAL(521, nHeight);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx
index 43b71e6c0eac..ff5cc4b764af 100644
--- a/sw/qa/extras/layout/layout.cxx
+++ b/sw/qa/extras/layout/layout.cxx
@@ -3629,21 +3629,21 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf122878)
 {
     createSwDoc("tdf122878.docx");
     xmlDocUniquePtr pXmlDoc = parseLayoutDump();
-    // FIXME: the XPath should be adjusted when the proper floating table 
would be imported
     const sal_Int32 nTblTop
         = getXPath(pXmlDoc, 
"/root/page[1]/footer/txt/anchored/fly/tab/infos/bounds", "top")
               .toInt32();
-    const sal_Int32 nFirstPageParaCount
-        = getXPathContent(pXmlDoc, "count(/root/page[1]/body/txt)").toInt32();
-    CPPUNIT_ASSERT_EQUAL(sal_Int32(30), nFirstPageParaCount);
-    for (sal_Int32 i = 1; i <= nFirstPageParaCount; ++i)
+    SwDoc* pDoc = getSwDoc();
+    SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+    auto pPage1 = dynamic_cast<SwPageFrame*>(pLayout->Lower());
+    CPPUNIT_ASSERT(pPage1);
+    SwFrame* pBody = pPage1->FindBodyCont();
+    for (SwFrame* pFrame = pBody->GetLower(); pFrame; pFrame = 
pFrame->GetNext())
     {
-        const OString xPath = "/root/page[1]/body/txt[" + OString::number(i) + 
"]/infos/bounds";
-        const sal_Int32 nTxtBottom = getXPath(pXmlDoc, xPath.getStr(), 
"top").toInt32()
-                                     + getXPath(pXmlDoc, xPath.getStr(), 
"height").toInt32();
+        const sal_Int32 nTxtBottom = pFrame->getFrameArea().Bottom();
         // No body paragraphs should overlap the table in the footer
-        CPPUNIT_ASSERT_MESSAGE(OString("testing paragraph #" + 
OString::number(i)).getStr(),
-                               nTxtBottom <= nTblTop);
+        CPPUNIT_ASSERT_MESSAGE(
+            OString("testing paragraph #" + 
OString::number(pFrame->GetFrameId())).getStr(),
+            nTxtBottom <= nTblTop);
     }
 }
 
diff --git a/sw/source/core/inc/ftnboss.hxx b/sw/source/core/inc/ftnboss.hxx
index e60ff97de1a9..109c9df74e29 100644
--- a/sw/source/core/inc/ftnboss.hxx
+++ b/sw/source/core/inc/ftnboss.hxx
@@ -46,7 +46,7 @@ enum class SwNeighbourAdjust {
 
 typedef std::vector<SwFootnoteFrame*> SwFootnoteFrames;
 
-class SAL_DLLPUBLIC_RTTI SwFootnoteBossFrame: public SwLayoutFrame
+class SW_DLLPUBLIC SwFootnoteBossFrame: public SwLayoutFrame
 {
     // for private footnote operations
     friend class SwFrame;
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index 352ecb8d169a..9b3a605acfdd 100644
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -2701,7 +2701,11 @@ void SwTextFormatter::CalcFlyWidth( SwTextFormatInfo 
&rInf )
     if 
(GetTextFrame()->GetDoc().getIDocumentSettingAccess().get(DocumentSettingId::ADD_VERTICAL_FLY_OFFSETS)
         && IsFirstTextLine())
     {
-        const tools::Long nUpper = m_pFrame->getFramePrintArea().Top();
+        tools::Long nUpper = m_pFrame->getFramePrintArea().Top();
+        // Make sure that increase only happens in case the upper spacing 
comes from the upper
+        // margin of the current text frame, not because of a lower spacing of 
the previous text
+        // frame.
+        nUpper -= 
m_pFrame->GetUpperSpaceAmountConsideredForPrevFrameAndPageGrid();
         // Increase the rectangle
         if( nUpper > 0 && nTop >= nUpper  )
             aLine.SubTop( nUpper );

Reply via email to