xref: /aoo41x/main/vcl/source/gdi/impanmvw.cxx (revision 9f62ea84)
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