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 c716de571f2f1abc7b27170729a2107a1f87e533 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:05:36 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/+/188864 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 36fa8fcf009c..4ce0bdc00361 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 b1376f29c104..2ed94c85d3f7 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 d7768ff5eed2..5b2f02c4b15c 100644 --- a/sw/source/writerfilter/dmapper/GraphicImport.cxx +++ b/sw/source/writerfilter/dmapper/GraphicImport.cxx @@ -1334,6 +1334,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; @@ -1686,16 +1709,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; - } - } } } } @@ -1899,18 +1912,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 ||