sw/source/filter/ww8/attributeoutputbase.hxx |    2 
 sw/source/filter/ww8/docxattributeoutput.cxx |   10 -
 sw/source/filter/ww8/docxattributeoutput.hxx |    2 
 sw/source/filter/ww8/rtfattributeoutput.cxx  |    6 
 sw/source/filter/ww8/rtfattributeoutput.hxx  |    3 
 sw/source/filter/ww8/wrtw8sty.cxx            |  175 ++++++++++++---------------
 sw/source/filter/ww8/wrtww8.hxx              |   43 +++---
 sw/source/filter/ww8/ww8attributeoutput.hxx  |    2 
 8 files changed, 117 insertions(+), 126 deletions(-)

New commits:
commit a2a08463e0299d514e6e555ae61c68bb0e4348d0
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Thu Dec 8 10:56:52 2022 +0300
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Thu Dec 8 15:32:42 2022 +0000

    Simplify management of id-to-style-to-string-id mapping
    
    Instead of having three container objects for that, use one vector of
    appropriate structures. Slots are in sync and unique automatically.
    
    Change-Id: Ibb2c48ce42bf98f84df8230439ca98cb5b75051a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143807
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/sw/source/filter/ww8/attributeoutputbase.hxx 
b/sw/source/filter/ww8/attributeoutputbase.hxx
index d8a8be3e8f7f..ac3164ae2de6 100644
--- a/sw/source/filter/ww8/attributeoutputbase.hxx
+++ b/sw/source/filter/ww8/attributeoutputbase.hxx
@@ -275,7 +275,7 @@ public:
 
     /// Start of a style in the styles table.
     virtual void StartStyle( const OUString& rName, StyleType eType,
-            sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 nLink, sal_uInt16 
nWwId, sal_uInt16 nId,
+            sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 nLink, sal_uInt16 
nWwId, sal_uInt16 nSlot,
             bool bAutoUpdate ) = 0;
 
     /// End of a style in the styles table.
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index 5eb1c0ba306f..9084b9b6171a 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -7023,7 +7023,7 @@ static bool lcl_guessQFormat(const OUString& rName, 
sal_uInt16 nWwId)
 }
 
 void DocxAttributeOutput::StartStyle( const OUString& rName, StyleType eType,
-        sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 nLink, sal_uInt16 
nWwId, sal_uInt16 nId, bool bAutoUpdate )
+        sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 nLink, sal_uInt16 
nWwId, sal_uInt16 nSlot, bool bAutoUpdate )
 {
     bool bQFormat = false, bUnhideWhenUsed = false, bSemiHidden = false, 
bLocked = false, bDefault = false, bCustomStyle = false;
     OUString aRsid, aUiPriority;
@@ -7031,12 +7031,12 @@ void DocxAttributeOutput::StartStyle( const OUString& 
rName, StyleType eType,
     uno::Any aAny;
     if (eType == STYLE_TYPE_PARA || eType == STYLE_TYPE_CHAR)
     {
-        const SwFormat* pFormat = m_rExport.m_pStyles->GetSwFormat(nId);
+        const SwFormat* pFormat = m_rExport.m_pStyles->GetSwFormat(nSlot);
         pFormat->GetGrabBagItem(aAny);
     }
     else
     {
-        const SwNumRule* pRule = m_rExport.m_pStyles->GetSwNumRule(nId);
+        const SwNumRule* pRule = m_rExport.m_pStyles->GetSwNumRule(nSlot);
         pRule->GetGrabBagItem(aAny);
     }
     const uno::Sequence<beans::PropertyValue>& rGrabBag = aAny.get< 
uno::Sequence<beans::PropertyValue> >();
@@ -7081,7 +7081,7 @@ void DocxAttributeOutput::StartStyle( const OUString& 
rName, StyleType eType,
         case STYLE_TYPE_LIST: pType = "numbering"; break;
     }
     pStyleAttributeList->add(FSNS( XML_w, XML_type ), pType);
-    pStyleAttributeList->add(FSNS(XML_w, XML_styleId), 
m_rExport.m_pStyles->GetStyleId(nId));
+    pStyleAttributeList->add(FSNS(XML_w, XML_styleId), 
m_rExport.m_pStyles->GetStyleId(nSlot));
     if (bDefault)
         pStyleAttributeList->add(FSNS(XML_w, XML_default), "1");
     if (bCustomStyle)
@@ -7096,7 +7096,7 @@ void DocxAttributeOutput::StartStyle( const OUString& 
rName, StyleType eType,
                 FSNS( XML_w, XML_val ), m_rExport.m_pStyles->GetStyleId(nBase) 
);
     }
 
-    if ( nNext != nId && eType != STYLE_TYPE_LIST)
+    if ( nNext != nSlot && eType != STYLE_TYPE_LIST)
     {
         m_pSerializer->singleElementNS( XML_w, XML_next,
                 FSNS( XML_w, XML_val ), m_rExport.m_pStyles->GetStyleId(nNext) 
);
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx 
b/sw/source/filter/ww8/docxattributeoutput.hxx
index c5c74faa4e16..fd14524f6e77 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -286,7 +286,7 @@ public:
 
     /// Start of a style in the styles table.
     virtual void StartStyle( const OUString& rName, StyleType eType,
-            sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 nLink, sal_uInt16 
nWwId, sal_uInt16 nId,
+            sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 nLink, sal_uInt16 
nWwId, sal_uInt16 nSlot,
             bool bAutoUpdate ) override;
 
     /// End of a style in the styles table.
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx 
b/sw/source/filter/ww8/rtfattributeoutput.cxx
index 7645f89eb157..cd2f81a2463e 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -1175,7 +1175,7 @@ void RtfAttributeOutput::DefaultStyle() { /* noop, the 
default style is always 0
 
 void RtfAttributeOutput::StartStyle(const OUString& rName, StyleType eType, 
sal_uInt16 nBase,
                                     sal_uInt16 nNext, sal_uInt16 /*nLink*/, 
sal_uInt16 /*nWwId*/,
-                                    sal_uInt16 nId, bool bAutoUpdate)
+                                    sal_uInt16 nSlot, bool bAutoUpdate)
 {
     SAL_INFO("sw.rtf", __func__ << ", rName = '" << rName << "'");
 
@@ -1184,7 +1184,7 @@ void RtfAttributeOutput::StartStyle(const OUString& 
rName, StyleType eType, sal_
         m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_S);
     else
         m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_IGNORE 
OOO_STRING_SVTOOLS_RTF_CS);
-    m_aStylesheet.append(static_cast<sal_Int32>(nId));
+    m_aStylesheet.append(static_cast<sal_Int32>(nSlot));
 
     if (nBase != 0x0FFF)
     {
@@ -1199,7 +1199,7 @@ void RtfAttributeOutput::StartStyle(const OUString& 
rName, StyleType eType, sal_
         m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_SAUTOUPD);
 
     m_rStyleName = rName;
-    m_nStyleId = nId;
+    m_nStyleId = nSlot;
 }
 
 void RtfAttributeOutput::EndStyle()
diff --git a/sw/source/filter/ww8/rtfattributeoutput.hxx 
b/sw/source/filter/ww8/rtfattributeoutput.hxx
index a20719df6777..0ecf103a74fb 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.hxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.hxx
@@ -149,7 +149,8 @@ public:
 
     /// Start of a style in the styles table.
     void StartStyle(const OUString& rName, StyleType eType, sal_uInt16 nBase, 
sal_uInt16 nNext,
-                    sal_uInt16 nLink, sal_uInt16 nWwId, sal_uInt16 nId, bool 
bAutoUpdate) override;
+                    sal_uInt16 nLink, sal_uInt16 nWwId, sal_uInt16 nSlot,
+                    bool bAutoUpdate) override;
 
     /// End of a style in the styles table.
     void EndStyle() override;
