summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@suse.cz>2012-05-30 11:43:41 +0200
committerMichael Stahl <mstahl@redhat.com>2012-06-04 13:20:23 +0200
commitd366ae2031d13f3198cb58c715f18e8c8ce8686f (patch)
tree2ac02539c07069b5f8223e2eb918ed7477c7329f
parenta50c30bd01b0859d4b84c8ec24e9cabb68ee0714 (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.cxx20
-rw-r--r--writerfilter/source/rtftok/rtfsprm.cxx14
-rw-r--r--writerfilter/source/rtftok/rtfsprm.hxx2
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;