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