1*70f497fbSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*70f497fbSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*70f497fbSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*70f497fbSAndrew Rist  * distributed with this work for additional information
6*70f497fbSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*70f497fbSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*70f497fbSAndrew Rist  * "License"); you may not use this file except in compliance
9*70f497fbSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*70f497fbSAndrew Rist  *
11*70f497fbSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*70f497fbSAndrew Rist  *
13*70f497fbSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*70f497fbSAndrew Rist  * software distributed under the License is distributed on an
15*70f497fbSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*70f497fbSAndrew Rist  * KIND, either express or implied.  See the License for the
17*70f497fbSAndrew Rist  * specific language governing permissions and limitations
18*70f497fbSAndrew Rist  * under the License.
19*70f497fbSAndrew Rist  *
20*70f497fbSAndrew Rist  *************************************************************/
21*70f497fbSAndrew Rist 
22*70f497fbSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_slideshow.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir // must be first
28cdf0e10cSrcweir #include <canvas/debug.hxx>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #include <com/sun/star/awt/Rectangle.hpp>
31cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
32cdf0e10cSrcweir #include <com/sun/star/awt/FontWeight.hpp>
33cdf0e10cSrcweir #include <rtl/logfile.hxx>
34cdf0e10cSrcweir 
35cdf0e10cSrcweir #include <vcl/metaact.hxx>
36cdf0e10cSrcweir #include <vcl/gdimtf.hxx>
37cdf0e10cSrcweir 
38cdf0e10cSrcweir #include <basegfx/numeric/ftools.hxx>
39cdf0e10cSrcweir 
40cdf0e10cSrcweir #include <boost/bind.hpp>
41cdf0e10cSrcweir 
42cdf0e10cSrcweir #include <cmath> // for trigonometry and fabs
43cdf0e10cSrcweir #include <algorithm>
44cdf0e10cSrcweir #include <functional>
45cdf0e10cSrcweir #include <limits>
46cdf0e10cSrcweir 
47cdf0e10cSrcweir #include "backgroundshape.hxx"
48cdf0e10cSrcweir #include "slideshowexceptions.hxx"
49cdf0e10cSrcweir #include "slideshowcontext.hxx"
50cdf0e10cSrcweir #include "gdimtftools.hxx"
51cdf0e10cSrcweir #include "shape.hxx"
52cdf0e10cSrcweir #include "viewbackgroundshape.hxx"
53cdf0e10cSrcweir 
54cdf0e10cSrcweir 
55cdf0e10cSrcweir using namespace ::com::sun::star;
56cdf0e10cSrcweir 
57cdf0e10cSrcweir 
58cdf0e10cSrcweir namespace slideshow
59cdf0e10cSrcweir {
60cdf0e10cSrcweir     namespace internal
61cdf0e10cSrcweir     {
62cdf0e10cSrcweir         /** Representation of a draw document's background shape.
63cdf0e10cSrcweir 
64cdf0e10cSrcweir             This class implements the Shape interface for the
65cdf0e10cSrcweir             background shape. Since the background shape is neither
66cdf0e10cSrcweir             animatable nor attributable, those more specialized
67cdf0e10cSrcweir             derivations of the Shape interface are not implemented
68cdf0e10cSrcweir             here.
69cdf0e10cSrcweir 
70cdf0e10cSrcweir             @attention this class is to be treated 'final', i.e. one
71cdf0e10cSrcweir             should not derive from it.
72cdf0e10cSrcweir          */
73cdf0e10cSrcweir         class BackgroundShape : public Shape
74cdf0e10cSrcweir         {
75cdf0e10cSrcweir         public:
76cdf0e10cSrcweir             /** Create the background shape.
77cdf0e10cSrcweir 
78cdf0e10cSrcweir             	This method creates a shape that handles the
79cdf0e10cSrcweir             	peculiarities of the draw API regarding background
80cdf0e10cSrcweir             	content.
81cdf0e10cSrcweir              */
82cdf0e10cSrcweir             BackgroundShape( const ::com::sun::star::uno::Reference<
83cdf0e10cSrcweir                              	::com::sun::star::drawing::XDrawPage >& xDrawPage,
84cdf0e10cSrcweir                              const ::com::sun::star::uno::Reference<
85cdf0e10cSrcweir                              	::com::sun::star::drawing::XDrawPage >& xMasterPage,
86cdf0e10cSrcweir                              const SlideShowContext&                    rContext ); // throw ShapeLoadFailedException;
87cdf0e10cSrcweir 
88cdf0e10cSrcweir             virtual ::com::sun::star::uno::Reference<
89cdf0e10cSrcweir                 ::com::sun::star::drawing::XShape > getXShape() const;
90cdf0e10cSrcweir 
91cdf0e10cSrcweir             // View layer methods
92cdf0e10cSrcweir             //------------------------------------------------------------------
93cdf0e10cSrcweir 
94cdf0e10cSrcweir             virtual void addViewLayer( const ViewLayerSharedPtr& 	rNewLayer,
95cdf0e10cSrcweir                                        bool							bRedrawLayer );
96cdf0e10cSrcweir             virtual bool removeViewLayer( const ViewLayerSharedPtr& rNewLayer );
97cdf0e10cSrcweir             virtual bool clearAllViewLayers();
98cdf0e10cSrcweir 
99cdf0e10cSrcweir 
100cdf0e10cSrcweir             // attribute methods
101cdf0e10cSrcweir             //------------------------------------------------------------------
102cdf0e10cSrcweir 
103cdf0e10cSrcweir             virtual ::basegfx::B2DRectangle getBounds() const;
104cdf0e10cSrcweir             virtual ::basegfx::B2DRectangle getDomBounds() const;
105cdf0e10cSrcweir             virtual ::basegfx::B2DRectangle getUpdateArea() const;
106cdf0e10cSrcweir             virtual bool isVisible() const;
107cdf0e10cSrcweir             virtual double getPriority() const;
108cdf0e10cSrcweir             virtual bool isBackgroundDetached() const;
109cdf0e10cSrcweir 
110cdf0e10cSrcweir 
111cdf0e10cSrcweir             // render methods
112cdf0e10cSrcweir             //------------------------------------------------------------------
113cdf0e10cSrcweir 
114cdf0e10cSrcweir             virtual bool update() const;
115cdf0e10cSrcweir             virtual bool render() const;
116cdf0e10cSrcweir             virtual bool isContentChanged() const;
117cdf0e10cSrcweir 
118cdf0e10cSrcweir         private:
119cdf0e10cSrcweir             /// The metafile actually representing the Shape
120cdf0e10cSrcweir             GDIMetaFileSharedPtr		mpMtf;
121cdf0e10cSrcweir 
122cdf0e10cSrcweir             // The attributes of this Shape
123cdf0e10cSrcweir             ::basegfx::B2DRectangle		maBounds; // always needed for rendering
124cdf0e10cSrcweir 
125cdf0e10cSrcweir             /// the list of active view shapes (one for each registered view layer)
126cdf0e10cSrcweir             typedef ::std::vector< ViewBackgroundShapeSharedPtr > ViewBackgroundShapeVector;
127cdf0e10cSrcweir             ViewBackgroundShapeVector	maViewShapes;
128cdf0e10cSrcweir         };
129cdf0e10cSrcweir 
130cdf0e10cSrcweir 
131cdf0e10cSrcweir         ////////////////////////////////////////////////////////////////////////////////
132cdf0e10cSrcweir 
133cdf0e10cSrcweir 
BackgroundShape(const uno::Reference<drawing::XDrawPage> & xDrawPage,const uno::Reference<drawing::XDrawPage> & xMasterPage,const SlideShowContext & rContext)134cdf0e10cSrcweir         BackgroundShape::BackgroundShape( const uno::Reference< drawing::XDrawPage >& xDrawPage,
135cdf0e10cSrcweir                                           const uno::Reference< drawing::XDrawPage >& xMasterPage,
136cdf0e10cSrcweir                                           const SlideShowContext&                     rContext ) :
137cdf0e10cSrcweir             mpMtf(),
138cdf0e10cSrcweir             maBounds(),
139cdf0e10cSrcweir             maViewShapes()
140cdf0e10cSrcweir         {
141cdf0e10cSrcweir             uno::Reference< beans::XPropertySet > xPropSet( xDrawPage,
142cdf0e10cSrcweir                                                             uno::UNO_QUERY_THROW );
143cdf0e10cSrcweir             GDIMetaFileSharedPtr pMtf( new GDIMetaFile() );
144cdf0e10cSrcweir 
145cdf0e10cSrcweir             // first try the page background (overrides
146cdf0e10cSrcweir             // masterpage background), then try masterpage
147cdf0e10cSrcweir             if( !getMetaFile( uno::Reference<lang::XComponent>(xDrawPage, uno::UNO_QUERY),
148cdf0e10cSrcweir                               xDrawPage, *pMtf, MTF_LOAD_BACKGROUND_ONLY,
149cdf0e10cSrcweir                               rContext.mxComponentContext ) &&
150cdf0e10cSrcweir                 !getMetaFile( uno::Reference<lang::XComponent>(xMasterPage, uno::UNO_QUERY),
151cdf0e10cSrcweir                               xDrawPage, *pMtf, MTF_LOAD_BACKGROUND_ONLY,
152cdf0e10cSrcweir                               rContext.mxComponentContext ))
153cdf0e10cSrcweir             {
154cdf0e10cSrcweir                 throw ShapeLoadFailedException();
155cdf0e10cSrcweir             }
156cdf0e10cSrcweir 
157cdf0e10cSrcweir             // there is a special background shape, add it
158cdf0e10cSrcweir             // as the first one
159cdf0e10cSrcweir             // ---------------------------------------------------
160cdf0e10cSrcweir 
161cdf0e10cSrcweir             sal_Int32 nDocWidth=0;
162cdf0e10cSrcweir             sal_Int32 nDocHeight=0;
163cdf0e10cSrcweir             xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Width") ) ) >>= nDocWidth;
164cdf0e10cSrcweir             xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Height") ) ) >>= nDocHeight;
165cdf0e10cSrcweir 
166cdf0e10cSrcweir             mpMtf = pMtf;
167cdf0e10cSrcweir             maBounds = ::basegfx::B2DRectangle( 0,0,nDocWidth, nDocHeight );
168cdf0e10cSrcweir         }
169cdf0e10cSrcweir 
getXShape() const170cdf0e10cSrcweir         uno::Reference< drawing::XShape > BackgroundShape::getXShape() const
171cdf0e10cSrcweir         {
172cdf0e10cSrcweir             // no real XShape representative
173cdf0e10cSrcweir             return uno::Reference< drawing::XShape >();
174cdf0e10cSrcweir         }
175cdf0e10cSrcweir 
addViewLayer(const ViewLayerSharedPtr & rNewLayer,bool bRedrawLayer)176cdf0e10cSrcweir         void BackgroundShape::addViewLayer( const ViewLayerSharedPtr&	rNewLayer,
177cdf0e10cSrcweir                                             bool						bRedrawLayer )
178cdf0e10cSrcweir         {
179cdf0e10cSrcweir             ViewBackgroundShapeVector::iterator aEnd( maViewShapes.end() );
180cdf0e10cSrcweir 
181cdf0e10cSrcweir             // already added?
182cdf0e10cSrcweir             if( ::std::find_if( maViewShapes.begin(),
183cdf0e10cSrcweir                                 aEnd,
184cdf0e10cSrcweir                                 ::boost::bind<bool>(
185cdf0e10cSrcweir                                     ::std::equal_to< ViewLayerSharedPtr >(),
186cdf0e10cSrcweir                                     ::boost::bind( &ViewBackgroundShape::getViewLayer,
187cdf0e10cSrcweir                                                    _1 ),
188cdf0e10cSrcweir                                     ::boost::cref( rNewLayer ) ) ) != aEnd )
189cdf0e10cSrcweir             {
190cdf0e10cSrcweir                 // yes, nothing to do
191cdf0e10cSrcweir                 return;
192cdf0e10cSrcweir             }
193cdf0e10cSrcweir 
194cdf0e10cSrcweir             maViewShapes.push_back(
195cdf0e10cSrcweir                 ViewBackgroundShapeSharedPtr(
196cdf0e10cSrcweir                     new ViewBackgroundShape( rNewLayer,
197cdf0e10cSrcweir                                              maBounds ) ) );
198cdf0e10cSrcweir 
199cdf0e10cSrcweir             // render the Shape on the newly added ViewLayer
200cdf0e10cSrcweir             if( bRedrawLayer )
201cdf0e10cSrcweir                 maViewShapes.back()->render( mpMtf );
202cdf0e10cSrcweir         }
203cdf0e10cSrcweir 
removeViewLayer(const ViewLayerSharedPtr & rLayer)204cdf0e10cSrcweir         bool BackgroundShape::removeViewLayer( const ViewLayerSharedPtr& rLayer )
205cdf0e10cSrcweir         {
206cdf0e10cSrcweir             const ViewBackgroundShapeVector::iterator aEnd( maViewShapes.end() );
207cdf0e10cSrcweir 
208cdf0e10cSrcweir             OSL_ENSURE( ::std::count_if(maViewShapes.begin(),
209cdf0e10cSrcweir                                         aEnd,
210cdf0e10cSrcweir                                         ::boost::bind<bool>(
211cdf0e10cSrcweir                                             ::std::equal_to< ViewLayerSharedPtr >(),
212cdf0e10cSrcweir                                             ::boost::bind( &ViewBackgroundShape::getViewLayer,
213cdf0e10cSrcweir                                                            _1 ),
214cdf0e10cSrcweir                                             ::boost::cref( rLayer ) ) ) < 2,
215cdf0e10cSrcweir                         "BackgroundShape::removeViewLayer(): Duplicate ViewLayer entries!" );
216cdf0e10cSrcweir 
217cdf0e10cSrcweir             ViewBackgroundShapeVector::iterator aIter;
218cdf0e10cSrcweir 
219cdf0e10cSrcweir             if( (aIter=::std::remove_if( maViewShapes.begin(),
220cdf0e10cSrcweir                                          aEnd,
221cdf0e10cSrcweir                                          ::boost::bind<bool>(
222cdf0e10cSrcweir                                              ::std::equal_to< ViewLayerSharedPtr >(),
223cdf0e10cSrcweir                                              ::boost::bind( &ViewBackgroundShape::getViewLayer,
224cdf0e10cSrcweir                                                             _1 ),
225cdf0e10cSrcweir                                              ::boost::cref( rLayer ) ) )) == aEnd )
226cdf0e10cSrcweir             {
227cdf0e10cSrcweir                 // view layer seemingly was not added, failed
228cdf0e10cSrcweir                 return false;
229cdf0e10cSrcweir             }
230cdf0e10cSrcweir 
231cdf0e10cSrcweir             // actually erase from container
232cdf0e10cSrcweir             maViewShapes.erase( aIter, aEnd );
233cdf0e10cSrcweir 
234cdf0e10cSrcweir             return true;
235cdf0e10cSrcweir         }
236cdf0e10cSrcweir 
clearAllViewLayers()237cdf0e10cSrcweir         bool BackgroundShape::clearAllViewLayers()
238cdf0e10cSrcweir         {
239cdf0e10cSrcweir             maViewShapes.clear();
240cdf0e10cSrcweir             return true;
241cdf0e10cSrcweir         }
242cdf0e10cSrcweir 
getBounds() const243cdf0e10cSrcweir         ::basegfx::B2DRectangle BackgroundShape::getBounds() const
244cdf0e10cSrcweir         {
245cdf0e10cSrcweir             return maBounds;
246cdf0e10cSrcweir         }
247cdf0e10cSrcweir 
getDomBounds() const248cdf0e10cSrcweir         ::basegfx::B2DRectangle BackgroundShape::getDomBounds() const
249cdf0e10cSrcweir         {
250cdf0e10cSrcweir             return maBounds;
251cdf0e10cSrcweir         }
252cdf0e10cSrcweir 
getUpdateArea() const253cdf0e10cSrcweir         ::basegfx::B2DRectangle BackgroundShape::getUpdateArea() const
254cdf0e10cSrcweir         {
255cdf0e10cSrcweir             // TODO(F1): Need to expand background, too, when
256cdf0e10cSrcweir             // antialiasing?
257cdf0e10cSrcweir 
258cdf0e10cSrcweir             // no transformation etc. possible for background shape
259cdf0e10cSrcweir             return maBounds;
260cdf0e10cSrcweir         }
261cdf0e10cSrcweir 
isVisible() const262cdf0e10cSrcweir         bool BackgroundShape::isVisible() const
263cdf0e10cSrcweir         {
264cdf0e10cSrcweir             return true;
265cdf0e10cSrcweir         }
266cdf0e10cSrcweir 
getPriority() const267cdf0e10cSrcweir         double BackgroundShape::getPriority() const
268cdf0e10cSrcweir         {
269cdf0e10cSrcweir         	return 0.0; // lowest prio, we're the background
270cdf0e10cSrcweir         }
271cdf0e10cSrcweir 
update() const272cdf0e10cSrcweir         bool BackgroundShape::update() const
273cdf0e10cSrcweir         {
274cdf0e10cSrcweir             return render();
275cdf0e10cSrcweir         }
276cdf0e10cSrcweir 
render() const277cdf0e10cSrcweir         bool BackgroundShape::render() const
278cdf0e10cSrcweir         {
279cdf0e10cSrcweir             RTL_LOGFILE_CONTEXT( aLog, "::presentation::internal::BackgroundShape::render()" );
280cdf0e10cSrcweir             RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::presentation::internal::BackgroundShape: 0x%X", this );
281cdf0e10cSrcweir 
282cdf0e10cSrcweir             // gcc again...
283cdf0e10cSrcweir             const ::basegfx::B2DRectangle& rCurrBounds( BackgroundShape::getBounds() );
284cdf0e10cSrcweir 
285cdf0e10cSrcweir             if( rCurrBounds.getRange().equalZero() )
286cdf0e10cSrcweir             {
287cdf0e10cSrcweir                 // zero-sized shapes are effectively invisible,
288cdf0e10cSrcweir                 // thus, we save us the rendering...
289cdf0e10cSrcweir                 return true;
290cdf0e10cSrcweir             }
291cdf0e10cSrcweir 
292cdf0e10cSrcweir             // redraw all view shapes, by calling their render() method
293cdf0e10cSrcweir             if( ::std::count_if( maViewShapes.begin(),
294cdf0e10cSrcweir                                  maViewShapes.end(),
295cdf0e10cSrcweir                                  ::boost::bind( &ViewBackgroundShape::render,
296cdf0e10cSrcweir                                                 _1,
297cdf0e10cSrcweir                                                 ::boost::cref( mpMtf ) ) )
298cdf0e10cSrcweir                 != static_cast<ViewBackgroundShapeVector::difference_type>(maViewShapes.size()) )
299cdf0e10cSrcweir             {
300cdf0e10cSrcweir                 // at least one of the ViewBackgroundShape::render() calls did return
301cdf0e10cSrcweir                 // false - update failed on at least one ViewLayer
302cdf0e10cSrcweir                 return false;
303cdf0e10cSrcweir             }
304cdf0e10cSrcweir 
305cdf0e10cSrcweir             return true;
306cdf0e10cSrcweir         }
307cdf0e10cSrcweir 
isContentChanged() const308cdf0e10cSrcweir         bool BackgroundShape::isContentChanged() const
309cdf0e10cSrcweir         {
310cdf0e10cSrcweir             return false;
311cdf0e10cSrcweir         }
312cdf0e10cSrcweir 
isBackgroundDetached() const313cdf0e10cSrcweir         bool BackgroundShape::isBackgroundDetached() const
314cdf0e10cSrcweir         {
315cdf0e10cSrcweir             return false; // we're not animatable
316cdf0e10cSrcweir         }
317cdf0e10cSrcweir 
318cdf0e10cSrcweir         //////////////////////////////////////////////////////////
319cdf0e10cSrcweir 
createBackgroundShape(const uno::Reference<drawing::XDrawPage> & xDrawPage,const uno::Reference<drawing::XDrawPage> & xMasterPage,const SlideShowContext & rContext)320cdf0e10cSrcweir         ShapeSharedPtr createBackgroundShape(
321cdf0e10cSrcweir             const uno::Reference< drawing::XDrawPage >& xDrawPage,
322cdf0e10cSrcweir             const uno::Reference< drawing::XDrawPage >& xMasterPage,
323cdf0e10cSrcweir             const SlideShowContext&                     rContext )
324cdf0e10cSrcweir         {
325cdf0e10cSrcweir             return ShapeSharedPtr(
326cdf0e10cSrcweir                 new BackgroundShape(
327cdf0e10cSrcweir                     xDrawPage,
328cdf0e10cSrcweir                     xMasterPage,
329cdf0e10cSrcweir                     rContext ));
330cdf0e10cSrcweir         }
331cdf0e10cSrcweir     }
332cdf0e10cSrcweir }
333