diff options
author | Caolán McNamara <caolanm@redhat.com> | 2011-06-27 14:52:41 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2011-06-27 15:27:58 +0100 |
commit | b3cee382f449aa69213dc21f7b1ba6a5356d2865 (patch) | |
tree | 9a6e22aec6d3d13b7975a224670b048d8f045334 | |
parent | 3fb860ea50b12a40daa2f9062edf41138b0be976 (diff) |
Related: #i76955# make this 4+ times faster
-rw-r--r-- | sw/source/filter/inc/fltshell.hxx | 2 | ||||
-rw-r--r-- | sw/source/filter/ww1/fltshell.cxx | 104 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8par.cxx | 6 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8par.hxx | 2 |
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) { |