1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: layer.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_slideshow.hxx"
35 #include <canvas/debug.hxx>
37 #include <basegfx/range/b2drange.hxx>
38 #include <basegfx/range/b1drange.hxx>
39 #include <basegfx/range/b2dmultirange.hxx>
40 #include <basegfx/matrix/b2dhommatrix.hxx>
41 #include <basegfx/polygon/b2dpolypolygon.hxx>
45 #include <boost/bind.hpp>
48 using namespace ::com::sun::star
;
54 Layer::Layer( const basegfx::B2DRange
& rMaxLayerBounds
,
59 maMaxBounds( rMaxLayerBounds
),
61 mbBackgroundLayer(true),
66 Layer::Layer( const basegfx::B2DRange
& rMaxLayerBounds
) :
70 maMaxBounds( rMaxLayerBounds
),
72 mbBackgroundLayer(false),
77 ViewLayerSharedPtr
Layer::addView( const ViewSharedPtr
& rNewView
)
79 OSL_ASSERT( rNewView
);
81 ViewEntryVector::iterator aIter
;
82 const ViewEntryVector::iterator
aEnd( maViewEntries
.end() );
83 if( (aIter
=std::find_if( maViewEntries
.begin(),
86 std::equal_to
< ViewSharedPtr
>(),
87 boost::bind( &ViewEntry::getView
, _1
),
88 boost::cref( rNewView
)))) != aEnd
)
90 // already added - just return existing layer
91 return aIter
->mpViewLayer
;
95 // not yet added - create new view layer
96 ViewLayerSharedPtr pNewLayer
;
97 if( mbBackgroundLayer
)
100 pNewLayer
= rNewView
->createViewLayer(maBounds
);
103 maViewEntries
.push_back(
107 return maViewEntries
.back().mpViewLayer
;
110 ViewLayerSharedPtr
Layer::removeView( const ViewSharedPtr
& rView
)
114 ViewEntryVector::iterator aIter
;
115 const ViewEntryVector::iterator
aEnd( maViewEntries
.end() );
116 if( (aIter
=std::find_if( maViewEntries
.begin(),
119 std::equal_to
< ViewSharedPtr
>(),
120 boost::bind( &ViewEntry::getView
, _1
),
121 boost::cref( rView
)))) == aEnd
)
123 // View was not added/is already removed
124 return ViewLayerSharedPtr();
127 OSL_ENSURE( std::count_if( maViewEntries
.begin(),
130 std::equal_to
< ViewSharedPtr
>(),
131 boost::bind( &ViewEntry::getView
, _1
),
132 boost::cref( rView
))) == 1,
133 "Layer::removeView(): view added multiple times" );
135 ViewLayerSharedPtr
pRet( aIter
->mpViewLayer
);
136 maViewEntries
.erase(aIter
);
141 void Layer::viewChanged( const ViewSharedPtr
& rChangedView
)
143 ViewEntryVector::iterator aIter
;
144 const ViewEntryVector::iterator
aEnd( maViewEntries
.end() );
145 if( (aIter
=std::find_if( maViewEntries
.begin(),
148 std::equal_to
< ViewSharedPtr
>(),
149 boost::bind( &ViewEntry::getView
, _1
),
150 boost::cref( rChangedView
)))) !=
153 // adapt size of given ViewLayer - background layer
154 // resizes with view.
155 if( !mbBackgroundLayer
)
156 aIter
->mpViewLayer
->resize(maBounds
);
160 void Layer::viewsChanged()
162 // adapt size of given ViewLayer - background layer
163 // resizes with view.
164 if( !mbBackgroundLayer
)
166 std::for_each( maViewEntries
.begin(),
168 boost::bind( &ViewLayer::resize
,
169 boost::bind( &ViewEntry::getViewLayer
,
171 boost::cref(maBounds
)));
175 void Layer::setShapeViews( ShapeSharedPtr
const& rShape
) const
177 rShape
->clearAllViewLayers();
179 std::for_each( maViewEntries
.begin(),
181 boost::bind(&Shape::addViewLayer
,
183 boost::bind(&ViewEntry::getViewLayer
,
188 void Layer::setPriority( const ::basegfx::B1DRange
& rPrioRange
)
190 if( !mbBackgroundLayer
)
192 std::for_each( maViewEntries
.begin(),
194 boost::bind( &ViewLayer::setPriority
,
195 boost::bind( &ViewEntry::getViewLayer
,
197 boost::cref(rPrioRange
)));
201 void Layer::addUpdateRange( ::basegfx::B2DRange
const& rUpdateRange
)
203 // TODO(Q1): move this to B2DMultiRange
204 if( !rUpdateRange
.isEmpty() )
205 maUpdateAreas
.addRange( rUpdateRange
);
208 void Layer::updateBounds( ShapeSharedPtr
const& rShape
)
210 if( !mbBackgroundLayer
)
215 maNewBounds
.expand( rShape
->getUpdateArea() );
218 mbBoundsDirty
= true;
221 bool Layer::commitBounds()
223 mbBoundsDirty
= false;
225 if( mbBackgroundLayer
)
228 if( maNewBounds
== maBounds
)
231 maBounds
= maNewBounds
;
232 if( std::count_if( maViewEntries
.begin(),
234 boost::bind( &ViewLayer::resize
,
235 boost::bind( &ViewEntry::getViewLayer
,
237 boost::cref(maBounds
)) ) == 0 )
242 // layer content invalid, update areas have wrong
243 // coordinates/not sensible anymore.
249 void Layer::clearUpdateRanges()
251 maUpdateAreas
.reset();
254 void Layer::clearContent()
256 // clear content on all view layers
257 std::for_each( maViewEntries
.begin(),
262 &ViewEntry::getViewLayer
,
265 // layer content cleared, update areas are not sensible
270 class LayerEndUpdate
: private boost::noncopyable
273 LayerEndUpdate( LayerSharedPtr
const& rLayer
) :
277 ~LayerEndUpdate() { if(mpLayer
) mpLayer
->endUpdate(); }
279 void dismiss() { mpLayer
.reset(); }
282 LayerSharedPtr mpLayer
;
285 Layer::EndUpdater
Layer::beginUpdate()
287 if( !maUpdateAreas
.isEmpty() )
289 // perform proper layer update. That means, setup proper
290 // clipping, and render each shape that intersects with
291 // the calculated update area
292 ::basegfx::B2DPolyPolygon
aClip( maUpdateAreas
.getPolyPolygon() );
294 // actually, if there happen to be shapes with zero
295 // update area in the maUpdateAreas vector, the
296 // resulting clip polygon will be empty.
299 // set clip to all view layers
300 std::for_each( maViewEntries
.begin(),
305 &ViewEntry::getViewLayer
,
307 boost::cref(aClip
)));
309 // clear update area on all view layers
310 std::for_each( maViewEntries
.begin(),
315 &ViewEntry::getViewLayer
,
322 return EndUpdater(new LayerEndUpdate(shared_from_this()));
325 void Layer::endUpdate()
331 basegfx::B2DPolyPolygon aEmptyClip
;
332 std::for_each( maViewEntries
.begin(),
337 &ViewEntry::getViewLayer
,
339 boost::cref(aEmptyClip
)));
345 bool Layer::isInsideUpdateArea( ShapeSharedPtr
const& rShape
) const
347 return maUpdateAreas
.overlaps( rShape
->getUpdateArea() );
350 LayerSharedPtr
Layer::createBackgroundLayer( const basegfx::B2DRange
& rMaxLayerBounds
)
352 return LayerSharedPtr(new Layer( rMaxLayerBounds
,
356 LayerSharedPtr
Layer::createLayer( const basegfx::B2DRange
& rMaxLayerBounds
)
358 return LayerSharedPtr( new Layer( rMaxLayerBounds
) );