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.