1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: impanmvw.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
34 #include "impanmvw.hxx"
35 #include <vcl/virdev.hxx>
36 #include <vcl/window.hxx>
37 #include <vcl/salbtype.hxx>
43 ImplAnimView::ImplAnimView( Animation
* pParent
, OutputDevice
* pOut
,
44 const Point
& rPt
, const Size
& rSz
,
46 OutputDevice
* pFirstFrameOutDev
) :
48 mpOut ( pFirstFrameOutDev
? pFirstFrameOutDev
: pOut
),
49 mnExtraData ( nExtraData
),
52 maSzPix ( mpOut
->LogicToPixel( maSz
) ),
53 maClip ( mpOut
->GetClipRegion() ),
54 mpBackground ( new VirtualDevice
),
55 mpRestore ( new VirtualDevice
),
56 meLastDisposal ( DISPOSE_BACK
),
59 mbHMirr ( maSz
.Width() < 0L ),
60 mbVMirr ( maSz
.Height() < 0L )
62 mpParent
->ImplIncAnimCount();
64 // mirrored horizontically?
67 maDispPt
.X() = maPt
.X() + maSz
.Width() + 1L;
68 maDispSz
.Width() = -maSz
.Width();
69 maSzPix
.Width() = -maSzPix
.Width();
73 maDispPt
.X() = maPt
.X();
74 maDispSz
.Width() = maSz
.Width();
77 // mirrored vertically?
80 maDispPt
.Y() = maPt
.Y() + maSz
.Height() + 1L;
81 maDispSz
.Height() = -maSz
.Height();
82 maSzPix
.Height() = -maSzPix
.Height();
86 maDispPt
.Y() = maPt
.Y();
87 maDispSz
.Height() = maSz
.Height();
91 mpBackground
->SetOutputSizePixel( maSzPix
);
93 if( mpOut
->GetOutDevType() == OUTDEV_WINDOW
)
95 MapMode
aTempMap( mpOut
->GetMapMode() );
96 aTempMap
.SetOrigin( Point() );
97 mpBackground
->SetMapMode( aTempMap
);
98 ( (Window
*) mpOut
)->SaveBackground( maDispPt
, maDispSz
, Point(), *mpBackground
);
99 mpBackground
->SetMapMode( MapMode() );
102 mpBackground
->DrawOutDev( Point(), maSzPix
, maDispPt
, maDispSz
, *mpOut
);
104 // initial drawing to actual position
105 ImplDrawToPos( mpParent
->ImplGetCurPos() );
107 // if first frame OutputDevice is set, update variables now for real OutputDevice
108 if( pFirstFrameOutDev
)
109 maClip
= ( mpOut
= pOut
)->GetClipRegion();
112 // ------------------------------------------------------------------------
114 ImplAnimView::~ImplAnimView()
119 mpParent
->ImplDecAnimCount();
122 // ------------------------------------------------------------------------
124 BOOL
ImplAnimView::ImplMatches( OutputDevice
* pOut
, long nExtraData
) const
130 if( ( mnExtraData
== nExtraData
) && ( !pOut
|| ( pOut
== mpOut
) ) )
133 else if( !pOut
|| ( pOut
== mpOut
) )
139 // ------------------------------------------------------------------------
141 void ImplAnimView::ImplGetPosSize( const AnimationBitmap
& rAnm
, Point
& rPosPix
, Size
& rSizePix
)
143 const Size
& rAnmSize
= mpParent
->GetDisplaySizePixel();
144 Point
aPt2( rAnm
.aPosPix
.X() + rAnm
.aSizePix
.Width() - 1L,
145 rAnm
.aPosPix
.Y() + rAnm
.aSizePix
.Height() - 1L );
146 double fFactX
, fFactY
;
148 // calculate x scaling
149 if( rAnmSize
.Width() > 1L )
150 fFactX
= (double) ( maSzPix
.Width() - 1L ) / ( rAnmSize
.Width() - 1L );
154 // calculate y scaling
155 if( rAnmSize
.Height() > 1L )
156 fFactY
= (double) ( maSzPix
.Height() - 1L ) / ( rAnmSize
.Height() - 1L );
160 rPosPix
.X() = FRound( rAnm
.aPosPix
.X() * fFactX
);
161 rPosPix
.Y() = FRound( rAnm
.aPosPix
.Y() * fFactY
);
163 aPt2
.X() = FRound( aPt2
.X() * fFactX
);
164 aPt2
.Y() = FRound( aPt2
.Y() * fFactY
);
166 rSizePix
.Width() = aPt2
.X() - rPosPix
.X() + 1L;
167 rSizePix
.Height() = aPt2
.Y() - rPosPix
.Y() + 1L;
169 // mirrored horizontically?
171 rPosPix
.X() = maSzPix
.Width() - 1L - aPt2
.X();
173 // mirrored vertically?
175 rPosPix
.Y() = maSzPix
.Height() - 1L - aPt2
.Y();
178 // ------------------------------------------------------------------------
180 void ImplAnimView::ImplDrawToPos( ULONG nPos
)
183 Region
* pOldClip
= !maClip
.IsNull() ? new Region( mpOut
->GetClipRegion() ) : NULL
;
185 aVDev
.SetOutputSizePixel( maSzPix
, FALSE
);
186 nPos
= Min( nPos
, (ULONG
) mpParent
->Count() - 1UL );
188 for( ULONG i
= 0UL; i
<= nPos
; i
++ )
189 ImplDraw( i
, &aVDev
);
192 mpOut
->SetClipRegion( maClip
);
194 mpOut
->DrawOutDev( maDispPt
, maDispSz
, Point(), maSzPix
, aVDev
);
198 mpOut
->SetClipRegion( *pOldClip
);
203 // ------------------------------------------------------------------------
205 void ImplAnimView::ImplDraw( ULONG nPos
)
207 ImplDraw( nPos
, NULL
);
210 // ------------------------------------------------------------------------
212 void ImplAnimView::ImplDraw( ULONG nPos
, VirtualDevice
* pVDev
)
214 Rectangle
aOutRect( mpOut
->PixelToLogic( Point() ), mpOut
->GetOutputSize() );
216 // check, if output lies out of display
217 if( aOutRect
.Intersection( Rectangle( maDispPt
, maDispSz
) ).IsEmpty() )
218 ImplSetMarked( TRUE
);
226 const ULONG nLastPos
= mpParent
->Count() - 1;
227 const AnimationBitmap
& rAnm
= mpParent
->Get( (USHORT
) ( mnActPos
= Min( nPos
, nLastPos
) ) );
229 ImplGetPosSize( rAnm
, aPosPix
, aSizePix
);
231 // mirrored horizontically?
234 aBmpPosPix
.X() = aPosPix
.X() + aSizePix
.Width() - 1L;
235 aBmpSizePix
.Width() = -aSizePix
.Width();
239 aBmpPosPix
.X() = aPosPix
.X();
240 aBmpSizePix
.Width() = aSizePix
.Width();
243 // mirrored vertically?
246 aBmpPosPix
.Y() = aPosPix
.Y() + aSizePix
.Height() - 1L;
247 aBmpSizePix
.Height() = -aSizePix
.Height();
251 aBmpPosPix
.Y() = aPosPix
.Y();
252 aBmpSizePix
.Height() = aSizePix
.Height();
258 pDev
= new VirtualDevice
;
259 pDev
->SetOutputSizePixel( maSzPix
, FALSE
);
260 pDev
->DrawOutDev( Point(), maSzPix
, maDispPt
, maDispSz
, *mpOut
);
265 // restore background after each run
268 meLastDisposal
= DISPOSE_BACK
;
274 if( ( DISPOSE_NOT
!= meLastDisposal
) && maRestSz
.Width() && maRestSz
.Height() )
276 if( DISPOSE_BACK
== meLastDisposal
)
277 pDev
->DrawOutDev( maRestPt
, maRestSz
, maRestPt
, maRestSz
, *mpBackground
);
279 pDev
->DrawOutDev( maRestPt
, maRestSz
, Point(), maRestSz
, *mpRestore
);
282 meLastDisposal
= rAnm
.eDisposal
;
286 // Was muessen wir beim naechsten Mal restaurieren ?
287 // ==> ggf. in eine Bitmap stecken, ansonsten SaveBitmap
288 // aus Speichergruenden loeschen
289 if( ( meLastDisposal
== DISPOSE_BACK
) || ( meLastDisposal
== DISPOSE_NOT
) )
290 mpRestore
->SetOutputSizePixel( Size( 1, 1 ), FALSE
);
293 mpRestore
->SetOutputSizePixel( maRestSz
, FALSE
);
294 mpRestore
->DrawOutDev( Point(), maRestSz
, aPosPix
, aSizePix
, *pDev
);
297 pDev
->DrawBitmapEx( aBmpPosPix
, aBmpSizePix
, rAnm
.aBmpEx
);
301 Region
* pOldClip
= !maClip
.IsNull() ? new Region( mpOut
->GetClipRegion() ) : NULL
;
304 mpOut
->SetClipRegion( maClip
);
306 mpOut
->DrawOutDev( maDispPt
, maDispSz
, Point(), maSzPix
, *pDev
);
310 mpOut
->SetClipRegion( *pOldClip
);
316 if( mpOut
->GetOutDevType() == OUTDEV_WINDOW
)
317 ( (Window
*) mpOut
)->Sync();
322 // ------------------------------------------------------------------------
324 void ImplAnimView::ImplRepaint()
326 const BOOL bOldPause
= mbPause
;
328 if( mpOut
->GetOutDevType() == OUTDEV_WINDOW
)
330 MapMode
aTempMap( mpOut
->GetMapMode() );
331 aTempMap
.SetOrigin( Point() );
332 mpBackground
->SetMapMode( aTempMap
);
333 ( (Window
*) mpOut
)->SaveBackground( maDispPt
, maDispSz
, Point(), *mpBackground
);
334 mpBackground
->SetMapMode( MapMode() );
337 mpBackground
->DrawOutDev( Point(), maSzPix
, maDispPt
, maDispSz
, *mpOut
);
340 ImplDrawToPos( mnActPos
);
344 // ------------------------------------------------------------------------
346 AInfo
* ImplAnimView::ImplCreateAInfo() const
348 AInfo
* pAInfo
= new AInfo
;
350 pAInfo
->aStartOrg
= maPt
;
351 pAInfo
->aStartSize
= maSz
;
352 pAInfo
->pOutDev
= mpOut
;
353 pAInfo
->pViewData
= (void*) this;
354 pAInfo
->nExtraData
= mnExtraData
;
355 pAInfo
->bPause
= mbPause
;