1*9f62ea84SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*9f62ea84SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*9f62ea84SAndrew Rist * or more contributor license agreements. See the NOTICE file
5*9f62ea84SAndrew Rist * distributed with this work for additional information
6*9f62ea84SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*9f62ea84SAndrew Rist * to you under the Apache License, Version 2.0 (the
8*9f62ea84SAndrew Rist * "License"); you may not use this file except in compliance
9*9f62ea84SAndrew Rist * with the License. You may obtain a copy of the License at
10*9f62ea84SAndrew Rist *
11*9f62ea84SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*9f62ea84SAndrew Rist *
13*9f62ea84SAndrew Rist * Unless required by applicable law or agreed to in writing,
14*9f62ea84SAndrew Rist * software distributed under the License is distributed on an
15*9f62ea84SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*9f62ea84SAndrew Rist * KIND, either express or implied. See the License for the
17*9f62ea84SAndrew Rist * specific language governing permissions and limitations
18*9f62ea84SAndrew Rist * under the License.
19*9f62ea84SAndrew Rist *
20*9f62ea84SAndrew Rist *************************************************************/
21*9f62ea84SAndrew Rist
22*9f62ea84SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_vcl.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir #include "impanmvw.hxx"
28cdf0e10cSrcweir #include <vcl/virdev.hxx>
29cdf0e10cSrcweir #include <vcl/window.hxx>
30cdf0e10cSrcweir #include <vcl/salbtype.hxx>
31cdf0e10cSrcweir
32cdf0e10cSrcweir // ----------------
33cdf0e10cSrcweir // - ImplAnimView -
34cdf0e10cSrcweir // ----------------
35cdf0e10cSrcweir
ImplAnimView(Animation * pParent,OutputDevice * pOut,const Point & rPt,const Size & rSz,sal_uLong nExtraData,OutputDevice * pFirstFrameOutDev)36cdf0e10cSrcweir ImplAnimView::ImplAnimView( Animation* pParent, OutputDevice* pOut,
37cdf0e10cSrcweir const Point& rPt, const Size& rSz,
38cdf0e10cSrcweir sal_uLong nExtraData,
39cdf0e10cSrcweir OutputDevice* pFirstFrameOutDev ) :
40cdf0e10cSrcweir mpParent ( pParent ),
41cdf0e10cSrcweir mpOut ( pFirstFrameOutDev ? pFirstFrameOutDev : pOut ),
42cdf0e10cSrcweir mnExtraData ( nExtraData ),
43cdf0e10cSrcweir maPt ( rPt ),
44cdf0e10cSrcweir maSz ( rSz ),
45cdf0e10cSrcweir maSzPix ( mpOut->LogicToPixel( maSz ) ),
46cdf0e10cSrcweir maClip ( mpOut->GetClipRegion() ),
47cdf0e10cSrcweir mpBackground ( new VirtualDevice ),
48cdf0e10cSrcweir mpRestore ( new VirtualDevice ),
49cdf0e10cSrcweir meLastDisposal ( DISPOSE_BACK ),
50cdf0e10cSrcweir mbPause ( sal_False ),
51cdf0e10cSrcweir mbMarked ( sal_False ),
52cdf0e10cSrcweir mbHMirr ( maSz.Width() < 0L ),
53cdf0e10cSrcweir mbVMirr ( maSz.Height() < 0L )
54cdf0e10cSrcweir {
55cdf0e10cSrcweir mpParent->ImplIncAnimCount();
56cdf0e10cSrcweir
57cdf0e10cSrcweir // mirrored horizontically?
58cdf0e10cSrcweir if( mbHMirr )
59cdf0e10cSrcweir {
60cdf0e10cSrcweir maDispPt.X() = maPt.X() + maSz.Width() + 1L;
61cdf0e10cSrcweir maDispSz.Width() = -maSz.Width();
62cdf0e10cSrcweir maSzPix.Width() = -maSzPix.Width();
63cdf0e10cSrcweir }
64cdf0e10cSrcweir else
65cdf0e10cSrcweir {
66cdf0e10cSrcweir maDispPt.X() = maPt.X();
67cdf0e10cSrcweir maDispSz.Width() = maSz.Width();
68cdf0e10cSrcweir }
69cdf0e10cSrcweir
70cdf0e10cSrcweir // mirrored vertically?
71cdf0e10cSrcweir if( mbVMirr )
72cdf0e10cSrcweir {
73cdf0e10cSrcweir maDispPt.Y() = maPt.Y() + maSz.Height() + 1L;
74cdf0e10cSrcweir maDispSz.Height() = -maSz.Height();
75cdf0e10cSrcweir maSzPix.Height() = -maSzPix.Height();
76cdf0e10cSrcweir }
77cdf0e10cSrcweir else
78cdf0e10cSrcweir {
79cdf0e10cSrcweir maDispPt.Y() = maPt.Y();
80cdf0e10cSrcweir maDispSz.Height() = maSz.Height();
81cdf0e10cSrcweir }
82cdf0e10cSrcweir
83cdf0e10cSrcweir // save background
84cdf0e10cSrcweir mpBackground->SetOutputSizePixel( maSzPix );
85cdf0e10cSrcweir
86cdf0e10cSrcweir if( mpOut->GetOutDevType() == OUTDEV_WINDOW )
87cdf0e10cSrcweir {
88cdf0e10cSrcweir MapMode aTempMap( mpOut->GetMapMode() );
89cdf0e10cSrcweir aTempMap.SetOrigin( Point() );
90cdf0e10cSrcweir mpBackground->SetMapMode( aTempMap );
91cdf0e10cSrcweir ( (Window*) mpOut )->SaveBackground( maDispPt, maDispSz, Point(), *mpBackground );
92cdf0e10cSrcweir mpBackground->SetMapMode( MapMode() );
93cdf0e10cSrcweir }
94cdf0e10cSrcweir else
95cdf0e10cSrcweir mpBackground->DrawOutDev( Point(), maSzPix, maDispPt, maDispSz, *mpOut );
96cdf0e10cSrcweir
97cdf0e10cSrcweir // initial drawing to actual position
98cdf0e10cSrcweir ImplDrawToPos( mpParent->ImplGetCurPos() );
99cdf0e10cSrcweir
100cdf0e10cSrcweir // if first frame OutputDevice is set, update variables now for real OutputDevice
101cdf0e10cSrcweir if( pFirstFrameOutDev )
102cdf0e10cSrcweir maClip = ( mpOut = pOut )->GetClipRegion();
103cdf0e10cSrcweir }
104cdf0e10cSrcweir
105cdf0e10cSrcweir // ------------------------------------------------------------------------
106cdf0e10cSrcweir
~ImplAnimView()107cdf0e10cSrcweir ImplAnimView::~ImplAnimView()
108cdf0e10cSrcweir {
109cdf0e10cSrcweir delete mpBackground;
110cdf0e10cSrcweir delete mpRestore;
111cdf0e10cSrcweir
112cdf0e10cSrcweir mpParent->ImplDecAnimCount();
113cdf0e10cSrcweir }
114cdf0e10cSrcweir
115cdf0e10cSrcweir // ------------------------------------------------------------------------
116cdf0e10cSrcweir
ImplMatches(OutputDevice * pOut,long nExtraData) const117cdf0e10cSrcweir sal_Bool ImplAnimView::ImplMatches( OutputDevice* pOut, long nExtraData ) const
118cdf0e10cSrcweir {
119cdf0e10cSrcweir sal_Bool bRet = sal_False;
120cdf0e10cSrcweir
121cdf0e10cSrcweir if( nExtraData )
122cdf0e10cSrcweir {
123cdf0e10cSrcweir if( ( mnExtraData == nExtraData ) && ( !pOut || ( pOut == mpOut ) ) )
124cdf0e10cSrcweir bRet = sal_True;
125cdf0e10cSrcweir }
126cdf0e10cSrcweir else if( !pOut || ( pOut == mpOut ) )
127cdf0e10cSrcweir bRet = sal_True;
128cdf0e10cSrcweir
129cdf0e10cSrcweir return bRet;
130cdf0e10cSrcweir }
131cdf0e10cSrcweir
132cdf0e10cSrcweir // ------------------------------------------------------------------------
133cdf0e10cSrcweir
ImplGetPosSize(const AnimationBitmap & rAnm,Point & rPosPix,Size & rSizePix)134cdf0e10cSrcweir void ImplAnimView::ImplGetPosSize( const AnimationBitmap& rAnm, Point& rPosPix, Size& rSizePix )
135cdf0e10cSrcweir {
136cdf0e10cSrcweir const Size& rAnmSize = mpParent->GetDisplaySizePixel();
137cdf0e10cSrcweir Point aPt2( rAnm.aPosPix.X() + rAnm.aSizePix.Width() - 1L,
138cdf0e10cSrcweir rAnm.aPosPix.Y() + rAnm.aSizePix.Height() - 1L );
139cdf0e10cSrcweir double fFactX, fFactY;
140cdf0e10cSrcweir
141cdf0e10cSrcweir // calculate x scaling
142cdf0e10cSrcweir if( rAnmSize.Width() > 1L )
143cdf0e10cSrcweir fFactX = (double) ( maSzPix.Width() - 1L ) / ( rAnmSize.Width() - 1L );
144cdf0e10cSrcweir else
145cdf0e10cSrcweir fFactX = 1.0;
146cdf0e10cSrcweir
147cdf0e10cSrcweir // calculate y scaling
148cdf0e10cSrcweir if( rAnmSize.Height() > 1L )
149cdf0e10cSrcweir fFactY = (double) ( maSzPix.Height() - 1L ) / ( rAnmSize.Height() - 1L );
150cdf0e10cSrcweir else
151cdf0e10cSrcweir fFactY = 1.0;
152cdf0e10cSrcweir
153cdf0e10cSrcweir rPosPix.X() = FRound( rAnm.aPosPix.X() * fFactX );
154cdf0e10cSrcweir rPosPix.Y() = FRound( rAnm.aPosPix.Y() * fFactY );
155cdf0e10cSrcweir
156cdf0e10cSrcweir aPt2.X() = FRound( aPt2.X() * fFactX );
157cdf0e10cSrcweir aPt2.Y() = FRound( aPt2.Y() * fFactY );
158cdf0e10cSrcweir
159cdf0e10cSrcweir rSizePix.Width() = aPt2.X() - rPosPix.X() + 1L;
160cdf0e10cSrcweir rSizePix.Height() = aPt2.Y() - rPosPix.Y() + 1L;
161cdf0e10cSrcweir
162cdf0e10cSrcweir // mirrored horizontically?
163cdf0e10cSrcweir if( mbHMirr )
164cdf0e10cSrcweir rPosPix.X() = maSzPix.Width() - 1L - aPt2.X();
165cdf0e10cSrcweir
166cdf0e10cSrcweir // mirrored vertically?
167cdf0e10cSrcweir if( mbVMirr )
168cdf0e10cSrcweir rPosPix.Y() = maSzPix.Height() - 1L - aPt2.Y();
169cdf0e10cSrcweir }
170cdf0e10cSrcweir
171cdf0e10cSrcweir // ------------------------------------------------------------------------
172cdf0e10cSrcweir
ImplDrawToPos(sal_uLong nPos)173cdf0e10cSrcweir void ImplAnimView::ImplDrawToPos( sal_uLong nPos )
174cdf0e10cSrcweir {
175cdf0e10cSrcweir VirtualDevice aVDev;
176cdf0e10cSrcweir Region* pOldClip = !maClip.IsNull() ? new Region( mpOut->GetClipRegion() ) : NULL;
177cdf0e10cSrcweir
178cdf0e10cSrcweir aVDev.SetOutputSizePixel( maSzPix, sal_False );
179cdf0e10cSrcweir nPos = Min( nPos, (sal_uLong) mpParent->Count() - 1UL );
180cdf0e10cSrcweir
181cdf0e10cSrcweir for( sal_uLong i = 0UL; i <= nPos; i++ )
182cdf0e10cSrcweir ImplDraw( i, &aVDev );
183cdf0e10cSrcweir
184cdf0e10cSrcweir if( pOldClip )
185cdf0e10cSrcweir mpOut->SetClipRegion( maClip );
186cdf0e10cSrcweir
187cdf0e10cSrcweir mpOut->DrawOutDev( maDispPt, maDispSz, Point(), maSzPix, aVDev );
188cdf0e10cSrcweir
189cdf0e10cSrcweir if( pOldClip )
190cdf0e10cSrcweir {
191cdf0e10cSrcweir mpOut->SetClipRegion( *pOldClip );
192cdf0e10cSrcweir delete pOldClip;
193cdf0e10cSrcweir }
194cdf0e10cSrcweir }
195cdf0e10cSrcweir
196cdf0e10cSrcweir // ------------------------------------------------------------------------
197cdf0e10cSrcweir
ImplDraw(sal_uLong nPos)198cdf0e10cSrcweir void ImplAnimView::ImplDraw( sal_uLong nPos )
199cdf0e10cSrcweir {
200cdf0e10cSrcweir ImplDraw( nPos, NULL );
201cdf0e10cSrcweir }
202cdf0e10cSrcweir
203cdf0e10cSrcweir // ------------------------------------------------------------------------
204cdf0e10cSrcweir
ImplDraw(sal_uLong nPos,VirtualDevice * pVDev)205cdf0e10cSrcweir void ImplAnimView::ImplDraw( sal_uLong nPos, VirtualDevice* pVDev )
206cdf0e10cSrcweir {
207cdf0e10cSrcweir Rectangle aOutRect( mpOut->PixelToLogic( Point() ), mpOut->GetOutputSize() );
208cdf0e10cSrcweir
209cdf0e10cSrcweir // check, if output lies out of display
210cdf0e10cSrcweir if( aOutRect.Intersection( Rectangle( maDispPt, maDispSz ) ).IsEmpty() )
211cdf0e10cSrcweir ImplSetMarked( sal_True );
212cdf0e10cSrcweir else if( !mbPause )
213cdf0e10cSrcweir {
214cdf0e10cSrcweir VirtualDevice* pDev;
215cdf0e10cSrcweir Point aPosPix;
216cdf0e10cSrcweir Point aBmpPosPix;
217cdf0e10cSrcweir Size aSizePix;
218cdf0e10cSrcweir Size aBmpSizePix;
219cdf0e10cSrcweir const sal_uLong nLastPos = mpParent->Count() - 1;
220cdf0e10cSrcweir const AnimationBitmap& rAnm = mpParent->Get( (sal_uInt16) ( mnActPos = Min( nPos, nLastPos ) ) );
221cdf0e10cSrcweir
222cdf0e10cSrcweir ImplGetPosSize( rAnm, aPosPix, aSizePix );
223cdf0e10cSrcweir
224cdf0e10cSrcweir // mirrored horizontically?
225cdf0e10cSrcweir if( mbHMirr )
226cdf0e10cSrcweir {
227cdf0e10cSrcweir aBmpPosPix.X() = aPosPix.X() + aSizePix.Width() - 1L;
228cdf0e10cSrcweir aBmpSizePix.Width() = -aSizePix.Width();
229cdf0e10cSrcweir }
230cdf0e10cSrcweir else
231cdf0e10cSrcweir {
232cdf0e10cSrcweir aBmpPosPix.X() = aPosPix.X();
233cdf0e10cSrcweir aBmpSizePix.Width() = aSizePix.Width();
234cdf0e10cSrcweir }
235cdf0e10cSrcweir
236cdf0e10cSrcweir // mirrored vertically?
237cdf0e10cSrcweir if( mbVMirr )
238cdf0e10cSrcweir {
239cdf0e10cSrcweir aBmpPosPix.Y() = aPosPix.Y() + aSizePix.Height() - 1L;
240cdf0e10cSrcweir aBmpSizePix.Height() = -aSizePix.Height();
241cdf0e10cSrcweir }
242cdf0e10cSrcweir else
243cdf0e10cSrcweir {
244cdf0e10cSrcweir aBmpPosPix.Y() = aPosPix.Y();
245cdf0e10cSrcweir aBmpSizePix.Height() = aSizePix.Height();
246cdf0e10cSrcweir }
247cdf0e10cSrcweir
248cdf0e10cSrcweir // get output device
249cdf0e10cSrcweir if( !pVDev )
250cdf0e10cSrcweir {
251cdf0e10cSrcweir pDev = new VirtualDevice;
252cdf0e10cSrcweir pDev->SetOutputSizePixel( maSzPix, sal_False );
253cdf0e10cSrcweir pDev->DrawOutDev( Point(), maSzPix, maDispPt, maDispSz, *mpOut );
254cdf0e10cSrcweir }
255cdf0e10cSrcweir else
256cdf0e10cSrcweir pDev = pVDev;
257cdf0e10cSrcweir
258cdf0e10cSrcweir // restore background after each run
259cdf0e10cSrcweir if( !nPos )
260cdf0e10cSrcweir {
261cdf0e10cSrcweir meLastDisposal = DISPOSE_BACK;
262cdf0e10cSrcweir maRestPt = Point();
263cdf0e10cSrcweir maRestSz = maSzPix;
264cdf0e10cSrcweir }
265cdf0e10cSrcweir
266cdf0e10cSrcweir // restore
267cdf0e10cSrcweir if( ( DISPOSE_NOT != meLastDisposal ) && maRestSz.Width() && maRestSz.Height() )
268cdf0e10cSrcweir {
269cdf0e10cSrcweir if( DISPOSE_BACK == meLastDisposal )
270cdf0e10cSrcweir pDev->DrawOutDev( maRestPt, maRestSz, maRestPt, maRestSz, *mpBackground );
271cdf0e10cSrcweir else
272cdf0e10cSrcweir pDev->DrawOutDev( maRestPt, maRestSz, Point(), maRestSz, *mpRestore );
273cdf0e10cSrcweir }
274cdf0e10cSrcweir
275cdf0e10cSrcweir meLastDisposal = rAnm.eDisposal;
276cdf0e10cSrcweir maRestPt = aPosPix;
277cdf0e10cSrcweir maRestSz = aSizePix;
278cdf0e10cSrcweir
279cdf0e10cSrcweir // Was muessen wir beim naechsten Mal restaurieren ?
280cdf0e10cSrcweir // ==> ggf. in eine Bitmap stecken, ansonsten SaveBitmap
281cdf0e10cSrcweir // aus Speichergruenden loeschen
282cdf0e10cSrcweir if( ( meLastDisposal == DISPOSE_BACK ) || ( meLastDisposal == DISPOSE_NOT ) )
283cdf0e10cSrcweir mpRestore->SetOutputSizePixel( Size( 1, 1 ), sal_False );
284cdf0e10cSrcweir else
285cdf0e10cSrcweir {
286cdf0e10cSrcweir mpRestore->SetOutputSizePixel( maRestSz, sal_False );
287cdf0e10cSrcweir mpRestore->DrawOutDev( Point(), maRestSz, aPosPix, aSizePix, *pDev );
288cdf0e10cSrcweir }
289cdf0e10cSrcweir
290cdf0e10cSrcweir pDev->DrawBitmapEx( aBmpPosPix, aBmpSizePix, rAnm.aBmpEx );
291cdf0e10cSrcweir
292cdf0e10cSrcweir if( !pVDev )
293cdf0e10cSrcweir {
294cdf0e10cSrcweir Region* pOldClip = !maClip.IsNull() ? new Region( mpOut->GetClipRegion() ) : NULL;
295cdf0e10cSrcweir
296cdf0e10cSrcweir if( pOldClip )
297cdf0e10cSrcweir mpOut->SetClipRegion( maClip );
298cdf0e10cSrcweir
299cdf0e10cSrcweir mpOut->DrawOutDev( maDispPt, maDispSz, Point(), maSzPix, *pDev );
300cdf0e10cSrcweir
301cdf0e10cSrcweir if( pOldClip )
302cdf0e10cSrcweir {
303cdf0e10cSrcweir mpOut->SetClipRegion( *pOldClip );
304cdf0e10cSrcweir delete pOldClip;
305cdf0e10cSrcweir }
306cdf0e10cSrcweir
307cdf0e10cSrcweir delete pDev;
308cdf0e10cSrcweir
309cdf0e10cSrcweir if( mpOut->GetOutDevType() == OUTDEV_WINDOW )
310cdf0e10cSrcweir ( (Window*) mpOut )->Sync();
311cdf0e10cSrcweir }
312cdf0e10cSrcweir }
313cdf0e10cSrcweir }
314cdf0e10cSrcweir
315cdf0e10cSrcweir // ------------------------------------------------------------------------
316cdf0e10cSrcweir
ImplRepaint()317cdf0e10cSrcweir void ImplAnimView::ImplRepaint()
318cdf0e10cSrcweir {
319cdf0e10cSrcweir const sal_Bool bOldPause = mbPause;
320cdf0e10cSrcweir
321cdf0e10cSrcweir if( mpOut->GetOutDevType() == OUTDEV_WINDOW )
322cdf0e10cSrcweir {
323cdf0e10cSrcweir MapMode aTempMap( mpOut->GetMapMode() );
324cdf0e10cSrcweir aTempMap.SetOrigin( Point() );
325cdf0e10cSrcweir mpBackground->SetMapMode( aTempMap );
326cdf0e10cSrcweir ( (Window*) mpOut )->SaveBackground( maDispPt, maDispSz, Point(), *mpBackground );
327cdf0e10cSrcweir mpBackground->SetMapMode( MapMode() );
328cdf0e10cSrcweir }
329cdf0e10cSrcweir else
330cdf0e10cSrcweir mpBackground->DrawOutDev( Point(), maSzPix, maDispPt, maDispSz, *mpOut );
331cdf0e10cSrcweir
332cdf0e10cSrcweir mbPause = sal_False;
333cdf0e10cSrcweir ImplDrawToPos( mnActPos );
334cdf0e10cSrcweir mbPause = bOldPause;
335cdf0e10cSrcweir }
336cdf0e10cSrcweir
337cdf0e10cSrcweir // ------------------------------------------------------------------------
338cdf0e10cSrcweir
ImplCreateAInfo() const339cdf0e10cSrcweir AInfo* ImplAnimView::ImplCreateAInfo() const
340cdf0e10cSrcweir {
341cdf0e10cSrcweir AInfo* pAInfo = new AInfo;
342cdf0e10cSrcweir
343cdf0e10cSrcweir pAInfo->aStartOrg = maPt;
344cdf0e10cSrcweir pAInfo->aStartSize = maSz;
345cdf0e10cSrcweir pAInfo->pOutDev = mpOut;
346cdf0e10cSrcweir pAInfo->pViewData = (void*) this;
347cdf0e10cSrcweir pAInfo->nExtraData = mnExtraData;
348cdf0e10cSrcweir pAInfo->bPause = mbPause;
349cdf0e10cSrcweir
350cdf0e10cSrcweir return pAInfo;
351cdf0e10cSrcweir }
352