diff --git a/sw/source/filter/ww8/wrtw8sty.cxx 
b/sw/source/filter/ww8/wrtw8sty.cxx
index d766f4923f2e..f251f41cff15 100644
--- a/sw/source/filter/ww8/wrtw8sty.cxx
+++ b/sw/source/filter/ww8/wrtw8sty.cxx
@@ -121,14 +121,15 @@ public:
 
 //  Styles
 
-#define WW8_RESERVED_SLOTS 15
+// Immediately after reserved slots, character styles begin
+#define WW8_RESERVED_SLOTS 10
 
 // GetId( SwCharFormat ) for use in text -> zero is not allowed,
 // use "Default Char Style" instead
 sal_uInt16 MSWordExportBase::GetId( const SwCharFormat* pFormat ) const
 {
     sal_uInt16 nRet = m_pStyles->GetSlot( pFormat );
-    return ( nRet != 0x0fff ) ? nRet : 10;      // Default Char Style
+    return ( nRet != 0x0fff ) ? nRet : WW8_RESERVED_SLOTS;      // Default 
Char Style
 }
 
 // GetId( SwTextFormatColl ) for use in TextNodes -> zero is not allowed,
@@ -153,13 +154,7 @@ MSWordStyles::MSWordStyles( MSWordExportBase& rExport, 
bool bListStyles )
         m_rExport.m_rDoc.GetFootnoteInfo().GetAnchorCharFormat( 
m_rExport.m_rDoc );
         m_rExport.m_rDoc.GetFootnoteInfo().GetCharFormat( m_rExport.m_rDoc );
     }
