sw/qa/extras/ooxmlexport/ooxmlexport25.cxx | 13 ++++++++++--- sw/source/filter/ww8/docxattributeoutput.cxx | 6 +++++- 2 files changed, 15 insertions(+), 4 deletions(-)
New commits: commit b3e82cc18c6c61dfb3906631d311351355a476a0 Author: [email protected] <[email protected]> AuthorDate: Mon Jan 19 14:15:36 2026 -0500 Commit: Justin Luth <[email protected]> CommitDate: Tue Jan 20 13:31:02 2026 +0100 tdf#170389 docx export: don't spam inherited tabstops Until now, we had been duplicating inherited tabstops into the current style or paragraph. While not a terrible thing, it is unnecessary (assuming inheritance is working properly). Also, it COULD (though unlikely) contribute to hitting the 64 maximum tabstop limit that DOCX has. That could have resulted in discarding necessary tabstops. make CppunitTest_sw_ooxmlexport25 \ CPPUNIT_TEST_NAME=testTdf170389_manyTabstops Change-Id: Ib68eaf043af15384fea2cd96e8fe178a505ec1db Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197607 Reviewed-by: Justin Luth <[email protected]> Tested-by: Jenkins diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport25.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport25.cxx index 72fbe062ce04..2ea0d1a6a50f 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport25.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport25.cxx @@ -154,12 +154,19 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf170389_manyTabstops) { createSwDoc("tdf170389_manyTabstops.odt"); - save(TestFilter::DOCX); + saveAndReload(TestFilter::DOCX); xmlDocUniquePtr pXmlDoc = parseExport(u"word/document.xml"_ustr); // MS Word reports document as corrupt if it has more than 64 tabstops defined - // The paragraph itself defines 40, and inherits 40. Without the fix, this was 80 - assertXPath(pXmlDoc, "//w:tabs/w:tab", 64); + // The paragraph itself defines 40, and inherits 40. Without the fixes, this was 80 or 64 + assertXPath(pXmlDoc, "//w:tabs/w:tab", 40); + + xmlDocUniquePtr pLayout = parseLayoutDump(); + sal_Int32 nSize + = getXPath(pLayout, "//SwFixPortion[@type='PortionType::TabLeft']", "width").toInt32(); + // The word 'tabstop' should be almost at the very end of the line, starting at 6 inches. + // Without the fix, the tabstop's width was a tiny 247, now it is 1797. + CPPUNIT_ASSERT_GREATER(sal_Int32(1500), nSize); // nSize > 1500 } CPPUNIT_TEST_FIXTURE(Test, testInvalidDatetimeInProps) diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 73bc0c17509e..b8497eb475d9 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -9290,6 +9290,8 @@ void DocxAttributeOutput::ParaTabStop( const SvxTabStopItem& rTabStop ) // <w:tabs> may contain 64 <w:tab> entries at most, or else MS Word reports the file as corrupt sal_uInt32 nWrittenTabs = 0; + // do not output inherited tabs multiple times (inside styles and inside inline properties) + std::vector<bool> vInherited(nCount, false); // Get offset for tabs // In DOCX, w:pos specifies the position of the current custom tab stop with respect to the current page margins. @@ -9313,13 +9315,15 @@ void DocxAttributeOutput::ParaTabStop( const SvxTabStopItem& rTabStop ) FSNS( XML_w, XML_pos ), OString::number(pInheritedTabs->At(i).GetTabPos()) ); ++nWrittenTabs; } + else if (pInheritedTabs->At(i) == rTabStop[nCurrTab]) + vInherited[nCurrTab] = true; } for (sal_uInt16 i = 0; i < nCount; i++ ) { if( rTabStop[i].GetAdjustment() != SvxTabAdjust::Default ) { - if (nWrittenTabs < 64) + if (!vInherited[i] && nWrittenTabs < 64) { impl_WriteTabElement( m_pSerializer, rTabStop[i], tabsOffset ); ++nWrittenTabs;
