summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2021-09-24 13:17:34 +0200
committerLuboš Luňák <l.lunak@collabora.com>2021-09-28 13:48:18 +0200
commit9cd4845e50efb30c14407b139ef05a891dea1781 (patch)
treebfd25668416fc534c0a1dae672465144158d208d
parentfbaa1c3377f445180db2f7811b9516895b357aa8 (diff)
avoid repeated std::vector::erase() in SwRegionRects::Compress()
Change-Id: I5e646d2938dda7077e5e4ff40ab6caa847ac7a80 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122676 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
-rw-r--r--sw/source/core/bastyp/swregion.cxx29
1 files changed, 19 insertions, 10 deletions
diff --git a/sw/source/core/bastyp/swregion.cxx b/sw/source/core/bastyp/swregion.cxx
index 967bc44b2cb2..5b928a1ab9b0 100644
--- a/sw/source/core/bastyp/swregion.cxx
+++ b/sw/source/core/bastyp/swregion.cxx
@@ -159,31 +159,35 @@ void SwRegionRects::Compress( CompressType type )
{
sort( begin(), end(), []( const SwRect& l, const SwRect& r ) { return l.Top() < r.Top(); } );
bAgain = false;
+ bool bRemoved = false;
for (size_type i = 0; i < size(); ++i )
{
+ if( (*this)[i].IsEmpty())
+ continue;
// Rectangles are sorted by Y axis, so check only pairs of rectangles
// that are possibly overlapping or adjacent or close enough to be grouped by the fuzzy
// code below.
const tools::Long nFuzzy = type == CompressFuzzy ? 1361513 : 0;
const tools::Long yMax = (*this)[i].Top() + (*this)[i].Height() + nFuzzy
/ std::max<tools::Long>( 1, (*this)[i].Width());
- size_type j = i+1;
- while( j < size() && (*this)[j].Top() <= yMax )
- ++j;
- --j;
- // Walk backwards for simpler and faster erase().
- for ( ; j >= i+1; --j )
+ for(size_type j = i+1; j < size(); ++j)
{
+ if( (*this)[j].IsEmpty())
+ continue;
+ if( (*this)[j].Top() > yMax )
+ break;
// If one rectangle contains a second completely than the latter
// does not need to be stored and can be deleted
- if ( (*this)[i].Contains( (*this)[j] ) )
+ else if ( (*this)[i].Contains( (*this)[j] ) )
{
- erase( begin() + j );
+ (*this)[j].Width(0); // = erase(), see below
+ bRemoved = true;
}
else if ( (*this)[j].Contains( (*this)[i] ) )
{
(*this)[i] = (*this)[j];
- erase( begin() + j );
+ (*this)[j].Width(0);
+ bRemoved = true;
bAgain = true;
}
else
@@ -206,12 +210,17 @@ void SwRegionRects::Compress( CompressType type )
+ nFuzzy >= CalcArea( aUnion ) )
{
(*this)[i] = aUnion;
- erase( begin() + j );
+ (*this)[j].Width(0);
+ bRemoved = true;
bAgain = true;
}
}
}
}
+ // Instead of repeated erase() we Width(0) the elements, and now erase
+ // all empty elements just once.
+ if( bRemoved )
+ resize( std::remove_if(begin(), end(), [](const SwRect& rect) { return rect.IsEmpty(); }) - begin());
// Code paths setting bAgain alter elements of the vector, possibly breaking
// the Y-axis optimization, so run another pass just to make sure. The adjacent-rects
// merging code may possibly benefit from a repeated pass also if two pairs of merged