sw/source/core/bastyp/swregion.cxx | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-)
New commits: commit 9cd4845e50efb30c14407b139ef05a891dea1781 Author: Luboš Luňák <l.lu...@collabora.com> AuthorDate: Fri Sep 24 13:17:34 2021 +0200 Commit: Luboš Luňák <l.lu...@collabora.com> CommitDate: Tue Sep 28 13:48:18 2021 +0200 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.lu...@collabora.com> 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