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