summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <Michael.Stahl@cib.de>2018-10-11 18:03:27 +0200
committerMichael Stahl <Michael.Stahl@cib.de>2018-11-15 15:09:59 +0100
commit1813e7c7e3b66d9d52c69a589a311acc775cdc56 (patch)
tree89bc8a036642e71837bc6ecab5e20800f52d64e4
parente37cacc8bfe7ff16a0336cd2964525d8d3b8d64b (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.hxx10
-rw-r--r--sw/source/core/text/itrform2.cxx4
-rw-r--r--sw/source/core/text/itrform2.hxx4
-rw-r--r--sw/source/core/text/txtfld.cxx22
-rw-r--r--sw/source/core/text/txtfrm.cxx68
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)