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