diff options
author | Michael Stahl <Michael.Stahl@cib.de> | 2018-10-11 18:03:27 +0200 |
---|---|---|
committer | Michael Stahl <Michael.Stahl@cib.de> | 2018-11-15 15:09:59 +0100 |
commit | 1813e7c7e3b66d9d52c69a589a311acc775cdc56 (patch) | |
tree | 89bc8a036642e71837bc6ecab5e20800f52d64e4 | |
parent | e37cacc8bfe7ff16a0336cd2964525d8d3b8d64b (diff) |
sw_redlinehide_3: rewrite MergedAttrIterByEnd
It doesn't actually work with a similar logic to the other iterators,
because it iterates ByEnd but forwards, so the hints and the extents
don't come in a matching order.
To prevent complicating this further, replace it with a new
implementation that does only what the one client expects, and put it
directly in SwTextFormatter replacing the previous integer iterator
m_nHintEndIndex, so that it is created only once.
Change-Id: I144bfcf7e837a4fb0e7ec279edfba4732d0ae897
-rw-r--r-- | sw/source/core/inc/txtfrm.hxx | 10 | ||||
-rw-r--r-- | sw/source/core/text/itrform2.cxx | 4 | ||||
-rw-r--r-- | sw/source/core/text/itrform2.hxx | 4 | ||||
-rw-r--r-- | sw/source/core/text/txtfld.cxx | 22 | ||||
-rw-r--r-- | sw/source/core/text/txtfrm.cxx | 68 |
5 files changed, 53 insertions, 55 deletions
diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx index f28c5a825606..772c61a4e8da 100644 --- a/sw/source/core/inc/txtfrm.hxx +++ b/sw/source/core/inc/txtfrm.hxx @@ -972,11 +972,15 @@ public: }; class MergedAttrIterByEnd - : public MergedAttrIterBase { +private: + std::vector<std::pair<SwTextNode const*, SwTextAttr const*>> m_Hints; + SwTextNode const*const m_pNode; + size_t m_CurrentHint; public: - MergedAttrIterByEnd(SwTextFrame const& rFrame) : MergedAttrIterBase(rFrame) {} - SwTextAttr const* NextAttr(SwTextNode const** ppNode = nullptr); + MergedAttrIterByEnd(SwTextFrame const& rFrame); + SwTextAttr const* NextAttr(SwTextNode const*& rpNode); + void PrevAttr(); }; class MergedAttrIterReverse diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx index 87749f06b2de..473ed0ad5c63 100644 --- a/sw/source/core/text/itrform2.cxx +++ b/sw/source/core/text/itrform2.cxx @@ -97,7 +97,7 @@ void SwTextFormatter::CtorInitTextFormatter( SwTextFrame *pNewFrame, SwTextForma nCntMidHyph = 0; nLeftScanIdx = TextFrameIndex(COMPLETE_STRING); nRightScanIdx = TextFrameIndex(0); - m_nHintEndIndex = 0; + m_pByEndIter.reset(); m_pFirstOfBorderMerge = nullptr; if (m_nStart > TextFrameIndex(GetInfo().GetText().getLength())) @@ -289,7 +289,7 @@ SwLinePortion *SwTextFormatter::Underflow( SwTextFormatInfo &rInf ) static_cast<SwFieldPortion*>(pRest)->IsNoLength()) { // HACK: decrement again, so we pick up the suffix in next line! - --m_nHintEndIndex; + m_pByEndIter->PrevAttr(); } delete pRest; rInf.SetRest(nullptr); diff --git a/sw/source/core/text/itrform2.hxx b/sw/source/core/text/itrform2.hxx index ff430b8616d1..555fed20cdcc 100644 --- a/sw/source/core/text/itrform2.hxx +++ b/sw/source/core/text/itrform2.hxx @@ -31,6 +31,8 @@ class SwExpandPortion; class SwMultiPortion; class SwFootnotePortion; +namespace sw { class MergedAttrIterByEnd; } + class SwTextFormatter : public SwTextPainter { const SwFormatDrop *pDropFormat; @@ -43,7 +45,7 @@ class SwTextFormatter : public SwTextPainter bool bFlyInCntBase : 1; // Base reference that sets a character-bound frame bool bTruncLines : 1; // Flag for extending the repaint rect, if needed bool bUnclipped : 1; // Flag whether repaint is larger than the fixed line height - size_t m_nHintEndIndex; // HACK for TryNewNoLengthPortion + std::unique_ptr<sw::MergedAttrIterByEnd> m_pByEndIter; // HACK for TryNewNoLengthPortion SwLinePortion* m_pFirstOfBorderMerge; // The first text portion of a joined border (during portion building) SwLinePortion *NewPortion( SwTextFormatInfo &rInf ); diff --git a/sw/source/core/text/txtfld.cxx b/sw/source/core/text/txtfld.cxx index b70b4bc7456b..196b11b84cf9 100644 --- a/sw/source/core/text/txtfld.cxx +++ b/sw/source/core/text/txtfld.cxx @@ -307,9 +307,9 @@ static SwFieldPortion * lcl_NewMetaPortion(SwTextAttr & rHint, const bool bPrefi /** * Try to create a new portion with zero length, for an end of a hint * (where there is no CH_TXTATR). Because there may be multiple hint ends at a - * given index, m_nHintEndIndex is used to keep track of the already created + * given index, m_pByEndIter is used to keep track of the already created * portions. But the portions created here may actually be deleted again, - * due to Underflow. In that case, m_nHintEndIndex must be decremented, + * due to Underflow. In that case, m_pByEndIter must be decremented, * so the portion will be created again on the next line. */ SwExpandPortion * SwTextFormatter::TryNewNoLengthPortion(SwTextFormatInfo const & rInfo) @@ -319,26 +319,24 @@ SwExpandPortion * SwTextFormatter::TryNewNoLengthPortion(SwTextFormatInfo const // sw_redlinehide: because there is a dummy character at the start of these // hints, it's impossible to have ends of hints from different nodes at the // same view position, so it's sufficient to check the hints of the current - // node. However, m_nHintEndIndex exists for the whole text frame, so + // node. However, m_pByEndIter exists for the whole text frame, so // it's necessary to iterate all hints for that purpose... + if (!m_pByEndIter) + { + m_pByEndIter.reset(new sw::MergedAttrIterByEnd(*rInfo.GetTextFrame())); + } SwTextNode const* pNode(nullptr); - sw::MergedAttrIterByEnd iter(*rInfo.GetTextFrame()); - size_t i(0); - for (SwTextAttr const* pHint = iter.NextAttr(&pNode); pHint; - pHint = iter.NextAttr(&pNode)) + for (SwTextAttr const* pHint = m_pByEndIter->NextAttr(pNode); pHint; + pHint = m_pByEndIter->NextAttr(pNode)) { - if (i++ < m_nHintEndIndex) - { - continue; // skip ones that were handled earlier - } SwTextAttr & rHint(const_cast<SwTextAttr&>(*pHint)); TextFrameIndex const nEnd( rInfo.GetTextFrame()->MapModelToView(pNode, *rHint.GetAnyEnd())); if (nEnd > nIdx) { + m_pByEndIter->PrevAttr(); break; } - ++m_nHintEndIndex; if (nEnd == nIdx) { if (RES_TXTATR_METAFIELD == rHint.Which()) diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx index a476c711c1fb..8e574a55da8b 100644 --- a/sw/source/core/text/txtfrm.cxx +++ b/sw/source/core/text/txtfrm.cxx @@ -153,44 +153,24 @@ namespace sw { } } - SwTextAttr const* MergedAttrIterByEnd::NextAttr(SwTextNode const** ppNode) + MergedAttrIterByEnd::MergedAttrIterByEnd(SwTextFrame const& rFrame) + : m_pNode(rFrame.GetMergedPara() ? nullptr : rFrame.GetTextNodeFirst()) + , m_CurrentHint(0) { - if (m_pMerged) + if (!m_pNode) { - while (m_CurrentExtent < m_pMerged->extents.size()) + MergedAttrIterReverse iter(rFrame); + SwTextNode const* pNode(nullptr); + while (SwTextAttr const* pHint = iter.PrevAttr(&pNode)) { - sw::Extent const& rExtent(m_pMerged->extents[m_CurrentExtent]); - if (SwpHints const*const pHints = rExtent.pNode->GetpSwpHints()) - { - while (m_CurrentHint < pHints->Count()) - { - SwTextAttr const*const pHint( - pHints->GetSortedByEnd(m_CurrentHint)); - if (rExtent.nEnd <= *pHint->GetAnyEnd()) - { - break; - } - ++m_CurrentHint; - if (rExtent.nStart < *pHint->GetAnyEnd()) - { - if (ppNode) - { - *ppNode = rExtent.pNode; - } - return pHint; - } - } - } - ++m_CurrentExtent; - if (m_CurrentExtent < m_pMerged->extents.size() && - rExtent.pNode != m_pMerged->extents[m_CurrentExtent].pNode) - { - m_CurrentHint = 0; // reset - } + m_Hints.emplace_back(pNode, pHint); } - return nullptr; } - else + } + + SwTextAttr const* MergedAttrIterByEnd::NextAttr(SwTextNode const*& rpNode) + { + if (m_pNode) { SwpHints const*const pHints(m_pNode->GetpSwpHints()); if (pHints) @@ -200,15 +180,29 @@ namespace sw { SwTextAttr const*const pHint( pHints->GetSortedByEnd(m_CurrentHint)); ++m_CurrentHint; - if (ppNode) - { - *ppNode = m_pNode; - } + rpNode = m_pNode; return pHint; } } return nullptr; } + else + { + if (m_CurrentHint < m_Hints.size()) + { + auto const ret = m_Hints[m_Hints.size() - m_CurrentHint - 1]; + ++m_CurrentHint; + rpNode = ret.first; + return ret.second; + } + return nullptr; + } + } + + void MergedAttrIterByEnd::PrevAttr() + { + assert(0 < m_CurrentHint); // should only rewind as far as 0 + --m_CurrentHint; } MergedAttrIterReverse::MergedAttrIterReverse(SwTextFrame const& rFrame) |