--- /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 <coeaui.h>
+#include <coemain.h>
+#include <coedef.h>
+#include <coesndpy.h>
+#include <basched.h>
+#include <bassnd.h>
+#include <coeccntx.h>
+#include <ecom/ecom.h>
+#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; i<CountComponentControls(); i++)
+ {
+ CTestRectGc* pComponent = (CTestRectGc*)ComponentControl(i);
+ pComponent->NextFrame();
+ 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<KNumTestSteps)
+ {
+ //Create the control and setup its parameters. The top 2 bits of Phase define window ownership combination for
+ //the 2 sub levels of the animated control.
+ TInt OwnerMask = (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();
+ }