From 4600b07c1d787f959618d9ecf54161e4ea4ffa61 Mon Sep 17 00:00:00 2001 From: Mike Kaganski Date: Thu, 28 Jun 2018 14:51:31 +1000 Subject: tdf#102195: don't exclude everything between first and last subset When subsets are non-contiguous, we need to include the parts between subsets. Change-Id: I28214dccc75e6a6af5c65397b2126049a65bf79f Reviewed-on: https://gerrit.libreoffice.org/56571 Tested-by: Jenkins Reviewed-by: Mike Kaganski --- .../source/engine/shapes/drawshapesubsetting.cxx | 102 ++++++++++----------- .../source/engine/shapes/drawshapesubsetting.hxx | 8 +- slideshow/source/inc/doctreenode.hxx | 1 + 3 files changed, 52 insertions(+), 59 deletions(-) (limited to 'slideshow') diff --git a/slideshow/source/engine/shapes/drawshapesubsetting.cxx b/slideshow/source/engine/shapes/drawshapesubsetting.cxx index 1de7934719d9..849df8d9897c 100644 --- a/slideshow/source/engine/shapes/drawshapesubsetting.cxx +++ b/slideshow/source/engine/shapes/drawshapesubsetting.cxx @@ -164,50 +164,65 @@ namespace slideshow mbNodeTreeInitialized = true; } - void DrawShapeSubsetting::updateSubsetBounds( const SubsetEntry& rSubsetEntry ) + void DrawShapeSubsetting::excludeSubset(sal_Int32 nExcludedStart, sal_Int32 nExcludedEnd) { - // TODO(F1): This removes too much from non-contiguous subsets - mnMinSubsetActionIndex = ::std::min( - mnMinSubsetActionIndex, - rSubsetEntry.mnStartActionIndex ); - mnMaxSubsetActionIndex = ::std::max( - mnMaxSubsetActionIndex, - rSubsetEntry.mnEndActionIndex ); - } - - void DrawShapeSubsetting::updateSubsets() - { - maCurrentSubsets.clear(); + // If current subsets are empty, fill it with initial range + initCurrentSubsets(); + if (maCurrentSubsets.empty()) + { + // Non-subsetting mode (not a subset of anything; child subsets subtract content) + maCurrentSubsets.emplace_back(0, maActionClassVector.size()); + } - if( !maSubsetShapes.empty() ) + slideshow::internal::VectorOfDocTreeNodes aNodesToAppend; + for (auto i = maCurrentSubsets.begin(); i != maCurrentSubsets.end();) { - if( maSubset.isEmpty() ) + if (i->getStartIndex() < nExcludedStart) { - // non-subsetted node, with some child subsets - // that subtract from it - maCurrentSubsets.emplace_back( 0, - mnMinSubsetActionIndex ); - maCurrentSubsets.emplace_back( mnMaxSubsetActionIndex, - maActionClassVector.size() ); + if (i->getEndIndex() > nExcludedStart) + { + // Some overlap -> append new node (if required), and correct this node's end + if (i->getEndIndex() > nExcludedEnd) + { + aNodesToAppend.emplace_back(nExcludedEnd, i->getEndIndex()); + } + i->setEndIndex(nExcludedStart); + } + ++i; + } + else if (i->getStartIndex() < nExcludedEnd) + { + if (i->getEndIndex() > nExcludedEnd) + { + // Partial overlap; change the node's start + i->setStartIndex(nExcludedEnd); + ++i; + } + else + { + // Node is fully inside the removed range: erase it + i = maCurrentSubsets.erase(i); + } } else { - // subsetted node, from which some further child - // subsets subtract content - maCurrentSubsets.emplace_back( maSubset.getStartIndex(), - mnMinSubsetActionIndex ); - maCurrentSubsets.emplace_back( mnMaxSubsetActionIndex, - maSubset.getEndIndex() ); + // Node is fully outside (after) excluded range + ++i; } } - else + + maCurrentSubsets.insert(maCurrentSubsets.end(), aNodesToAppend.begin(), + aNodesToAppend.end()); + } + + void DrawShapeSubsetting::updateSubsets() + { + maCurrentSubsets.clear(); + initCurrentSubsets(); + + for (const auto& rSubsetShape : maSubsetShapes) { - // no further child subsets, simply add our subset (if any) - if( !maSubset.isEmpty() ) - { - // subsetted node, without any subset children - maCurrentSubsets.push_back( maSubset ); - } + excludeSubset(rSubsetShape.mnStartActionIndex, rSubsetShape.mnEndActionIndex); } } @@ -220,8 +235,6 @@ namespace slideshow mpMtf(), maSubset(), maSubsetShapes(), - mnMinSubsetActionIndex( SAL_MAX_INT32 ), - mnMaxSubsetActionIndex(0), maCurrentSubsets(), mbNodeTreeInitialized( false ) { @@ -233,8 +246,6 @@ namespace slideshow mpMtf( rMtf ), maSubset( rShapeSubset ), maSubsetShapes(), - mnMinSubsetActionIndex( SAL_MAX_INT32 ), - mnMaxSubsetActionIndex(0), maCurrentSubsets(), mbNodeTreeInitialized( false ) { @@ -250,8 +261,6 @@ namespace slideshow mpMtf.reset(); maSubset.reset(); maSubsetShapes.clear(); - mnMinSubsetActionIndex = SAL_MAX_INT32; - mnMaxSubsetActionIndex = 0; maCurrentSubsets.clear(); mbNodeTreeInitialized = false; } @@ -326,9 +335,7 @@ namespace slideshow maSubsetShapes.insert( aEntry ); - // update cached subset borders - updateSubsetBounds( aEntry ); - updateSubsets(); + excludeSubset(aEntry.mnStartActionIndex, aEntry.mnEndActionIndex); } } @@ -380,19 +387,10 @@ namespace slideshow // part of this shape that is visible, i.e. not displayed // in subset shapes) - - // init bounds - mnMinSubsetActionIndex = SAL_MAX_INT32; - mnMaxSubsetActionIndex = 0; - // TODO(P2): This is quite expensive, when // after every subset effect end, we have to scan // the whole shape set - // determine new subset range - for( const auto& rSubsetShape : maSubsetShapes ) - updateSubsetBounds( rSubsetShape ); - updateSubsets(); return true; diff --git a/slideshow/source/engine/shapes/drawshapesubsetting.hxx b/slideshow/source/engine/shapes/drawshapesubsetting.hxx index 06d399d4d88e..68e541bf7fb1 100644 --- a/slideshow/source/engine/shapes/drawshapesubsetting.hxx +++ b/slideshow/source/engine/shapes/drawshapesubsetting.hxx @@ -202,7 +202,7 @@ namespace slideshow typedef ::std::set< SubsetEntry > ShapeSet; void ensureInitializedNodeTree() const; - void updateSubsetBounds( const SubsetEntry& rSubsetEntry ); + void excludeSubset(sal_Int32 nExcludedStart, sal_Int32 nExcludedEnd); void updateSubsets(); void initCurrentSubsets(); void reset(); @@ -226,12 +226,6 @@ namespace slideshow /// the list of subset shapes spawned from this one. ShapeSet maSubsetShapes; - /// caches minimal subset index from maSubsetShapes - sal_Int32 mnMinSubsetActionIndex; - - /// caches maximal subset index from maSubsetShapes - sal_Int32 mnMaxSubsetActionIndex; - /** Current number of subsets to render (calculated from maSubset and mnMin/MaxSubsetActionIndex). diff --git a/slideshow/source/inc/doctreenode.hxx b/slideshow/source/inc/doctreenode.hxx index 5cd3fe6fe07c..008979651b8a 100644 --- a/slideshow/source/inc/doctreenode.hxx +++ b/slideshow/source/inc/doctreenode.hxx @@ -90,6 +90,7 @@ namespace slideshow bool isEmpty() const { return mnStartIndex == mnEndIndex; } sal_Int32 getStartIndex() const { return mnStartIndex; } + void setStartIndex( sal_Int32 nIndex ) { mnStartIndex = nIndex; } sal_Int32 getEndIndex() const { return mnEndIndex; } void setEndIndex( sal_Int32 nIndex ) { mnEndIndex = nIndex; } -- cgit