summaryrefslogtreecommitdiff
path: root/slideshow/source/engine/slide/layermanager.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'slideshow/source/engine/slide/layermanager.cxx')
-rw-r--r--slideshow/source/engine/slide/layermanager.cxx923
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: */