summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2011-06-27 14:52:41 +0100
committerCaolán McNamara <caolanm@redhat.com>2011-06-27 15:27:58 +0100
commitb3cee382f449aa69213dc21f7b1ba6a5356d2865 (patch)
tree9a6e22aec6d3d13b7975a224670b048d8f045334
parent3fb860ea50b12a40daa2f9062edf41138b0be976 (diff)
Related: #i76955# make this 4+ times faster
-rw-r--r--sw/source/filter/inc/fltshell.hxx2
-rw-r--r--sw/source/filter/ww1/fltshell.cxx104
-rw-r--r--sw/source/filter/ww8/ww8par.cxx6
-rw-r--r--sw/source/filter/ww8/ww8par.hxx2
4 files changed, 89 insertions, 25 deletions
diff --git a/sw/source/filter/inc/fltshell.hxx b/sw/source/filter/inc/fltshell.hxx
index fc30294613ea..66e284125657 100644
--- a/sw/source/filter/inc/fltshell.hxx
+++ b/sw/source/filter/inc/fltshell.hxx
@@ -169,7 +169,7 @@ public:
void NewAttr(const SwPosition& rPos, const SfxPoolItem & rAttr );
- virtual void SetAttr(const SwPosition& rPos, sal_uInt16 nAttrId=0, sal_Bool bTstEnde=sal_True, long nHand = LONG_MAX, sal_Bool consumedByField=sal_False);
+ virtual SwFltStackEntry* SetAttr(const SwPosition& rPos, sal_uInt16 nAttrId=0, sal_Bool bTstEnde=sal_True, long nHand = LONG_MAX, sal_Bool consumedByField=sal_False);
void StealAttr(const SwNodeIndex& rNode, sal_uInt16 nAttrId = 0);
void MarkAllAttrsOld();
diff --git a/sw/source/filter/ww1/fltshell.cxx b/sw/source/filter/ww1/fltshell.cxx
index 09de3f6686f2..6e269b333567 100644
--- a/sw/source/filter/ww1/fltshell.cxx
+++ b/sw/source/filter/ww1/fltshell.cxx
@@ -222,14 +222,39 @@ void SwFltControlStack::MarkAllAttrsOld()
maEntries[i].bOld = sal_True;
}
-void SwFltControlStack::NewAttr(const SwPosition& rPos, const SfxPoolItem & rAttr )
+namespace
{
- SwFltStackEntry *pTmp = new SwFltStackEntry(rPos, rAttr.Clone() );
- sal_uInt16 nWhich = pTmp->pAttr->Which();
- SetAttr(rPos, nWhich);// Ende von evtl. gleichen Attributen auf dem Stack
- // Setzen, damit sich die Attribute nicht auf
- // dem Stack haeufen
- maEntries.push_back(pTmp);
+ bool couldExtendEntry(const SwFltStackEntry *pExtendCandidate,
+ const SfxPoolItem& rAttr)
+ {
+ return (pExtendCandidate &&
+ !pExtendCandidate->bConsumedByField &&
+ //potentially more, but lets keep it simple
+ (isPARATR_LIST(rAttr.Which()) || isCHRATR(rAttr.Which())) &&
+ *(pExtendCandidate->pAttr) == rAttr);
+ }
+}
+
+void SwFltControlStack::NewAttr(const SwPosition& rPos, const SfxPoolItem& rAttr)
+{
+ sal_uInt16 nWhich = rAttr.Which();
+ // Ende von evtl. gleichen Attributen auf dem Stack Setzen, damit sich die
+ // Attribute nicht auf dem Stack haeufen
+ SwFltStackEntry *pExtendCandidate = SetAttr(rPos, nWhich);
+ if (couldExtendEntry(pExtendCandidate, rAttr))
+ {
+ //Here we optimize by seeing if there is an attribute uncommited
+ //to the document which
+ //
+ //a) has the same value as this attribute
+ //b) is already open, or ends at the same place as where we're starting
+ //from. If so we merge it with this one and elide adding another
+ //to the stack
+ pExtendCandidate->SetEndPos(rPos);
+ pExtendCandidate->bLocked=true;
+ }
+ else
+ maEntries.push_back(new SwFltStackEntry(rPos, rAttr.Clone()));
}
void SwFltControlStack::DeleteAndDestroy(Entries::size_type nCnt)
@@ -291,28 +316,39 @@ void SwFltControlStack::KillUnlockedAttrs(const SwPosition& rPos)
// alle anderen im Document setzen und wieder aus dem Stack loeschen
// Returned, ob das gesuchte Attribut / die gesuchten Attribute
// ueberhaupt auf dem Stack standen
-void SwFltControlStack::SetAttr(const SwPosition& rPos, sal_uInt16 nAttrId,
- sal_Bool bTstEnde, long nHand, sal_Bool consumedByField )
+SwFltStackEntry* SwFltControlStack::SetAttr(const SwPosition& rPos,
+ sal_uInt16 nAttrId, sal_Bool bTstEnde, long nHand,
+ sal_Bool consumedByField)
{
+ SwFltStackEntry *pRet = NULL;
+
+ SwFltPosition aFltPos(rPos);
+
OSL_ENSURE(!nAttrId ||
(POOLATTR_BEGIN <= nAttrId && POOLATTR_END > nAttrId) ||
(RES_FLTRATTR_BEGIN <= nAttrId && RES_FLTRATTR_END > nAttrId),
"Falsche Id fuers Attribut");
- size_t nCnt = maEntries.size();
- for (size_t i=0; i < nCnt; ++i)
+ myEIter aI = maEntries.begin();
+ while (aI != maEntries.end())
{
- SwFltStackEntry& rEntry = maEntries[i];
+ SwFltStackEntry& rEntry = *aI;
if (rEntry.bLocked)
{
// setze das Ende vom Attribut
bool bF = false;
- if (!nAttrId ){
+ if (!nAttrId )
+ {
bF = true;
- }else if( nAttrId == rEntry.pAttr->Which()){
- if( nAttrId != RES_FLTR_BOOKMARK ){ // Handle abfragen
+ }
+ else if (nAttrId == rEntry.pAttr->Which())
+ {
+ if( nAttrId != RES_FLTR_BOOKMARK )
+ {
+ // Handle abfragen
bF = true;
- }else if( nHand == ((SwFltBookmark*)(rEntry.pAttr))->GetHandle() )
+ }
+ else if (nHand == ((SwFltBookmark*)(rEntry.pAttr))->GetHandle())
{
bF = true;
}
@@ -321,7 +357,14 @@ void SwFltControlStack::SetAttr(const SwPosition& rPos, sal_uInt16 nAttrId,
{
rEntry.bConsumedByField = consumedByField;
rEntry.SetEndPos(rPos);
+ if (nAttrId == rEntry.pAttr->Which())
+ {
+ //potential candidate for merging with an identical
+ //property beginning at rPos
+ pRet = &rEntry;
+ }
}
+ ++aI;
continue;
}
@@ -331,14 +374,33 @@ void SwFltControlStack::SetAttr(const SwPosition& rPos, sal_uInt16 nAttrId,
// Beim Ende-Stack niemals ausser am DocEnde reinsetzen
if (bTstEnde)
{
- if (bIsEndStack || rEntry.m_aPtPos.m_nNode.GetIndex()+1 ==
- rPos.nNode.GetIndex())
- continue;
+ if (bIsEndStack)
+ {
+ ++aI;
+ continue;
+ }
+
+ //defer inserting this attribute into the document until
+ //we advance to the next node, or finish processing the document
+ if (rEntry.m_aPtPos.m_nNode.GetIndex() == aFltPos.m_nNode.GetIndex())
+ {
+ if (nAttrId == rEntry.pAttr->Which() &&
+ rEntry.m_aPtPos.m_nCntnt == aFltPos.m_nCntnt)
+ {
+ //potential candidate for merging with an identical
+ //property beginning at rPos
+ pRet = &rEntry;
+ }
+
+ ++aI;
+ continue;
+ }
}
SetAttrInDoc(rPos, rEntry);
- DeleteAndDestroy(i); // loesche aus dem Stack
- i--; nCnt--; // Danach rutschen alle folgenden nach unten
+ aI = maEntries.erase(aI);
}
+
+ return pRet;
}
static void MakePoint(const SwFltStackEntry& rEntry, SwDoc* pDoc,
diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index c6adbb2814dc..0438d0692545 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -982,9 +982,10 @@ void SwWW8FltControlStack::NewAttr(const SwPosition& rPos,
SwFltControlStack::NewAttr(rPos, rAttr);
}
-void SwWW8FltControlStack::SetAttr(const SwPosition& rPos, sal_uInt16 nAttrId,
+SwFltStackEntry* SwWW8FltControlStack::SetAttr(const SwPosition& rPos, sal_uInt16 nAttrId,
sal_Bool bTstEnde, long nHand, sal_Bool )
{
+ SwFltStackEntry *pRet = NULL;
//Doing a textbox, and using the control stack only as a temporary
//collection point for properties which will are not to be set into
//the real document
@@ -1002,7 +1003,8 @@ void SwWW8FltControlStack::SetAttr(const SwPosition& rPos, sal_uInt16 nAttrId,
}
}
else //Normal case, set the attribute into the document
- SwFltControlStack::SetAttr(rPos, nAttrId, bTstEnde, nHand);
+ pRet = SwFltControlStack::SetAttr(rPos, nAttrId, bTstEnde, nHand);
+ return pRet;
}
long GetListFirstLineIndent(const SwNumFmt &rFmt)
diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx
index 85fbafe72487..e70e099cc785 100644
--- a/sw/source/filter/ww8/ww8par.hxx
+++ b/sw/source/filter/ww8/ww8par.hxx
@@ -377,7 +377,7 @@ public:
void NewAttr(const SwPosition& rPos, const SfxPoolItem& rAttr);
- virtual void SetAttr(const SwPosition& rPos, sal_uInt16 nAttrId=0, sal_Bool bTstEnde=sal_True, long nHand=LONG_MAX, sal_Bool consumedByField=sal_False);
+ virtual SwFltStackEntry* SetAttr(const SwPosition& rPos, sal_uInt16 nAttrId=0, sal_Bool bTstEnde=sal_True, long nHand=LONG_MAX, sal_Bool consumedByField=sal_False);
void SetToggleAttr(sal_uInt8 nId, bool bOn)
{