sw/qa/extras/ooxmlexport/ooxmlexport22.cxx | 5 - sw/source/filter/ww8/docxattributeoutput.cxx | 69 +++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 4 deletions(-)
New commits: commit 8b097a952b556c3ba28e32658de702ae8c183c96 Author: Justin Luth <jl...@mail.com> AuthorDate: Sat Aug 9 08:35:22 2025 -0400 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Tue Aug 19 16:49:35 2025 +0200 tdf#167721 docx export: add w:left=0 when w:leftChars=0 Setting w:leftChars to zero means that it is disabled. It will use w:left instead. Since w:left could otherwise be inherited from the paragraph style, make sure that it is specified as zero. Change-Id: I9b14d96aae4b5128e3dc490a57022832eee9b2f0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189268 Tested-by: Jenkins Reviewed-by: Justin Luth <jl...@mail.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189552 diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 76481ed82c68..cd8042d56eaa 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -9411,6 +9411,10 @@ void DocxAttributeOutput::FormatFirstLineIndent(SvxFirstLineIndentItem const& rF { AddToAttrList(m_pLRSpaceAttrList, FSNS(XML_w, XML_firstLineChars), OString::number(stValue.m_dValue * 100.0)); + + // handle special value "zero" which disables firstLineChars + if (stValue.m_dValue == 0.0) + AddToAttrList(m_pLRSpaceAttrList, FSNS(XML_w, XML_firstLine), OString::number(0)); } else { @@ -9499,6 +9503,11 @@ void DocxAttributeOutput::FormatTextLeftMargin(SvxTextLeftMarginItem const& rTex AddToAttrList(m_pLRSpaceAttrList, FSNS(XML_w, (bEcma1st ? XML_leftChars : XML_startChars)), OString::number(stValue.m_dValue * 100.0)); + + // handle special value "zero" which disables leftChars + if (stValue.m_dValue == 0.0) + AddToAttrList(m_pLRSpaceAttrList, FSNS(XML_w, (bEcma1st ? XML_left : XML_start)), + OString::number(0)); return; } @@ -9534,6 +9543,11 @@ void DocxAttributeOutput::FormatRightMargin(SvxRightMarginItem const& rRightMarg { AddToAttrList(m_pLRSpaceAttrList, FSNS(XML_w, (bEcma1st ? XML_rightChars : XML_endChars)), OString::number(stValue.m_dValue * 100.0)); + + // handle special value "zero" which disables rightChars + if (stValue.m_dValue == 0.0) + AddToAttrList(m_pLRSpaceAttrList, FSNS(XML_w, (bEcma1st ? XML_right : XML_end)), + OString::number(0)); return; } commit 5ff90b9dc4574e3c9de24801db9cfd66c1e24db9 Author: Justin Luth <jl...@mail.com> AuthorDate: Sat Aug 9 11:23:23 2025 -0400 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Tue Aug 19 16:49:23 2025 +0200 tdf#167721 docx export: disable inherited leftChars when writing w:left There are two w:ind items that can affect the left margin, and leftChars has the priority. So if the parent style's left margin was written as a leftChars, then a non-leftChars w:left needs to also disable w:leftChars. make CppunitTest_sw_ooxmlexport22 \ CPPUNIT_TEST_NAME=testTdf167721_chUnits3 Change-Id: Ie0126ea5e5409907d4edc999ec13ac5f667aa682 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189267 Reviewed-by: Justin Luth <jl...@mail.com> Tested-by: Jenkins Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189551 diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport22.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport22.cxx index 246fd3674d83..f6765cab81ea 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport22.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport22.cxx @@ -309,7 +309,7 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf167721_chUnits2) CPPUNIT_ASSERT_EQUAL(double(2), aRightCh.First); } -CPPUNIT_TEST_FIXTURE(Test, testTdf167721_chUnits3) +DECLARE_OOXMLEXPORT_TEST(testTdf167721_chUnits3, "tdf167721_chUnits3.docx") { // given a nasty edge-case document // Style "List Paragraph": left = 2 inch, right = 2 cm, first line = none @@ -319,9 +319,6 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf167721_chUnits3) // Paragraph: left = 0, right = 0.14 inch, first line = +2 inch // <w:ind w:rightChars="0" w:hangingChars="0" w:firstLine="2880" /> - createSwDoc("tdf167721_chUnits3.docx"); - // saveAndReload(mpFilter); - // Test the parent style ###################################################################### uno::Reference<beans::XPropertySet> xStyle( getStyles(u"ParagraphStyles"_ustr)->getByName(u"List Paragraph"_ustr), uno::UNO_QUERY); diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 58d4338ac682..76481ed82c68 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -9422,6 +9422,26 @@ void DocxAttributeOutput::FormatFirstLineIndent(SvxFirstLineIndentItem const& rF } sal_Int32 const nFirstLineAdjustment(rFirstLine.ResolveTextFirstLineOffset({})); + + // if the parent style wrote a FONT_CJK_ADVANCE margin (which has inheritance priority) + // then hangingChars/firstLineChars (either one) needs to be disabled + const SvxFirstLineIndentItem* pInherited = nullptr; + if (auto pNd = dynamic_cast<const SwContentNode*>(m_rExport.m_pOutFormatNode)) //paragraph + pInherited = &static_cast<SwTextFormatColl&>(pNd->GetAnyFormatColl()).GetAttrSet().GetFirstLineIndent(); + else if (m_rExport.m_bStyDef && m_rExport.m_pCurrentStyle && m_rExport.m_pCurrentStyle->DerivedFrom()) //style + pInherited = &m_rExport.m_pCurrentStyle->DerivedFrom()->GetFirstLineIndent(); + if (pInherited) + { + stValue = pInherited->GetTextFirstLineOffset(); + if (stValue.m_nUnit == css::util::MeasureUnit::FONT_CJK_ADVANCE) + { + AddToAttrList(m_pLRSpaceAttrList, + FSNS(XML_w, + nFirstLineAdjustment > 0 ? XML_firstLineChars : XML_hangingChars), + OString::number(0)); + } + } + if (nFirstLineAdjustment > 0) { AddToAttrList(m_pLRSpaceAttrList, FSNS(XML_w, XML_firstLine), @@ -9482,6 +9502,24 @@ void DocxAttributeOutput::FormatTextLeftMargin(SvxTextLeftMarginItem const& rTex return; } + // if the parent style wrote a FONT_CJK_ADVANCE margin (which has inheritance priority) + // then leftChars needs to be disabled + const SvxTextLeftMarginItem* pInherited = nullptr; + if (auto pNd = dynamic_cast<const SwContentNode*>(m_rExport.m_pOutFormatNode)) //paragraph + pInherited = &static_cast<SwTextFormatColl&>(pNd->GetAnyFormatColl()).GetAttrSet().GetTextLeftMargin(); + else if (m_rExport.m_bStyDef && m_rExport.m_pCurrentStyle && m_rExport.m_pCurrentStyle->DerivedFrom()) //style + pInherited = &m_rExport.m_pCurrentStyle->DerivedFrom()->GetTextLeftMargin(); + if (pInherited) + { + stValue = pInherited->GetTextLeft(); + if (stValue.m_nUnit == css::util::MeasureUnit::FONT_CJK_ADVANCE) + { + AddToAttrList(m_pLRSpaceAttrList, + FSNS(XML_w, bEcma1st ? XML_leftChars : XML_startChars), + OString::number(0)); + } + } + AddToAttrList(m_pLRSpaceAttrList, FSNS(XML_w, (bEcma1st ? XML_left : XML_start)), OString::number(pTextLeftMargin->ResolveTextLeft({}))); } @@ -9499,6 +9537,23 @@ void DocxAttributeOutput::FormatRightMargin(SvxRightMarginItem const& rRightMarg return; } + // if the parent style wrote a FONT_CJK_ADVANCE margin (which has inheritance priority) + // then rightChars needs to be disabled + const SvxRightMarginItem* pInherited = nullptr; + if (auto pNd = dynamic_cast<const SwContentNode*>(m_rExport.m_pOutFormatNode)) //paragraph + pInherited = &static_cast<SwTextFormatColl&>(pNd->GetAnyFormatColl()).GetAttrSet().GetRightMargin(); + else if (m_rExport.m_bStyDef && m_rExport.m_pCurrentStyle && m_rExport.m_pCurrentStyle->DerivedFrom()) //style + pInherited = &m_rExport.m_pCurrentStyle->DerivedFrom()->GetRightMargin(); + if (pInherited) + { + stValue = pInherited->GetRight(); + if (stValue.m_nUnit == css::util::MeasureUnit::FONT_CJK_ADVANCE) + { + AddToAttrList(m_pLRSpaceAttrList, FSNS(XML_w, bEcma1st ? XML_rightChars : XML_endChars), + OString::number(0)); + } + } + AddToAttrList(m_pLRSpaceAttrList, FSNS(XML_w, (bEcma1st ? XML_right : XML_end)), OString::number(rRightMargin.ResolveRight({}))); }