sw/qa/extras/ooxmlexport/ooxmlexport21.cxx | 3 sw/qa/extras/ooxmlimport/ooxmlimport.cxx | 3 sw/source/writerfilter/dmapper/GraphicImport.cxx | 74 ++++++++++++++++------- 3 files changed, 58 insertions(+), 22 deletions(-)
New commits: commit 5b6dbf694ad8d86ab500aab3789a52e5a9fff16d Author: Justin Luth <justin.l...@collabora.com> AuthorDate: Fri Aug 1 17:53:44 2025 -0400 Commit: Michael Stahl <michael.st...@collabora.com> CommitDate: Mon Aug 4 12:04:59 2025 +0200 tdf#167770 writerfilter: zero out margin if left/right aligned Both shapes and graphics should be flush against the edge of the page/paragraph when they are right or left aligned. During layout, MS Word doesn't save space for "text wrapping" on the side where there can be no text, so this is best emulated by zeroing out what LO calls the "margin". This has been partially done since 2006, but now I'm trying to consistently cover all cases. This longstanding bug became more prominent in 24.8 with commit eacf8dc7ab850f2d00bd4b327f830c55cf2a0d92 Author: Justin Luth on Tue Mar 5 19:22:34 2024 -0500 tdf#160049 dml import: use margins with left/right HoriOrientRelation Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164443 For now, just keep it simple to see the bugfix changes. Later, this can be dedupped into a single function. make CppunitTest_sw_ooxmlexport21 \ CPPUNIT_TEST_NAME=testTdf160049_anchorMargin2 make CppunitTest_sw_ooxmlimport CPPUNIT_TEST_NAME=testTdf96218 Change-Id: I62a2434212bd050922b74a0105ef30c8c4c3c393 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188786 Tested-by: Jenkins Reviewed-by: Justin Luth <jl...@mail.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188861 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Michael Stahl <michael.st...@collabora.com> diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx index a388b7a3657a..9b9796098788 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx @@ -490,6 +490,9 @@ DECLARE_OOXMLEXPORT_TEST(testTdf160049_anchorMargin2, "tdf160049_anchorMargin2.d // which is "Paragraph text area"/PRINT_AREA/1, not "Entire paragraph area"/FRAME/0 CPPUNIT_ASSERT_EQUAL(css::text::RelOrientation::PRINT_AREA, getProperty<sal_Int16>(getShape(1), u"HoriOrientRelation"_ustr)); + + // tdf#167770: emulate no text-wrap gap when left-aligned-to-paragraph-margin instead of 0.90cm + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(getShape(1), u"LeftMargin"_ustr)); } DECLARE_OOXMLEXPORT_TEST(testTdf160049_anchorMargin14, "tdf160049_anchorMargin14.docx") diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx index 4ce5edb38557..35675a0d587e 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx @@ -1570,6 +1570,9 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf96218) createSwDoc("tdf96218.docx"); // Image had a bad position because layoutInCell attribute was not ignored CPPUNIT_ASSERT(!getProperty<bool>(getShape(1), u"IsFollowingTextFlow"_ustr)); + + // tdf#167770: emulate no text-wrap gap when right-aligned-to-page-edge instead of 0.32cm + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(getShape(1), u"RightMargin"_ustr)); } CPPUNIT_TEST_FIXTURE(Test, testTdf101626) diff --git a/sw/source/writerfilter/dmapper/GraphicImport.cxx b/sw/source/writerfilter/dmapper/GraphicImport.cxx index d1df5176c917..b5ae4f5e8ef2 100644 --- a/sw/source/writerfilter/dmapper/GraphicImport.cxx +++ b/sw/source/writerfilter/dmapper/GraphicImport.cxx @@ -1336,6 +1336,29 @@ void GraphicImport::lcl_attribute(Id nName, const Value& rValue) m_pImpl->m_nHoriRelation = text::RelOrientation::PRINT_AREA; } + // adjust margins + // when impossible to wrap text on a side, remove the margin gap + if (m_pImpl->m_nHoriRelation != text::RelOrientation::CHAR) + { + const bool bRightSide + = m_pImpl->m_nHoriRelation == text::RelOrientation::PAGE_RIGHT + || m_pImpl->m_nHoriRelation == text::RelOrientation::FRAME_RIGHT; + const bool bLeftSide + = m_pImpl->m_nHoriRelation == text::RelOrientation::PAGE_LEFT + || m_pImpl->m_nHoriRelation == text::RelOrientation::FRAME_LEFT; + + assert(bRightSide || bLeftSide + || m_pImpl->m_nHoriRelation == text::RelOrientation::PAGE_PRINT_AREA //margin + || m_pImpl->m_nHoriRelation == text::RelOrientation::PAGE_FRAME // page + || m_pImpl->m_nHoriRelation == text::RelOrientation::PRINT_AREA // column + || m_pImpl->m_nHoriRelation == text::RelOrientation::FRAME /*margin*/ ); + + if (m_pImpl->m_nHoriOrient == text::HoriOrientation::LEFT && !bRightSide) + m_pImpl->m_nLeftMargin = 0; + else if (m_pImpl->m_nHoriOrient == text::HoriOrientation::RIGHT && !bLeftSide) + m_pImpl->m_nRightMargin = 0; + } + // Anchored: Word only supports at-char in that case. text::TextContentAnchorType eAnchorType = text::TextContentAnchorType_AT_CHARACTER; @@ -1688,16 +1711,6 @@ void GraphicImport::lcl_sprm(Sprm& rSprm) m_pImpl->m_bPageToggle = pHandler->GetPageToggle(); m_pImpl->m_nHoriOrient = pHandler->orientation(); m_pImpl->m_nLeftPosition = pHandler->position(); - - // Left adjustments: if horizontally aligned to left of margin, then remove the - // left wrapping. - if (m_pImpl->m_nHoriOrient == text::HoriOrientation::LEFT) - { - if (m_pImpl->m_nHoriRelation == text::RelOrientation::PAGE_PRINT_AREA) - { - m_pImpl->m_nLeftMargin = 0; - } - } } } } @@ -1901,18 +1914,35 @@ rtl::Reference<SwXTextGraphicObject> GraphicImport::createGraphicObject(uno::Ref } //adjust margins - if( (m_pImpl->m_nHoriOrient == text::HoriOrientation::LEFT && - (m_pImpl->m_nHoriRelation == text::RelOrientation::PAGE_PRINT_AREA || - m_pImpl->m_nHoriRelation == text::RelOrientation::FRAME) ) || - (m_pImpl->m_nHoriOrient == text::HoriOrientation::INSIDE && - m_pImpl->m_nHoriRelation == text::RelOrientation::PAGE_PRINT_AREA )) - m_pImpl->m_nLeftMargin = 0; - if((m_pImpl->m_nHoriOrient == text::HoriOrientation::RIGHT && - (m_pImpl->m_nHoriRelation == text::RelOrientation::PAGE_PRINT_AREA || - m_pImpl->m_nHoriRelation == text::RelOrientation::FRAME) ) || - (m_pImpl->m_nHoriOrient == text::HoriOrientation::INSIDE && - m_pImpl->m_nHoriRelation == text::RelOrientation::PAGE_PRINT_AREA )) - m_pImpl->m_nRightMargin = 0; + // when impossible to wrap text on a side, remove the margin gap + if (m_pImpl->m_nHoriRelation != text::RelOrientation::CHAR) + { + const bool bRightSide + = m_pImpl->m_nHoriRelation == text::RelOrientation::PAGE_RIGHT + || m_pImpl->m_nHoriRelation == text::RelOrientation::FRAME_RIGHT; + const bool bLeftSide + = m_pImpl->m_nHoriRelation == text::RelOrientation::PAGE_LEFT + || m_pImpl->m_nHoriRelation == text::RelOrientation::FRAME_LEFT; + + assert(bRightSide || bLeftSide + || m_pImpl->m_nHoriRelation == text::RelOrientation::PAGE_PRINT_AREA // margin + || m_pImpl->m_nHoriRelation == text::RelOrientation::PAGE_FRAME // page + || m_pImpl->m_nHoriRelation == text::RelOrientation::PRINT_AREA // column + || m_pImpl->m_nHoriRelation == text::RelOrientation::FRAME /*margin*/ ); + + if (m_pImpl->m_nHoriOrient == text::HoriOrientation::LEFT && !bRightSide) + m_pImpl->m_nLeftMargin = 0; + else if (m_pImpl->m_nHoriOrient == text::HoriOrientation::RIGHT && !bLeftSide) + m_pImpl->m_nRightMargin = 0; + else if (m_pImpl->m_nHoriOrient == text::HoriOrientation::INSIDE) + { + if (m_pImpl->m_nHoriRelation == text::RelOrientation::PAGE_PRINT_AREA) + { + m_pImpl->m_nLeftMargin = 0; + m_pImpl->m_nRightMargin = 0; + } + } + } // adjust top/bottom margins if( m_pImpl->m_nVertOrient == text::VertOrientation::TOP && ( m_pImpl->m_nVertRelation == text::RelOrientation::PAGE_PRINT_AREA ||