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;

Reply via email to