xref: /trunk/main/slideshow/source/engine/transitions/combtransition.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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 #include <canvas/debug.hxx>
32*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx>
33*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontools.hxx>
34*cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx>
35*cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrixtools.hxx>
36*cdf0e10cSrcweir 
37*cdf0e10cSrcweir #include <cppcanvas/spritecanvas.hxx>
38*cdf0e10cSrcweir 
39*cdf0e10cSrcweir #include "combtransition.hxx"
40*cdf0e10cSrcweir 
41*cdf0e10cSrcweir #include <boost/bind.hpp>
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir namespace slideshow {
45*cdf0e10cSrcweir namespace internal {
46*cdf0e10cSrcweir 
47*cdf0e10cSrcweir namespace {
48*cdf0e10cSrcweir 
49*cdf0e10cSrcweir basegfx::B2DPolyPolygon createClipPolygon(
50*cdf0e10cSrcweir     const ::basegfx::B2DVector& rDirection,
51*cdf0e10cSrcweir     const ::basegfx::B2DSize& rSlideSize,
52*cdf0e10cSrcweir     int nNumStrips, int nOffset )
53*cdf0e10cSrcweir {
54*cdf0e10cSrcweir     // create clip polygon in standard orientation (will later
55*cdf0e10cSrcweir     // be rotated to match direction vector)
56*cdf0e10cSrcweir     ::basegfx::B2DPolyPolygon aClipPoly;
57*cdf0e10cSrcweir 
58*cdf0e10cSrcweir     // create nNumStrips/2 vertical strips
59*cdf0e10cSrcweir     for( int i=nOffset; i<nNumStrips; i+=2 )
60*cdf0e10cSrcweir     {
61*cdf0e10cSrcweir         aClipPoly.append(
62*cdf0e10cSrcweir             ::basegfx::tools::createPolygonFromRect(
63*cdf0e10cSrcweir                 ::basegfx::B2DRectangle( double(i)/nNumStrips, 0.0,
64*cdf0e10cSrcweir                                          double(i+1)/nNumStrips, 1.0) ) );
65*cdf0e10cSrcweir 
66*cdf0e10cSrcweir     }
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir     // rotate polygons, such that the strips are parallel to
69*cdf0e10cSrcweir     // the given direction vector
70*cdf0e10cSrcweir     const ::basegfx::B2DVector aUpVec(0.0, 1.0);
71*cdf0e10cSrcweir     basegfx::B2DHomMatrix aMatrix(basegfx::tools::createRotateAroundPoint(0.5, 0.5, aUpVec.angle( rDirection )));
72*cdf0e10cSrcweir 
73*cdf0e10cSrcweir     // blow up clip polygon to slide size
74*cdf0e10cSrcweir     aMatrix.scale( rSlideSize.getX(),
75*cdf0e10cSrcweir                    rSlideSize.getY() );
76*cdf0e10cSrcweir 
77*cdf0e10cSrcweir     aClipPoly.transform( aMatrix );
78*cdf0e10cSrcweir 
79*cdf0e10cSrcweir     return aClipPoly;
80*cdf0e10cSrcweir }
81*cdf0e10cSrcweir 
82*cdf0e10cSrcweir }
83*cdf0e10cSrcweir 
84*cdf0e10cSrcweir CombTransition::CombTransition(
85*cdf0e10cSrcweir     boost::optional<SlideSharedPtr> const & leavingSlide,
86*cdf0e10cSrcweir     const SlideSharedPtr&                   pEnteringSlide,
87*cdf0e10cSrcweir     const SoundPlayerSharedPtr&             pSoundPlayer,
88*cdf0e10cSrcweir     const UnoViewContainer&                 rViewContainer,
89*cdf0e10cSrcweir     ScreenUpdater&                          rScreenUpdater,
90*cdf0e10cSrcweir     EventMultiplexer&                       rEventMultiplexer,
91*cdf0e10cSrcweir     const ::basegfx::B2DVector&             rPushDirection,
92*cdf0e10cSrcweir     sal_Int32                               nNumStripes )
93*cdf0e10cSrcweir     : SlideChangeBase( leavingSlide, pEnteringSlide, pSoundPlayer,
94*cdf0e10cSrcweir                        rViewContainer, rScreenUpdater, rEventMultiplexer,
95*cdf0e10cSrcweir                        false /* no leaving sprite */,
96*cdf0e10cSrcweir                        false /* no entering sprite */ ),
97*cdf0e10cSrcweir       maPushDirectionUnit( rPushDirection ),
98*cdf0e10cSrcweir       mnNumStripes( nNumStripes )
99*cdf0e10cSrcweir {
100*cdf0e10cSrcweir }
101*cdf0e10cSrcweir 
102*cdf0e10cSrcweir void CombTransition::renderComb( double           t,
103*cdf0e10cSrcweir                                  const ViewEntry& rViewEntry ) const
104*cdf0e10cSrcweir {
105*cdf0e10cSrcweir     const SlideBitmapSharedPtr& pEnteringBitmap = getEnteringBitmap(rViewEntry);
106*cdf0e10cSrcweir     const cppcanvas::CanvasSharedPtr pCanvas_ = rViewEntry.mpView->getCanvas();
107*cdf0e10cSrcweir 
108*cdf0e10cSrcweir     if( !pEnteringBitmap || !pCanvas_ )
109*cdf0e10cSrcweir         return;
110*cdf0e10cSrcweir 
111*cdf0e10cSrcweir     // calc bitmap offsets. The enter/leaving bitmaps are only
112*cdf0e10cSrcweir     // as large as the actual slides. For scaled-down
113*cdf0e10cSrcweir     // presentations, we have to move the left, top edge of
114*cdf0e10cSrcweir     // those bitmaps to the actual position, governed by the
115*cdf0e10cSrcweir     // given view transform. The aBitmapPosPixel local
116*cdf0e10cSrcweir     // variable is already in device coordinate space
117*cdf0e10cSrcweir     // (i.e. pixel).
118*cdf0e10cSrcweir 
119*cdf0e10cSrcweir     // TODO(F2): Properly respect clip here. Might have to be transformed, too.
120*cdf0e10cSrcweir     const basegfx::B2DHomMatrix viewTransform( rViewEntry.mpView->getTransformation() );
121*cdf0e10cSrcweir     const basegfx::B2DPoint pageOrigin( viewTransform * basegfx::B2DPoint() );
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir     // change transformation on cloned canvas to be in
124*cdf0e10cSrcweir     // device pixel
125*cdf0e10cSrcweir     cppcanvas::CanvasSharedPtr pCanvas( pCanvas_->clone() );
126*cdf0e10cSrcweir     basegfx::B2DPoint p;
127*cdf0e10cSrcweir 
128*cdf0e10cSrcweir     // TODO(Q2): Use basegfx bitmaps here
129*cdf0e10cSrcweir     // TODO(F1): SlideBitmap is not fully portable between different canvases!
130*cdf0e10cSrcweir 
131*cdf0e10cSrcweir     const basegfx::B2DSize enteringSizePixel(
132*cdf0e10cSrcweir         getEnteringSlideSizePixel( rViewEntry.mpView) );
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir     const basegfx::B2DVector aPushDirection = basegfx::B2DVector(
135*cdf0e10cSrcweir         enteringSizePixel * maPushDirectionUnit );
136*cdf0e10cSrcweir     const basegfx::B2DPolyPolygon aClipPolygon1 = basegfx::B2DPolyPolygon(
137*cdf0e10cSrcweir         createClipPolygon( maPushDirectionUnit,
138*cdf0e10cSrcweir                            enteringSizePixel,
139*cdf0e10cSrcweir                            mnNumStripes, 0 ) );
140*cdf0e10cSrcweir     const basegfx::B2DPolyPolygon aClipPolygon2 = basegfx::B2DPolyPolygon(
141*cdf0e10cSrcweir         createClipPolygon( maPushDirectionUnit,
142*cdf0e10cSrcweir                            enteringSizePixel,
143*cdf0e10cSrcweir                            mnNumStripes, 1 ) );
144*cdf0e10cSrcweir 
145*cdf0e10cSrcweir     SlideBitmapSharedPtr const & pLeavingBitmap = getLeavingBitmap(rViewEntry);
146*cdf0e10cSrcweir     if( pLeavingBitmap )
147*cdf0e10cSrcweir     {
148*cdf0e10cSrcweir         // render odd strips:
149*cdf0e10cSrcweir         pLeavingBitmap->clip( aClipPolygon1 );
150*cdf0e10cSrcweir         // don't modify bitmap object (no move!):
151*cdf0e10cSrcweir         p = basegfx::B2DPoint( pageOrigin + (t * aPushDirection) );
152*cdf0e10cSrcweir         pCanvas->setTransformation(basegfx::tools::createTranslateB2DHomMatrix(p.getX(), p.getY()));
153*cdf0e10cSrcweir         pLeavingBitmap->draw( pCanvas );
154*cdf0e10cSrcweir 
155*cdf0e10cSrcweir         // render even strips:
156*cdf0e10cSrcweir         pLeavingBitmap->clip( aClipPolygon2 );
157*cdf0e10cSrcweir         // don't modify bitmap object (no move!):
158*cdf0e10cSrcweir         p = basegfx::B2DPoint( pageOrigin - (t * aPushDirection) );
159*cdf0e10cSrcweir         pCanvas->setTransformation(basegfx::tools::createTranslateB2DHomMatrix(p.getX(), p.getY()));
160*cdf0e10cSrcweir         pLeavingBitmap->draw( pCanvas );
161*cdf0e10cSrcweir     }
162*cdf0e10cSrcweir 
163*cdf0e10cSrcweir     // TODO(Q2): Use basegfx bitmaps here
164*cdf0e10cSrcweir     // TODO(F1): SlideBitmap is not fully portable between different canvases!
165*cdf0e10cSrcweir 
166*cdf0e10cSrcweir     // render odd strips:
167*cdf0e10cSrcweir     pEnteringBitmap->clip( aClipPolygon1 );
168*cdf0e10cSrcweir     // don't modify bitmap object (no move!):
169*cdf0e10cSrcweir     p = basegfx::B2DPoint( pageOrigin + ((t - 1.0) * aPushDirection) );
170*cdf0e10cSrcweir     pCanvas->setTransformation(basegfx::tools::createTranslateB2DHomMatrix(p.getX(), p.getY()));
171*cdf0e10cSrcweir     pEnteringBitmap->draw( pCanvas );
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir     // render even strips:
174*cdf0e10cSrcweir     pEnteringBitmap->clip( aClipPolygon2 );
175*cdf0e10cSrcweir     // don't modify bitmap object (no move!):
176*cdf0e10cSrcweir     p = basegfx::B2DPoint( pageOrigin + ((1.0 - t) * aPushDirection) );
177*cdf0e10cSrcweir     pCanvas->setTransformation(basegfx::tools::createTranslateB2DHomMatrix(p.getX(), p.getY()));
178*cdf0e10cSrcweir     pEnteringBitmap->draw( pCanvas );
179*cdf0e10cSrcweir }
180*cdf0e10cSrcweir 
181*cdf0e10cSrcweir bool CombTransition::operator()( double t )
182*cdf0e10cSrcweir {
183*cdf0e10cSrcweir     std::for_each( beginViews(),
184*cdf0e10cSrcweir                    endViews(),
185*cdf0e10cSrcweir                    boost::bind( &CombTransition::renderComb,
186*cdf0e10cSrcweir                                 this,
187*cdf0e10cSrcweir                                 t,
188*cdf0e10cSrcweir                                 _1 ));
189*cdf0e10cSrcweir 
190*cdf0e10cSrcweir     getScreenUpdater().notifyUpdate();
191*cdf0e10cSrcweir 
192*cdf0e10cSrcweir     return true;
193*cdf0e10cSrcweir }
194*cdf0e10cSrcweir 
195*cdf0e10cSrcweir } // namespace internal
196*cdf0e10cSrcweir } // namespace presentation
197