os/graphics/windowing/windowserver/stdgraphic/BITMAPANIMATIONGRAPHICDRAWER.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200 (2014-06-10)
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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