-    sal_uInt32 nAlloc = WW8_RESERVED_SLOTS + 
m_rExport.m_rDoc.GetCharFormats()->size() - 1 +
-                                         
m_rExport.m_rDoc.GetTextFormatColls()->size() - 1 +
-                                         (bListStyles ? 
m_rExport.m_rDoc.GetNumRuleTable().size() - 1 : 0);
-    nAlloc = std::min<sal_uInt32>(nAlloc, MSWORD_MAX_STYLES_LIMIT);
 
-    // somewhat generous ( free for up to 15 )
-    m_aFormatA.resize(nAlloc, nullptr);
     memset( m_aHeadingParagraphStyles, -1 , MAXLEVEL * sizeof( sal_uInt16));
 
     BuildStylesTable();
@@ -173,21 +168,19 @@ MSWordStyles::~MSWordStyles()
 // Sty_SetWWSlot() dependencies for the styles -> zero is allowed
 sal_uInt16 MSWordStyles::GetSlot( const SwFormat* pFormat ) const
 {
-    sal_uInt16 n;
-    for ( n = 0; n < m_nUsedSlots; n++ )
-        if ( m_aFormatA[n] == pFormat )
-            return n;
+    for (size_t slot = 0; slot < m_aStyles.size(); ++slot)
+        if (m_aStyles[slot].format == pFormat)
+            return slot;
     return 0xfff;                   // 0xfff: WW: zero
 }
 
-sal_uInt16 MSWordStyles::BuildGetSlot( const SwFormat& rFormat )
+/// Get reserved slot number during building the style table.
+static sal_uInt16 BuildGetSlot(const SwFormat& rFormat)
 {
-    sal_uInt16 nRet = rFormat.GetPoolFormatId();
-    switch ( nRet )
+    switch (sal_uInt16 nRet = rFormat.GetPoolFormatId())
     {
         case RES_POOLCOLL_STANDARD:
-            nRet = 0;
-            break;
+            return 0;
 
         case RES_POOLCOLL_HEADLINE1:
         case RES_POOLCOLL_HEADLINE2:
@@ -199,13 +192,10 @@ sal_uInt16 MSWordStyles::BuildGetSlot( const SwFormat& 
rFormat )
         case RES_POOLCOLL_HEADLINE8:
         case RES_POOLCOLL_HEADLINE9:
             nRet -= RES_POOLCOLL_HEADLINE1-1;
-            break;
-
-        default:
-            nRet = m_nUsedSlots++;
-            break;
+            assert(nRet < WW8_RESERVED_SLOTS);
+            return nRet;
     }
-    return nRet;
+    return 0xfff;
 }
 
 
