Kaydet (Commit) 651d045c authored tarafından Caolán McNamara's avatar Caolán McNamara

Resolves: rhbz#825548 some rtf documents take vast amounts of time to load

rtf documents with vast sequences of replicated properties without any pard
resets to defaults create huge vectors of properties that eat time and memory

So if we are adding a property which already exists and there are no
intermediate properties which would cause side effects to the property then
update the existing one instead

Only implemented this optimization for some selected character properties

This takes my load time down to 7 seconds from effectively some "infinite"
hour+ load time.

Change-Id: I520779233180f4d9faf9fb0989d546e08fc6cabd
üst 48e74fb6
...@@ -84,6 +84,57 @@ static Id lcl_getParagraphBorder(sal_uInt32 nIndex) ...@@ -84,6 +84,57 @@ static Id lcl_getParagraphBorder(sal_uInt32 nIndex)
return aBorderIds[nIndex]; return aBorderIds[nIndex];
} }
namespace
{
bool isTrivialCharSprm(Id nSprm)
{
bool bRet = false;
switch (nSprm)
{
case NS_sprm::LN_CRgFtc0:
case NS_sprm::LN_CRgFtc1:
case NS_sprm::LN_CRgFtc2:
case NS_sprm::LN_CHps:
case NS_sprm::LN_CHpsBi:
case NS_sprm::LN_CSfxText:
case NS_sprm::LN_CDxaSpace:
case NS_sprm::LN_CHpsKern:
case NS_sprm::LN_CCharScale:
case NS_sprm::LN_CRgLid0:
case NS_sprm::LN_CRgLid1:
case NS_sprm::LN_CLidBi:
bRet = true;
break;
default:
break;
}
return bRet;
}
//rhbz#825548. rtf documents with vast sequences of replicated properties without
//any resets to defaults create a huge vector of properties and eat time and memory
//
//So if we are adding a property which already exists and there are no intermediate
//properties which would cause side effects to the property then update the existing
//one instead
bool tryToSafelyUpdateAnExistingProp(RTFSprms &rSprms, Id nSprm, RTFValue::Pointer_t xArg)
{
if (!isTrivialCharSprm(nSprm))
return false;
for (RTFSprms::ReverseIterator_t i = rSprms.rbegin(); i != rSprms.rend() && isTrivialCharSprm(i->first); ++i)
{
if (i->first == nSprm)
{
i->second = xArg;
return true;
}
}
return false;
}
}
static void lcl_putNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId, RTFValue::Pointer_t pValue, static void lcl_putNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId, RTFValue::Pointer_t pValue,
bool bOverwrite = false, bool bAttribute = true) bool bOverwrite = false, bool bAttribute = true)
{ {
...@@ -107,7 +158,8 @@ static void lcl_putNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId, RTFValu ...@@ -107,7 +158,8 @@ static void lcl_putNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId, RTFValu
} }
} }
} }
rAttributes.push_back(make_pair(nId, pValue)); if (!tryToSafelyUpdateAnExistingProp(rAttributes, nId, pValue))
rAttributes.push_back(make_pair(nId, pValue));
} }
static void lcl_putNestedSprm(RTFSprms& rSprms, Id nParent, Id nId, RTFValue::Pointer_t pValue, bool bOverwrite = false) static void lcl_putNestedSprm(RTFSprms& rSprms, Id nParent, Id nId, RTFValue::Pointer_t pValue, bool bOverwrite = false)
...@@ -2227,7 +2279,9 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) ...@@ -2227,7 +2279,9 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
} }
if (nSprm > 0) if (nSprm > 0)
{ {
m_aStates.top().aCharacterSprms.push_back(make_pair(nSprm, pIntValue)); RTFSprms &rSprms = m_aStates.top().aCharacterSprms;
if (!tryToSafelyUpdateAnExistingProp(rSprms, nSprm, pIntValue))
rSprms.push_back(make_pair(nSprm, pIntValue));
// Language is a character property, but we should store it at a paragraph level as well for fields. // Language is a character property, but we should store it at a paragraph level as well for fields.
if (nKeyword == RTF_LANG && m_bNeedPap) if (nKeyword == RTF_LANG && m_bNeedPap)
m_aStates.top().aParagraphSprms.push_back(make_pair(nSprm, pIntValue)); m_aStates.top().aParagraphSprms.push_back(make_pair(nSprm, pIntValue));
...@@ -2310,7 +2364,9 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) ...@@ -2310,7 +2364,9 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
{ {
int nFontIndex = getFontIndex(nParam); int nFontIndex = getFontIndex(nParam);
RTFValue::Pointer_t pValue(new RTFValue(nFontIndex)); RTFValue::Pointer_t pValue(new RTFValue(nFontIndex));
m_aStates.top().aCharacterSprms.push_back(make_pair(NS_sprm::LN_CRgFtc0, pValue)); RTFSprms &rSprms = m_aStates.top().aCharacterSprms;
if (!tryToSafelyUpdateAnExistingProp(rSprms, NS_sprm::LN_CRgFtc0, pValue))
rSprms.push_back(make_pair(NS_sprm::LN_CRgFtc0, pValue));
m_aStates.top().nCurrentEncoding = getEncoding(nFontIndex); m_aStates.top().nCurrentEncoding = getEncoding(nFontIndex);
} }
break; break;
......
...@@ -40,6 +40,7 @@ namespace writerfilter { ...@@ -40,6 +40,7 @@ namespace writerfilter {
typedef ::boost::shared_ptr<RTFSprms> Pointer_t; typedef ::boost::shared_ptr<RTFSprms> Pointer_t;
typedef std::pair<Id, RTFValue::Pointer_t> id_val; typedef std::pair<Id, RTFValue::Pointer_t> id_val;
typedef std::vector< id_val >::iterator Iterator_t; typedef std::vector< id_val >::iterator Iterator_t;
typedef std::vector< id_val >::reverse_iterator ReverseIterator_t;
RTFSprms(); RTFSprms();
RTFSprms(const RTFSprms& rSprms); RTFSprms(const RTFSprms& rSprms);
RTFSprms& operator=(const RTFSprms& rOther); RTFSprms& operator=(const RTFSprms& rOther);
...@@ -51,6 +52,8 @@ namespace writerfilter { ...@@ -51,6 +52,8 @@ namespace writerfilter {
id_val& back() { return m_aSprms.back(); } id_val& back() { return m_aSprms.back(); }
Iterator_t begin() { return m_aSprms.begin(); } Iterator_t begin() { return m_aSprms.begin(); }
Iterator_t end() { return m_aSprms.end(); } Iterator_t end() { return m_aSprms.end(); }
ReverseIterator_t rbegin() { return m_aSprms.rbegin(); }
ReverseIterator_t rend() { return m_aSprms.rend(); }
void push_back(id_val aVal) { m_aSprms.push_back(aVal); } void push_back(id_val aVal) { m_aSprms.push_back(aVal); }
void clear() { return m_aSprms.clear(); } void clear() { return m_aSprms.clear(); }
private: private:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment