sw/qa/extras/ooxmlexport/ooxmlexport25.cxx | 13 ++++++++++--- sw/source/filter/ww8/docxattributeoutput.cxx | 6 +++++- 2 files changed, 15 insertions(+), 4 deletions(-)
New commits: commit f1a85b03fd5a58a9e9e961d96eaa298d2a136b4c Author: [email protected] <[email protected]> AuthorDate: Mon Jan 19 14:15:36 2026 -0500 Commit: Miklos Vajna <[email protected]> CommitDate: Wed Jan 21 09:27:46 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 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197661 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport25.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport25.cxx index e380b9e8975f..48105aa5e2b0 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport25.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport25.cxx @@ -113,12 +113,19 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf170389_manyTabstops) { createSwDoc("tdf170389_manyTabstops.odt"); - save(TestFilter::DOCX); + saveAndReload(u"Office Open XML Text"_ustr); 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, testTdf169413_asciiTheme) diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 6a1d3d1684c7..e34bba03119e 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -9268,6 +9268,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. @@ -9291,13 +9293,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;