@@ -281,28 +271,38 @@ sal_uInt16 MSWordStyles::GetWWId( const SwFormat& rFormat 
)
 
 void MSWordStyles::BuildStylesTable()
 {
-    m_nUsedSlots = WW8_RESERVED_SLOTS;  // reserved slots for standard, 
headingX, and others
+    assert(m_aStyles.empty());
+    // Put reserved slots first, then character styles, then paragraph styles
+    m_aStyles.resize(WW8_RESERVED_SLOTS);
 
     const SwCharFormats& rArr = *m_rExport.m_rDoc.GetCharFormats();       // 
first CharFormat
     // the default character style ( 0 ) will not be outputted !
-    for (size_t n = 1; n < rArr.size() && m_nUsedSlots < 
MSWORD_MAX_STYLES_LIMIT; ++n)
-    {
-        SwCharFormat* pFormat = rArr[n];
-        m_aFormatA[ BuildGetSlot( *pFormat ) ] = pFormat;
-    }
+    for (size_t n = 1; n < rArr.size() && m_aStyles.size() < 
MSWORD_MAX_STYLES_LIMIT; ++n)
+        m_aStyles.emplace_back(rArr[n]);
 
     const SwTextFormatColls& rArr2 = *m_rExport.m_rDoc.GetTextFormatColls();   
// then TextFormatColls
-    // the default character style ( 0 ) will not be outputted !
-    for (size_t n = 1; n < rArr2.size() && m_nUsedSlots < 
MSWORD_MAX_STYLES_LIMIT; ++n)
+    // the default paragraph style ( 0 ) will not be outputted !
+    for (size_t n = 1; n < rArr2.size(); ++n)
     {
         SwTextFormatColl* pFormat = rArr2[n];
-        sal_uInt16 nId = BuildGetSlot( *pFormat ) ;
-        m_aFormatA[ nId ] = pFormat;
+
+        sal_uInt16 nSlot = BuildGetSlot(*pFormat);
+        if (nSlot != 0xfff)
+        {
+            m_aStyles[nSlot].format = pFormat;
+        }
+        else
+        {
+            if (m_aStyles.size() >= MSWORD_MAX_STYLES_LIMIT)
+                continue;
+            m_aStyles.emplace_back(pFormat);
+            nSlot = m_aStyles.size() - 1;
+        }
         if ( pFormat->IsAssignedToListLevelOfOutlineStyle() )
         {
             int nLvl = pFormat->GetAssignedOutlineStyleLevel() ;
             if (nLvl >= 0 && nLvl < MAXLEVEL)
-                m_aHeadingParagraphStyles[nLvl] = nId ;
+                m_aHeadingParagraphStyles[nLvl] = nSlot;
         }
     }
 
@@ -310,13 +310,12 @@ void MSWordStyles::BuildStylesTable()
         return;
 
     const SwNumRuleTable& rNumRuleTable = m_rExport.m_rDoc.GetNumRuleTable();
-    for (size_t i = 0; i < rNumRuleTable.size() && m_nUsedSlots < 
MSWORD_MAX_STYLES_LIMIT; ++i)
+    for (size_t i = 0; i < rNumRuleTable.size() && m_aStyles.size() < 
MSWORD_MAX_STYLES_LIMIT; ++i)
     {
         const SwNumRule* pNumRule = rNumRuleTable[i];
         if (pNumRule->IsAutoRule() || pNumRule->GetName().startsWith("WWNum"))
             continue;
-        sal_uInt16 nSlot = BuildGetSlot(*pNumRule);
-        m_aNumRules[nSlot] = pNumRule;
+        m_aStyles.emplace_back(pNumRule);
     }
 }
 
