356 lines
11 KiB
C++
356 lines
11 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*************************************************************************
|
|
*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* This file is part of OpenOffice.org.
|
|
*
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
* only, as published by the Free Software Foundation.
|
|
*
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License version 3 for more details
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
* <http://www.openoffice.org/license.html>
|
|
* for a copy of the LGPLv3 License.
|
|
*
|
|
************************************************************************/
|
|
|
|
|
|
#include "impanmvw.hxx"
|
|
#include <vcl/virdev.hxx>
|
|
#include <vcl/window.hxx>
|
|
#include <vcl/salbtype.hxx>
|
|
|
|
// ----------------
|
|
// - ImplAnimView -
|
|
// ----------------
|
|
|
|
ImplAnimView::ImplAnimView( Animation* pParent, OutputDevice* pOut,
|
|
const Point& rPt, const Size& rSz,
|
|
sal_uLong nExtraData,
|
|
OutputDevice* pFirstFrameOutDev ) :
|
|
mpParent ( pParent ),
|
|
mpOut ( pFirstFrameOutDev ? pFirstFrameOutDev : pOut ),
|
|
mnExtraData ( nExtraData ),
|
|
maPt ( rPt ),
|
|
maSz ( rSz ),
|
|
maSzPix ( mpOut->LogicToPixel( maSz ) ),
|
|
maClip ( mpOut->GetClipRegion() ),
|
|
mpBackground ( new VirtualDevice ),
|
|
mpRestore ( new VirtualDevice ),
|
|
meLastDisposal ( DISPOSE_BACK ),
|
|
mbPause ( sal_False ),
|
|
mbMarked ( sal_False ),
|
|
mbHMirr ( maSz.Width() < 0L ),
|
|
mbVMirr ( maSz.Height() < 0L )
|
|
{
|
|
mpParent->ImplIncAnimCount();
|
|
|
|
// mirrored horizontically?
|
|
if( mbHMirr )
|
|
{
|
|
maDispPt.X() = maPt.X() + maSz.Width() + 1L;
|
|
maDispSz.Width() = -maSz.Width();
|
|
maSzPix.Width() = -maSzPix.Width();
|
|
}
|
|
else
|
|
{
|
|
maDispPt.X() = maPt.X();
|
|
maDispSz.Width() = maSz.Width();
|
|
}
|
|
|
|
// mirrored vertically?
|
|
if( mbVMirr )
|
|
{
|
|
maDispPt.Y() = maPt.Y() + maSz.Height() + 1L;
|
|
maDispSz.Height() = -maSz.Height();
|
|
maSzPix.Height() = -maSzPix.Height();
|
|
}
|
|
else
|
|
{
|
|
maDispPt.Y() = maPt.Y();
|
|
maDispSz.Height() = maSz.Height();
|
|
}
|
|
|
|
// save background
|
|
mpBackground->SetOutputSizePixel( maSzPix );
|
|
|
|
if( mpOut->GetOutDevType() == OUTDEV_WINDOW )
|
|
{
|
|
MapMode aTempMap( mpOut->GetMapMode() );
|
|
aTempMap.SetOrigin( Point() );
|
|
mpBackground->SetMapMode( aTempMap );
|
|
( (Window*) mpOut )->SaveBackground( maDispPt, maDispSz, Point(), *mpBackground );
|
|
mpBackground->SetMapMode( MapMode() );
|
|
}
|
|
else
|
|
mpBackground->DrawOutDev( Point(), maSzPix, maDispPt, maDispSz, *mpOut );
|
|
|
|
// initial drawing to actual position
|
|
ImplDrawToPos( mpParent->ImplGetCurPos() );
|
|
|
|
// if first frame OutputDevice is set, update variables now for real OutputDevice
|
|
if( pFirstFrameOutDev )
|
|
maClip = ( mpOut = pOut )->GetClipRegion();
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
ImplAnimView::~ImplAnimView()
|
|
{
|
|
delete mpBackground;
|
|
delete mpRestore;
|
|
|
|
mpParent->ImplDecAnimCount();
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
sal_Bool ImplAnimView::ImplMatches( OutputDevice* pOut, long nExtraData ) const
|
|
{
|
|
sal_Bool bRet = sal_False;
|
|
|
|
if( nExtraData )
|
|
{
|
|
if( ( mnExtraData == nExtraData ) && ( !pOut || ( pOut == mpOut ) ) )
|
|
bRet = sal_True;
|
|
}
|
|
else if( !pOut || ( pOut == mpOut ) )
|
|
bRet = sal_True;
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
void ImplAnimView::ImplGetPosSize( const AnimationBitmap& rAnm, Point& rPosPix, Size& rSizePix )
|
|
{
|
|
const Size& rAnmSize = mpParent->GetDisplaySizePixel();
|
|
Point aPt2( rAnm.aPosPix.X() + rAnm.aSizePix.Width() - 1L,
|
|
rAnm.aPosPix.Y() + rAnm.aSizePix.Height() - 1L );
|
|
double fFactX, fFactY;
|
|
|
|
// calculate x scaling
|
|
if( rAnmSize.Width() > 1L )
|
|
fFactX = (double) ( maSzPix.Width() - 1L ) / ( rAnmSize.Width() - 1L );
|
|
else
|
|
fFactX = 1.0;
|
|
|
|
// calculate y scaling
|
|
if( rAnmSize.Height() > 1L )
|
|
fFactY = (double) ( maSzPix.Height() - 1L ) / ( rAnmSize.Height() - 1L );
|
|
else
|
|
fFactY = 1.0;
|
|
|
|
rPosPix.X() = FRound( rAnm.aPosPix.X() * fFactX );
|
|
rPosPix.Y() = FRound( rAnm.aPosPix.Y() * fFactY );
|
|
|
|
aPt2.X() = FRound( aPt2.X() * fFactX );
|
|
aPt2.Y() = FRound( aPt2.Y() * fFactY );
|
|
|
|
rSizePix.Width() = aPt2.X() - rPosPix.X() + 1L;
|
|
rSizePix.Height() = aPt2.Y() - rPosPix.Y() + 1L;
|
|
|
|
// mirrored horizontically?
|
|
if( mbHMirr )
|
|
rPosPix.X() = maSzPix.Width() - 1L - aPt2.X();
|
|
|
|
// mirrored vertically?
|
|
if( mbVMirr )
|
|
rPosPix.Y() = maSzPix.Height() - 1L - aPt2.Y();
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
void ImplAnimView::ImplDrawToPos( sal_uLong nPos )
|
|
{
|
|
VirtualDevice aVDev;
|
|
Region* pOldClip = !maClip.IsNull() ? new Region( mpOut->GetClipRegion() ) : NULL;
|
|
|
|
aVDev.SetOutputSizePixel( maSzPix, sal_False );
|
|
nPos = Min( nPos, (sal_uLong) mpParent->Count() - 1UL );
|
|
|
|
for( sal_uLong i = 0UL; i <= nPos; i++ )
|
|
ImplDraw( i, &aVDev );
|
|
|
|
if( pOldClip )
|
|
mpOut->SetClipRegion( maClip );
|
|
|
|
mpOut->DrawOutDev( maDispPt, maDispSz, Point(), maSzPix, aVDev );
|
|
|
|
if( pOldClip )
|
|
{
|
|
mpOut->SetClipRegion( *pOldClip );
|
|
delete pOldClip;
|
|
}
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
void ImplAnimView::ImplDraw( sal_uLong nPos )
|
|
{
|
|
ImplDraw( nPos, NULL );
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
void ImplAnimView::ImplDraw( sal_uLong nPos, VirtualDevice* pVDev )
|
|
{
|
|
Rectangle aOutRect( mpOut->PixelToLogic( Point() ), mpOut->GetOutputSize() );
|
|
|
|
// check, if output lies out of display
|
|
if( aOutRect.Intersection( Rectangle( maDispPt, maDispSz ) ).IsEmpty() )
|
|
ImplSetMarked( sal_True );
|
|
else if( !mbPause )
|
|
{
|
|
VirtualDevice* pDev;
|
|
Point aPosPix;
|
|
Point aBmpPosPix;
|
|
Size aSizePix;
|
|
Size aBmpSizePix;
|
|
const sal_uLong nLastPos = mpParent->Count() - 1;
|
|
const AnimationBitmap& rAnm = mpParent->Get( (sal_uInt16) ( mnActPos = Min( nPos, nLastPos ) ) );
|
|
|
|
ImplGetPosSize( rAnm, aPosPix, aSizePix );
|
|
|
|
// mirrored horizontically?
|
|
if( mbHMirr )
|
|
{
|
|
aBmpPosPix.X() = aPosPix.X() + aSizePix.Width() - 1L;
|
|
aBmpSizePix.Width() = -aSizePix.Width();
|
|
}
|
|
else
|
|
{
|
|
aBmpPosPix.X() = aPosPix.X();
|
|
aBmpSizePix.Width() = aSizePix.Width();
|
|
}
|
|
|
|
// mirrored vertically?
|
|
if( mbVMirr )
|
|
{
|
|
aBmpPosPix.Y() = aPosPix.Y() + aSizePix.Height() - 1L;
|
|
aBmpSizePix.Height() = -aSizePix.Height();
|
|
}
|
|
else
|
|
{
|
|
aBmpPosPix.Y() = aPosPix.Y();
|
|
aBmpSizePix.Height() = aSizePix.Height();
|
|
}
|
|
|
|
// get output device
|
|
if( !pVDev )
|
|
{
|
|
pDev = new VirtualDevice;
|
|
pDev->SetOutputSizePixel( maSzPix, sal_False );
|
|
pDev->DrawOutDev( Point(), maSzPix, maDispPt, maDispSz, *mpOut );
|
|
}
|
|
else
|
|
pDev = pVDev;
|
|
|
|
// restore background after each run
|
|
if( !nPos )
|
|
{
|
|
meLastDisposal = DISPOSE_BACK;
|
|
maRestPt = Point();
|
|
maRestSz = maSzPix;
|
|
}
|
|
|
|
// restore
|
|
if( ( DISPOSE_NOT != meLastDisposal ) && maRestSz.Width() && maRestSz.Height() )
|
|
{
|
|
if( DISPOSE_BACK == meLastDisposal )
|
|
pDev->DrawOutDev( maRestPt, maRestSz, maRestPt, maRestSz, *mpBackground );
|
|
else
|
|
pDev->DrawOutDev( maRestPt, maRestSz, Point(), maRestSz, *mpRestore );
|
|
}
|
|
|
|
meLastDisposal = rAnm.eDisposal;
|
|
maRestPt = aPosPix;
|
|
maRestSz = aSizePix;
|
|
|
|
// Was muessen wir beim naechsten Mal restaurieren ?
|
|
// ==> ggf. in eine Bitmap stecken, ansonsten SaveBitmap
|
|
// aus Speichergruenden loeschen
|
|
if( ( meLastDisposal == DISPOSE_BACK ) || ( meLastDisposal == DISPOSE_NOT ) )
|
|
mpRestore->SetOutputSizePixel( Size( 1, 1 ), sal_False );
|
|
else
|
|
{
|
|
mpRestore->SetOutputSizePixel( maRestSz, sal_False );
|
|
mpRestore->DrawOutDev( Point(), maRestSz, aPosPix, aSizePix, *pDev );
|
|
}
|
|
|
|
pDev->DrawBitmapEx( aBmpPosPix, aBmpSizePix, rAnm.aBmpEx );
|
|
|
|
if( !pVDev )
|
|
{
|
|
Region* pOldClip = !maClip.IsNull() ? new Region( mpOut->GetClipRegion() ) : NULL;
|
|
|
|
if( pOldClip )
|
|
mpOut->SetClipRegion( maClip );
|
|
|
|
mpOut->DrawOutDev( maDispPt, maDispSz, Point(), maSzPix, *pDev );
|
|
|
|
if( pOldClip )
|
|
{
|
|
mpOut->SetClipRegion( *pOldClip );
|
|
delete pOldClip;
|
|
}
|
|
|
|
delete pDev;
|
|
|
|
if( mpOut->GetOutDevType() == OUTDEV_WINDOW )
|
|
( (Window*) mpOut )->Sync();
|
|
}
|
|
}
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
void ImplAnimView::ImplRepaint()
|
|
{
|
|
const sal_Bool bOldPause = mbPause;
|
|
|
|
if( mpOut->GetOutDevType() == OUTDEV_WINDOW )
|
|
{
|
|
MapMode aTempMap( mpOut->GetMapMode() );
|
|
aTempMap.SetOrigin( Point() );
|
|
mpBackground->SetMapMode( aTempMap );
|
|
( (Window*) mpOut )->SaveBackground( maDispPt, maDispSz, Point(), *mpBackground );
|
|
mpBackground->SetMapMode( MapMode() );
|
|
}
|
|
else
|
|
mpBackground->DrawOutDev( Point(), maSzPix, maDispPt, maDispSz, *mpOut );
|
|
|
|
mbPause = sal_False;
|
|
ImplDrawToPos( mnActPos );
|
|
mbPause = bOldPause;
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
AInfo* ImplAnimView::ImplCreateAInfo() const
|
|
{
|
|
AInfo* pAInfo = new AInfo;
|
|
|
|
pAInfo->aStartOrg = maPt;
|
|
pAInfo->aStartSize = maSz;
|
|
pAInfo->pOutDev = mpOut;
|
|
pAInfo->pViewData = (void*) this;
|
|
pAInfo->nExtraData = mnExtraData;
|
|
pAInfo->bPause = mbPause;
|
|
|
|
return pAInfo;
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|