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 #include <tools/diagnose_ex.h>
34*cdf0e10cSrcweir 
35*cdf0e10cSrcweir #include <animatedsprite.hxx>
36*cdf0e10cSrcweir 
37*cdf0e10cSrcweir #include <cppcanvas/canvas.hxx>
38*cdf0e10cSrcweir #include <canvas/canvastools.hxx>
39*cdf0e10cSrcweir 
40*cdf0e10cSrcweir #include <basegfx/vector/b2dvector.hxx>
41*cdf0e10cSrcweir #include <basegfx/point/b2dpoint.hxx>
42*cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx>
43*cdf0e10cSrcweir #include <basegfx/numeric/ftools.hxx>
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir using namespace ::com::sun::star;
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir namespace slideshow
49*cdf0e10cSrcweir {
50*cdf0e10cSrcweir     namespace internal
51*cdf0e10cSrcweir     {
52*cdf0e10cSrcweir         AnimatedSprite::AnimatedSprite( const ViewLayerSharedPtr&	rViewLayer,
53*cdf0e10cSrcweir                                         const ::basegfx::B2DSize& 	rSpriteSizePixel,
54*cdf0e10cSrcweir                                         double                      nSpritePrio ) :
55*cdf0e10cSrcweir             mpViewLayer( rViewLayer ),
56*cdf0e10cSrcweir             mpSprite(),
57*cdf0e10cSrcweir             maEffectiveSpriteSizePixel( rSpriteSizePixel ),
58*cdf0e10cSrcweir             maContentPixelOffset(),
59*cdf0e10cSrcweir             mnSpritePrio(nSpritePrio),
60*cdf0e10cSrcweir             mnAlpha(0.0),
61*cdf0e10cSrcweir             maPosPixel(),
62*cdf0e10cSrcweir             maClip(),
63*cdf0e10cSrcweir             maTransform(),
64*cdf0e10cSrcweir             mbSpriteVisible( false )
65*cdf0e10cSrcweir         {
66*cdf0e10cSrcweir             ENSURE_OR_THROW( mpViewLayer, "AnimatedSprite::AnimatedSprite(): Invalid view layer" );
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir             // Add half a pixel tolerance to sprite size, since we later on compare
69*cdf0e10cSrcweir             // against it in resize(). And view transformations will almost never yield
70*cdf0e10cSrcweir             // the same data bits when transforming to device coordinates
71*cdf0e10cSrcweir             maEffectiveSpriteSizePixel += ::basegfx::B2DSize(0.5, 0.5);
72*cdf0e10cSrcweir 
73*cdf0e10cSrcweir             mpSprite = mpViewLayer->createSprite( maEffectiveSpriteSizePixel,
74*cdf0e10cSrcweir                                                   mnSpritePrio );
75*cdf0e10cSrcweir 
76*cdf0e10cSrcweir             ENSURE_OR_THROW( mpSprite, "AnimatedSprite::AnimatedSprite(): Could not create sprite" );
77*cdf0e10cSrcweir         }
78*cdf0e10cSrcweir 
79*cdf0e10cSrcweir         ::cppcanvas::CanvasSharedPtr AnimatedSprite::getContentCanvas() const
80*cdf0e10cSrcweir         {
81*cdf0e10cSrcweir             ENSURE_OR_THROW( mpViewLayer->getCanvas(), "AnimatedSprite::getContentCanvas(): No view layer canvas" );
82*cdf0e10cSrcweir 
83*cdf0e10cSrcweir             const ::cppcanvas::CanvasSharedPtr pContentCanvas( mpSprite->getContentCanvas() );
84*cdf0e10cSrcweir             pContentCanvas->clear();
85*cdf0e10cSrcweir 
86*cdf0e10cSrcweir             // extract linear part of canvas view transformation
87*cdf0e10cSrcweir             // (linear means: without translational components). The
88*cdf0e10cSrcweir             // only translation that is imposed at the view transform
89*cdf0e10cSrcweir             // is the local content pixel offset.
90*cdf0e10cSrcweir             //
91*cdf0e10cSrcweir             // We can apply that directly here, no need to call
92*cdf0e10cSrcweir             // aLinearTransform.translate(), since, as said above, the
93*cdf0e10cSrcweir             // last column of aLinearTransform is assumed [0 0 1]
94*cdf0e10cSrcweir             ::basegfx::B2DHomMatrix aLinearTransform( mpViewLayer->getTransformation() );
95*cdf0e10cSrcweir             aLinearTransform.set( 0, 2, maContentPixelOffset.getX() );
96*cdf0e10cSrcweir             aLinearTransform.set( 1, 2, maContentPixelOffset.getY() );
97*cdf0e10cSrcweir 
98*cdf0e10cSrcweir             // apply linear part of canvas view transformation to sprite canvas
99*cdf0e10cSrcweir             pContentCanvas->setTransformation( aLinearTransform );
100*cdf0e10cSrcweir 
101*cdf0e10cSrcweir             return pContentCanvas;
102*cdf0e10cSrcweir         }
103*cdf0e10cSrcweir 
104*cdf0e10cSrcweir         bool AnimatedSprite::resize( const ::basegfx::B2DSize& rSpriteSizePixel )
105*cdf0e10cSrcweir         {
106*cdf0e10cSrcweir             // Enlarge or reduce the sprite size, if necessary.  This
107*cdf0e10cSrcweir             // method employs a strategy similar to container, when
108*cdf0e10cSrcweir             // allocating memory: size is doubled or halved everytime
109*cdf0e10cSrcweir             // the limit is reached. This makes for amortized constant
110*cdf0e10cSrcweir             // time in runtime complexity. Note that we take exact
111*cdf0e10cSrcweir             // powers of two here, since several HW-accelerated canvas
112*cdf0e10cSrcweir             // implementations are limited to such sprite sizes
113*cdf0e10cSrcweir             // (otherwise, those implementations would internally
114*cdf0e10cSrcweir             // round up, too, wasting precious mem).
115*cdf0e10cSrcweir             ::basegfx::B2DSize	aNewSize( maEffectiveSpriteSizePixel );
116*cdf0e10cSrcweir             bool				bNeedResize( false );
117*cdf0e10cSrcweir 
118*cdf0e10cSrcweir             if( rSpriteSizePixel.getX() > maEffectiveSpriteSizePixel.getX() ||
119*cdf0e10cSrcweir                 rSpriteSizePixel.getX() < 0.5*maEffectiveSpriteSizePixel.getX() )
120*cdf0e10cSrcweir             {
121*cdf0e10cSrcweir                 // enlarge or shrink width
122*cdf0e10cSrcweir                 aNewSize.setX( ::canvas::tools::nextPow2( ::basegfx::fround(rSpriteSizePixel.getX()) ) );
123*cdf0e10cSrcweir                 bNeedResize = true;
124*cdf0e10cSrcweir             }
125*cdf0e10cSrcweir 
126*cdf0e10cSrcweir             if( rSpriteSizePixel.getY() > maEffectiveSpriteSizePixel.getY() ||
127*cdf0e10cSrcweir                 rSpriteSizePixel.getY() < 0.5*maEffectiveSpriteSizePixel.getY() )
128*cdf0e10cSrcweir             {
129*cdf0e10cSrcweir                 // enlarge or shrink height, by doubling it
130*cdf0e10cSrcweir                 aNewSize.setY( ::canvas::tools::nextPow2( ::basegfx::fround(rSpriteSizePixel.getY()) ) );
131*cdf0e10cSrcweir                 bNeedResize = true;
132*cdf0e10cSrcweir             }
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir             if( bNeedResize )
135*cdf0e10cSrcweir             {
136*cdf0e10cSrcweir                 // as the old sprite might have already been altered
137*cdf0e10cSrcweir                 // (and therefore been placed in the update list of
138*cdf0e10cSrcweir                 // the spritecanvas for this frame), must hide it
139*cdf0e10cSrcweir                 // here, to ensure it's not visible on screen any
140*cdf0e10cSrcweir                 // longer.
141*cdf0e10cSrcweir                 mpSprite->hide();
142*cdf0e10cSrcweir 
143*cdf0e10cSrcweir                 maEffectiveSpriteSizePixel = aNewSize;
144*cdf0e10cSrcweir                 mpSprite = mpViewLayer->createSprite( maEffectiveSpriteSizePixel,
145*cdf0e10cSrcweir                                                       mnSpritePrio );
146*cdf0e10cSrcweir 
147*cdf0e10cSrcweir                 ENSURE_OR_THROW( mpSprite,
148*cdf0e10cSrcweir                                   "AnimatedSprite::resize(): Could not create new sprite" );
149*cdf0e10cSrcweir 
150*cdf0e10cSrcweir                 // set attributes similar to previous sprite
151*cdf0e10cSrcweir                 if( mpSprite && mbSpriteVisible )
152*cdf0e10cSrcweir                 {
153*cdf0e10cSrcweir                     mpSprite->show();
154*cdf0e10cSrcweir                     mpSprite->setAlpha( mnAlpha );
155*cdf0e10cSrcweir 
156*cdf0e10cSrcweir                     if( maPosPixel )
157*cdf0e10cSrcweir                         mpSprite->movePixel( *maPosPixel );
158*cdf0e10cSrcweir 
159*cdf0e10cSrcweir                     if( maClip )
160*cdf0e10cSrcweir                         mpSprite->setClip( *maClip );
161*cdf0e10cSrcweir                 }
162*cdf0e10cSrcweir             }
163*cdf0e10cSrcweir 
164*cdf0e10cSrcweir 			return mpSprite;
165*cdf0e10cSrcweir         }
166*cdf0e10cSrcweir 
167*cdf0e10cSrcweir         void AnimatedSprite::setPixelOffset( const ::basegfx::B2DSize& rPixelOffset )
168*cdf0e10cSrcweir         {
169*cdf0e10cSrcweir             maContentPixelOffset = rPixelOffset;
170*cdf0e10cSrcweir         }
171*cdf0e10cSrcweir 
172*cdf0e10cSrcweir         ::basegfx::B2DSize AnimatedSprite::getPixelOffset() const
173*cdf0e10cSrcweir         {
174*cdf0e10cSrcweir             return maContentPixelOffset;
175*cdf0e10cSrcweir         }
176*cdf0e10cSrcweir 
177*cdf0e10cSrcweir         void AnimatedSprite::movePixel( const ::basegfx::B2DPoint& rNewPos )
178*cdf0e10cSrcweir         {
179*cdf0e10cSrcweir             maPosPixel.reset( rNewPos );
180*cdf0e10cSrcweir             mpSprite->movePixel( rNewPos );
181*cdf0e10cSrcweir         }
182*cdf0e10cSrcweir 
183*cdf0e10cSrcweir         void AnimatedSprite::setAlpha( double nAlpha )
184*cdf0e10cSrcweir         {
185*cdf0e10cSrcweir             mnAlpha = nAlpha;
186*cdf0e10cSrcweir             mpSprite->setAlpha( nAlpha );
187*cdf0e10cSrcweir         }
188*cdf0e10cSrcweir 
189*cdf0e10cSrcweir         void AnimatedSprite::clip( const ::basegfx::B2DPolyPolygon& rClip )
190*cdf0e10cSrcweir         {
191*cdf0e10cSrcweir             maClip.reset( rClip );
192*cdf0e10cSrcweir             mpSprite->setClipPixel( rClip );
193*cdf0e10cSrcweir         }
194*cdf0e10cSrcweir 
195*cdf0e10cSrcweir         void AnimatedSprite::clip()
196*cdf0e10cSrcweir         {
197*cdf0e10cSrcweir             maClip.reset();
198*cdf0e10cSrcweir             mpSprite->setClip();
199*cdf0e10cSrcweir         }
200*cdf0e10cSrcweir 
201*cdf0e10cSrcweir         void AnimatedSprite::transform( const ::basegfx::B2DHomMatrix& rTransform )
202*cdf0e10cSrcweir         {
203*cdf0e10cSrcweir             maTransform.reset( rTransform );
204*cdf0e10cSrcweir             mpSprite->transform( rTransform );
205*cdf0e10cSrcweir         }
206*cdf0e10cSrcweir 
207*cdf0e10cSrcweir 		void AnimatedSprite::setPriority( double nPrio )
208*cdf0e10cSrcweir 		{
209*cdf0e10cSrcweir             mpSprite->setPriority( nPrio );
210*cdf0e10cSrcweir 		}
211*cdf0e10cSrcweir 
212*cdf0e10cSrcweir         void AnimatedSprite::hide()
213*cdf0e10cSrcweir         {
214*cdf0e10cSrcweir             mpSprite->hide();
215*cdf0e10cSrcweir             mbSpriteVisible = false;
216*cdf0e10cSrcweir         }
217*cdf0e10cSrcweir 
218*cdf0e10cSrcweir         void AnimatedSprite::show()
219*cdf0e10cSrcweir         {
220*cdf0e10cSrcweir             mbSpriteVisible = true;
221*cdf0e10cSrcweir             mpSprite->show();
222*cdf0e10cSrcweir         }
223*cdf0e10cSrcweir 
224*cdf0e10cSrcweir     }
225*cdf0e10cSrcweir }
226