diff options
Diffstat (limited to 'slideshow/source/engine/slide/layermanager.cxx')
-rw-r--r-- | slideshow/source/engine/slide/layermanager.cxx | 923 |
1 files changed, 0 insertions, 923 deletions
diff --git a/slideshow/source/engine/slide/layermanager.cxx b/slideshow/source/engine/slide/layermanager.cxx deleted file mode 100644 index ed7a14acc..000000000 --- a/slideshow/source/engine/slide/layermanager.cxx +++ /dev/null @@ -1,923 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_slideshow.hxx" - -#include <canvas/debug.hxx> -#include <tools/diagnose_ex.h> -#include <basegfx/range/b1drange.hxx> -#include <basegfx/matrix/b2dhommatrix.hxx> - -#include <comphelper/anytostring.hxx> -#include <cppuhelper/exc_hlp.hxx> - -#include <boost/bind.hpp> -#include <algorithm> - -#include <o3tl/compat_functional.hxx> - -#include "layermanager.hxx" - -using namespace ::com::sun::star; - -namespace boost -{ - // add operator!= for weak_ptr - inline bool operator!=( slideshow::internal::LayerWeakPtr const& rLHS, - slideshow::internal::LayerWeakPtr const& rRHS ) - { - return (rLHS<rRHS) || (rRHS<rLHS); - } -} - -namespace slideshow -{ - namespace internal - { - template<typename LayerFunc, - typename ShapeFunc> void LayerManager::manageViews( - LayerFunc layerFunc, - ShapeFunc shapeFunc ) - { - LayerSharedPtr pCurrLayer; - ViewLayerSharedPtr pCurrViewLayer; - LayerShapeMap::const_iterator aIter( maAllShapes.begin() ); - const LayerShapeMap::const_iterator aEnd ( maAllShapes.end() ); - while( aIter != aEnd ) - { - LayerSharedPtr pLayer = aIter->second.lock(); - if( pLayer && pLayer != pCurrLayer ) - { - pCurrLayer = pLayer; - pCurrViewLayer = layerFunc(pCurrLayer); - } - - if( pCurrViewLayer ) - shapeFunc(aIter->first,pCurrViewLayer); - - ++aIter; - } - } - - LayerManager::LayerManager( const UnoViewContainer& rViews, - const ::basegfx::B2DRange& rPageBounds, - bool bDisableAnimationZOrder ) : - mrViews(rViews), - maLayers(), - maXShapeHash( 101 ), - maAllShapes(), - maUpdateShapes(), - maPageBounds( rPageBounds ), - mnActiveSprites(0), - mbLayerAssociationDirty(false), - mbActive(false), - mbDisableAnimationZOrder(bDisableAnimationZOrder) - { - // prevent frequent resizes (won't have more than 4 layers - // for 99.9% of the cases) - maLayers.reserve(4); - - // create initial background layer - maLayers.push_back( - Layer::createBackgroundLayer( - maPageBounds )); - - // init views - std::for_each( mrViews.begin(), - mrViews.end(), - ::boost::bind(&LayerManager::viewAdded, - this, - _1) ); - } - - void LayerManager::activate( bool bSlideBackgoundPainted ) - { - mbActive = true; - maUpdateShapes.clear(); // update gets forced via area, or - // has happend outside already - - if( !bSlideBackgoundPainted ) - { - std::for_each(mrViews.begin(), - mrViews.end(), - boost::mem_fn(&View::clearAll)); - - // force update of whole slide area - std::for_each( maLayers.begin(), - maLayers.end(), - boost::bind( &Layer::addUpdateRange, - _1, - boost::cref(maPageBounds) )); - } - else - { - // clear all possibly pending update areas - content - // is there, already - std::for_each( maLayers.begin(), - maLayers.end(), - boost::mem_fn( &Layer::clearUpdateRanges )); - } - - updateShapeLayers( bSlideBackgoundPainted ); - } - - void LayerManager::deactivate() - { - // TODO(F3): This is mostly a hack. Problem is, there's - // currently no smart way of telling shapes "remove your - // sprites". Others, like MediaShapes, listen to - // start/stop animation events, which is too much overhead - // for all shapes, though. - - const bool bMoreThanOneLayer(maLayers.size() > 1); - if( mnActiveSprites || bMoreThanOneLayer ) - { - // clear all viewlayers, dump everything but the - // background layer - this will also remove all shape - // sprites - std::for_each(maAllShapes.begin(), - maAllShapes.end(), - boost::bind( &Shape::clearAllViewLayers, - boost::bind( o3tl::select1st<LayerShapeMap::value_type>(), - _1 ))); - - for (LayerShapeMap::iterator - iShape (maAllShapes.begin()), - iEnd (maAllShapes.end()); - iShape!=iEnd; - ++iShape) - { - iShape->second.reset(); - } - - if( bMoreThanOneLayer ) - maLayers.erase(maLayers.begin()+1, - maLayers.end()); - - mbLayerAssociationDirty = true; - } - - mbActive = false; - - // only background layer left - OSL_ASSERT( maLayers.size() == 1 && maLayers.front()->isBackgroundLayer() ); - } - - void LayerManager::viewAdded( const UnoViewSharedPtr& rView ) - { - // view must be member of mrViews container - OSL_ASSERT( std::find(mrViews.begin(), - mrViews.end(), - rView) != mrViews.end() ); - - // init view content - if( mbActive ) - rView->clearAll(); - - // add View to all registered shapes - manageViews( - boost::bind(&Layer::addView, - _1, - boost::cref(rView)), - // repaint on view add - boost::bind(&Shape::addViewLayer, - _1, - _2, - true) ); - - // in case we haven't reached all layers from the - // maAllShapes, issue addView again for good measure - std::for_each( maLayers.begin(), - maLayers.end(), - boost::bind( &Layer::addView, - _1, - boost::cref(rView) )); - } - - void LayerManager::viewRemoved( const UnoViewSharedPtr& rView ) - { - // view must not be member of mrViews container anymore - OSL_ASSERT( std::find(mrViews.begin(), - mrViews.end(), - rView) == mrViews.end() ); - - // remove View from all registered shapes - manageViews( - boost::bind(&Layer::removeView, - _1, - boost::cref(rView)), - boost::bind(&Shape::removeViewLayer, - _1, - _2) ); - - // in case we haven't reached all layers from the - // maAllShapes, issue removeView again for good measure - std::for_each( maLayers.begin(), - maLayers.end(), - boost::bind( &Layer::removeView, - _1, - boost::cref(rView) )); - } - - void LayerManager::viewChanged( const UnoViewSharedPtr& rView ) - { - (void)rView; - - // view must be member of mrViews container - OSL_ASSERT( std::find(mrViews.begin(), - mrViews.end(), - rView) != mrViews.end() ); - - // TODO(P2): selectively update only changed view - viewsChanged(); - } - - void LayerManager::viewsChanged() - { - if( !mbActive ) - return; - - // clear view area - ::std::for_each( mrViews.begin(), - mrViews.end(), - ::boost::mem_fn(&View::clearAll) ); - - // TODO(F3): resize and repaint all layers - - // render all shapes - std::for_each( maAllShapes.begin(), - maAllShapes.end(), - boost::bind(&Shape::render, - boost::bind( ::o3tl::select1st<LayerShapeMap::value_type>(), _1)) ); - } - - void LayerManager::addShape( const ShapeSharedPtr& rShape ) - { - OSL_ASSERT( !maLayers.empty() ); // always at least background layer - ENSURE_OR_THROW( rShape, "LayerManager::addShape(): invalid Shape" ); - - // add shape to XShape hash map - if( !maXShapeHash.insert( - XShapeHash::value_type( rShape->getXShape(), - rShape) ).second ) - { - // entry already present, nothing to do - return; - } - - // add shape to appropriate layer - implAddShape( rShape ); - } - - void LayerManager::putShape2BackgroundLayer( LayerShapeMap::value_type& rShapeEntry ) - { - LayerSharedPtr& rBgLayer( maLayers.front() ); - rBgLayer->setShapeViews(rShapeEntry.first); - rShapeEntry.second = rBgLayer; - } - - void LayerManager::implAddShape( const ShapeSharedPtr& rShape ) - { - OSL_ASSERT( !maLayers.empty() ); // always at least background layer - ENSURE_OR_THROW( rShape, "LayerManager::implAddShape(): invalid Shape" ); - - LayerShapeMap::value_type aValue (rShape, LayerWeakPtr()); - - OSL_ASSERT( maAllShapes.find(rShape) == maAllShapes.end() ); // shape must not be added already - mbLayerAssociationDirty = true; - - if( mbDisableAnimationZOrder ) - putShape2BackgroundLayer( - *maAllShapes.insert(aValue).first ); - else - maAllShapes.insert(aValue); - - // update shape, it's just added and not yet painted - if( rShape->isVisible() ) - notifyShapeUpdate( rShape ); - } - - bool LayerManager::removeShape( const ShapeSharedPtr& rShape ) - { - // remove shape from XShape hash map - if( maXShapeHash.erase( rShape->getXShape() ) == 0 ) - return false; // shape not in map - - OSL_ASSERT( maAllShapes.find(rShape) != maAllShapes.end() ); - - implRemoveShape( rShape ); - - return true; - } - - void LayerManager::implRemoveShape( const ShapeSharedPtr& rShape ) - { - OSL_ASSERT( !maLayers.empty() ); // always at least background layer - ENSURE_OR_THROW( rShape, "LayerManager::implRemoveShape(): invalid Shape" ); - - const LayerShapeMap::iterator aShapeEntry( maAllShapes.find(rShape) ); - - if( aShapeEntry == maAllShapes.end() ) - return; - - const bool bShapeUpdateNotified = maUpdateShapes.erase( rShape ) != 0; - - // Enter shape area to the update area, but only if shape - // is visible and not in sprite mode (otherwise, updating - // the area doesn't do actual harm, but costs time) - // Actually, also add it if it was listed in - // maUpdateShapes (might have just gone invisible). - if( bShapeUpdateNotified || - (rShape->isVisible() && - !rShape->isBackgroundDetached()) ) - { - LayerSharedPtr pLayer = aShapeEntry->second.lock(); - if( pLayer ) - { - // store area early, once the shape is removed from - // the layers, it no longer has any view references - pLayer->addUpdateRange( rShape->getUpdateArea() ); - } - } - - rShape->clearAllViewLayers(); - maAllShapes.erase( aShapeEntry ); - - mbLayerAssociationDirty = true; - } - - ShapeSharedPtr LayerManager::lookupShape( const uno::Reference< drawing::XShape >& xShape ) const - { - ENSURE_OR_THROW( xShape.is(), "LayerManager::lookupShape(): invalid Shape" ); - - const XShapeHash::const_iterator aIter( maXShapeHash.find( xShape )); - if( aIter == maXShapeHash.end() ) - return ShapeSharedPtr(); // not found - - // found, return data part of entry pair. - return aIter->second; - } - - AttributableShapeSharedPtr LayerManager::getSubsetShape( const AttributableShapeSharedPtr& rOrigShape, - const DocTreeNode& rTreeNode ) - { - OSL_ASSERT( !maLayers.empty() ); // always at least background layer - - AttributableShapeSharedPtr pSubset; - - // shape already added? - if( rOrigShape->createSubset( pSubset, - rTreeNode ) ) - { - OSL_ENSURE( pSubset, "LayerManager::getSubsetShape(): failed to create subset" ); - - // don't add to shape hash, we're dupes to the - // original XShape anyway - all subset shapes return - // the same XShape as the original one. - - // add shape to corresponding layer - implAddShape( pSubset ); - - // update original shape, it now shows less content - // (the subset is removed from its displayed - // output). Subset shape is updated within - // implAddShape(). - if( rOrigShape->isVisible() ) - notifyShapeUpdate( rOrigShape ); - } - - return pSubset; - } - - void LayerManager::revokeSubset( const AttributableShapeSharedPtr& rOrigShape, - const AttributableShapeSharedPtr& rSubsetShape ) - { - OSL_ASSERT( !maLayers.empty() ); // always at least background layer - - if( rOrigShape->revokeSubset( rSubsetShape ) ) - { - OSL_ASSERT( maAllShapes.find(rSubsetShape) != maAllShapes.end() ); - - implRemoveShape( rSubsetShape ); - - // update original shape, it now shows more content - // (the subset is added back to its displayed output) - if( rOrigShape->isVisible() ) - notifyShapeUpdate( rOrigShape ); - } - } - - void LayerManager::enterAnimationMode( const AnimatableShapeSharedPtr& rShape ) - { - OSL_ASSERT( !maLayers.empty() ); // always at least background layer - ENSURE_OR_THROW( rShape, "LayerManager::enterAnimationMode(): invalid Shape" ); - - const bool bPrevAnimState( rShape->isBackgroundDetached() ); - - rShape->enterAnimationMode(); - - // if this call _really_ enabled the animation mode at - // rShape, insert it to our enter animation queue, to - // perform the necessary layer reorg lazily on - // LayerManager::update()/render(). - if( bPrevAnimState != rShape->isBackgroundDetached() ) - { - ++mnActiveSprites; - mbLayerAssociationDirty = true; - - // area needs update (shape is removed from normal - // slide, and now rendered as an autonomous - // sprite). store in update set - if( rShape->isVisible() ) - addUpdateArea( rShape ); - } - - // TODO(P1): this can lead to potential wasted effort, if - // a shape gets toggled animated/unanimated a few times - // between two frames, returning to the original state. - } - - void LayerManager::leaveAnimationMode( const AnimatableShapeSharedPtr& rShape ) - { - ENSURE_OR_THROW( !maLayers.empty(), "LayerManager::leaveAnimationMode(): no layers" ); - ENSURE_OR_THROW( rShape, "LayerManager::leaveAnimationMode(): invalid Shape" ); - - const bool bPrevAnimState( rShape->isBackgroundDetached() ); - - rShape->leaveAnimationMode(); - - // if this call _really_ ended the animation mode at - // rShape, insert it to our leave animation queue, to - // perform the necessary layer reorg lazily on - // LayerManager::update()/render(). - if( bPrevAnimState != rShape->isBackgroundDetached() ) - { - --mnActiveSprites; - mbLayerAssociationDirty = true; - - // shape needs update, no previous rendering, fast - // update possible. - if( rShape->isVisible() ) - notifyShapeUpdate( rShape ); - } - - // TODO(P1): this can lead to potential wasted effort, if - // a shape gets toggled animated/unanimated a few times - // between two frames, returning to the original state. - } - - void LayerManager::notifyShapeUpdate( const ShapeSharedPtr& rShape ) - { - if( !mbActive || mrViews.empty() ) - return; - - // hidden sprite-shape needs render() call still, to hide sprite - if( rShape->isVisible() || rShape->isBackgroundDetached() ) - maUpdateShapes.insert( rShape ); - else - addUpdateArea( rShape ); - } - - bool LayerManager::isUpdatePending() const - { - if( !mbActive ) - return false; - - if( mbLayerAssociationDirty || !maUpdateShapes.empty() ) - return true; - - const LayerVector::const_iterator aEnd( maLayers.end() ); - if( std::find_if( maLayers.begin(), - aEnd, - boost::mem_fn(&Layer::isUpdatePending)) != aEnd ) - return true; - - return false; - } - - bool LayerManager::updateSprites() - { - bool bRet(true); - - // send update() calls to every shape in the - // maUpdateShapes set, which is _animated_ (i.e. a - // sprite). - const ShapeUpdateSet::const_iterator aEnd=maUpdateShapes.end(); - ShapeUpdateSet::const_iterator aCurrShape=maUpdateShapes.begin(); - while( aCurrShape != aEnd ) - { - if( (*aCurrShape)->isBackgroundDetached() ) - { - // can update shape directly, without - // affecting layer content (shape is - // currently displayed in a sprite) - if( !(*aCurrShape)->update() ) - bRet = false; // delay error exit - } - else - { - // TODO(P2): addUpdateArea() involves log(n) - // search for shape layer. Have a frequent - // shape/layer association cache, or ptr back to - // layer at the shape? - - // cannot update shape directly, it's not - // animated and update() calls will prolly - // overwrite other page content. - addUpdateArea( *aCurrShape ); - } - - ++aCurrShape; - } - - maUpdateShapes.clear(); - - return bRet; - } - - bool LayerManager::update() - { - bool bRet = true; - - if( !mbActive ) - return bRet; - - // going to render - better flush any pending layer reorg - // now - updateShapeLayers(false); - - // all sprites - bRet = updateSprites(); - - // any non-sprite update areas left? - if( std::find_if( maLayers.begin(), - maLayers.end(), - boost::mem_fn( &Layer::isUpdatePending )) == maLayers.end() ) - return bRet; // nope, done. - - // update each shape on each layer, that has - // isUpdatePending() - bool bIsCurrLayerUpdating(false); - Layer::EndUpdater aEndUpdater; - LayerSharedPtr pCurrLayer; - LayerShapeMap::const_iterator aIter( maAllShapes.begin() ); - const LayerShapeMap::const_iterator aEnd ( maAllShapes.end() ); - while( aIter != aEnd ) - { - LayerSharedPtr pLayer = aIter->second.lock(); - if( pLayer != pCurrLayer ) - { - pCurrLayer = pLayer; - bIsCurrLayerUpdating = pCurrLayer->isUpdatePending(); - - if( bIsCurrLayerUpdating ) - aEndUpdater = pCurrLayer->beginUpdate(); - } - - if( bIsCurrLayerUpdating && - !aIter->first->isBackgroundDetached() && - pCurrLayer->isInsideUpdateArea(aIter->first) ) - { - if( !aIter->first->render() ) - bRet = false; - } - - ++aIter; - } - - return bRet; - } - - namespace - { - /** Little wrapper around a Canvas, to render one-shot - into a canvas - */ - class DummyLayer : public ViewLayer - { - public: - explicit DummyLayer( const ::cppcanvas::CanvasSharedPtr& rCanvas ) : - mpCanvas( rCanvas ) - { - } - - virtual bool isOnView(boost::shared_ptr<View> const& /*rView*/) const - { - return true; // visible on all views - } - - virtual ::cppcanvas::CanvasSharedPtr getCanvas() const - { - return mpCanvas; - } - - virtual void clear() const - { - // NOOP - } - - virtual void clearAll() const - { - // NOOP - } - - virtual ::cppcanvas::CustomSpriteSharedPtr createSprite( const ::basegfx::B2DSize& /*rSpriteSizePixel*/, - double /*nSpritePrio*/ ) const - { - ENSURE_OR_THROW( false, - "DummyLayer::createSprite(): This method is not supposed to be called!" ); - return ::cppcanvas::CustomSpriteSharedPtr(); - } - - virtual void setPriority( const basegfx::B1DRange& /*rRange*/ ) - { - OSL_FAIL( "BitmapView::setPriority(): This method is not supposed to be called!" ); - } - - virtual ::basegfx::B2DHomMatrix getTransformation() const - { - return mpCanvas->getTransformation(); - } - - virtual ::basegfx::B2DHomMatrix getSpriteTransformation() const - { - OSL_FAIL( "BitmapView::getSpriteTransformation(): This method is not supposed to be called!" ); - return ::basegfx::B2DHomMatrix(); - } - - virtual void setClip( const ::basegfx::B2DPolyPolygon& /*rClip*/ ) - { - OSL_FAIL( "BitmapView::setClip(): This method is not supposed to be called!" ); - } - - virtual bool resize( const ::basegfx::B2DRange& /*rArea*/ ) - { - OSL_FAIL( "BitmapView::resize(): This method is not supposed to be called!" ); - return false; - } - - private: - ::cppcanvas::CanvasSharedPtr mpCanvas; - }; - } - - bool LayerManager::renderTo( const ::cppcanvas::CanvasSharedPtr& rTargetCanvas ) const - { - bool bRet( true ); - ViewLayerSharedPtr pTmpLayer( new DummyLayer( rTargetCanvas ) ); - - LayerShapeMap::const_iterator aIter( maAllShapes.begin() ); - const LayerShapeMap::const_iterator aEnd ( maAllShapes.end() ); - while( aIter != aEnd ) - { - try - { - // forward to all shape's addViewLayer method (which - // we request to render the Shape on the new - // ViewLayer. Since we add the shapes in the - // maShapeSet order (which is also the render order), - // this is equivalent to a subsequent render() call) - aIter->first->addViewLayer( pTmpLayer, - true ); - - // and remove again, this is only temporary - aIter->first->removeViewLayer( pTmpLayer ); - } - catch( uno::Exception& ) - { - // TODO(E1): Might be superfluous. Nowadays, - // addViewLayer swallows all errors, anyway. - OSL_FAIL( rtl::OUStringToOString( - comphelper::anyToString( cppu::getCaughtException() ), - RTL_TEXTENCODING_UTF8 ).getStr() ); - - // at least one shape could not be rendered - bRet = false; - } - - ++aIter; - } - - return bRet; - } - - void LayerManager::addUpdateArea( ShapeSharedPtr const& rShape ) - { - OSL_ASSERT( !maLayers.empty() ); // always at least background layer - ENSURE_OR_THROW( rShape, "LayerManager::addUpdateArea(): invalid Shape" ); - - const LayerShapeMap::const_iterator aShapeEntry( maAllShapes.find(rShape) ); - - if( aShapeEntry == maAllShapes.end() ) - return; - - LayerSharedPtr pLayer = aShapeEntry->second.lock(); - if( pLayer ) - pLayer->addUpdateRange( rShape->getUpdateArea() ); - } - - void LayerManager::commitLayerChanges( std::size_t nCurrLayerIndex, - LayerShapeMap::const_iterator aFirstLayerShape, - LayerShapeMap::const_iterator aEndLayerShapes ) - { - const bool bLayerExists( maLayers.size() > nCurrLayerIndex ); - if( bLayerExists ) - { - const LayerSharedPtr& rLayer( maLayers.at(nCurrLayerIndex) ); - const bool bLayerResized( rLayer->commitBounds() ); - rLayer->setPriority( basegfx::B1DRange(nCurrLayerIndex, - nCurrLayerIndex+1) ); - - if( bLayerResized ) - { - // need to re-render whole layer - start from - // clean state - rLayer->clearContent(); - - // render and remove from update set - while( aFirstLayerShape != aEndLayerShapes ) - { - maUpdateShapes.erase(aFirstLayerShape->first); - aFirstLayerShape->first->render(); - ++aFirstLayerShape; - } - } - } - } - - LayerSharedPtr LayerManager::createForegroundLayer() const - { - OSL_ASSERT( mbActive ); - - LayerSharedPtr pLayer( Layer::createLayer( - maPageBounds )); - - // create ViewLayers for all registered views, and add to - // newly created layer. - ::std::for_each( mrViews.begin(), - mrViews.end(), - boost::bind( &Layer::addView, - boost::cref(pLayer), - _1 )); - - return pLayer; - } - - void LayerManager::updateShapeLayers( bool bBackgroundLayerPainted ) - { - OSL_ASSERT( !maLayers.empty() ); // always at least background layer - OSL_ASSERT( mbActive ); - - // do we need to process shapes? - if( !mbLayerAssociationDirty ) - return; - - if( mbDisableAnimationZOrder ) - { - // layer setup happened elsewhere, is only bg layer - // anyway. - mbLayerAssociationDirty = false; - return; - } - - // scan through maAllShapes, and determine shape animation - // discontinuities: when a shape that has - // isBackgroundDetached() return false follows a shape - // with isBackgroundDetached() true, the former and all - // following ones must be moved into an own layer. - - // to avoid tons of temporaries, create weak_ptr to Layers - // beforehand - std::vector< LayerWeakPtr > aWeakLayers(maLayers.size()); - std::copy(maLayers.begin(),maLayers.end(),aWeakLayers.begin()); - - std::size_t nCurrLayerIndex(0); - bool bIsBackgroundLayer(true); - bool bLastWasBackgroundDetached(false); // last shape sprite state - LayerShapeMap::iterator aCurrShapeEntry( maAllShapes.begin() ); - LayerShapeMap::iterator aCurrLayerFirstShapeEntry( maAllShapes.begin() ); - const LayerShapeMap::iterator aEndShapeEntry ( maAllShapes.end() ); - ShapeUpdateSet aUpdatedShapes; // shapes that need update - while( aCurrShapeEntry != aEndShapeEntry ) - { - const ShapeSharedPtr pCurrShape( aCurrShapeEntry->first ); - const bool bThisIsBackgroundDetached( - pCurrShape->isBackgroundDetached() ); - - if( bLastWasBackgroundDetached == true && - bThisIsBackgroundDetached == false ) - { - // discontinuity found - current shape needs to - // get into a new layer - // -------------------------------------------- - - // commit changes to previous layer - commitLayerChanges(nCurrLayerIndex, - aCurrLayerFirstShapeEntry, - aCurrShapeEntry); - aCurrLayerFirstShapeEntry=aCurrShapeEntry; - ++nCurrLayerIndex; - bIsBackgroundLayer = false; - - if( aWeakLayers.size() <= nCurrLayerIndex || - aWeakLayers.at(nCurrLayerIndex) != aCurrShapeEntry->second ) - { - // no more layers left, or shape was not - // member of this layer - create a new one - maLayers.insert( maLayers.begin()+nCurrLayerIndex, - createForegroundLayer() ); - aWeakLayers.insert( aWeakLayers.begin()+nCurrLayerIndex, - maLayers[nCurrLayerIndex] ); - } - } - - OSL_ASSERT( maLayers.size() == aWeakLayers.size() ); - - // note: using indices here, since vector::insert - // above invalidates iterators - LayerSharedPtr& rCurrLayer( maLayers.at(nCurrLayerIndex) ); - LayerWeakPtr& rCurrWeakLayer( aWeakLayers.at(nCurrLayerIndex) ); - if( rCurrWeakLayer != aCurrShapeEntry->second ) - { - // mismatch: shape is not contained in current - // layer - move shape to that layer, then. - maLayers.at(nCurrLayerIndex)->setShapeViews( - pCurrShape ); - - // layer got new shape(s), need full repaint, if - // non-sprite shape - if( !bThisIsBackgroundDetached && pCurrShape->isVisible() ) - { - LayerSharedPtr pOldLayer( aCurrShapeEntry->second.lock() ); - if( pOldLayer ) - { - // old layer still valid? then we need to - // repaint former shape area - pOldLayer->addUpdateRange( - pCurrShape->getUpdateArea() ); - } - - // render on new layer (only if not - // explicitely disabled) - if( !(bBackgroundLayerPainted && bIsBackgroundLayer) ) - maUpdateShapes.insert( pCurrShape ); - } - - aCurrShapeEntry->second = rCurrWeakLayer; - } - - // update layerbounds regardless of the fact that the - // shape might be contained in said layer - // already. updateBounds() is dumb and needs to - // collect all shape bounds. - // of course, no need to expand layer bounds for - // shapes that reside in sprites themselves. - if( !bThisIsBackgroundDetached && !bIsBackgroundLayer ) - rCurrLayer->updateBounds( pCurrShape ); - - bLastWasBackgroundDetached = bThisIsBackgroundDetached; - ++aCurrShapeEntry; - } - - // commit very last layer data - commitLayerChanges(nCurrLayerIndex, - aCurrLayerFirstShapeEntry, - aCurrShapeEntry); - - // any layers left? Bin them! - if( maLayers.size() > nCurrLayerIndex+1 ) - maLayers.erase(maLayers.begin()+nCurrLayerIndex+1, - maLayers.end()); - - mbLayerAssociationDirty = false; - } - } -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |