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 { 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 75cdf0e10cSrcweir ::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 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 163cdf0e10cSrcweir void AnimatedSprite::setPixelOffset( const ::basegfx::B2DSize& rPixelOffset ) 164cdf0e10cSrcweir { 165cdf0e10cSrcweir maContentPixelOffset = rPixelOffset; 166cdf0e10cSrcweir } 167cdf0e10cSrcweir 168cdf0e10cSrcweir ::basegfx::B2DSize AnimatedSprite::getPixelOffset() const 169cdf0e10cSrcweir { 170cdf0e10cSrcweir return maContentPixelOffset; 171cdf0e10cSrcweir } 172cdf0e10cSrcweir 173cdf0e10cSrcweir void AnimatedSprite::movePixel( const ::basegfx::B2DPoint& rNewPos ) 174cdf0e10cSrcweir { 175cdf0e10cSrcweir maPosPixel.reset( rNewPos ); 176cdf0e10cSrcweir mpSprite->movePixel( rNewPos ); 177cdf0e10cSrcweir } 178cdf0e10cSrcweir 179cdf0e10cSrcweir void AnimatedSprite::setAlpha( double nAlpha ) 180cdf0e10cSrcweir { 181cdf0e10cSrcweir mnAlpha = nAlpha; 182cdf0e10cSrcweir mpSprite->setAlpha( nAlpha ); 183cdf0e10cSrcweir } 184cdf0e10cSrcweir 185cdf0e10cSrcweir void AnimatedSprite::clip( const ::basegfx::B2DPolyPolygon& rClip ) 186cdf0e10cSrcweir { 187cdf0e10cSrcweir maClip.reset( rClip ); 188cdf0e10cSrcweir mpSprite->setClipPixel( rClip ); 189cdf0e10cSrcweir } 190cdf0e10cSrcweir 191cdf0e10cSrcweir void AnimatedSprite::clip() 192cdf0e10cSrcweir { 193cdf0e10cSrcweir maClip.reset(); 194cdf0e10cSrcweir mpSprite->setClip(); 195cdf0e10cSrcweir } 196cdf0e10cSrcweir 197cdf0e10cSrcweir void AnimatedSprite::transform( const ::basegfx::B2DHomMatrix& rTransform ) 198cdf0e10cSrcweir { 199cdf0e10cSrcweir maTransform.reset( rTransform ); 200cdf0e10cSrcweir mpSprite->transform( rTransform ); 201cdf0e10cSrcweir } 202cdf0e10cSrcweir 203cdf0e10cSrcweir void AnimatedSprite::setPriority( double nPrio ) 204cdf0e10cSrcweir { 205cdf0e10cSrcweir mpSprite->setPriority( nPrio ); 206cdf0e10cSrcweir } 207cdf0e10cSrcweir 208cdf0e10cSrcweir void AnimatedSprite::hide() 209cdf0e10cSrcweir { 210cdf0e10cSrcweir mpSprite->hide(); 211cdf0e10cSrcweir mbSpriteVisible = false; 212cdf0e10cSrcweir } 213cdf0e10cSrcweir 214cdf0e10cSrcweir void AnimatedSprite::show() 215cdf0e10cSrcweir { 216cdf0e10cSrcweir mbSpriteVisible = true; 217cdf0e10cSrcweir mpSprite->show(); 218cdf0e10cSrcweir } 219cdf0e10cSrcweir 220cdf0e10cSrcweir } 221cdf0e10cSrcweir } 222