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