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