1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <canvas/debug.hxx>
22 #include <tools/diagnose_ex.h>
23 #include <basegfx/range/b1drange.hxx>
24 #include <basegfx/matrix/b2dhommatrix.hxx>
26 #include <comphelper/anytostring.hxx>
27 #include <cppuhelper/exc_hlp.hxx>
29 #include <boost/bind.hpp>
32 #include <o3tl/compat_functional.hxx>
34 #include "layermanager.hxx"
36 using namespace ::com::sun::star
;
40 // add operator!= for weak_ptr
41 inline bool operator!=( slideshow::internal::LayerWeakPtr
const& rLHS
,
42 slideshow::internal::LayerWeakPtr
const& rRHS
)
44 return (rLHS
<rRHS
) || (rRHS
<rLHS
);
52 template<typename LayerFunc
,
53 typename ShapeFunc
> void LayerManager::manageViews(
57 LayerSharedPtr pCurrLayer
;
58 ViewLayerSharedPtr pCurrViewLayer
;
59 LayerShapeMap::const_iterator
aIter( maAllShapes
.begin() );
60 const LayerShapeMap::const_iterator
aEnd ( maAllShapes
.end() );
61 while( aIter
!= aEnd
)
63 LayerSharedPtr pLayer
= aIter
->second
.lock();
64 if( pLayer
&& pLayer
!= pCurrLayer
)
67 pCurrViewLayer
= layerFunc(pCurrLayer
);
71 shapeFunc(aIter
->first
,pCurrViewLayer
);
77 LayerManager::LayerManager( const UnoViewContainer
& rViews
,
78 const ::basegfx::B2DRange
& rPageBounds
,
79 bool bDisableAnimationZOrder
) :
85 maPageBounds( rPageBounds
),
87 mbLayerAssociationDirty(false),
89 mbDisableAnimationZOrder(bDisableAnimationZOrder
)
91 // prevent frequent resizes (won't have more than 4 layers
92 // for 99.9% of the cases)
95 // create initial background layer
97 Layer::createBackgroundLayer(
101 std::for_each( mrViews
.begin(),
103 ::boost::bind(&LayerManager::viewAdded
,
108 void LayerManager::activate( bool bSlideBackgoundPainted
)
111 maUpdateShapes
.clear(); // update gets forced via area, or
112 // has happened outside already
114 if( !bSlideBackgoundPainted
)
116 std::for_each(mrViews
.begin(),
118 boost::mem_fn(&View::clearAll
));
120 // force update of whole slide area
121 std::for_each( maLayers
.begin(),
123 boost::bind( &Layer::addUpdateRange
,
125 boost::cref(maPageBounds
) ));
129 // clear all possibly pending update areas - content
131 std::for_each( maLayers
.begin(),
133 boost::mem_fn( &Layer::clearUpdateRanges
));
136 updateShapeLayers( bSlideBackgoundPainted
);
139 void LayerManager::deactivate()
141 // TODO(F3): This is mostly a hack. Problem is, there's
142 // currently no smart way of telling shapes "remove your
143 // sprites". Others, like MediaShapes, listen to
144 // start/stop animation events, which is too much overhead
145 // for all shapes, though.
147 const bool bMoreThanOneLayer(maLayers
.size() > 1);
148 if( mnActiveSprites
|| bMoreThanOneLayer
)
150 // clear all viewlayers, dump everything but the
151 // background layer - this will also remove all shape
153 std::for_each(maAllShapes
.begin(),
155 boost::bind( &Shape::clearAllViewLayers
,
156 boost::bind( o3tl::select1st
<LayerShapeMap::value_type
>(),
159 for (LayerShapeMap::iterator
160 iShape (maAllShapes
.begin()),
161 iEnd (maAllShapes
.end());
165 iShape
->second
.reset();
168 if( bMoreThanOneLayer
)
169 maLayers
.erase(maLayers
.begin()+1,
172 mbLayerAssociationDirty
= true;
177 // only background layer left
178 OSL_ASSERT( maLayers
.size() == 1 && maLayers
.front()->isBackgroundLayer() );
181 void LayerManager::viewAdded( const UnoViewSharedPtr
& rView
)
183 // view must be member of mrViews container
184 OSL_ASSERT( std::find(mrViews
.begin(),
186 rView
) != mrViews
.end() );
192 // add View to all registered shapes
194 boost::bind(&Layer::addView
,
197 // repaint on view add
198 boost::bind(&Shape::addViewLayer
,
203 // in case we haven't reached all layers from the
204 // maAllShapes, issue addView again for good measure
205 std::for_each( maLayers
.begin(),
207 boost::bind( &Layer::addView
,
209 boost::cref(rView
) ));
212 void LayerManager::viewRemoved( const UnoViewSharedPtr
& rView
)
214 // view must not be member of mrViews container anymore
215 OSL_ASSERT( std::find(mrViews
.begin(),
217 rView
) == mrViews
.end() );
219 // remove View from all registered shapes
221 boost::bind(&Layer::removeView
,
224 boost::bind(&Shape::removeViewLayer
,
228 // in case we haven't reached all layers from the
229 // maAllShapes, issue removeView again for good measure
230 std::for_each( maLayers
.begin(),
232 boost::bind( &Layer::removeView
,
234 boost::cref(rView
) ));
237 void LayerManager::viewChanged( const UnoViewSharedPtr
& rView
)
241 // view must be member of mrViews container
242 OSL_ASSERT( std::find(mrViews
.begin(),
244 rView
) != mrViews
.end() );
246 // TODO(P2): selectively update only changed view
250 void LayerManager::viewsChanged()
256 ::std::for_each( mrViews
.begin(),
258 ::boost::mem_fn(&View::clearAll
) );
260 // TODO(F3): resize and repaint all layers
263 std::for_each( maAllShapes
.begin(),
265 boost::bind(&Shape::render
,
266 boost::bind( ::o3tl::select1st
<LayerShapeMap::value_type
>(), _1
)) );
269 void LayerManager::addShape( const ShapeSharedPtr
& rShape
)
271 OSL_ASSERT( !maLayers
.empty() ); // always at least background layer
272 ENSURE_OR_THROW( rShape
, "LayerManager::addShape(): invalid Shape" );
274 // add shape to XShape hash map
275 if( !maXShapeHash
.insert(
276 XShapeHash::value_type( rShape
->getXShape(),
279 // entry already present, nothing to do
283 // add shape to appropriate layer
284 implAddShape( rShape
);
287 void LayerManager::putShape2BackgroundLayer( LayerShapeMap::value_type
& rShapeEntry
)
289 LayerSharedPtr
& rBgLayer( maLayers
.front() );
290 rBgLayer
->setShapeViews(rShapeEntry
.first
);
291 rShapeEntry
.second
= rBgLayer
;
294 void LayerManager::implAddShape( const ShapeSharedPtr
& rShape
)
296 OSL_ASSERT( !maLayers
.empty() ); // always at least background layer
297 ENSURE_OR_THROW( rShape
, "LayerManager::implAddShape(): invalid Shape" );
299 LayerShapeMap::value_type
aValue (rShape
, LayerWeakPtr());
301 OSL_ASSERT( maAllShapes
.find(rShape
) == maAllShapes
.end() ); // shape must not be added already
302 mbLayerAssociationDirty
= true;
304 if( mbDisableAnimationZOrder
)
305 putShape2BackgroundLayer(
306 *maAllShapes
.insert(aValue
).first
);
308 maAllShapes
.insert(aValue
);
310 // update shape, it's just added and not yet painted
311 if( rShape
->isVisible() )
312 notifyShapeUpdate( rShape
);
315 void LayerManager::implRemoveShape( const ShapeSharedPtr
& rShape
)
317 OSL_ASSERT( !maLayers
.empty() ); // always at least background layer
318 ENSURE_OR_THROW( rShape
, "LayerManager::implRemoveShape(): invalid Shape" );
320 const LayerShapeMap::iterator
aShapeEntry( maAllShapes
.find(rShape
) );
322 if( aShapeEntry
== maAllShapes
.end() )
325 const bool bShapeUpdateNotified
= maUpdateShapes
.erase( rShape
) != 0;
327 // Enter shape area to the update area, but only if shape
328 // is visible and not in sprite mode (otherwise, updating
329 // the area doesn't do actual harm, but costs time)
330 // Actually, also add it if it was listed in
331 // maUpdateShapes (might have just gone invisible).
332 if( bShapeUpdateNotified
||
333 (rShape
->isVisible() &&
334 !rShape
->isBackgroundDetached()) )
336 LayerSharedPtr pLayer
= aShapeEntry
->second
.lock();
339 // store area early, once the shape is removed from
340 // the layers, it no longer has any view references
341 pLayer
->addUpdateRange( rShape
->getUpdateArea() );
345 rShape
->clearAllViewLayers();
346 maAllShapes
.erase( aShapeEntry
);
348 mbLayerAssociationDirty
= true;
351 ShapeSharedPtr
LayerManager::lookupShape( const uno::Reference
< drawing::XShape
>& xShape
) const
353 ENSURE_OR_THROW( xShape
.is(), "LayerManager::lookupShape(): invalid Shape" );
355 const XShapeHash::const_iterator
aIter( maXShapeHash
.find( xShape
));
356 if( aIter
== maXShapeHash
.end() )
357 return ShapeSharedPtr(); // not found
359 // found, return data part of entry pair.
360 return aIter
->second
;
363 AttributableShapeSharedPtr
LayerManager::getSubsetShape( const AttributableShapeSharedPtr
& rOrigShape
,
364 const DocTreeNode
& rTreeNode
)
366 OSL_ASSERT( !maLayers
.empty() ); // always at least background layer
368 AttributableShapeSharedPtr pSubset
;
370 // shape already added?
371 if( rOrigShape
->createSubset( pSubset
,
374 OSL_ENSURE( pSubset
, "LayerManager::getSubsetShape(): failed to create subset" );
376 // don't add to shape hash, we're dupes to the
377 // original XShape anyway - all subset shapes return
378 // the same XShape as the original one.
380 // add shape to corresponding layer
381 implAddShape( pSubset
);
383 // update original shape, it now shows less content
384 // (the subset is removed from its displayed
385 // output). Subset shape is updated within
387 if( rOrigShape
->isVisible() )
388 notifyShapeUpdate( rOrigShape
);
394 void LayerManager::revokeSubset( const AttributableShapeSharedPtr
& rOrigShape
,
395 const AttributableShapeSharedPtr
& rSubsetShape
)
397 OSL_ASSERT( !maLayers
.empty() ); // always at least background layer
399 if( rOrigShape
->revokeSubset( rSubsetShape
) )
401 OSL_ASSERT( maAllShapes
.find(rSubsetShape
) != maAllShapes
.end() );
403 implRemoveShape( rSubsetShape
);
405 // update original shape, it now shows more content
406 // (the subset is added back to its displayed output)
407 if( rOrigShape
->isVisible() )
408 notifyShapeUpdate( rOrigShape
);
412 void LayerManager::enterAnimationMode( const AnimatableShapeSharedPtr
& rShape
)
414 OSL_ASSERT( !maLayers
.empty() ); // always at least background layer
415 ENSURE_OR_THROW( rShape
, "LayerManager::enterAnimationMode(): invalid Shape" );
417 const bool bPrevAnimState( rShape
->isBackgroundDetached() );
419 rShape
->enterAnimationMode();
421 // if this call _really_ enabled the animation mode at
422 // rShape, insert it to our enter animation queue, to
423 // perform the necessary layer reorg lazily on
424 // LayerManager::update()/render().
425 if( bPrevAnimState
!= rShape
->isBackgroundDetached() )
428 mbLayerAssociationDirty
= true;
430 // area needs update (shape is removed from normal
431 // slide, and now rendered as an autonomous
432 // sprite). store in update set
433 if( rShape
->isVisible() )
434 addUpdateArea( rShape
);
437 // TODO(P1): this can lead to potential wasted effort, if
438 // a shape gets toggled animated/unanimated a few times
439 // between two frames, returning to the original state.
442 void LayerManager::leaveAnimationMode( const AnimatableShapeSharedPtr
& rShape
)
444 ENSURE_OR_THROW( !maLayers
.empty(), "LayerManager::leaveAnimationMode(): no layers" );
445 ENSURE_OR_THROW( rShape
, "LayerManager::leaveAnimationMode(): invalid Shape" );
447 const bool bPrevAnimState( rShape
->isBackgroundDetached() );
449 rShape
->leaveAnimationMode();
451 // if this call _really_ ended the animation mode at
452 // rShape, insert it to our leave animation queue, to
453 // perform the necessary layer reorg lazily on
454 // LayerManager::update()/render().
455 if( bPrevAnimState
!= rShape
->isBackgroundDetached() )
458 mbLayerAssociationDirty
= true;
460 // shape needs update, no previous rendering, fast
462 if( rShape
->isVisible() )
463 notifyShapeUpdate( rShape
);
466 // TODO(P1): this can lead to potential wasted effort, if
467 // a shape gets toggled animated/unanimated a few times
468 // between two frames, returning to the original state.
471 void LayerManager::notifyShapeUpdate( const ShapeSharedPtr
& rShape
)
473 if( !mbActive
|| mrViews
.empty() )
476 // hidden sprite-shape needs render() call still, to hide sprite
477 if( rShape
->isVisible() || rShape
->isBackgroundDetached() )
478 maUpdateShapes
.insert( rShape
);
480 addUpdateArea( rShape
);
483 bool LayerManager::isUpdatePending() const
488 if( mbLayerAssociationDirty
|| !maUpdateShapes
.empty() )
491 const LayerVector::const_iterator
aEnd( maLayers
.end() );
492 if( std::find_if( maLayers
.begin(),
494 boost::mem_fn(&Layer::isUpdatePending
)) != aEnd
)
500 bool LayerManager::updateSprites()
504 // send update() calls to every shape in the
505 // maUpdateShapes set, which is _animated_ (i.e. a
507 const ShapeUpdateSet::const_iterator aEnd
=maUpdateShapes
.end();
508 ShapeUpdateSet::const_iterator aCurrShape
=maUpdateShapes
.begin();
509 while( aCurrShape
!= aEnd
)
511 if( (*aCurrShape
)->isBackgroundDetached() )
513 // can update shape directly, without
514 // affecting layer content (shape is
515 // currently displayed in a sprite)
516 if( !(*aCurrShape
)->update() )
517 bRet
= false; // delay error exit
521 // TODO(P2): addUpdateArea() involves log(n)
522 // search for shape layer. Have a frequent
523 // shape/layer association cache, or ptr back to
524 // layer at the shape?
526 // cannot update shape directly, it's not
527 // animated and update() calls will prolly
528 // overwrite other page content.
529 addUpdateArea( *aCurrShape
);
535 maUpdateShapes
.clear();
540 bool LayerManager::update()
547 // going to render - better flush any pending layer reorg
549 updateShapeLayers(false);
552 bRet
= updateSprites();
554 // any non-sprite update areas left?
555 if( std::find_if( maLayers
.begin(),
557 boost::mem_fn( &Layer::isUpdatePending
)) == maLayers
.end() )
558 return bRet
; // nope, done.
560 // update each shape on each layer, that has
562 bool bIsCurrLayerUpdating(false);
563 Layer::EndUpdater aEndUpdater
;
564 LayerSharedPtr pCurrLayer
;
565 LayerShapeMap::const_iterator
aIter( maAllShapes
.begin() );
566 const LayerShapeMap::const_iterator
aEnd ( maAllShapes
.end() );
567 while( aIter
!= aEnd
)
569 LayerSharedPtr pLayer
= aIter
->second
.lock();
570 if( pLayer
!= pCurrLayer
)
573 bIsCurrLayerUpdating
= pCurrLayer
->isUpdatePending();
575 if( bIsCurrLayerUpdating
)
576 aEndUpdater
= pCurrLayer
->beginUpdate();
579 if( bIsCurrLayerUpdating
&&
580 !aIter
->first
->isBackgroundDetached() &&
581 pCurrLayer
->isInsideUpdateArea(aIter
->first
) )
583 if( !aIter
->first
->render() )
595 /** Little wrapper around a Canvas, to render one-shot
598 class DummyLayer
: public ViewLayer
601 explicit DummyLayer( const ::cppcanvas::CanvasSharedPtr
& rCanvas
) :
606 virtual bool isOnView(boost::shared_ptr
<View
> const& /*rView*/) const
608 return true; // visible on all views
611 virtual ::cppcanvas::CanvasSharedPtr
getCanvas() const
616 virtual void clear() const
621 virtual void clearAll() const
626 virtual ::cppcanvas::CustomSpriteSharedPtr
createSprite( const ::basegfx::B2DSize
& /*rSpriteSizePixel*/,
627 double /*nSpritePrio*/ ) const
629 ENSURE_OR_THROW( false,
630 "DummyLayer::createSprite(): This method is not supposed to be called!" );
631 return ::cppcanvas::CustomSpriteSharedPtr();
634 virtual void setPriority( const basegfx::B1DRange
& /*rRange*/ )
636 OSL_FAIL( "BitmapView::setPriority(): This method is not supposed to be called!" );
639 virtual ::basegfx::B2DHomMatrix
getTransformation() const
641 return mpCanvas
->getTransformation();
644 virtual ::basegfx::B2DHomMatrix
getSpriteTransformation() const
646 OSL_FAIL( "BitmapView::getSpriteTransformation(): This method is not supposed to be called!" );
647 return ::basegfx::B2DHomMatrix();
650 virtual void setClip( const ::basegfx::B2DPolyPolygon
& /*rClip*/ )
652 OSL_FAIL( "BitmapView::setClip(): This method is not supposed to be called!" );
655 virtual bool resize( const ::basegfx::B2DRange
& /*rArea*/ )
657 OSL_FAIL( "BitmapView::resize(): This method is not supposed to be called!" );
662 ::cppcanvas::CanvasSharedPtr mpCanvas
;
666 bool LayerManager::renderTo( const ::cppcanvas::CanvasSharedPtr
& rTargetCanvas
) const
669 ViewLayerSharedPtr
pTmpLayer( new DummyLayer( rTargetCanvas
) );
671 LayerShapeMap::const_iterator
aIter( maAllShapes
.begin() );
672 const LayerShapeMap::const_iterator
aEnd ( maAllShapes
.end() );
673 while( aIter
!= aEnd
)
677 // forward to all shape's addViewLayer method (which
678 // we request to render the Shape on the new
679 // ViewLayer. Since we add the shapes in the
680 // maShapeSet order (which is also the render order),
681 // this is equivalent to a subsequent render() call)
682 aIter
->first
->addViewLayer( pTmpLayer
,
685 // and remove again, this is only temporary
686 aIter
->first
->removeViewLayer( pTmpLayer
);
688 catch( uno::Exception
& )
690 // TODO(E1): Might be superfluous. Nowadays,
691 // addViewLayer swallows all errors, anyway.
692 OSL_FAIL( OUStringToOString(
693 comphelper::anyToString( cppu::getCaughtException() ),
694 RTL_TEXTENCODING_UTF8
).getStr() );
696 // at least one shape could not be rendered
706 void LayerManager::addUpdateArea( ShapeSharedPtr
const& rShape
)
708 OSL_ASSERT( !maLayers
.empty() ); // always at least background layer
709 ENSURE_OR_THROW( rShape
, "LayerManager::addUpdateArea(): invalid Shape" );
711 const LayerShapeMap::const_iterator
aShapeEntry( maAllShapes
.find(rShape
) );
713 if( aShapeEntry
== maAllShapes
.end() )
716 LayerSharedPtr pLayer
= aShapeEntry
->second
.lock();
718 pLayer
->addUpdateRange( rShape
->getUpdateArea() );
721 void LayerManager::commitLayerChanges( std::size_t nCurrLayerIndex
,
722 LayerShapeMap::const_iterator aFirstLayerShape
,
723 LayerShapeMap::const_iterator aEndLayerShapes
)
725 const bool bLayerExists( maLayers
.size() > nCurrLayerIndex
);
728 const LayerSharedPtr
& rLayer( maLayers
.at(nCurrLayerIndex
) );
729 const bool bLayerResized( rLayer
->commitBounds() );
730 rLayer
->setPriority( basegfx::B1DRange(nCurrLayerIndex
,
731 nCurrLayerIndex
+1) );
735 // need to re-render whole layer - start from
737 rLayer
->clearContent();
739 // render and remove from update set
740 while( aFirstLayerShape
!= aEndLayerShapes
)
742 maUpdateShapes
.erase(aFirstLayerShape
->first
);
743 aFirstLayerShape
->first
->render();
750 LayerSharedPtr
LayerManager::createForegroundLayer() const
752 OSL_ASSERT( mbActive
);
754 LayerSharedPtr
pLayer( Layer::createLayer(
757 // create ViewLayers for all registered views, and add to
758 // newly created layer.
759 ::std::for_each( mrViews
.begin(),
761 boost::bind( &Layer::addView
,
768 void LayerManager::updateShapeLayers( bool bBackgroundLayerPainted
)
770 OSL_ASSERT( !maLayers
.empty() ); // always at least background layer
771 OSL_ASSERT( mbActive
);
773 // do we need to process shapes?
774 if( !mbLayerAssociationDirty
)
777 if( mbDisableAnimationZOrder
)
779 // layer setup happened elsewhere, is only bg layer
781 mbLayerAssociationDirty
= false;
785 // scan through maAllShapes, and determine shape animation
786 // discontinuities: when a shape that has
787 // isBackgroundDetached() return false follows a shape
788 // with isBackgroundDetached() true, the former and all
789 // following ones must be moved into an own layer.
791 // to avoid tons of temporaries, create weak_ptr to Layers
793 std::vector
< LayerWeakPtr
> aWeakLayers(maLayers
.size());
794 std::copy(maLayers
.begin(),maLayers
.end(),aWeakLayers
.begin());
796 std::size_t nCurrLayerIndex(0);
797 bool bIsBackgroundLayer(true);
798 bool bLastWasBackgroundDetached(false); // last shape sprite state
799 LayerShapeMap::iterator
aCurrShapeEntry( maAllShapes
.begin() );
800 LayerShapeMap::iterator
aCurrLayerFirstShapeEntry( maAllShapes
.begin() );
801 const LayerShapeMap::iterator
aEndShapeEntry ( maAllShapes
.end() );
802 ShapeUpdateSet aUpdatedShapes
; // shapes that need update
803 while( aCurrShapeEntry
!= aEndShapeEntry
)
805 const ShapeSharedPtr
pCurrShape( aCurrShapeEntry
->first
);
806 const bool bThisIsBackgroundDetached(
807 pCurrShape
->isBackgroundDetached() );
809 if( bLastWasBackgroundDetached
== true &&
810 bThisIsBackgroundDetached
== false )
812 // discontinuity found - current shape needs to
813 // get into a new layer
814 // --------------------------------------------
816 // commit changes to previous layer
817 commitLayerChanges(nCurrLayerIndex
,
818 aCurrLayerFirstShapeEntry
,
820 aCurrLayerFirstShapeEntry
=aCurrShapeEntry
;
822 bIsBackgroundLayer
= false;
824 if( aWeakLayers
.size() <= nCurrLayerIndex
||
825 aWeakLayers
.at(nCurrLayerIndex
) != aCurrShapeEntry
->second
)
827 // no more layers left, or shape was not
828 // member of this layer - create a new one
829 maLayers
.insert( maLayers
.begin()+nCurrLayerIndex
,
830 createForegroundLayer() );
831 aWeakLayers
.insert( aWeakLayers
.begin()+nCurrLayerIndex
,
832 maLayers
[nCurrLayerIndex
] );
836 OSL_ASSERT( maLayers
.size() == aWeakLayers
.size() );
838 // note: using indices here, since vector::insert
839 // above invalidates iterators
840 LayerSharedPtr
& rCurrLayer( maLayers
.at(nCurrLayerIndex
) );
841 LayerWeakPtr
& rCurrWeakLayer( aWeakLayers
.at(nCurrLayerIndex
) );
842 if( rCurrWeakLayer
!= aCurrShapeEntry
->second
)
844 // mismatch: shape is not contained in current
845 // layer - move shape to that layer, then.
846 maLayers
.at(nCurrLayerIndex
)->setShapeViews(
849 // layer got new shape(s), need full repaint, if
851 if( !bThisIsBackgroundDetached
&& pCurrShape
->isVisible() )
853 LayerSharedPtr
pOldLayer( aCurrShapeEntry
->second
.lock() );
856 // old layer still valid? then we need to
857 // repaint former shape area
858 pOldLayer
->addUpdateRange(
859 pCurrShape
->getUpdateArea() );
862 // render on new layer (only if not
863 // explicitly disabled)
864 if( !(bBackgroundLayerPainted
&& bIsBackgroundLayer
) )
865 maUpdateShapes
.insert( pCurrShape
);
868 aCurrShapeEntry
->second
= rCurrWeakLayer
;
871 // update layerbounds regardless of the fact that the
872 // shape might be contained in said layer
873 // already. updateBounds() is dumb and needs to
874 // collect all shape bounds.
875 // of course, no need to expand layer bounds for
876 // shapes that reside in sprites themselves.
877 if( !bThisIsBackgroundDetached
&& !bIsBackgroundLayer
)
878 rCurrLayer
->updateBounds( pCurrShape
);
880 bLastWasBackgroundDetached
= bThisIsBackgroundDetached
;
884 // commit very last layer data
885 commitLayerChanges(nCurrLayerIndex
,
886 aCurrLayerFirstShapeEntry
,
889 // any layers left? Bin them!
890 if( maLayers
.size() > nCurrLayerIndex
+1 )
891 maLayers
.erase(maLayers
.begin()+nCurrLayerIndex
+1,
894 mbLayerAssociationDirty
= false;
899 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */