diff -r 000000000000 -r 2f259fa3e83a lafagnosticuifoundation/cone/tef/TConeInvalidate.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lafagnosticuifoundation/cone/tef/TConeInvalidate.cpp Tue Feb 02 01:00:49 2010 +0200 @@ -0,0 +1,646 @@ +// Copyright (c) 2005-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: +// Off-screen bitmap Gc test to observe correct redraw behaviour with respect to sub-rect invalidation and redraw capability +// makes use of the introduced CCoeControl::DrawNow(TRect &) function and CWindowGc derivable class. +// Test intended for OS v9.1 and onward. +// The screen display, from left to right is displayed as follows: +// a) The standard control as a sub-divided hierachical component with background +// b) Offscreen bitmap #1 overlayed (blended) onto background +// c) Offscreen bitmap #2 overlayed (blended) onto background +// The original control is set into the offscreen Gcs as a chequer board where "black squares" are drawn to Gc #1 and +// "white squares" are drawn to Gc #2. +// Note: During the test a blank rectangle is displayed in the DrawNow(TRect&) position on the original control, +// this is the windows server screen invalidate and cannot be overridden by test code. +// Specifically this code performs the following tests: +// 1) Rectangle refresh drawing down a hierarchical composition of child controls with varied window ownership properties +// (including background redraw). This is to ensure the integrity of the subrect as the draw code passes down through the +// control hierarchy. +// 2) Offscreen drawing to multiple Gcs with respect to test 1); the offscreen Gc uses RDrawableWindow::GetDrawRect to +// obtain current window the draw region. See TTransGC.cpp for offscreen bitmap Gc functionality. +// 3) The correct drawing of background regions with respect to each window, the behaviour of which is in part specified by +// the Draw client +// The chequer pattern will be drawn within the DRAW_SIZE region on the second two controls (offscreen Gc maps). +// Note: the second half of the tests will show "black" square regions because each square is a true window owner. +// +// + +/** + @file + @internalComponent - Internal Symbian test code + @SYMTestCaseID App-Framework/Cone/TConeInvalidate + @SYMPREQ 915 + @SYMTestCaseDesc + @SYMTestPriority Medium + @SYMTestStatus Implemented + @SYMTestActions + @SYMTestExpectedResults +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "TConeInvalidate.h" +#include "TTransGc.h" + +//Variable to offset animation start frames +#define KNumAnimFrames 32 +#define KNumTestSteps 16 +#define KAlphaOpaque 255 +TInt g_FrameStart = 0; + +//Every background will use the same image +CFbsBitmap* CTestRectGc::iBmpBackground = 0; + +/** The COffScreenBitmapGc class handles all variables and functions to maintain an offscreen bitmap for drawing + in 16M alpha mode. */ +COffScreenBitmapGc::COffScreenBitmapGc() + { + + } + +COffScreenBitmapGc::~COffScreenBitmapGc() + { + delete iGraphContext; + delete iMainFbsBitGc; + delete iBitmapDevice2; + delete iBitmapView; + } + +COffScreenBitmapGc* COffScreenBitmapGc::NewL(const TSize &aSize) + { + COffScreenBitmapGc *pGC; + + pGC = new (ELeave) COffScreenBitmapGc(); + + const CCoeEnv* env = CCoeEnv::Static(); + + + CWsScreenDevice* screenDevice=env->ScreenDevice(); + + TDisplayMode dispMode = screenDevice->DisplayMode(); + + //Override display mode so that we have an alpha channel in the target bitmap; + dispMode = EColor16MA; + + //Allocate windows server bitmap + pGC->iBitmapView = new (ELeave) CWsBitmap(env->WsSession()); + + User::LeaveIfError(pGC->iBitmapView->Create(aSize, dispMode)); + + //Create a device for the bitmap + pGC->iBitmapDevice2 = CFbsBitmapDevice::NewL(pGC->iBitmapView); + + //Graphic Context to draw to + pGC->iMainFbsBitGc=CFbsBitGc::NewL(); + pGC->iMainFbsBitGc->Activate(pGC->iBitmapDevice2); + + pGC->iGraphContext = CTransGc::NewL(*screenDevice,*pGC->iMainFbsBitGc); // takes place of iMainFbsBitGc (not passing ownership of context here !) + + return pGC; + } + +CTransGc *COffScreenBitmapGc::OffScreenGc() + { + return iGraphContext; + } + + +CWsBitmap *COffScreenBitmapGc::GetBitmap() + { + return iBitmapView; + } + +//----------------------------------------------------- +void CTestRectGc::ConstructL(TPoint aPt, TSize aSize, TRgb aPenColor, TRgb aBrushColor, CGraphicsContext::TBrushStyle aBrushStyle) + { + SetPenColor(aPenColor); + SetBrushColor(aBrushColor); + + SetBrushStyle(aBrushStyle); + SetDrawType(EDrawRect); + SetExtent(aPt, aSize); + + iFrameNo = g_FrameStart+=5; //Offset frame start for next control + g_FrameStart %= KNumAnimFrames; + } + + + +CTestRectGc::~CTestRectGc() + { + } + + +//Basic colour setting functions +void CTestRectGc::SetPenColor(const TRgb &aPenColor) + { + iPenColor = aPenColor; + } +void CTestRectGc::SetBrushColor(const TRgb &aBrushColor) + { + iBrushColor = aBrushColor; + } +void CTestRectGc::SetBrushStyle(const CGraphicsContext::TBrushStyle aBrushStyle) + { + iBrushStyle = aBrushStyle; + } +void CTestRectGc::SetDrawType(const TDrawType DrawType) + { + iDrawType = DrawType; + } +void CTestRectGc::NextFrame() + { + iFrameNo = (iFrameNo+1) & 0x1f; + } + +//Main control drawing function +void CTestRectGc::Draw(const TRect& aRect) const + { + + CWindowGc& gc=SystemGc(); + + TRect rc = Rect(); + + gc.SetClippingRect(aRect); + + switch(iDrawType) + { + case EDrawRect: + + gc.SetPenColor(TRgb(0,0,0,KAlphaOpaque)); + gc.SetBrushColor(TRgb(0,0,0,KAlphaOpaque)); + gc.SetBrushStyle(CGraphicsContext::ENullBrush); + gc.DrawRect(rc); + break; + + case EDrawEllipse: + { + + //Frame index is a ping-pong animation 0->15->0 + TInt FrameIndex = (iFrameNo&0x10)? 0xf - (iFrameNo & 0xf) : iFrameNo & 0xf; + + //The shade of red is an offset multiple of the frame number (0-NUM_ANIM_FRAMES-1). + TRgb col(0xff&(128+(iFrameNo<<3)), 0, 0); + + //The size of the ellipse ranges from 0->height->0 over the NUM_ANIM_FRAMES period + TInt BoxSize = (FrameIndex * ((rc.Height() << 15) / 0x10)) >> 16; + rc.Shrink(0, BoxSize); + + gc.SetPenColor(col); + gc.SetBrushColor(col); + gc.SetBrushStyle(CGraphicsContext::ESolidBrush); + + gc.DrawEllipse(rc); + break; + } + default: + + break; //Do nothing, blank but not erased + } + + gc.CancelClippingRect(); + + } + + +//Background drawing function +void CTestRectGc::Draw(CWindowGc& aGc, const CCoeControl& aControl, const TRect& aRect) const + { + if (iBmpBackground) + { + + TPoint a = PositionRelativeToScreen(); + TPoint b = aControl.PositionRelativeToScreen(); + + //The source rect of the background is the relationship between this control and the control being drawn (child) + //plus the subrect (aRect) to be drawn. + TRect SourceRect(b-a+aRect.iTl, aRect.Size()); + + aGc.SetDrawMode(CGraphicsContext::EDrawModePEN); + aGc.BitBlt(aRect.iTl, iBmpBackground, SourceRect); + aGc.SetDrawMode(CGraphicsContext::EDrawModePEN); + } + else + { + TRect rc; + aGc.SetClippingRect(aRect); + aGc.SetBrushStyle(CGraphicsContext::ESolidBrush); + aGc.SetBrushColor(iBrushColor); + aGc.SetBrushStyle(iBrushStyle); + aGc.DrawRect(rc); + aGc.CancelClippingRect(); + + } + } + +/** Create a child control. + if the LSB of aOwners is true, then this control is window owning. + Recursively called aChildren times */ + +void CComponentControl::CreateChildControlL(TInt aChildren, TInt aOwners, TPoint aPt, TSize aSize, TRgb aPenColor, TRgb aBrushColor, CGraphicsContext::TBrushStyle aBrushStyle) + { + CTestRectGc *pControl; + + if (aChildren) + { + pControl = new (ELeave) CComponentControl(); + } + else + { + pControl = new (ELeave) CTestRectGc(); + } + + if (aOwners&1) + { + pControl->CreateWindowL(this); + } + else + { + pControl->SetContainerWindowL(*this); + pControl->SetParent(this); + } + + if (aChildren) + { + ((CComponentControl*)pControl)->ConstructL(aChildren-1, aOwners, aPt, aSize, KRgbBlack, KRgbRed, CGraphicsContext::ESolidBrush); + } + else + { + pControl->ConstructL(aPt, aSize, aPenColor, aBrushColor, aBrushStyle); + } + + Components().AppendLC(pControl); + + pControl->SetDrawType(EDrawEllipse); + + CleanupStack::Pop(pControl); + } + +/** Construct a control which is recursively sub-divided into four more windows. + If the LSB of aOwners is true, then the parent control (this) is a window owning control + Recursively called aChildren times */ + +void CComponentControl::ConstructL(TInt aChildren, TInt aOwners, TPoint aPt, TSize aSize, TRgb aPenColor, TRgb aBrushColor, CGraphicsContext::TBrushStyle aBrushStyle) + { + //Construct the base window of the control + CTestRectGc::ConstructL(aPt, aSize, aPenColor, aBrushColor, aBrushStyle); + InitComponentArrayL(); + + TSize ChildSize(aSize.iWidth/2, aSize.iHeight/2); + + TPoint Offset; + if (aOwners&1) + Offset.SetXY(0,0); + else + Offset = aPt; + + CreateChildControlL(aChildren, aOwners>>1, Offset, ChildSize, aPenColor, aBrushColor, aBrushStyle); + CreateChildControlL(aChildren, aOwners>>1, Offset+TSize(ChildSize.iWidth, 0), ChildSize, aPenColor, aBrushColor, aBrushStyle); + CreateChildControlL(aChildren, aOwners>>1, Offset+TSize(0, ChildSize.iHeight), ChildSize, aPenColor, aBrushColor, aBrushStyle); + CreateChildControlL(aChildren, aOwners>>1, Offset+TSize(ChildSize.iWidth, ChildSize.iHeight), ChildSize, aPenColor, aBrushColor, aBrushStyle); + + } + +//Destroy component controls within this control +CComponentControl::~CComponentControl() + { + while (CountComponentControls()) + { + CCoeControl *pControl; + pControl = ComponentControl(0); + Components().Remove(pControl); + delete pControl; + } + } + + void CComponentControl::Draw(const TRect& /*aRect*/) const + { + // CTestRectGc::Draw(aRect); + return; + } + +//Recursively drill down to each control level and step their frame counters. +void CComponentControl::AnimateComponents() + { + for (TInt i=0; iNextFrame(); + if (pComponent->CountComponentControls()) + ((CComponentControl*)pComponent)->AnimateComponents(); + } + } + +/** Create the compound control, the owner mask defines window ownership for each hierarchical control level + (LSB = top level parent window). */ +void CTestRectBackground::CreateComponentControlL(TInt aNumChildren, TInt aOwnerMask) +{ + Components().RemoveById(999); + delete iControl; + + iControl = new (ELeave) CComponentControl(); + iControl->CreateWindowL(this); + Components().AppendLC(iControl, 999); + + iControl->ConstructL(aNumChildren, aOwnerMask, TPoint(10,36),TSize(128,128), KRgbBlack, KRgbRed, CGraphicsContext::ESolidBrush); + CleanupStack::Pop(iControl) ; + iControl->SetParent(this); + iControl->ActivateL(); +} + +void CTestRectBackground::ConstructL() + { + CreateWindowL(); + CTestRectGc::ConstructL(TPoint(20,20),TSize(600,200), KRgbBlack, KRgbYellow, CGraphicsContext::ESolidBrush); + InitComponentArrayL(); + + //Create a default control + CreateComponentControlL(2, 7); + + //Control to display the offscreen bitmap + iControlImage = new (ELeave) CTestRectImageGc(); + iControlImage->CreateWindowL(this); + iControlImage->DrawableWindow()->SetRequiredDisplayMode(EColor16MA); + iControlImage->ConstructL(TPoint(200,36),TSize(128,128), KRgbRed, KRgbGreen, CGraphicsContext::ESolidBrush); + iControlImage->ActivateL(); + + //Second control to display blended overlay + iControlImage2 = new (ELeave) CTestRectImageGc(); + iControlImage2->CreateWindowL(this); + iControlImage2->DrawableWindow()->SetRequiredDisplayMode(EColor16MA); + iControlImage2->ConstructL(TPoint(400,36),TSize(128,128), KRgbRed, KRgbGreen, CGraphicsContext::ESolidBrush); + iControlImage2->ActivateL(); + + //Create an offscreen bitmap + iOffScreen = COffScreenBitmapGc::NewL(TSize(128,128)); + + //Create a second offscreen bitmap + iOffScreen2 = COffScreenBitmapGc::NewL(TSize(128,128)); + + //Set up the control images to display the two offscreen maps + iControlImage->SetBitmap(iOffScreen->GetBitmap()); + iControlImage2->SetBitmap(iOffScreen2->GetBitmap()); + + iBmpBackground = new (ELeave) CFbsBitmap(); + User::LeaveIfError(iBmpBackground->Load(_L("z:\\conetest\\city.mbm"))); + + //Set up the Gc origin so that the offscreen bitmaps can be tiled in the same way as the screen drawn control + TPoint ControlPos = iControl->PositionRelativeToScreen(); + iOffScreen->OffScreenGc()->SetWindowOrigin(ControlPos); + iOffScreen2->OffScreenGc()->SetWindowOrigin(ControlPos); + + ActivateL(); + + } + + + + +CTestRectBackground::~CTestRectBackground() + { + Components().RemoveById(999); + delete iControl; + + delete iControlImage; + delete iControlImage2; + + delete iBmpBackground; + + delete iOffScreen; + delete iOffScreen2; + + delete iContext; + } + + +void CTestRectBackground::Draw(const TRect& aRect) const + { + CTestRectGc::Draw(aRect); + } + + + +void CTestRectImageGc::Draw(const TRect& aRect) const + { + + CWindowGc& gc=SystemGc(); + + TRect rc = Rect(); + gc.SetClippingRect(aRect); + if(iBmp) + { + gc.BitBlt(rc.iTl, iBmp); + } + } + +CTConeInvalidateAppUi::CTConeInvalidateAppUi(CTmsTestStep* aStep) : +CTestCoeAppUi(aStep) +{} + +CTConeInvalidateAppUi::~CTConeInvalidateAppUi() + { + RemoveFromStack(iViewControl); + delete iViewControl; + } + + +//Standard Implementation +void CTConeInvalidateAppUi::ConstructL() + { + CTestCoeAppUi::ConstructL(); + + iViewControl=new(ELeave) CTestRectBackground; + iViewControl->ConstructL(); + AddToStackL(iViewControl); + AutoTestManager().StartAutoTest(); + } + +//Standard Implementation +TKeyResponse CTConeInvalidateAppUi::HandleKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType) + { + TKeyResponse ret=EKeyWasNotConsumed; + if (aType==EEventKey && aKeyEvent.iCode==CTRL('e')) + { + CBaActiveScheduler::Exit(); + ret=EKeyWasConsumed; + } + return ret; + } + + +void CTConeInvalidateAppUi::RunTestStepL(TInt aStepNum) + { + #define DRAW_SIZE 48 + #define DRAW_BORDER 8 + #define PARENT_HALF_WIDTH 64 + + //Clear the offscreen bitmap to solid black, so that at each iteration we can see what is drawn during that frame. + CTransGc *pOffGc = ((CTransGc*)iViewControl->iOffScreen->OffScreenGc()); + pOffGc->SetOrigin(TPoint(0,0)); + pOffGc->SetAlphaLevel(KAlphaOpaque); + pOffGc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha); + pOffGc->SetBrushColor(TRgb(0,0,0,0)); + pOffGc->Clear(); + + //1/4 transparent (or 3/4 opaque). + pOffGc->SetAlphaLevel(192); + + //Clear the 2nd offscreen bitmap + pOffGc = ((CTransGc*)iViewControl->iOffScreen2->OffScreenGc()); + pOffGc->SetOrigin(TPoint(0,0)); + pOffGc->SetAlphaLevel(KAlphaOpaque); + pOffGc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha); + pOffGc->SetBrushColor(TRgb(0,0,0,0)); + pOffGc->Clear(); + //1/4 transparent (or 3/4 opaque). + pOffGc->SetAlphaLevel(192); + + TPoint drawOffset; + + TInt Phase = aStepNum - 1; + + if (Phase>2); + //The LSB is set to 1 (the parent which is always window owning). + iViewControl->CreateComponentControlL(1, OwnerMask<<1|1); + + //Set backgrounds for the original control and the overlayed controls. + iViewControl->iControl->SetBackground(iViewControl->iControl); + iViewControl->iControlImage->SetBackground(iViewControl->iControlImage); + iViewControl->iControlImage2->SetBackground(iViewControl->iControlImage2); + + //The lower two bits of Phase define the redraw rectangle position in the sequence (tl, tr, br, bl) and repeats this cycle. + + TInt Region = Phase & 3; + + switch (Region) + { + case 0: drawOffset = TPoint(DRAW_BORDER, DRAW_BORDER); break; + case 1: drawOffset = TPoint(PARENT_HALF_WIDTH+DRAW_BORDER, DRAW_BORDER); break; + case 2: drawOffset = TPoint(PARENT_HALF_WIDTH+DRAW_BORDER, PARENT_HALF_WIDTH+DRAW_BORDER); break; + case 3: drawOffset = TPoint(DRAW_BORDER, PARENT_HALF_WIDTH+DRAW_BORDER); break; + default : break; + } + + + INFO_PRINTF6(_L("Invalidate rect: Step=%2d, OwnerMask=%1d%1d%1d, Region=%1d"), aStepNum, OwnerMask>>1&1, OwnerMask&1, 1, Region); + + //Set up the redraw rectangle for this test run + TRect redrawRect(drawOffset, TSize(DRAW_SIZE,DRAW_SIZE)); + + //Draw the main control, before we set any special Gcs + iViewControl->iControl->DrawNow(); + + //Now set each control to an offscreen Gc in "chequer board fashion" + + for (TInt j=0; j<4; j++) + for (TInt k=0; k<4; k++) + { + CCoeControl *pControl = iViewControl->iControl-> ComponentControl(j)-> + ComponentControl(k); + + if ((k==0)||(k==3)) //is the chequer pattern + pControl->SetGc(iViewControl->iOffScreen->OffScreenGc()); + else + pControl->SetGc(iViewControl->iOffScreen2->OffScreenGc()); + + + } + + + //and set the control without a background, for the subrect redraw + iViewControl->iControl->SetBackground(NULL); + + for (TInt i=0; i<50; i++) //Animation cycle whilst the rectangular region is being updated + { + + //Reset the Gcs' window cache variable, required every redraw cycle so the Gc knows when a clear is required + ((CTransGc*)iViewControl->iOffScreen->OffScreenGc())->iWin = NULL; + ((CTransGc*)iViewControl->iOffScreen2->OffScreenGc())->iWin = NULL; + + //Animate the controls + iViewControl->iControl->AnimateComponents(); + + //Instruct the control the redraw the desired rectangle + iViewControl->iControl->DrawNow(redrawRect); + + //Draw the whole offscreen image so that we can check the correct part of the rectangle was drawn + iViewControl->iControlImage->DrawNow(); + + //Draw the offscreen image blended over background. + iViewControl->iControlImage2->DrawNow(); + + User::After(TTimeIntervalMicroSeconds32(1000)); + } + } + else + { + AutoTestManager().FinishAllTestCases(CAutoTestManager::EPass); + } + } + +//---------- +void CTConeInvalidateStep::ConstructAppL(CCoeEnv* aCoe) + { // runs inside a TRAP harness + aCoe->ConstructL(); + CTConeInvalidateAppUi* appUi= new (ELeave) CTConeInvalidateAppUi(this); + aCoe->SetAppUi(appUi); + appUi->ConstructL(); + } + +CTConeInvalidateStep::CTConeInvalidateStep() + { + SetTestStepName(KTConeInvalidateStep); + } + +CTConeInvalidateStep::~CTConeInvalidateStep() + {} + + +TVerdict CTConeInvalidateStep::doTestStepL() // main function called by E32 + { + INFO_PRINTF1(_L("Test Started")); + + PreallocateHALBuffer(); + + __UHEAP_MARK; + SetTestStepID(_L("UIF-Cone-TConeInvalidate")); + CCoeEnv* coe=new(ELeave) CCoeEnv; + TRAPD(err,ConstructAppL(coe)); + + if (!err) + coe->ExecuteD(); + else + { + SetTestStepResult(EFail); + delete coe; + } + + REComSession::FinalClose(); + + RecordTestResultL(); + CloseTMSGraphicsStep(); + __UHEAP_MARKEND; + + INFO_PRINTF1(_L("Test Finished")); + return TestStepResult(); + }