sw/qa/extras/ooxmlexport/ooxmlexport22.cxx | 10 +++++----- sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx | 8 +++++++- sw/source/writerfilter/dmapper/StyleSheetTable.cxx | 10 ++++++++++ 3 files changed, 22 insertions(+), 6 deletions(-)
New commits: commit 3abee091cd10f634b00e3bca733f3deff1dafd86 Author: Justin Luth <jl...@mail.com> AuthorDate: Tue Aug 12 09:25:09 2025 -0400 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Tue Aug 19 16:50:03 2025 +0200 tdf#167721 writerfilter: adjust disabled leftChars by hangingChars Sixth Problem - in a very inconsistent move, with hangingChars MS Word ignores the fact that w:leftChars=0 has been disabled, (or even never defined) and simply treats it as a zero margin, even if a w:left margin has been defined. I imagine this is actually a bug in MS Word. That bug is seen in MS Word 2003 / 2010 and still exists in MS Word 2024. There are even weirder things happening with styles, but when I actually apply a style to a paragraph, then that paragraph gets different margin properties than what is shown for the style, so probably best not to attempt any changes to styles at all. make CppunitTest_sw_ooxmlexport22 \ CPPUNIT_TEST_NAME=testTdf167721_chUnits Change-Id: I689853f631aa1cb5e144e43e75672b177fd81537 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189437 Reviewed-by: Justin Luth <jl...@mail.com> Tested-by: Jenkins Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189554 diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport22.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport22.cxx index 6f3e412bbeba..a929eb6faad0 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport22.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport22.cxx @@ -245,7 +245,9 @@ DECLARE_OOXMLEXPORT_TEST(testTdf167721_chUnits, "tdf167721_chUnits.docx") = getProperty<css::beans::Pair<double, sal_Int16>>(xPara, u"ParaFirstLineIndentUnit"_ustr); CPPUNIT_ASSERT_EQUAL(double(-1), aFirstCh.First); - CPPUNIT_ASSERT_EQUAL(sal_Int32(5001), getProperty<sal_Int32>(xPara, u"ParaLeftMargin"_ustr)); + // oddly, w:left is always ignored by MS Word in special case with hangingChars indent + aLeftCh = getProperty<css::beans::Pair<double, sal_Int16>>(xPara, u"ParaLeftMarginUnit"_ustr); + CPPUNIT_ASSERT_EQUAL(double(1), aLeftCh.First); aRightCh = getProperty<css::beans::Pair<double, sal_Int16>>(xPara, u"ParaRightMarginUnit"_ustr); CPPUNIT_ASSERT_EQUAL(double(2), aRightCh.First); diff --git a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx index 6a23771998f1..0765810528ef 100644 --- a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx +++ b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx @@ -3160,9 +3160,15 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap, con // tdf#83844: DOCX stores left and leftChars differently with hanging // indentation. Character-based hanging indentation must be pre-added // to the left margin here. - if (bLeftChSet && stFirstCh.First < 0.0) + + // tdf#167721: Oddball MS Word implementation: + // Even if LeftChars is disabled/undefined and a w:left is provided, + // when a hangingChars is also provided + // then the w:left is ignored and treated as a zero. + if (stFirstCh.First < 0.0) { stLeftCh.First -= stFirstCh.First; + bLeftChSet = true; } if (bLeftChSet) commit 8a11beb71eff1b4c7fa2a4b61394cec825e7a804 Author: Justin Luth <jl...@mail.com> AuthorDate: Sat Aug 9 10:40:42 2025 -0400 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Tue Aug 19 16:49:48 2025 +0200 tdf#167721 writerfilter styles: adjust leftChars by hangingChars Fifth Problem - styles import needs to adjust the left margin just like the paragraph import does. The way MS implements "hanging" is that w:hanging defines where the first line starts and w:left defines how much further the remaining lines start. This is opposed to "firstLine" where w:firstLine defines the additional indent for the first line and w:left defines where the entire paragraph's indent. LO's implementation is much nicer, where the left margin always defines the entire paragraph's indent. make CppunitTest_sw_ooxmlexport22 \ CPPUNIT_TEST_NAME=testTdf167721_chUnits Change-Id: I6ac4b49350d33d31d0948530910b4d4712bdc403 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189269 Tested-by: Jenkins Reviewed-by: Justin Luth <jl...@mail.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189553 diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport22.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport22.cxx index f6765cab81ea..6f3e412bbeba 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport22.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport22.cxx @@ -208,7 +208,7 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf166553_paraStyleAfterBreak) CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xPara, u"CharWeight"_ustr)); } -CPPUNIT_TEST_FIXTURE(Test, testTdf167721_chUnits) +DECLARE_OOXMLEXPORT_TEST(testTdf167721_chUnits, "tdf167721_chUnits.docx") { // given a document that specifies some margins using Ch-based Left/Right indentation // where w:rightChars is inherited from the parent styles - so it overrides w:right @@ -220,8 +220,6 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf167721_chUnits) // inherited formatting from the style chain in styles.xml // <w:ind w:rightChars="200" (2 ic) w:hangingChars=400 (4 ic) // w:leftChars="300" (3 ic) w:left="2834"/> (5 cm) - createSwDoc("tdf167721_chUnits.docx"); - // saveAndReload(mpFilter); // Test the style ############################################################################# uno::Reference<beans::XPropertySet> xStyle( @@ -234,7 +232,7 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf167721_chUnits) auto aLeftCh = getProperty<css::beans::Pair<double, sal_Int16>>(xStyle, u"ParaLeftMarginUnit"_ustr); - CPPUNIT_ASSERT_EQUAL(double(3), aLeftCh.First); + CPPUNIT_ASSERT_EQUAL(double(7), aLeftCh.First); auto aRightCh = getProperty<css::beans::Pair<double, sal_Int16>>(xStyle, u"ParaRightMarginUnit"_ustr); diff --git a/sw/source/writerfilter/dmapper/StyleSheetTable.cxx b/sw/source/writerfilter/dmapper/StyleSheetTable.cxx index bbd0b0c35b1c..9f5fe3dd9955 100644 --- a/sw/source/writerfilter/dmapper/StyleSheetTable.cxx +++ b/sw/source/writerfilter/dmapper/StyleSheetTable.cxx @@ -1433,6 +1433,16 @@ void StyleSheetTable::ApplyStyleSheetsImpl(const FontTablePtr& rFontTable, std:: == getPropertyName(PROP_PARA_FIRST_LINE_INDENT_UNIT); }); } + + // hanging margins need to alter the left margin + if (bLeftChSet && stFirstCh.First < 0.0) + { + stLeftCh.First -= stFirstCh.First; + beans::PropertyValue aPV( + getPropertyName(PROP_PARA_LEFT_MARGIN_UNIT), 0, + uno::Any(stLeftCh), beans::PropertyState_DIRECT_VALUE); + aPropValues.push_back(aPV); + } } if (bFirstSet && bFirstChSet)