diff -r bf7481649c98 -r 7f25ef56562d windowing/windowserver/tauto/tcrpanim.cpp --- a/windowing/windowserver/tauto/tcrpanim.cpp Fri Jun 11 14:58:47 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1464 +0,0 @@ -// Copyright (c) 2007-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: -// Implements CTCrpAnim -// Test CRP animations & their interaction with overlapping transparent/non-transparent windows -// & wserv's underlying redraw-store strategies -// -// - -/** - @file - @test - @internalComponent - Internal Symbian test code -*/ - -#include -#include "tcrpanim.h" - -// RUN_SAMPLE_ON_LEFT allows the demo animation to run in the left-hand window during testing. -// Used for demonstration purposes only -#define RUN_SAMPLE_ON_LEFT - -namespace //anonymous local scope - { - const TInt KAnimationFrameDelayTime = 50000; // delay in microseconds between frames - const TInt KShortDelayLoop = 2*KAnimationFrameDelayTime; // delay time in microseconds used in test cases - const TInt KAnimationTotalFrames = 40; // total number of frames in a CWsGraphicBitmapAnimation - const TInt KAnimDimension = 40; // animation width/height. We're enforcing a square animation here - const TInt KFrameMissedAnimationsThreshold = 10; // maximum number of missed frame steps allowed - const TInt KAnimationTearWidthThreshold = 4; // maximum columns permitted between a tear - const TInt KMinGoodFrameThreshold = 30; // percentage threshold for number of good frames detected in a test - const TInt KMaxXY = 200; // arbitrary maximum size of square used to invalidate a window - const TInt KMaxRepeatDraw = 2; // arbitrary value for DrawLine calls during a Draw - TUid KUidTestAnimation2 = {0xBAADF00D}; // unique id. for CWsGraphicBitmapAnimation object - const TUint32 KWhitePixels = 0xFFFFFFFF; // 32-bit mask value for rgb white - const TUint32 KBlackPixels = 0x00000000; // 32-bit value for rgb black - const TPoint KPointZero(0,0); // initial point used for animation creation & manipulation (currently 0,0) - const TPoint KPointOffsite(1000,1000); // point used to draw off-screen - const TDisplayMode KTestDisplayMode = EColor16MU; // display mode used for testing - const TInt KFrameStepCalculation = Max(1, KAnimDimension/Max(1, KAnimationTotalFrames)); // determine framestep size in columns - - enum TColorDetected - { - ECantTell=0, - EDetRed=1, - EDetGreen=2, - EDetBlue=4, - EDetBlack=0x10, - EDetGrey=0x20, - EDetWhite=0x40 - }; - - class CCrpAnim; - class CAnimRedrawWindow : public CTWin - { - public: - CAnimRedrawWindow(CCrpAnim *aAnimWindow, TBool aIsBase); - ~CAnimRedrawWindow(); - void Draw(); - private: - CCrpAnim *iAnimWindow; - TBool iIsBase; - }; - - class CCrpAnim : public CBase - { - friend class CAnimRedrawWindow; - public: - enum TWinType - { - ERedraw, - EBlank, // note: not currently used in tcrpanim tests - EBackedUp // note: not currently used in tcrpanim tests - }; - public: - CCrpAnim(TBool aIsBase, TWinType aWinType); - ~CCrpAnim(); - enum - { - ENoTransparency=0x100 - }; - void ConstructL(const TPoint &aPos, const TSize &aSize,const TInt aAlphaValue=ENoTransparency); - void DoDraw(TBool aBlankIt); - inline void DoDraw(); - void DoDrawEllipse(); - inline TSize Size() {return iCtWin->Size();}; - inline RWindowBase* BaseWin() const {return iCtWin->BaseWin();}; - inline RWindow* Window() const {return STATIC_CAST(RWindow*, iCtWin->BaseWin());}; - inline CTBaseWin* CtBaseWin() {return iCtWin;}; - inline void Invalidate() {CTUser::Splat(TheClient, TRect(iCtWin->Position(), iCtWin->Size()), KRgbGray);}; - void Invalidate(const TRect &aRect); - static void SetEllipseDrawMode(CGraphicsContext::TDrawMode aEllipseDrawMode); - void InvalidateAndRedraw(TBool aUseBlankItMember,TBool aBlankIt,TBool aUseRWindowInvalidate,TRect* aRect=NULL); - - //A bit of an animation interface... - //I have written this interface to be amenable to playing multiple animations, - //which I think needs testing, - //but the underlying implementation assumes one animation at present. - //Your mission, should you choose to accept it, .... - - void SetPosAnimation(const TUid& aUid, const TRect& aRect); - TRect* GetPosAnimation(const TUid& aUid); - TWsGraphicAnimation* SetAnimation(TUid); - TWsGraphicAnimation* GetAnimation(TUid); - TBool RemoveAnimation(TUid); - inline void SetBlankIt(TBool aNewVal) {iBlankIt = aNewVal;}; - inline void SetRepeatDrawMax(TInt aVal) {iRepeatDrawMax = aVal;}; - protected: - static void Draw(CBitmapContext *aGc, const TSize &aSize, TBool aIsBase,const TRect &aRect, TBool aBlankIt,TInt aRepeat, TInt aAlphaValue); - static void DrawEllipse(CBitmapContext *aGc, const TRect &aRect, TInt aAlphaValue); - CTBaseWin *iCtWin; - TWinType iWinType; - TBool iIsBase; - TBool iBlankIt; - TRect iRect; - TInt iRepeatDrawMax; - static CGraphicsContext::TDrawMode iEllipseDrawMode; - TUid iAnimUid; - TWsGraphicAnimation iAnimData; - TRect iAnimPos; - TInt iAlphaValue; - }; - -/* Using this time delay class in order to allow animations to play in our draw. - User::Wait does not allow the draw to occur (aparrently) - Note when using this time-delay class: because other active objects can perform part of their - processing whilst we wait, wrapping calls to this in __UHEAP_MARK / __UHEAP_MARKEND - is likely to fail. The data providers and animators are a major cause of this. -*/ - class CActiveWait : public CActive - { - public: - static CActiveWait* NewL(); - ~CActiveWait(); - void Wait(TInt aDelay); - // From CActive: - void RunL(); - void DoCancel(); - TInt RunError(TInt aError); - protected: - CActiveWait(); - void ConstructL(); - protected: - RTimer iTimer; - TTime iFromTime; - }; - - CActiveWait* CActiveWait::NewL() - { - CActiveWait* self = new (ELeave) CActiveWait; - CleanupStack::PushL(self); - self->ConstructL(); - CleanupStack::Pop(self); - return self; - } - - void CActiveWait::ConstructL() - { - User::LeaveIfError(iTimer.CreateLocal()); - CActiveScheduler::Add(this); - } - - CActiveWait::CActiveWait() : CActive(EPriorityNormal) - { - iFromTime.HomeTime(); - } - - CActiveWait::~CActiveWait() - { - Cancel(); - iTimer.Close(); - } - - void CActiveWait::DoCancel() - { - iTimer.Cancel(); - CActiveScheduler::Stop(); - } - - void CActiveWait::RunL() - { - CActiveScheduler::Stop(); - } - - TInt CActiveWait::RunError(TInt aError) - { - return aError; // exists so a break point can be placed on it. - } - -/* Note when using this : because other active objects can perform part of their - processing whilst we wait, wrapping calls to this in __UHEAP_MARK / __UHEAP_MARKEND - is likely to fail. The data providers and animators are a major cause of this. -*/ - void CActiveWait::Wait(TInt aDelay) - { - iTimer.After(iStatus, aDelay); - SetActive(); - CActiveScheduler::Start(); - } - CGraphicsContext::TDrawMode CCrpAnim::iEllipseDrawMode; - -// - } //end anonymous local scope -// - -/** This fn allocates an animation frame of the specified dimensions. - Not tested outside the current limited parameter set (16/2/2007). - Note the use of 32-bit integers for pixel/colour values. Using display mode lower than 24bpp may not produce correct results - My attempt to write animation generating code that avoids CIclLoader and Decoder class. - @param aDelayUs the display time for the frame - @param aImageType Colour format for colour plane. 24MA currently not flagged correctly I expect. - @param aMaskType Format for mask. ENone for no mask. - @param aImageSize Width/height of bitmap area - @param aImageOffset Optional offset for bitmap area - @param aTotalSize Optional width/height of whole animation (I think) - @return CFrame filled in with allocated bitmaps. The get methods for the bitmaps return const type. -**/ -static CWsGraphicBitmapAnimation::CFrame* NewFrameLC(TInt aDelayUs,TDisplayMode aImageType,TDisplayMode aMaskType,const TSize& aImageSize,const TPoint& aImageOffset=KPointZero,const TSize& aTotalSize=TSize(0,0)) - { - TFrameInfo info; - info.iFrameCoordsInPixels = TRect(aImageOffset,aImageSize); - info.iFrameSizeInTwips = aImageSize; //this is zero in the gif loader - info.iDelay = TTimeIntervalMicroSeconds(aDelayUs); - info.iFlags = TFrameInfo::EColor|TFrameInfo::ELeaveInPlace|TFrameInfo::EUsesFrameSizeInPixels; - if (aMaskType != ENone) - { - info.iFlags|=TFrameInfo::ETransparencyPossible; - } - if ((aTotalSize.iHeight > 0) && (aTotalSize.iWidth > 0)) - { - // restrict the size of the frame to specified size of the animation - info.iOverallSizeInPixels = aTotalSize; - } - else - { - // assign the size of the frame to the size of the entire bitmap area - info.iOverallSizeInPixels = info.iFrameCoordsInPixels.iBr.AsSize(); - } - info.iFrameDisplayMode = aImageType; - info.iBackgroundColor = KRgbGreen; - - CWsGraphicBitmapAnimation::CFrame* frame = CWsGraphicBitmapAnimation::CFrame::NewL(); - CleanupStack::PushL(frame); - frame->SetFrameInfo(info); - CFbsBitmap* bitmap = new(ELeave) CFbsBitmap; - frame->SetBitmap(bitmap); //takes ownership - TSize frameInfoSize = info.iFrameCoordsInPixels.Size(); - User::LeaveIfError(bitmap->Create(frameInfoSize, aImageType)); - if((TFrameInfo::EAlphaChannel|TFrameInfo::ETransparencyPossible) & info.iFlags) - { - CFbsBitmap* mask = new(ELeave) CFbsBitmap; - frame->SetMask(mask); //takes ownership - User::LeaveIfError(mask->Create(frameInfoSize, aMaskType)); - } - return frame; - } - -// -// function called back by TCleanupItem frameListCleanup from within CreateAnimFramesL(..) method -// -void CleanupFrameList(TAny* aPtr) - { - RPointerArray* ptrArray = STATIC_CAST(RPointerArray*, aPtr); - ptrArray->ResetAndDestroy(); - ptrArray->Close(); - } - -/** Helper function for making animation frames. - //Called from CreateAnimL(...) - @param aDelayUs the delay between frames - @param aNumFrames number of frames (approx - image width is a factor) - @param aImageType colour format of colour data. This may not work properly for non-32-bit, but I haven't fully understood TBitmapUtil documentation. - @param aMaskType format for mask - ENone for no mask. - @param aImageSize width/height of animation - @param aBgCol background colour for image non-masked areas. Masked areas are black. - @param aFgCol foreground colour of animating area - @param aFrames frames that the animation is constructed from -**/ -static void CreateAnimFramesL(TInt aDelayUs,TInt aNumFrames,TDisplayMode aImageType,TDisplayMode aMaskType,TSize aImageSize,TRgb aBgCol,TRgb aFgCol, RPointerArray& aFrames) - { - const TInt animWH = aImageSize.iWidth; - const TInt animStep = Max(1,animWH/Max(1,aNumFrames)); //note this intentionally rounds down to avoid overflows - for (TInt ii = 0 ; ii < animWH ; ii += animStep) - { - CWsGraphicBitmapAnimation::CFrame* frame = NewFrameLC(aDelayUs,aImageType,aMaskType,aImageSize,KPointZero,aImageSize); - aFrames.AppendL(frame); - CleanupStack::Pop(frame); - TBitmapUtil utilMask(CONST_CAST(CFbsBitmap*, frame->Mask())); - TBitmapUtil utilCol(CONST_CAST(CFbsBitmap*, frame->Bitmap())); - utilCol.Begin(KPointZero); - - // cycle through the frame's actual bitmap & assign each pixel a value identical to the specified colours - TUint32 colback=aBgCol.Internal(); - TUint32 colfront=aFgCol.Internal(); - TInt row = KErrNone; - TInt col = KErrNone; - for (row = 0 ; row < aImageSize.iHeight ; row++) - { - utilCol.SetPos(TPoint(0, row)); - for (col = 0 ; col < aImageSize.iWidth ; col++) - { - utilCol.SetPixel(colback); - utilCol.IncXPos(); - } - utilCol.SetPos(TPoint(ii, row)); - for (col = 0 ; col < animStep ; col++) //Note I rely on intentional rounding down here! - { - utilCol.SetPixel(colfront); - utilCol.IncXPos(); - } - } - - if (aMaskType) - { - // cycle through each pixel of the frame's mask & assign a default pixel a colour value - utilMask.Begin(KPointZero); - for (row = 0 ; row < aImageSize.iHeight ; row++) - { - utilMask.SetPos(TPoint(0,row)); - for (col = 0 ; col < aImageSize.iWidth ; col++) - { - utilMask.SetPixel(KWhitePixels); - utilMask.IncXPos(); - } - } - - const TInt maxmaskWidth = Min(8,Max(animWH/3,2)); - - //cut the corners off the mask - for (row = 0 ; row < maxmaskWidth ; row++) - { - TInt currentX = maxmaskWidth - row; - TInt xPos = KErrNone; - - utilCol.SetPos(TPoint(0,row)); - utilMask.SetPos(TPoint(0,row)); - for(xPos = currentX ; xPos >= 0 ; xPos--) - { - utilCol.SetPixel(KBlackPixels); - utilCol.IncXPos(); - utilMask.SetPixel(KBlackPixels); - utilMask.IncXPos(); - } - - utilCol.SetPos(TPoint(animWH - 1, row)); - utilMask.SetPos(TPoint(animWH - 1, row)); - for(xPos = currentX ; xPos >= 0 ; xPos--) - { - utilCol.SetPixel(KBlackPixels); - utilCol.DecXPos(); - utilMask.SetPixel(KBlackPixels); - utilMask.DecXPos(); - } - - utilCol.SetPos(TPoint(0, animWH - 1 - row)); - utilMask.SetPos(TPoint(0, animWH - 1 - row)); - for(xPos = currentX ; xPos >= 0 ; xPos--) - { - utilCol.SetPixel(KBlackPixels); - utilCol.IncXPos(); - utilMask.SetPixel(KBlackPixels); - utilMask.IncXPos(); - } - - utilCol.SetPos(TPoint(animWH - 1, animWH - 1 - row)); - utilMask.SetPos(TPoint(animWH - 1, animWH - 1 - row)); - for(xPos = currentX ; xPos >= 0 ; xPos--) - { - utilCol.SetPixel(KBlackPixels); - utilCol.DecXPos(); - utilMask.SetPixel(KBlackPixels); - utilMask.DecXPos(); - } - } - utilMask.End(); - } - utilCol.End(); - } - } - -/** My attempt to write animation generating code that avoids CIclLoader and Decoder class. - //It is better if this test class used it's own generated animation - //rather than relying on the GIF loader in order to reduce the cross-dependencies. - //The animation generated is a simple vertical line moving from left to right. - //To prove the masking, I cut the corners off. - @param aDelayUs the delay between frames - @param aNumFrames number of frames (approx - image width is a factor) - @param aImageType colour format of colour data. This may not work properly for non-32-bit, but I haven't fully understood TBitmapUtil documentation. - @param aMaskType format for mask - ENone for no mask. - @param aImageSize width/height of animation - @param aBgCol background colour for image non-masked areas. Masked areas are black. - @param aFgCol foreground colour of animating area - @param aTUid TUid assigned to animation - @return CWsGraphicBitmapAnimation allocated to represent the final animation -**/ -static CWsGraphicBitmapAnimation* CreateAnimL(TInt aDelayUs,TInt aNumFrames,TDisplayMode aImageType,TDisplayMode aMaskType,TSize aImageSize,TRgb aBgCol,TRgb aFgCol,TUid& aTUid) - { - RPointerArray frames; - TCleanupItem frameListCleanup(CleanupFrameList, &frames); - CleanupStack::PushL(frameListCleanup); - - CreateAnimFramesL(aDelayUs, aNumFrames, aImageType, aMaskType, aImageSize,aBgCol, aFgCol, frames); - - CWsGraphicBitmapAnimation* anim = CWsGraphicBitmapAnimation::NewL(aTUid,frames.Array()); - CleanupStack::PopAndDestroy(&frames); - return anim; - } - -// -// Describes the pure colour of the RGB value. yellow/magenta/cyan set 2 bits. White/grey is seperately flagged. -// This method attempts to determine the strongest primary colour present in any given pixel. -// Note: The algorithm used is known to work for the current test cases only but requires careful review -// for anyone making additional changes to tcrpanim. Given time, improved algorithm should be developed -// to replace the current one -// -TUint PredominantColour(TUint aCol) - { //I don't like all these ifs, but I don't see an easy alternative - //Possibly a bit look-up of the deltas from average would work - //(ignoring the bottom 5 bits =32, not 0x30=48. Ignore bottom 4 bits and accept 3-same answers, or divide by delta?) - // - const TInt Kdelta=0x30; - TInt red=(aCol&0x00ff0000)>>16; - TInt green=(aCol&0x0000ff00)>>8; - TInt blue=(aCol&0x000000ff); - TInt ave=((red+green+blue)*(65536/3))>>16; - TBool rOverA=(red>ave); - TBool gOverA=(green>ave); - TBool bOverA=(blue>ave); - TInt numOverAve=(rOverA?1:0)+(gOverA?1:0)+(bOverA?1:0); - - if (numOverAve==1) - { - if (rOverA) - { - if (red>ave+Kdelta) - { - if ((green-blue)>-Kdelta && (green-blue)ave-Kdelta && blue>ave-Kdelta) - { - if (ave>256-Kdelta) - return EDetWhite; - else - return EDetGrey; - } - } - } - } - - if (gOverA) - { - if (green>ave+Kdelta) - { - if ((blue-red)>-Kdelta && (blue-red)ave-Kdelta && blue>ave-Kdelta) - if (ave>256-Kdelta) - return EDetWhite; - else - return EDetGrey; - } - } - } - - if (bOverA) - { - if (blue>ave+Kdelta) - { - if ((green-red)>-Kdelta && (green-red)ave-Kdelta && green>ave-Kdelta) - if (ave>256-Kdelta) - return EDetWhite; - else - return EDetGrey; - } - } - } - } - else - { - if (!rOverA) - if (red-Kdelta && (green-blue)256-Kdelta) - return EDetWhite; - else - { - if (blue-Kdelta && (blue-red)256-Kdelta) - return EDetWhite; - else - { - if (blue-Kdelta && (green-red)256-Kdelta) - return EDetWhite; - else - { - if (rediGroup->WinTreeNode()->SetOrdinalPosition(0); - iRedrawWin=new(ELeave) CCrpAnim(EFalse, CCrpAnim::ERedraw); - iBaseWin=new(ELeave) CCrpAnim(EFalse, CCrpAnim::ERedraw); - iOverWin=new(ELeave) CCrpAnim(EFalse, CCrpAnim::ERedraw); - - TSize screenSize=TheClient->iGroup->Size(); - TInt winWidth=(screenSize.iWidth/3)-10; - TInt winHeight=screenSize.iHeight-10; - TSize windowSize(winWidth,winHeight); - - iRedrawWin->ConstructL(TPoint(screenSize.iWidth/3*2+5,5), windowSize); - iBaseWin->ConstructL(TPoint(screenSize.iWidth/3+5,5), windowSize); - - //Create a transparent window that exactly overlaps the test window - //If transparency is not supported the leave causes the window to be destroyed and set to NULL. - //There is a test for transparency supported, but that simply creates a temp window to test anyway... - - //Note that when I originally wrote this test to fix PDEF101991, it generated white areas that I detected. - //However, if this transparent window used for extended tests is created over the test window, - //that somehow stops the white fill from occurring. - //The fault still occurs, but the previous screen contents are left behind. - //So now this window is created at an off-screen location. - TRAPD(err, iOverWin->ConstructL(KPointOffsite, windowSize, 0x80); iOverWin->SetBlankIt(ETrue); iOverWin->SetRepeatDrawMax(KMaxRepeatDraw);); - if (err) - { - delete iOverWin; - iOverWin = NULL; - } - - iTestWin = iRedrawWin; - iTestWin->SetRepeatDrawMax(KMaxRepeatDraw); - iBaseWin->SetRepeatDrawMax(KMaxRepeatDraw); - - // create animation object & share it with everyone - iAnim = CreateAnimL(KAnimationFrameDelayTime,KAnimationTotalFrames,KTestDisplayMode,EGray256,TSize(KAnimDimension, KAnimDimension),KRgbBlue,KRgbRed,KUidTestAnimation2); - if (!iAnim) - { - User::Leave(KErrNoMemory); - } - iAnim->ShareGlobally(); - - // calculate minimum length of the red line - const TInt maxmaskHeight = Min(8, Max(KAnimDimension/3,2)); // note this calculation mimics that for the size of the corners cut from the mask in CreateAnimL above - iMinimumCalcRedLine = KAnimDimension - maxmaskHeight*2; // the height of the image minus the two cut corners - - // create the timer object - iWaiter = CActiveWait::NewL(); - - // create screen bitmap object & scanline buffer - iScreenBitmap = new (ELeave) CFbsBitmap; - User::LeaveIfError(iScreenBitmap->Create(TSize(KAnimDimension, KAnimDimension), KTestDisplayMode)); - TInt bufLength = iScreenBitmap->ScanLineLength(windowSize.iHeight, KTestDisplayMode); - iScanlineBuf = HBufC8::NewL(bufLength); - - #ifdef RUN_SAMPLE_ON_LEFT - { - // play animation on iBaseWin window - iBaseWin->SetAnimation(KUidTestAnimation2)->Play(ETrue); - TSize subsize1 = iTestWin->BaseWin()->Size(); - TRect subposition1(subsize1); - CalcCentredAnimPosition(subposition1, subsize1); - iBaseWin->SetPosAnimation(KUidTestAnimation2, subposition1); - iBaseWin->InvalidateAndRedraw(ETrue,EFalse,ETrue); - } - #endif - } - -CTCrpAnim::~CTCrpAnim() - { - delete iRedrawWin; - delete iBaseWin; - delete iOverWin; - if (iAnim) - { - // destroy the animation object - iAnim->UnShareGlobally(); - iAnim->Destroy(); - delete iAnim; - iAnim = NULL; - } - if (iWaiter) - { - // destroy the timer object - delete iWaiter; - iWaiter = NULL; - } - if (iScreenBitmap) - { - // destroy the screen capture of the animation - delete iScreenBitmap; - iScreenBitmap = NULL; - } - if (iScanlineBuf) - { - // destroy the scanline buffer - delete iScanlineBuf; - iScanlineBuf = NULL; - } - User::After(200000); - } - -// -// This method checks the animation contained in the aAnimWin window has progressed. That is -// that it's drawn a sufficient number of concurrent frames to screen & the animation is -// drawn properly to screen -// returns a Bool identifying whether the animation is considered 'good' or not -// -void CTCrpAnim::CheckAnimProgressedL(CAnonAnimWindow* aAnimWin, TInt aAdditionalFrameCount, TBool aCaptureFrameResult) - { - TBool goodAnimation = ETrue; - - // retrieve the rect from the screen's bitmap that contains the animation - CWsScreenDevice* screen = TheClient->iScreen; - TRect animPos = *aAnimWin->GetPosAnimation(KUidTestAnimation2); - CTBaseWin* bWin = aAnimWin->CtBaseWin(); - animPos.Move(bWin->Position()); - User::LeaveIfError(screen->CopyScreenToBitmap(iScreenBitmap, animPos)); - - TInt frameNum = DetermineApproxFrameNum(iScreenBitmap, aCaptureFrameResult); // determines the frame Number & checks quality of animation (no tearing, etc) - TBool frameIdentified=(frameNum>=0); - - if (aCaptureFrameResult) - { - if (frameIdentified) - { - if (iPreviousFrameNum != KErrNotFound) - { - if (iPreviousFrameNum < frameNum) - { - TInt frameStep = KFrameStepCalculation * aAdditionalFrameCount; - iPreviousFrameNum += frameStep; // move to our *expected* framenumber - if (frameNum > iPreviousFrameNum) - { - // the frame number is ahead of it's expected position - // This suggests we've possibly missed animating a frame in wserv - // or test code isn't getting a chance to execute as crp animations taking all cpu cycles - // If its significantly outside norms, we log the fact (as a performance metric) - TInt performance = ((frameNum - iPreviousFrameNum) / frameStep); - if (performance > KFrameMissedAnimationsThreshold) - { - iFrameStatus.iFrameSkipped++; - goodAnimation = EFalse; - } - } - // else we're animating above an acceptable threshold - } - else if (iPreviousFrameNum == frameNum) // potentially not animating anymore - { - iFrameStatus.iFrameIdentical++; - goodAnimation = EFalse; - } - // else animation is progressing fine - } - // ignore iPreviousFrameNum == KErrNotFound - } - else - { - goodAnimation = EFalse; // couldn't id the red line - } - - if (goodAnimation) - { - iFrameStatus.iFrameOK++; - } - } - // else we were only interested in calculating the frameNum - iPreviousFrameNum = frameNum; - } - -// -// method to estimate the framenumber based on the location of the thin, red line. -// Also checks whether tearing of the animation has occured or the animation -// is only partially drawn. -// These are known issues with wserv animation performance & so we give some allowance for error -// -TInt CTCrpAnim::DetermineApproxFrameNum(CFbsBitmap* aBitmap, TBool aCaptureFrameResult) - { - TInt colFirstTear = KErrNotFound; // column id'ing the first tear in the vertical line - TPtr8 des = iScanlineBuf->Des(); // ptr to the scanline buffer - - // locate the thin, red line in the bitmap - for (TInt xPos = 0 ; xPos < aBitmap->SizeInPixels().iWidth ; xPos++) - { - aBitmap->GetVerticalScanLine(des, xPos, EColor16MA); - TUint32* pixel = (TUint32*) des.Ptr(); - TInt colour = KErrNone; - - for (TInt ii = 0 ; ii < aBitmap->SizeInPixels().iHeight ; ii++) - { - colour = PredominantColour(*pixel); - if (colour & EDetRed) - { - if (colFirstTear < 0) - { - // check the length of the red line is a good length - pixel += (iMinimumCalcRedLine - 1); // minus the one pixel to position on last pixel in red line - colour = PredominantColour(*pixel); - if (colour & EDetRed) - { - // good line - return xPos; - } - else // we've detected first part of a torn line - { - colFirstTear = xPos; - } - } - else - { - // located second part of torn line - if ((xPos - colFirstTear) > KAnimationTearWidthThreshold) - { - if (aCaptureFrameResult) - { - iFrameStatus.iFrameTearing++; - } - xPos = KErrNotFound; - } - return xPos; - } - break; - } - pixel++; - } - } - if (aCaptureFrameResult) - { - if (colFirstTear < 0) - { - iFrameStatus.iFrameEmpty++; // we never located any red line at all - } - else - { - iFrameStatus.iFramePartial++; // we only located a single, small part of the red line - } - } - return KErrNotFound; - } - -/** This internal loop tests that the animation and the foreground interact correctly - The primary test is that the outline of the animation - intersects the lines drawn on the foreground correctly, compared to a reference version. - The iBaseWin is already showing this reference anim. - If the animation is not drawn, or the foreground is wiped, then this test will fail. -**/ -void CTCrpAnim::TestSpriteLoopL(TBool aAnimForeground,TBool aDrawForeground) - { - _LIT(KForegroundInfo,"TestSpriteLoop animForeground [%d] drawForeground [%d]"); - INFO_PRINTF3(KForegroundInfo, aAnimForeground, aDrawForeground); - - if (!iOverWin && (aAnimForeground || aDrawForeground)) - { - User::Leave(KErrGeneral); // unable to run this test without iOverWin - } - - ResetFrameCounters(); - iTestWin->RemoveAnimation(KUidTestAnimation2); - iTestWin->SetBlankIt(ETrue); - if (iOverWin) - { - iOverWin->RemoveAnimation(KUidTestAnimation2); - iOverWin->SetBlankIt(ETrue); - } - - // determine which window holds the animation, & which will be invalidated with progressively larger rects - CCrpAnim* animWin=aAnimForeground?iOverWin:iTestWin; - CCrpAnim* paintWin=aDrawForeground?iOverWin:iTestWin; - paintWin->SetBlankIt(EFalse); - - // set & play the animation on the specified window (animWin) - animWin->SetAnimation(KUidTestAnimation2)->Play(ETrue); - TSize subsize1 = paintWin->BaseWin()->Size(); - TRect subposition1(subsize1); - CalcCentredAnimPosition(subposition1, subsize1); - animWin->SetPosAnimation(KUidTestAnimation2, subposition1); - - #ifdef RUN_SAMPLE_ON_LEFT - // play the demo animation in the left-hand window also - iBaseWin->InvalidateAndRedraw(ETrue, EFalse, ETrue); - #endif - - iTestWin->InvalidateAndRedraw(ETrue,EFalse,ETrue); - if (iOverWin) - { - iOverWin->InvalidateAndRedraw(ETrue,EFalse,ETrue); - } - - // invalidate increasingly larger squares on paintWin - // note, some fully overlap the animation, some partially overlap, and some don't overlap at all - TInt invalidateWaitTime=KAnimationFrameDelayTime*3/4; // microseconds - TInt temp = KErrNotFound; - for (TInt step=30;stepInvalidateAndRedraw(ETrue,EFalse,ETrue,&invalidRect); - - // calculate any additional frames that may be drawn by above. Note intentionally ignore frame result - temp = iPreviousFrameNum; - CheckAnimProgressedL(animWin, 1, EFalse); - - //new defect DEF101896: Test runs faster with this line removed, but there is evident tearing - iWaiter->Wait(invalidateWaitTime); //DEF101896 search string: //interrupt_foreground_draw - - if (temp == iPreviousFrameNum) - { - // give wserv more time to animate the frame - iWaiter->Wait(invalidateWaitTime); - } - CheckAnimProgressedL(animWin, 1); // calculate the frame drawn. Capture frame result - } - } - } - - // determine whether the animation was successful (ie: enough Good frames were detected) or not - // Note KMinGoodFrameThreshold is essentially an arbitrary number. This can be adjusted to accommodate - // performance requirements as needed - temp = LogResults(); - TInt quality = 100*iFrameStatus.iFrameOK/temp; - TEST(quality > KMinGoodFrameThreshold); - - ResetFrameCounters(); - iWaiter->Cancel(); - iTestWin->RemoveAnimation(KUidTestAnimation2); - iTestWin->SetBlankIt(ETrue); - if (iOverWin) - { - iOverWin->RemoveAnimation(KUidTestAnimation2); - iOverWin->SetBlankIt(ETrue); - } - } - -// -// resets the frame trackers to intial values -// -void CTCrpAnim::ResetFrameCounters() - { - iPreviousFrameNum = KErrNotFound; - iFrameStatus.iFrameOK = 0; - iFrameStatus.iFramePartial = 0; - iFrameStatus.iFrameIdentical = 0; - iFrameStatus.iFrameEmpty = 0; - iFrameStatus.iFrameTearing = 0; - iFrameStatus.iFrameSkipped = 0; - } - -// -// Log the current frame results & return the total number of frame calculations -// -// Calculated : the total number of frame-checks run -// Good: the frame was successfully drawn to screen & within specified tolerances for tearing, expected position & colour -// Partial: the frame was only partially drawn to screen. Specifcally the animated red line was only partially drawn -// Identical: the frame was in the same position as the last frame -// Empty: no redline was detected at all in the frame -// Skipped: the position of the frame was beyond the expected position -// -// There is a dependency on the timing as to when the frame is animated hence tolerances are used to allow -// for this. -// -TInt CTCrpAnim::LogResults() - { - TInt result = iFrameStatus.iFrameOK + iFrameStatus.iFramePartial + iFrameStatus.iFrameIdentical + - iFrameStatus.iFrameEmpty + iFrameStatus.iFrameTearing + iFrameStatus.iFrameSkipped; - INFO_PRINTF4(_L("\tAnimation results: Calculated[%d], Good[%d], Partial[%d]"), result, iFrameStatus.iFrameOK, iFrameStatus.iFramePartial); - INFO_PRINTF5(_L("\tAnimation results: Identical[%d], Empty[%d], Tearing[%d], Skipped[%d]"), iFrameStatus.iFrameIdentical, iFrameStatus.iFrameEmpty, iFrameStatus.iFrameTearing, iFrameStatus.iFrameSkipped); - return result; - } - -/** This test tests the result of drawing an animation and main draw to two windows that overlap. - The two windows are placed in exactly the same location, so the result of splitting the drawing across them should be "identical". - Note that when the anim and the draw are on different screens the lines are seen merged over the anim. -**/ -void CTCrpAnim::TestOverlappingWindowsL() - { - if (!iOverWin) - { - INFO_PRINTF1(_L("- Test skipped - transparency not supported")); - return; - } - - // setup necessary params - // Note we place the overlapping transparent window (iOverWin) directly on top of the test window (iTestWin) - iOverWin->BaseWin()->SetPosition(iTestWin->BaseWin()->Position()); - - enum - { - EAllBackground=0, - EForegroundDraw=1, - EForegroundAnim=2, - EAllForeGround=3, - ECountModes, - EFirstMode=EAllBackground, - }; - - // test the various permutations of overlapping vs animated windows - for (TInt mode = EFirstMode ; mode < ECountModes ; mode++) - { - INFO_PRINTF2(_L("TestOverlappingWindowsL [%d]"), mode); - TestSpriteLoopL((mode&EForegroundAnim)!=0,(mode&EForegroundDraw)!=0); - } - } - -/** - This method demonstrates clipping of an animation running behind a transparent window. - No main window redraw takes place here. -**/ -void CTCrpAnim::DemoClippingWindowsL() - { - if (!iOverWin) - { - INFO_PRINTF1(_L("- Test skipped - transparency not supported")); - return; - } - - // setup test case params. Note we calculate three different positions for the overlapping window - RWindow* win = iTestWin->Window(); - - TPoint screenPos= win->Position(); - TSize screenSize = win->Size(); - TRect subposition1(screenSize); - CalcCentredAnimPosition(subposition1, screenSize); - - TPoint testPositions[]= - { - //first test: window clips corner of anim - TPoint(screenPos.iX+screenSize.iWidth/2-10,screenPos.iY+screenSize.iHeight/2-10), - //test: window clips all of anim - TPoint(screenPos.iX+screenSize.iWidth/3,screenPos.iY+screenSize.iHeight/3), - //test: window clips none of anim - TPoint(screenPos.iX+screenSize.iWidth*2/3,screenPos.iY+screenSize.iHeight*2/3), - }; - - // calculate roughly number of frames we expect to have drawn - TInt loopWaitTime = KShortDelayLoop; // time given to allow animation to progress (arbitrary number) - float expectedFrameCount = 1; - if (loopWaitTime > KAnimationFrameDelayTime) - { - expectedFrameCount = loopWaitTime/KAnimationFrameDelayTime; - } - - for (TInt ii = 0; ii < ((sizeof testPositions)/(sizeof testPositions[0])) ; ii++) - { - // initialise test windows to known state with no active animations - ResetFrameCounters(); - iTestWin->RemoveAnimation(KUidTestAnimation2); - iTestWin->SetBlankIt(EFalse); - iOverWin->SetBlankIt(ETrue); - iOverWin->RemoveAnimation(KUidTestAnimation2); - - // position animation windows - iTestWin->SetAnimation(KUidTestAnimation2)->Play(ETrue); - iTestWin->SetPosAnimation(KUidTestAnimation2, subposition1); - iOverWin->BaseWin()->SetPosition(testPositions[ii]); // positions the transparent overlapping window - - // redraw both test windows - iTestWin->InvalidateAndRedraw(ETrue,EFalse,ETrue); - iOverWin->InvalidateAndRedraw(ETrue,EFalse,ETrue); - - // run the animation for an arbitrary period - for (TInt loopit = 0 ; loopit < 20 ; loopit++) - { - iWaiter->Wait(loopWaitTime); - CheckAnimProgressedL(iTestWin,static_cast(expectedFrameCount)); // log the frame result - } - - // calculate & log frame results. Test an acceptable number of frames were successfully animated - TInt total = LogResults(); - TInt qA = 100*iFrameStatus.iFrameOK/total; - TEST(qA > KMinGoodFrameThreshold); - } - } - -/** In this version, the background window is updated in patches. - If the animation intersects the transparent window then the whole transparent window is redrawn. -**/ -void CTCrpAnim::TestClippingWindowsL() - { - if (!iOverWin) - { - INFO_PRINTF1(_L("- Test skipped - transparency not supported")); - return; - } - // setup test case params. Note we calculate three different positions for the overlapping window - RWindow* win = iTestWin->Window(); - TPoint screenPos= win->Position(); - TSize screenSize = win->Size(); - - TPoint testPositions[]= - { - //first test: window clips corner of anim - TPoint(screenPos.iX+screenSize.iWidth/2-10,screenPos.iY+screenSize.iHeight/2-10), - //test: window clips all of anim - TPoint(screenPos.iX+screenSize.iWidth/3,screenPos.iY+screenSize.iHeight/3), - //test: window clips none of anim - TPoint(screenPos.iX+screenSize.iWidth*2/3,screenPos.iY+screenSize.iHeight*2/3), - }; - - for (TInt loopIt = 0; loopIt < ((sizeof testPositions)/(sizeof testPositions[0])) ; loopIt++) - { - iOverWin->BaseWin()->SetPosition(testPositions[loopIt]); // position the overlapping window - TestSpriteLoopL(EFalse,EFalse); - } - } - -/** This just demonstrates that an animation plays - for about 1 second. -**/ -void CTCrpAnim::BasicCRPDemo() - { - // draw the animation in two positions - TSize subsize1 = iTestWin->BaseWin()->Size(); - TRect subposition1(subsize1); - CalcCentredAnimPosition(subposition1, subsize1); - - if (iOverWin) - { - iOverWin->BaseWin()->SetPosition(KPointOffsite); //way away! - iOverWin->InvalidateAndRedraw(EFalse,EFalse,ETrue); - } - - CCrpAnim *animWin= iTestWin; - animWin->SetAnimation(KUidTestAnimation2)->Play(ETrue); - animWin->SetPosAnimation(KUidTestAnimation2, subposition1); - iTestWin->InvalidateAndRedraw(ETrue,EFalse,ETrue); - iBaseWin->InvalidateAndRedraw(ETrue,EFalse,ETrue); - - // allow the animation to play for ~1 second. Purpose is to demonstrate animation to an observer - iWaiter->Wait(KShortDelayLoop); - - ResetFrameCounters(); - iWaiter->Cancel(); - iTestWin->RemoveAnimation(KUidTestAnimation2); - } - -/** -@SYMTestCaseID GRAPHICS-WSERV-CRP01-0001 - -@SYMDEF DEF100356 - -@SYMTestCaseDesc CRP animation test for redraw storing interrupting main draw - -@SYMTestPriority High - -@SYMTestStatus Implemented - -@SYMTestActions Creates a CRP animation and runs it on the server scheduler - while also running redraws of the window. - - With Redraw storing this has been known to cause problems - sharing and resetting the window iDisplayRegion. - This is evidenced by white areas. - - -@SYMTestExpectedResults - The LHS window shows what the animation should look like just animating, - while the RHS window demonstrates the simultanious animation and redraw. - No White patches should be in evidence, and no missing fragments of animation. - The TEST should detect white patches. -*/ -void CTCrpAnim::TestSpriteInterruptsForegroundL() - { - // setup test params - TSize subsize1(iTestWin->BaseWin()->Size()); - TRect subposition1(subsize1); - CalcCentredAnimPosition(subposition1, subsize1); - if (iOverWin) - { - iOverWin->BaseWin()->SetPosition(KPointOffsite); // ensure overlapping transparent window DOESN'T overlap the test window - } - - // execute test loop - TestSpriteLoopL(EFalse,EFalse); - } - -void CTCrpAnim::RunTestCaseL(TInt /*aCurTestCase*/) - { - _LIT(KTest1,"1: Basic CRP demo"); - _LIT(KTest2,"2: sprite anim interrupts foreground"); - _LIT(KTest3,"3: translucent windows"); - _LIT(KTest4,"4: CRP clipping windows"); - _LIT(KTest5,"5: CRP & redraw clipping windows"); - _LIT(KTest6,"6: CRP Invalidation"); - - ((CTCrpAnimStep*)iStep)->SetTestStepID(KUnknownSYMTestCaseIDName); - switch(++iTest->iState) - { - case 1: -/** -@SYMTestCaseID GRAPHICS-WSERV-CRP01-0002 -*/ - ((CTCrpAnimStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-CRP01-0002")); - iTest->LogSubTest(KTest1); - BasicCRPDemo(); - break; - case 2: - ((CTCrpAnimStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-CRP01-0001")); - iTest->LogSubTest(KTest2); - TestSpriteInterruptsForegroundL(); - break; - case 3: -/** -@SYMTestCaseID GRAPHICS-WSERV-CRP01-0003 -*/ - ((CTCrpAnimStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-CRP01-0003")); - iTest->LogSubTest(KTest3); - TestOverlappingWindowsL(); - break; - case 4: -/** -@SYMTestCaseID GRAPHICS-WSERV-CRP01-0004 -*/ - ((CTCrpAnimStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-CRP01-0004")); - iTest->LogSubTest(KTest4); - DemoClippingWindowsL(); - break; - case 5: -/** -@SYMTestCaseID GRAPHICS-WSERV-CRP01-0005 -*/ - ((CTCrpAnimStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-CRP01-0005")); - iTest->LogSubTest(KTest5); - TestClippingWindowsL(); - break; - case 6: -/** -@SYMTestCaseID GRAPHICS-WSERV-CRP01-0006 -*/ - ((CTCrpAnimStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-CRP01-0006")); - iTest->LogSubTest(KTest6); - //this testcase is removed, because invalidation is removed from CWsGraphicDrawer destructor (due to flickering) - break; - default: - ((CTCrpAnimStep*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName); - ((CTCrpAnimStep*)iStep)->CloseTMSGraphicsStep(); - TestComplete(); - } - ((CTCrpAnimStep*)iStep)->RecordTestResultL(); - } - -// -namespace //anonymous namespace - { -// - CAnimRedrawWindow::CAnimRedrawWindow(CCrpAnim *aAnimWindow, TBool aIsBase) : CTWin(), - iAnimWindow(aAnimWindow), - iIsBase(aIsBase) - { - } - - CAnimRedrawWindow::~CAnimRedrawWindow() - { - } - - void CAnimRedrawWindow::Draw() - { - CCrpAnim::Draw(Gc(),Size(),iIsBase,iAnimWindow->iRect,iAnimWindow->iBlankIt,iAnimWindow->iRepeatDrawMax,iAnimWindow->iAlphaValue); - if (iAnimWindow->iAnimUid!=TUid::Null()) - { - TheClient->Flush(); - Gc()->DrawWsGraphic(iAnimWindow->iAnimUid,iAnimWindow->iAnimPos,iAnimWindow->iAnimData.Pckg()); - TheClient->Flush(); - } - } - - // - - CCrpAnim::CCrpAnim(TBool aIsBase, TWinType aWinType) - : iWinType(aWinType), - iIsBase(aIsBase), - iBlankIt(EFalse), - iRepeatDrawMax(1), - iAnimUid(TUid::Null()), - iAlphaValue(ENoTransparency) - { - } - - CCrpAnim::~CCrpAnim() - { - delete iCtWin; - } - - void CCrpAnim::ConstructL(const TPoint &aPos, const TSize &aSize, TInt aAlphaValue) - { - TDisplayMode reqMode = EColor16MA; //for transparency we need 16ma or 16map mode - TDisplayMode *pReqMode=&reqMode; - switch(iWinType) - { - case ERedraw: - iCtWin = new(ELeave) CAnimRedrawWindow(this, iIsBase); - break; - case EBlank: - iCtWin = new(ELeave) CTBlankWindow(); - break; - case EBackedUp: - iCtWin = new(ELeave) CTBackedUpWin(EColor64K); - pReqMode = NULL; - break; - } - iCtWin->SetUpL(aPos, aSize, TheClient->iGroup, *TheClient->iGc, pReqMode, ETrue); - if (aAlphaValue != ENoTransparency) - { - User::LeaveIfError(Window()->SetTransparencyAlphaChannel()); - //the window itself should be completely transparent, the draw commands will use the alpha value - Window()->SetBackgroundColor(TRgb(0, 0, 0, 0)); - iAlphaValue = aAlphaValue; - } - } - - void CCrpAnim::SetEllipseDrawMode(CGraphicsContext::TDrawMode aEllipseDrawMode) - { - iEllipseDrawMode = aEllipseDrawMode; - } - - void CCrpAnim::DrawEllipse(CBitmapContext *aGc, const TRect &aRect, TInt aAlphaValue) - { - if(aAlphaValue != ENoTransparency) - { - aGc->SetBrushColor(TRgb(85,85,85, aAlphaValue)); - aGc->SetPenColor(TRgb(170,170,170, aAlphaValue)); - } - else - { - aGc->SetBrushColor(TRgb(85,85,85)); - aGc->SetPenColor(TRgb(170,170,170)); - } - aGc->SetDrawMode(iEllipseDrawMode); - aGc->SetBrushStyle(CGraphicsContext::ESolidBrush); - aGc->DrawEllipse(aRect); - } - - void CCrpAnim::Draw(CBitmapContext *aGc, const TSize &aSize, TBool aIsBase, const TRect &aRect, TBool aBlankIt,TInt aRepeat, TInt aAlphaValue) - { - static TInt sGrey=0; - sGrey+=3; - if (sGrey>0x40) - sGrey-=0x40; - sGrey=sGrey^0x20; - if(aAlphaValue != ENoTransparency) - { - aGc->SetBrushColor(TRgb(sGrey, sGrey, sGrey, aAlphaValue)); - aGc->SetPenColor(TRgb(KRgbGreen.Value(), aAlphaValue)); - } - else - { - aGc->SetBrushColor(TRgb::Gray256(sGrey)); - aGc->SetPenColor(KRgbGreen); - } - aGc->Clear(); - TInt xPos=aSize.iHeight,yPos=aSize.iWidth; - - // The test windows are created relative to screen size. The - // number of green lines generated needs to be tied into the - // window size to prevent green becoming the dominant colour - // when blended with the second animation, which would - // prevent the PredominantColour() algorithm from discovering - // the red line. - TInt yStep = aSize.iHeight/14; - TInt xStep = aSize.iWidth/6; - - //This paint is intentionally complex and slow so that the animation timer is likely to interrupt it. - if (!aBlankIt) - for (TInt nn = 0 ; nn < aRepeat ; nn++) - for(yPos=0 ; yPos < aSize.iHeight ; yPos += yStep) - for(xPos=0 ; xPos < aSize.iWidth ; xPos += xStep) - aGc->DrawLine(aRect.Center(),TPoint(xPos,yPos)); - if (aIsBase) - DrawEllipse(aGc, aRect, aAlphaValue); - } - - //This simple API may need replacing by a list and search if multiple anims are played together - TWsGraphicAnimation* CCrpAnim::SetAnimation(TUid aUid) - { //currently only have 1 animation - it gets replaced. It could get refiused - iAnimUid=aUid; - return &iAnimData; - } - - TWsGraphicAnimation* CCrpAnim::GetAnimation(TUid aUid) - { //currently only have 1 animation - if (iAnimUid==aUid) - return &iAnimData; - else - return NULL; - } - - void CCrpAnim::SetPosAnimation(const TUid& aUid, const TRect& aRect) - { //currently only have 1 animation - if (iAnimUid==aUid) - iAnimPos = aRect; - } - - TRect* CCrpAnim::GetPosAnimation(const TUid& aUid) - { //currently only have 1 animation - if (iAnimUid==aUid) - return &iAnimPos; - else - return NULL; - } - - TBool CCrpAnim::RemoveAnimation(TUid) - { - iAnimUid=TUid::Null(); - iAnimData.Stop(EFalse); - return ETrue; - } - - void CCrpAnim::DoDraw() - { - DoDraw(iBlankIt); - } - - inline void CCrpAnim::DoDraw(TBool aBlankIt) - { - __ASSERT_ALWAYS(iWinType!=EBlank,AutoPanic(EAutoPanicWindowType)); - iCtWin->Gc()->Activate(*Window()); - Draw(iCtWin->Gc(),Size(),iIsBase,iRect,aBlankIt,iRepeatDrawMax,iAlphaValue); - if (iAnimUid!=TUid::Null()) - iCtWin->Gc()->DrawWsGraphic(iAnimUid,iAnimPos,iAnimData.Pckg()); - iCtWin->Gc()->Deactivate(); - } - - void CCrpAnim::DoDrawEllipse() - { - __ASSERT_ALWAYS(iWinType!=EBlank,AutoPanic(EAutoPanicWindowType)); - iCtWin->Gc()->Activate(*Window()); - DrawEllipse(iCtWin->Gc(),iRect,iAlphaValue); - iCtWin->Gc()->Deactivate(); - } - - void CCrpAnim::InvalidateAndRedraw(TBool /*aUseBlankItMember*/,TBool /*aBlankIt*/,TBool aUseRWindowInvalidate,TRect* aRect) - { - RWindow& win = *Window(); - if (aRect) - { - if (aUseRWindowInvalidate) - win.Invalidate(*aRect); - else - Invalidate(*aRect); - } - else - { - if (aUseRWindowInvalidate) - win.Invalidate(); - else - Invalidate(); - } - if (aRect) - win.BeginRedraw(*aRect); - else - win.BeginRedraw(); - DoDraw(); - win.EndRedraw(); - TheClient->Flush(); - } - - void CCrpAnim::Invalidate(const TRect &aRect) - { - TRect rect(aRect); - rect.Move(iCtWin->Position()); - CTUser::Splat(TheClient,rect,TRgb::Gray256(0)); - } - -// - } //end anonymous namespace -// -__WS_CONSTRUCT_STEP__(CrpAnim)