sw/qa/extras/ooxmlexport/data/tdf165047_contextualSpacingTopMargin.docx |binary
 sw/qa/extras/ooxmlexport/ooxmlexport22.cxx                              |   19 
++++++++++
 sw/source/core/layout/flowfrm.cxx                                       |   13 
+++++-
 3 files changed, 30 insertions(+), 2 deletions(-)

New commits:
commit be07e6e8bef7f594494a866e36e972a379aa0513
Author:     Justin Luth <justin.l...@collabora.com>
AuthorDate: Wed Apr 2 14:58:45 2025 -0400
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Thu Apr 3 09:01:16 2025 +0200

    tdf#165047 sw mso-compat layout: always honour contextualSpacing
    
    This improves 25.8 commit ae7900dd42a65aaf60df6b21b9ad511496b209d9
    tdf#164095 sw: fix missing top margin on paragraph
                   after changing page style
    which was backported to 24.8.5.
    
    The problem is that you can't just simply apply the top margin.
    Even though it may be across a page break,
    or even in a different section,
    the fact that the previous paragraph is the same style
    means that we simply don't add any upper spacing to this paragraph.
    
    make CppunitTest_sw_ooxmlexport22 \
        CPPUNIT_TEST_NAME=testTdf165047_contextualSpacingTopMargin
    
    Change-Id: I12712e5421e20ea0757c59029c6890bff9d81b94
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183643
    Reviewed-by: Justin Luth <jl...@mail.com>
    Tested-by: Jenkins
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183650
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git 
a/sw/qa/extras/ooxmlexport/data/tdf165047_contextualSpacingTopMargin.docx 
b/sw/qa/extras/ooxmlexport/data/tdf165047_contextualSpacingTopMargin.docx
new file mode 100644
index 000000000000..f6710de3e4a1
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/tdf165047_contextualSpacingTopMargin.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport22.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport22.cxx
index e01e03f07028..f67344a82904 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport22.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport22.cxx
@@ -61,6 +61,25 @@ CPPUNIT_TEST_FIXTURE(Test, 
testTdf165047_consolidatedTopMargin)
     CPPUNIT_ASSERT_EQUAL(static_cast<SwTwips>(200), nParaTopMargin);
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testTdf165047_contextualSpacingTopMargin)
+{
+    // Given a two page document with a section page break
+    // which is preceded by a paragraph with a lot of lower spacing
+    // and followed by a paragraph with a lot of upper spacing,
+    // but that paragraph says "don't add space between identical paragraph 
styles...
+    loadAndSave("tdf165047_contextualSpacingTopMargin.docx");
+
+    // the upper spacing is ignored since the paragraph styles are the same
+    CPPUNIT_ASSERT_EQUAL(2, getPages());
+
+    // When laying out that document:
+    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+    // The effective top margin (after the page break) must be 0
+    SwTwips nParaTopMargin
+        = getXPath(pXmlDoc, "/root/page[2]/body/section/infos/prtBounds", 
"top").toInt32();
+    CPPUNIT_ASSERT_EQUAL(static_cast<SwTwips>(0), nParaTopMargin);
+}
+
 } // end of anonymous namespace
 CPPUNIT_PLUGIN_IMPLEMENT();
 
diff --git a/sw/source/core/layout/flowfrm.cxx 
b/sw/source/core/layout/flowfrm.cxx
index 1a82925021ac..a2c83b864ae6 100644
--- a/sw/source/core/layout/flowfrm.cxx
+++ b/sw/source/core/layout/flowfrm.cxx
@@ -1502,13 +1502,14 @@ const SwFrame* 
SwFlowFrame::GetPrevFrameForUpperSpaceCalc_( const SwFrame* _pPro
 
 // This should be renamed to something like lcl_UseULSpacing
 /// Compare styles attached to these text frames.
-static bool lcl_IdenticalStyles(const SwFrame* pPrevFrame, const SwFrame* 
pFrame)
+static bool lcl_IdenticalStyles(const SwFrame* pPrevFrame, const SwFrame* 
pFrame,
+                                bool bAllowAcrossSections = false)
 {
     if (!pFrame || !pFrame->IsTextFrame())
         return false;
 
     // Identical styles only applies if "the paragraphs belong to the same 
content area".
-    if (pPrevFrame && pPrevFrame->FindSctFrame() != pFrame->FindSctFrame())
+    if (!bAllowAcrossSections && pPrevFrame && pPrevFrame->FindSctFrame() != 
pFrame->FindSctFrame())
         return false;
 
     SwTextFormatColl *pPrevFormatColl = nullptr;
@@ -1558,6 +1559,14 @@ static void lcl_PartiallyCollapseUpper(const SwFrame& 
rFrame, SwTwips& rUpper)
     if (!pPrevPara || pPrevPara->IsInTab())
         return;
 
+    // MSO skips space between same-style paragraphs even at a 
sectionPageBreak.
+    const bool bContextualSpacing = 
pTextFrame->GetAttrSet()->GetULSpace().GetContext();
+    const bool bIdenticalStyles
+        = bContextualSpacing
+            && lcl_IdenticalStyles(pPrevPara, pTextFrame, 
/*AllowAcrossSections*/ true);
+    if (bIdenticalStyles)
+        rUpper = 0;
+    else
     {
         // MSO is also hyper-consistent about consolidating
         // the lower-space from the previous paragraph

Reply via email to