@@ -342,18 +341,23 @@ void MSWordStyles::BuildStyleIds()
 {
     std::unordered_set<OString> aUsed;
 
-    m_aStyleIds.emplace_back("Normal");
+    assert(!m_aStyles.empty());
+    m_aStyles[0].style_id = "Normal";
     aUsed.insert("normal");
 
-    for (sal_uInt16 n = 1; n < m_nUsedSlots; ++n)
+    for (auto& entry : m_aStyles)
     {
-        OUString aName;
-        if (m_aFormatA[n])
-            aName = m_aFormatA[n]->GetName();
-        else if (m_aNumRules.find(n) != m_aNumRules.end())
-            aName = m_aNumRules[n]->GetName();
+        if (!entry.style_id.isEmpty())
+            continue; // "Normal" is already added
+
+        assert(entry.style_id.isEmpty());
+        OUString name;
+        if (entry.format)
+            name = entry.format->GetName();
+        else if (entry.num_rule)
+            name = entry.num_rule->GetName();
 
-        OString aStyleId = CreateStyleId(aName);
+        OString aStyleId = CreateStyleId(name);
 
         if (aStyleId.isEmpty())
             aStyleId = "Style";
@@ -361,24 +365,22 @@ void MSWordStyles::BuildStyleIds()
         OString aLower(aStyleId.toAsciiLowerCase());
 
         // check for uniqueness & construct something unique if we have to
-        if (aUsed.insert(aLower).second)
-        {
-            m_aStyleIds.push_back(aStyleId);
-        }
-        else
+        if (!aUsed.insert(aLower).second)
         {
             int nFree = 1;
             while (!aUsed.insert(aLower + OString::number(nFree)).second)
                 ++nFree;
 
-            m_aStyleIds.emplace_back(aStyleId + OString::number(nFree));
+            aStyleId += OString::number(nFree);
         }
+        entry.style_id = aStyleId;
     }
 }
 
-OString const & MSWordStyles::GetStyleId(sal_uInt16 nId) const
+OString const & MSWordStyles::GetStyleId(sal_uInt16 nSlot) const
 {
-    return m_aStyleIds[nId];
+    assert(!m_aStyles[nSlot].style_id.isEmpty());
+    return m_aStyles[nSlot].style_id;
 }
 
 /// For WW8 only - extend pO so that the size of pTableStrm is even.
@@ -403,7 +405,7 @@ void WW8AttributeOutput::EndStyle()
 }
 
 void WW8AttributeOutput::StartStyle( const OUString& rName, StyleType eType, 
sal_uInt16 nWwBase,
-    sal_uInt16 nWwNext, sal_uInt16 /*nWwLink*/, sal_uInt16 nWwId, sal_uInt16 
/*nId*/, bool bAutoUpdate )
+    sal_uInt16 nWwNext, sal_uInt16 /*nWwLink*/, sal_uInt16 nWwId, sal_uInt16 
/*nSlot*/, bool bAutoUpdate )
 {
     sal_uInt8 aWW8_STD[ sizeof( WW8_STD ) ] = {};
     sal_uInt8* pData = aWW8_STD;
@@ -549,7 +551,7 @@ void WW8AttributeOutput::EndStyleProperties( bool 
/*bParProp*/ )
     ShortToSVBT16( nLen, pUpxLen );                 // add default length
 }
 
