windowing/windowserver/stdgraphic/BITMAPANIMATIONGRAPHICDRAWER.CPP
changeset 0 5d03bc08d59c
child 121 d72fc2aace31
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "stdgraphicdrawer.h"
       
    17 #include "wsgraphicdrawercontext.h"
       
    18 #include "Graphics/WSGRAPHICMSGBUF.H"
       
    19 #include "Graphics/W32STDGRAPHICTEST.H"
       
    20 #include <s32mem.h>
       
    21 #include <fbs.h>
       
    22 #include "W32STDGRAPHIC.H"
       
    23 
       
    24 // CWsGraphicDrawerBitmapAnimation::CFrame \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ 
       
    25 
       
    26 NONSHARABLE_STRUCT(CWsGraphicDrawerBitmapAnimation::CFrame): public CBase
       
    27 	{
       
    28 	~CFrame();
       
    29 	TFrameInfo iFrameInfo;
       
    30 	CFbsBitmap* iBitmap;
       
    31 	CFbsBitmap* iMask;
       
    32 	mutable RRegionBuf<12> iVisibleRegion;
       
    33 	};
       
    34 
       
    35 CWsGraphicDrawerBitmapAnimation::CFrame::~CFrame()
       
    36 	{
       
    37 	delete iBitmap;
       
    38 	delete iMask;
       
    39 	iVisibleRegion.Close();
       
    40 	}
       
    41 
       
    42 // CWsGraphicDrawerBitmapAnimation \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ 
       
    43 
       
    44 CWsGraphicDrawerBitmapAnimation* CWsGraphicDrawerBitmapAnimation::CreateL()
       
    45 	{
       
    46 	return new(ELeave) CWsGraphicDrawerBitmapAnimation;
       
    47 	}
       
    48 
       
    49 CWsGraphicDrawerBitmapAnimation::CWsGraphicDrawerBitmapAnimation()
       
    50 	{
       
    51 	}
       
    52 
       
    53 CWsGraphicDrawerBitmapAnimation::~CWsGraphicDrawerBitmapAnimation()
       
    54 	{
       
    55 	if (iContext)
       
    56 		{
       
    57 		iContext->Destroy();
       
    58 		iContext = NULL;
       
    59 		}
       
    60 	iFrames.ResetAndDestroy();
       
    61 	}
       
    62 
       
    63 void CWsGraphicDrawerBitmapAnimation::ConstructL(MWsGraphicDrawerEnvironment& aEnv,const TGraphicDrawerId& aId,MWsClient& aOwner,const TDesC8& aData)
       
    64 	{
       
    65 	__ASSERT_COMPILE(sizeof(TInt) == sizeof(TInt32));
       
    66 	RDesReadStream in(aData);
       
    67 	in.PushL();
       
    68 	const TInt count = in.ReadInt32L();
       
    69 	for(TInt i=0; i<count; i++)
       
    70 		{
       
    71 		CFrame* frame = new(ELeave) CFrame;
       
    72 		CleanupStack::PushL(frame);
       
    73 		in.ReadL(reinterpret_cast<TUint8*>(&(frame->iFrameInfo)),sizeof(TFrameInfo));
       
    74 		const TInt bitmapHandle = in.ReadInt32L();
       
    75 		if(bitmapHandle)
       
    76 			{
       
    77 			frame->iBitmap = new(ELeave) CFbsBitmap;
       
    78 			User::LeaveIfError(frame->iBitmap->Duplicate(bitmapHandle));
       
    79 			}
       
    80 		const TInt maskHandle = in.ReadInt32L();
       
    81 		if(maskHandle)
       
    82 			{
       
    83 			frame->iMask = new(ELeave) CFbsBitmap;
       
    84 			User::LeaveIfError(frame->iMask->Duplicate(maskHandle));
       
    85 			}
       
    86 		iFrames.AppendL(frame);
       
    87 		CleanupStack::Pop(frame);
       
    88 		TInt64 delay = frame->iFrameInfo.iDelay.Int64();
       
    89 		if((delay < 0) || (delay > KMaxTUint32))
       
    90 			{
       
    91 			User::Leave(KErrCorrupt);
       
    92 			}
       
    93 		iAnimationLength += delay;
       
    94 		}
       
    95 	in.Pop();
       
    96 	BaseConstructL(aEnv,aId,aOwner);
       
    97 	if (!(aEnv.Screen(0)->ResolveObjectInterface(KMWsCompositionContext) || aEnv.Screen(0)->ResolveObjectInterface(KMWsScene)))
       
    98 		{
       
    99 		iContext = CWsGraphicDrawerNonNgaContext::NewL();
       
   100 		}
       
   101 	else
       
   102 		{
       
   103 		iContext = CWsGraphicDrawerNgaContext::NewL();
       
   104 		}
       
   105 	}
       
   106 
       
   107 void CWsGraphicDrawerBitmapAnimation::DoDraw(MWsGc& aGc,const TRect& aRect,const TDesC8& aData) const
       
   108 	{
       
   109 	const TInt count = iFrames.Count();
       
   110 	if(0 >= count)
       
   111 		{
       
   112 		return;
       
   113 		}
       
   114 
       
   115 	TWsGraphicMsgBufParser buf(aData);
       
   116 	if(KErrNone != buf.Verify())
       
   117 		{
       
   118 		return;
       
   119 		}
       
   120 			
       
   121 	TWsGraphicMsgAnimation anim;
       
   122  	if (KErrNone != anim.Load(buf))
       
   123  		{
       
   124  		return;
       
   125  		}
       
   126 
       
   127 	if (KErrNone != iContext->Push(aGc))
       
   128 		{
       
   129 		return;
       
   130 		}
       
   131 
       
   132 	const TInt64 now_microseconds = (iAnimationLength ? anim.AnimationTime(iContext->Now(aGc),iAnimationLength).Int64(): 0LL);
       
   133 	TInt64 time_microseconds = 0LL;
       
   134 
       
   135 	// find end frame
       
   136 	TInt endFrame = 0;
       
   137 	while((endFrame<count) && (time_microseconds <= now_microseconds))
       
   138 		{
       
   139 		// work out timing
       
   140 		time_microseconds += iFrames[endFrame]->iFrameInfo.iDelay.Int64();
       
   141 		endFrame++;
       
   142 		}
       
   143 
       
   144 	TBool drawError = EFalse;
       
   145 	// work out visible regions
       
   146 	for(TInt i = 0; (i < endFrame) && !drawError; i++)
       
   147 		{
       
   148 		const CFrame* frame = iFrames[i];
       
   149 		const TRect frameRect(frame->iFrameInfo.iFrameCoordsInPixels);
       
   150  		frame->iVisibleRegion.Clear();
       
   151 
       
   152  		if((i == (endFrame - 1)) || frame->iFrameInfo.iFlags & TFrameInfo::ELeaveInPlace)	// ELeave - Enum TFrameInfo::ELeaveInPlace triggers leavescan
       
   153  			{
       
   154  			frame->iVisibleRegion.AddRect(frameRect);
       
   155  			drawError = frame->iVisibleRegion.CheckError();
       
   156  			}
       
   157  		else
       
   158    			{
       
   159    			if(frame->iFrameInfo.iFlags & TFrameInfo::ERestoreToBackground) 
       
   160  				{
       
   161  				for(TInt j = 0; j <= i; j++)
       
   162  					{
       
   163  					iFrames[j]->iVisibleRegion.SubRect(frameRect);
       
   164  					// coverity[unchecked_value]
       
   165  					drawError |= iFrames[j]->iVisibleRegion.CheckError();
       
   166  					}
       
   167  				}
       
   168  			else if(!(frame->iFrameInfo.iFlags & TFrameInfo::ERestoreToPrevious))  // if no disposal method is set, treat it as leave in place
       
   169  				{
       
   170  				frame->iVisibleRegion.AddRect(frameRect);
       
   171  				drawError = frame->iVisibleRegion.CheckError();
       
   172  				}
       
   173    			}
       
   174 		}
       
   175 
       
   176 	//draw each of the visible sub frames
       
   177 	for(TInt i = 0; (i < endFrame) && !drawError; i++)
       
   178 		{
       
   179 		const CFrame* frame = iFrames[i];
       
   180 		if(frame->iBitmap)
       
   181 			{
       
   182 			const TRegionFix<1> bitmapRegion(frame->iFrameInfo.iFrameCoordsInPixels);
       
   183 			frame->iVisibleRegion.Intersect(bitmapRegion);
       
   184 			frame->iVisibleRegion.Tidy();
       
   185 			if(frame->iVisibleRegion.CheckError())
       
   186 				{
       
   187 				drawError = ETrue;
       
   188 				break;
       
   189 				}
       
   190 			else
       
   191 				{
       
   192 				const TInt clipCount = frame->iVisibleRegion.Count();
       
   193  				for(TInt j = 0; j < clipCount; j++)
       
   194 					{
       
   195  					TRect frameRect = frame->iVisibleRegion.RectangleList()[j];
       
   196  					TRect clipRect(frameRect);
       
   197  					clipRect.Move(aRect.iTl);
       
   198  					clipRect.Intersection(aRect);
       
   199 
       
   200  					frameRect.Move(aRect.iTl);
       
   201  					frameRect.Intersection(aRect);
       
   202  					frameRect.Move(-aRect.iTl);
       
   203  					frameRect.Move(-frame->iFrameInfo.iFrameCoordsInPixels.iTl);
       
   204 
       
   205 					if(!clipRect.IsEmpty() && !frameRect.IsEmpty())
       
   206 						{
       
   207 						iContext->DrawBitmap(aGc,clipRect.iTl, frame->iBitmap, frameRect, frame->iMask);
       
   208 						}
       
   209 					}
       
   210 				}
       
   211 			}
       
   212 		}
       
   213 
       
   214 	if(0 <= buf.Find(TUid::Uid(TWsGraphicFrameRate::ETypeId)))
       
   215 		{
       
   216 		iContext->DrawFrameRate(aGc,aRect,iFps);
       
   217 		}
       
   218 	iFps.Sample();
       
   219 	
       
   220 	if(anim.IsPlaying(iContext->Now(aGc),iAnimationLength))
       
   221 		{
       
   222 		iContext->ScheduleAnimation(aGc, aRect,(time_microseconds - now_microseconds));
       
   223 		}
       
   224 	else if(drawError)
       
   225  		{
       
   226  		iContext->ScheduleAnimation(aGc, aRect,now_microseconds + 1000000); // retry in 1 second
       
   227  		}
       
   228  
       
   229 	iContext->Pop(aGc);
       
   230 	}
       
   231 
       
   232 void CWsGraphicDrawerBitmapAnimation::HandleMessage(const TDesC8& /*aData*/)
       
   233 	{
       
   234 	}
       
   235