windowing/windowserver/stdgraphic/BITMAPANIMATIONGRAPHICDRAWER.CPP
changeset 0 5d03bc08d59c
child 121 d72fc2aace31
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserver/stdgraphic/BITMAPANIMATIONGRAPHICDRAWER.CPP	Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,235 @@
+// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "stdgraphicdrawer.h"
+#include "wsgraphicdrawercontext.h"
+#include "Graphics/WSGRAPHICMSGBUF.H"
+#include "Graphics/W32STDGRAPHICTEST.H"
+#include <s32mem.h>
+#include <fbs.h>
+#include "W32STDGRAPHIC.H"
+
+// CWsGraphicDrawerBitmapAnimation::CFrame \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ 
+
+NONSHARABLE_STRUCT(CWsGraphicDrawerBitmapAnimation::CFrame): public CBase
+	{
+	~CFrame();
+	TFrameInfo iFrameInfo;
+	CFbsBitmap* iBitmap;
+	CFbsBitmap* iMask;
+	mutable RRegionBuf<12> iVisibleRegion;
+	};
+
+CWsGraphicDrawerBitmapAnimation::CFrame::~CFrame()
+	{
+	delete iBitmap;
+	delete iMask;
+	iVisibleRegion.Close();
+	}
+
+// CWsGraphicDrawerBitmapAnimation \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ 
+
+CWsGraphicDrawerBitmapAnimation* CWsGraphicDrawerBitmapAnimation::CreateL()
+	{
+	return new(ELeave) CWsGraphicDrawerBitmapAnimation;
+	}
+
+CWsGraphicDrawerBitmapAnimation::CWsGraphicDrawerBitmapAnimation()
+	{
+	}
+
+CWsGraphicDrawerBitmapAnimation::~CWsGraphicDrawerBitmapAnimation()
+	{
+	if (iContext)
+		{
+		iContext->Destroy();
+		iContext = NULL;
+		}
+	iFrames.ResetAndDestroy();
+	}
+
+void CWsGraphicDrawerBitmapAnimation::ConstructL(MWsGraphicDrawerEnvironment& aEnv,const TGraphicDrawerId& aId,MWsClient& aOwner,const TDesC8& aData)
+	{
+	__ASSERT_COMPILE(sizeof(TInt) == sizeof(TInt32));
+	RDesReadStream in(aData);
+	in.PushL();
+	const TInt count = in.ReadInt32L();
+	for(TInt i=0; i<count; i++)
+		{
+		CFrame* frame = new(ELeave) CFrame;
+		CleanupStack::PushL(frame);
+		in.ReadL(reinterpret_cast<TUint8*>(&(frame->iFrameInfo)),sizeof(TFrameInfo));
+		const TInt bitmapHandle = in.ReadInt32L();
+		if(bitmapHandle)
+			{
+			frame->iBitmap = new(ELeave) CFbsBitmap;
+			User::LeaveIfError(frame->iBitmap->Duplicate(bitmapHandle));
+			}
+		const TInt maskHandle = in.ReadInt32L();
+		if(maskHandle)
+			{
+			frame->iMask = new(ELeave) CFbsBitmap;
+			User::LeaveIfError(frame->iMask->Duplicate(maskHandle));
+			}
+		iFrames.AppendL(frame);
+		CleanupStack::Pop(frame);
+		TInt64 delay = frame->iFrameInfo.iDelay.Int64();
+		if((delay < 0) || (delay > KMaxTUint32))
+			{
+			User::Leave(KErrCorrupt);
+			}
+		iAnimationLength += delay;
+		}
+	in.Pop();
+	BaseConstructL(aEnv,aId,aOwner);
+	if (!(aEnv.Screen(0)->ResolveObjectInterface(KMWsCompositionContext) || aEnv.Screen(0)->ResolveObjectInterface(KMWsScene)))
+		{
+		iContext = CWsGraphicDrawerNonNgaContext::NewL();
+		}
+	else
+		{
+		iContext = CWsGraphicDrawerNgaContext::NewL();
+		}
+	}
+
+void CWsGraphicDrawerBitmapAnimation::DoDraw(MWsGc& aGc,const TRect& aRect,const TDesC8& aData) const
+	{
+	const TInt count = iFrames.Count();
+	if(0 >= count)
+		{
+		return;
+		}
+
+	TWsGraphicMsgBufParser buf(aData);
+	if(KErrNone != buf.Verify())
+		{
+		return;
+		}
+			
+	TWsGraphicMsgAnimation anim;
+ 	if (KErrNone != anim.Load(buf))
+ 		{
+ 		return;
+ 		}
+
+	if (KErrNone != iContext->Push(aGc))
+		{
+		return;
+		}
+
+	const TInt64 now_microseconds = (iAnimationLength ? anim.AnimationTime(iContext->Now(aGc),iAnimationLength).Int64(): 0LL);
+	TInt64 time_microseconds = 0LL;
+
+	// find end frame
+	TInt endFrame = 0;
+	while((endFrame<count) && (time_microseconds <= now_microseconds))
+		{
+		// work out timing
+		time_microseconds += iFrames[endFrame]->iFrameInfo.iDelay.Int64();
+		endFrame++;
+		}
+
+	TBool drawError = EFalse;
+	// work out visible regions
+	for(TInt i = 0; (i < endFrame) && !drawError; i++)
+		{
+		const CFrame* frame = iFrames[i];
+		const TRect frameRect(frame->iFrameInfo.iFrameCoordsInPixels);
+ 		frame->iVisibleRegion.Clear();
+
+ 		if((i == (endFrame - 1)) || frame->iFrameInfo.iFlags & TFrameInfo::ELeaveInPlace)	// ELeave - Enum TFrameInfo::ELeaveInPlace triggers leavescan
+ 			{
+ 			frame->iVisibleRegion.AddRect(frameRect);
+ 			drawError = frame->iVisibleRegion.CheckError();
+ 			}
+ 		else
+   			{
+   			if(frame->iFrameInfo.iFlags & TFrameInfo::ERestoreToBackground) 
+ 				{
+ 				for(TInt j = 0; j <= i; j++)
+ 					{
+ 					iFrames[j]->iVisibleRegion.SubRect(frameRect);
+ 					// coverity[unchecked_value]
+ 					drawError |= iFrames[j]->iVisibleRegion.CheckError();
+ 					}
+ 				}
+ 			else if(!(frame->iFrameInfo.iFlags & TFrameInfo::ERestoreToPrevious))  // if no disposal method is set, treat it as leave in place
+ 				{
+ 				frame->iVisibleRegion.AddRect(frameRect);
+ 				drawError = frame->iVisibleRegion.CheckError();
+ 				}
+   			}
+		}
+
+	//draw each of the visible sub frames
+	for(TInt i = 0; (i < endFrame) && !drawError; i++)
+		{
+		const CFrame* frame = iFrames[i];
+		if(frame->iBitmap)
+			{
+			const TRegionFix<1> bitmapRegion(frame->iFrameInfo.iFrameCoordsInPixels);
+			frame->iVisibleRegion.Intersect(bitmapRegion);
+			frame->iVisibleRegion.Tidy();
+			if(frame->iVisibleRegion.CheckError())
+				{
+				drawError = ETrue;
+				break;
+				}
+			else
+				{
+				const TInt clipCount = frame->iVisibleRegion.Count();
+ 				for(TInt j = 0; j < clipCount; j++)
+					{
+ 					TRect frameRect = frame->iVisibleRegion.RectangleList()[j];
+ 					TRect clipRect(frameRect);
+ 					clipRect.Move(aRect.iTl);
+ 					clipRect.Intersection(aRect);
+
+ 					frameRect.Move(aRect.iTl);
+ 					frameRect.Intersection(aRect);
+ 					frameRect.Move(-aRect.iTl);
+ 					frameRect.Move(-frame->iFrameInfo.iFrameCoordsInPixels.iTl);
+
+					if(!clipRect.IsEmpty() && !frameRect.IsEmpty())
+						{
+						iContext->DrawBitmap(aGc,clipRect.iTl, frame->iBitmap, frameRect, frame->iMask);
+						}
+					}
+				}
+			}
+		}
+
+	if(0 <= buf.Find(TUid::Uid(TWsGraphicFrameRate::ETypeId)))
+		{
+		iContext->DrawFrameRate(aGc,aRect,iFps);
+		}
+	iFps.Sample();
+	
+	if(anim.IsPlaying(iContext->Now(aGc),iAnimationLength))
+		{
+		iContext->ScheduleAnimation(aGc, aRect,(time_microseconds - now_microseconds));
+		}
+	else if(drawError)
+ 		{
+ 		iContext->ScheduleAnimation(aGc, aRect,now_microseconds + 1000000); // retry in 1 second
+ 		}
+ 
+	iContext->Pop(aGc);
+	}
+
+void CWsGraphicDrawerBitmapAnimation::HandleMessage(const TDesC8& /*aData*/)
+	{
+	}
+