-void MSWordStyles::GetStyleData( SwFormat* pFormat, bool& bFormatColl, 
sal_uInt16& nBase, sal_uInt16& nNext, sal_uInt16& nLink )
+void MSWordStyles::GetStyleData( const SwFormat* pFormat, bool& bFormatColl, 
sal_uInt16& nBase, sal_uInt16& nNext, sal_uInt16& nLink )
 {
     bFormatColl = pFormat->Which() == RES_TXTFMTCOLL || pFormat->Which() == 
RES_CONDTXTFMTCOLL;
 
@@ -560,18 +562,18 @@ void MSWordStyles::GetStyleData( SwFormat* pFormat, bool& 
bFormatColl, sal_uInt1
     if ( !pFormat->IsDefault() )
         nBase = GetSlot( pFormat->DerivedFrom() );
 
-    SwFormat* pNext;
+    const SwFormat* pNext;
     const SwFormat* pLink = nullptr;
     if ( bFormatColl )
     {
-        auto pFormatColl = static_cast<SwTextFormatColl*>(pFormat);
+        auto pFormatColl = static_cast<const SwTextFormatColl*>(pFormat);
         pNext = &pFormatColl->GetNextTextFormatColl();
         pLink = pFormatColl->GetLinkedCharFormat();
     }
     else
     {
         pNext = pFormat; // CharFormat: next CharFormat == self
-        auto pCharFormat = static_cast<SwCharFormat*>(pFormat);
+        auto pCharFormat = static_cast<const SwCharFormat*>(pFormat);
         pLink = pCharFormat->GetLinkedParaFormat();
     }
 
@@ -588,17 +590,17 @@ void WW8AttributeOutput::DefaultStyle()
     m_rWW8Export.m_pTableStrm->WriteUInt16(0);   // empty Style
 }
 
-void MSWordStyles::OutputStyle(const SwNumRule* pNumRule, sal_uInt16 nPos)
+void MSWordStyles::OutputStyle(const SwNumRule* pNumRule, sal_uInt16 nSlot)
 {
     m_rExport.AttrOutput().StartStyle( pNumRule->GetName(), STYLE_TYPE_LIST,
-            /*nBase =*/ 0, /*nWwNext =*/ 0, /*nWwLink =*/ 0, /*nWWId =*/ 0, 
nPos,
+            /*nBase =*/ 0, /*nWwNext =*/ 0, /*nWwLink =*/ 0, /*nWWId =*/ 0, 
nSlot,
             /*bAutoUpdateFormat =*/ false );
 
     m_rExport.AttrOutput().EndStyle();
 }
 
 // OutputStyle applies for TextFormatColls and CharFormats
-void MSWordStyles::OutputStyle( SwFormat* pFormat, sal_uInt16 nPos )
+void MSWordStyles::OutputStyle( const SwFormat* pFormat, sal_uInt16 nSlot)
 {
     if ( !pFormat )
         m_rExport.AttrOutput().DefaultStyle();
@@ -614,7 +616,7 @@ void MSWordStyles::OutputStyle( SwFormat* pFormat, 
sal_uInt16 nPos )
         // We want to map LO's default style to Word's "Normal" style.
         // Word looks for this specific style name when reading docx files.
         // (It must be the English word regardless of language settings)
-        if ( nPos == 0 )
+        if (nSlot == 0)
         {
             assert( pFormat->GetPoolFormatId() == RES_POOLCOLL_STANDARD );
             aName = "Normal";
@@ -626,35 +628,30 @@ void MSWordStyles::OutputStyle( SwFormat* pFormat, 
sal_uInt16 nPos )
             aName = aBaseName;
             // Check if we still have a clash, in which case we add a suffix
             for ( int nSuffix = 0; ; ++nSuffix ) {
-                bool clash=false;
-                for ( sal_uInt16 n = 1; n < m_nUsedSlots; ++n )
-                    if ( m_aFormatA[n] &&
-                         m_aFormatA[n]->GetName().equalsIgnoreAsciiCase(aName) 
)
-                    {
-                        clash = true;
-                        break;
-                    }
-                if (!clash)
-                    break;
-                // TODO: verify if we really need to increment nSuffix in 2 
places
-                aName = aBaseName + OUString::number(++nSuffix);
+                if (std::none_of(m_aStyles.begin() + 1, m_aStyles.end(),
+                                 [&aName](const auto& entry) {
+                                     return entry.format
+                                            && 
entry.format->GetName().equalsIgnoreAsciiCase(aName);
+                                 }))
+                    break; // Found a unique name
+                aName = aBaseName + OUString::number(nSuffix);
             }
         }
         else if (!bFormatColl && m_rExport.GetExportFormat() == 
MSWordExportBase::DOCX &&
-                        
m_rExport.m_pStyles->GetStyleId(nPos).startsWith("ListLabel"))
+                        
m_rExport.m_pStyles->GetStyleId(nSlot).startsWith("ListLabel"))
         {
             // tdf#92335 don't export redundant DOCX import style "ListLabel"
             return;
         }
 
         m_rExport.AttrOutput().StartStyle( aName, (bFormatColl ? 
STYLE_TYPE_PARA : STYLE_TYPE_CHAR),
-                nBase, nWwNext, nWwLink, GetWWId( *pFormat ), nPos,
+                nBase, nWwNext, nWwLink, GetWWId( *pFormat ), nSlot,
                 pFormat->IsAutoUpdateFormat() );
 
         if ( bFormatColl )
-            WriteProperties( pFormat, true, nPos, nBase==0xfff );           // 
UPX.papx
+            WriteProperties( pFormat, true, nSlot, nBase==0xfff );           
// UPX.papx
 
-        WriteProperties( pFormat, false, nPos, bFormatColl && nBase==0xfff );  
// UPX.chpx
+        WriteProperties( pFormat, false, nSlot, bFormatColl && nBase==0xfff ); 
 // UPX.chpx
 
         m_rExport.AttrOutput().EndStyle();
     }
