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