diff options
author | Miklos Vajna <vmiklos@suse.cz> | 2012-05-30 11:43:41 +0200 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2012-06-04 13:20:23 +0200 |
commit | d366ae2031d13f3198cb58c715f18e8c8ce8686f (patch) | |
tree | 2ac02539c07069b5f8223e2eb918ed7477c7329f | |
parent | a50c30bd01b0859d4b84c8ec24e9cabb68ee0714 (diff) |
fdo#49968 speed up RTF import of repeated character/paragraph properties
Most RTF documents (produced by Word/Writer) reset character and
paragraph properties at the start of each paragraph. Because of this,
appending properties of the same type didn't cause any noticable
performance problems. However, it's valid to not reset these properties,
and in this case a longer document takes forever to import.
Filter these duplicates at the tokenizer level for trivial properties to
get acceptable import speed.
Also fixes rhbz#825548 in an easier-to-backport way.
Change-Id: Id0b7289323d45ff0d747c74bb78d8eb7def0cfc2
(cherry picked from commit a5328cf5605cdc243522eddcaffe7336196a4900)
Signed-off-by: Michael Stahl <mstahl@redhat.com>
-rw-r--r-- | writerfilter/source/rtftok/rtfdocumentimpl.cxx | 20 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtfsprm.cxx | 14 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtfsprm.hxx | 2 |
3 files changed, 26 insertions, 10 deletions
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx index 063d94b5a5cd..ea14c57cb543 100644 --- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx +++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx @@ -1664,7 +1664,7 @@ int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword) if (nParam >= 0) { RTFValue::Pointer_t pValue(new RTFValue(nParam)); - m_aStates.top().aParagraphSprms->push_back(make_pair(NS_sprm::LN_PJc, pValue)); + m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PJc, pValue); return 0; } @@ -2222,7 +2222,7 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) } if (nSprm > 0) { - m_aStates.top().aCharacterSprms->push_back(make_pair(nSprm, pIntValue)); + m_aStates.top().aCharacterSprms.set(nSprm, pIntValue); // Language is a character property, but we should store it at a paragraph level as well for fields. if (nKeyword == RTF_LANG && m_bNeedPap) m_aStates.top().aParagraphSprms->push_back(make_pair(nSprm, pIntValue)); @@ -2240,7 +2240,7 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) } if (nSprm > 0) { - m_aStates.top().aParagraphSprms->push_back(make_pair(nSprm, pIntValue)); + m_aStates.top().aParagraphSprms.set(nSprm, pIntValue); if (nKeyword == RTF_ITAP && nParam > 0) // Invalid tables may omit INTBL after ITAP dispatchFlag(RTF_INTBL); @@ -2305,7 +2305,7 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) { int nFontIndex = getFontIndex(nParam); RTFValue::Pointer_t pValue(new RTFValue(nFontIndex)); - m_aStates.top().aCharacterSprms->push_back(make_pair(NS_sprm::LN_CRgFtc0, pValue)); + m_aStates.top().aCharacterSprms.set(NS_sprm::LN_CRgFtc0, pValue); m_aStates.top().nCurrentEncoding = getEncoding(nFontIndex); } break; @@ -2353,7 +2353,7 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) m_aStates.top().aTableAttributes->push_back(make_pair(NS_rtf::LN_SGC, pValue)); // paragraph style } else - m_aStates.top().aParagraphAttributes->push_back(make_pair(NS_rtf::LN_ISTD, pIntValue)); + m_aStates.top().aParagraphAttributes.set(NS_rtf::LN_ISTD, pIntValue); break; case RTF_CS: if (m_aStates.top().nDestinationState == DESTINATION_STYLESHEET) @@ -2814,11 +2814,11 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) break; case RTF_SB: lcl_putNestedAttribute(m_aStates.top().aParagraphSprms, - NS_ooxml::LN_CT_PPrBase_spacing, NS_ooxml::LN_CT_Spacing_before, pIntValue); + NS_ooxml::LN_CT_PPrBase_spacing, NS_ooxml::LN_CT_Spacing_before, pIntValue, true); break; case RTF_SA: lcl_putNestedAttribute(m_aStates.top().aParagraphSprms, - NS_ooxml::LN_CT_PPrBase_spacing, NS_ooxml::LN_CT_Spacing_after, pIntValue); + NS_ooxml::LN_CT_PPrBase_spacing, NS_ooxml::LN_CT_Spacing_after, pIntValue, true); break; case RTF_DPX: m_aStates.top().aDrawingObject.nLeft = TWIP_TO_MM100(nParam); @@ -2847,11 +2847,11 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) m_aStates.top().nBinaryToRead = nParam; break; case RTF_LI: - m_aStates.top().aParagraphSprms->push_back(make_pair(NS_sprm::LN_PDxaLeft, pIntValue)); + m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PDxaLeft, pIntValue); // It turns out \li should reset the \fi inherited from the stylesheet. // So set the direct formatting to zero, if we don't have such direct formatting yet. if (!m_aStates.top().aParagraphSprms.find(NS_sprm::LN_PDxaLeft1).get()) - m_aStates.top().aParagraphSprms->push_back(make_pair(NS_sprm::LN_PDxaLeft1, RTFValue::Pointer_t(new RTFValue(0)))); + m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PDxaLeft1, RTFValue::Pointer_t(new RTFValue(0))); break; default: #if OSL_DEBUG_LEVEL > 1 @@ -2934,7 +2934,7 @@ int RTFDocumentImpl::dispatchToggle(RTFKeyword nKeyword, bool bParam, int nParam } if (nSprm >= 0) { - m_aStates.top().aCharacterSprms->push_back(make_pair(nSprm, pBoolValue)); + m_aStates.top().aCharacterSprms.set(nSprm, pBoolValue); return 0; } diff --git a/writerfilter/source/rtftok/rtfsprm.cxx b/writerfilter/source/rtftok/rtfsprm.cxx index 976505f78292..72793fe7c8d8 100644 --- a/writerfilter/source/rtftok/rtfsprm.cxx +++ b/writerfilter/source/rtftok/rtfsprm.cxx @@ -105,6 +105,20 @@ RTFValue::Pointer_t RTFSprms::find(Id nKeyword) return pValue; } +void RTFSprms::set(Id nKeyword, RTFValue::Pointer_t pValue, bool bOverwrite) +{ + if (bOverwrite) + { + for (RTFSprms::Iterator_t i = m_aSprms.begin(); i != m_aSprms.end(); ++i) + if (i->first == nKeyword) + { + i->second = pValue; + return; + } + } + m_aSprms.push_back(std::make_pair(nKeyword, pValue)); +} + bool RTFSprms::erase(Id nKeyword) { for (RTFSprms::Iterator_t i = m_aSprms.begin(); i != m_aSprms.end(); ++i) diff --git a/writerfilter/source/rtftok/rtfsprm.hxx b/writerfilter/source/rtftok/rtfsprm.hxx index dbf2e2f375db..df33e5fa59e8 100644 --- a/writerfilter/source/rtftok/rtfsprm.hxx +++ b/writerfilter/source/rtftok/rtfsprm.hxx @@ -43,6 +43,8 @@ namespace writerfilter { RTFSprms(const RTFSprms& rSprms); std::vector< std::pair<Id, RTFValue::Pointer_t> >* operator->(); RTFValue::Pointer_t find(Id nKeyword); + /// Does the same as ->push_back(), except that it can overwrite existing entries. + void set(Id nKeyword, RTFValue::Pointer_t pValue, bool bOverwrite = true); bool erase(Id nKeyword); private: std::vector< std::pair<Id, RTFValue::Pointer_t> > m_aSprms; |