@@ -696,35 +693,25 @@ void MSWordStyles::OutputStylesTable()
 
     m_rExport.AttrOutput().StartStyles();
 
-    sal_uInt16 n;
     // HACK
     // Ms Office seems to have an internal limitation of 4091 styles
     // and refuses to load .docx with more, even though the spec seems to 
allow that;
     // so simply if there are more styles, don't export those
     // Implementing check for all exports DOCX, DOC, RTF
-    sal_uInt16 const nLimit = MSWORD_MAX_STYLES_LIMIT;
-    m_nUsedSlots = std::min(nLimit, m_nUsedSlots);
-
-    for ( n = 0; n < m_nUsedSlots; n++ )
+    assert(m_aStyles.size() <= MSWORD_MAX_STYLES_LIMIT);
+    for (size_t slot = 0; slot < m_aStyles.size(); ++slot)
     {
-        if (m_aNumRules.find(n) != m_aNumRules.end())
-            OutputStyle(m_aNumRules[n], n);
+        if (m_aStyles[slot].num_rule)
+            OutputStyle(m_aStyles[slot].num_rule, slot);
         else
-            OutputStyle(m_aFormatA[n], n);
+            OutputStyle(m_aStyles[slot].format, slot);
     }
 
-    m_rExport.AttrOutput().EndStyles( m_nUsedSlots );
+    m_rExport.AttrOutput().EndStyles(m_aStyles.size());
 
     m_rExport.m_bStyDef = false;
 }
 
-const SwNumRule* MSWordStyles::GetSwNumRule(sal_uInt16 nId) const
-{
-    std::map<sal_uInt16, const SwNumRule*>::const_iterator it = 
m_aNumRules.find(nId);
-    assert(it != m_aNumRules.end());
-    return it->second;
-}
-
 //          Fonts
 
 wwFont::wwFont(std::u16string_view rFamilyName, FontPitch ePitch, FontFamily 
eFamily,
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index db06ca60790b..5af10e91fdc3 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -1581,26 +1581,29 @@ class MSWordStyles
 {
     MSWordExportBase& m_rExport;
     sal_uInt16 m_aHeadingParagraphStyles[MAXLEVEL];
-    std::vector<SwFormat*> m_aFormatA; ///< Slot <-> Character and paragraph 
style array (0 for list styles).
-    sal_uInt16 m_nUsedSlots;
-    bool m_bListStyles; ///< If list styles are requested to be exported as 
well.
-    std::map<sal_uInt16, const SwNumRule*> m_aNumRules; ///< Slot <-> List 
style map.
 
-    /// We need to build style id's for DOCX export; ideally we should 
roundtrip that, but this is good enough.
-    std::vector<OString> m_aStyleIds;
+    struct MapEntry
+    {
+        const SwFormat* format = nullptr;
+        const SwNumRule* num_rule = nullptr;
+        /// We need to build style id's for DOCX export; ideally we should 
roundtrip that, but this is good enough.
+        OString style_id;
+
+        MapEntry() = default;
+        MapEntry(const SwFormat* f) : format(f) {}
+        MapEntry(const SwNumRule* r) : num_rule(r) {}
+    };
+    std::vector<MapEntry> m_aStyles; ///< Slot <-> Character/paragraph/list 
style array.
+    bool m_bListStyles; ///< If list styles are requested to be exported as 
well.
 
     /// Create the style table, called from the constructor.
     void BuildStylesTable();
 
-    /// Based on pFormatA, fill in m_aStyleIds with unique, MS-like names.
+    /// Based on style names, fill in unique, MS-like names.
     void BuildStyleIds();
 
-    /// Get slot number during building the style table.
-    sal_uInt16 BuildGetSlot( const SwFormat& rFormat );
-    sal_uInt16 BuildGetSlot( const SwNumRule& /*rNumRule*/ ) { return 
m_nUsedSlots++;}
-
     /// Return information about one style.
-    void GetStyleData( SwFormat* pFormat, bool& bFormatColl, sal_uInt16& 
nBase, sal_uInt16& nNext, sal_uInt16& nLink );
+    void GetStyleData( const SwFormat* pFormat, bool& bFormatColl, sal_uInt16& 
nBase, sal_uInt16& nNext, sal_uInt16& nLink );
 
     /// Outputs attributes of one style.
     void WriteProperties( const SwFormat* pFormat, bool bPap, sal_uInt16 nPos, 
bool bInsDefCharSiz );
@@ -1610,8 +1613,8 @@ class MSWordStyles
     void SetStyleDefaults( const SwFormat& rFormat, bool bPap );
 
     /// Outputs one style - called (in a loop) from OutputStylesTable().
-    void OutputStyle( SwFormat* pFormat, sal_uInt16 nPos );
-    void OutputStyle( const SwNumRule* pNumRule, sal_uInt16 nPos );
+    void OutputStyle( const SwFormat* pFormat, sal_uInt16 nSlot );
+    void OutputStyle( const SwNumRule* pNumRule, sal_uInt16 nSlot);
 
     MSWordStyles( const MSWordStyles& ) = delete;
     MSWordStyles& operator=( const MSWordStyles& ) = delete;
@@ -1623,18 +1626,18 @@ public:
     /// Output the styles table.
     void OutputStylesTable();
 
-    /// Get id of the style (rFormat).
+    /// Get slot of the style (rFormat).
     sal_uInt16 GetSlot( const SwFormat* pFormat ) const;
 
     /// create style id using only ASCII characters of the style name
     static OString CreateStyleId(std::u16string_view aName);
 
-    /// Get styleId of the nId-th style (nId is its position in pFormatA).
-    OString const & GetStyleId(sal_uInt16 nId) const;
+    /// Get styleId of the nSlot-th style (nSlot is its position in m_aStyles).
+    OString const & GetStyleId(sal_uInt16 nSlot) const;
 
-    const SwFormat* GetSwFormat(sal_uInt16 nId) const { return 
m_aFormatA[nId]; }
-    /// Get numbering rule of the nId-th style
-    const SwNumRule* GetSwNumRule(sal_uInt16 nId) const;
+    const SwFormat* GetSwFormat(sal_uInt16 nSlot) const { return 
m_aStyles[nSlot].format; }
+    /// Get numbering rule of the nSlot-th style
+    const SwNumRule* GetSwNumRule(sal_uInt16 nSlot) const { return 
m_aStyles[nSlot].num_rule; }
     sal_uInt16 GetHeadingParagraphStyleId(sal_uInt16 nLevel) const { return 
m_aHeadingParagraphStyles[ nLevel ]; }
 };
 
diff --git a/sw/source/filter/ww8/ww8attributeoutput.hxx 
b/sw/source/filter/ww8/ww8attributeoutput.hxx
index efb317df9305..3b78c33317d7 100644
--- a/sw/source/filter/ww8/ww8attributeoutput.hxx
+++ b/sw/source/filter/ww8/ww8attributeoutput.hxx
@@ -126,7 +126,7 @@ public:
 
     /// Start of a style in the styles table.
     virtual void StartStyle( const OUString& rName, StyleType eType,
-            sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 nLink, sal_uInt16 
nWwIdi, sal_uInt16 nId,
+            sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 nLink, sal_uInt16 
nWwIdi, sal_uInt16 nSlot,
             bool bAutoUpdate ) override;
 
     /// End of a style in the styles table.

Reply via email to