/*
* Copyright (c) 2008-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: Definition of CHuiCanvasWsBitGc.
*
*/
#include "huicanvaswsbitgc.h"
#include "uiacceltk/HuiCanvasVisual.h"
#include <graphics/wsgraphicscontext.h>
#include <e32cmn.h>
#include <AknLayoutFont.h>
#include <gdi.h>
CHuiCanvasWsBitGc* CHuiCanvasWsBitGc::NewL()
{
CHuiCanvasWsBitGc* self = new ( ELeave ) CHuiCanvasWsBitGc;
CleanupStack::PushL( self );
self->ConstructL();
CleanupStack::Pop();
return self;
}
CHuiCanvasWsBitGc::CHuiCanvasWsBitGc()
{
}
void CHuiCanvasWsBitGc::ConstructL()
{
CHuiCanvasWsSwGc::ConstructL();
}
CHuiCanvasWsBitGc::~CHuiCanvasWsBitGc()
{
}
void CHuiCanvasWsBitGc::BeginActionL(TInt aAction, TRect /*aDisplayRect*/, const CHuiCanvasVisual& aUser, TBool aIsCachePrepared, const TRegion& aUpdateRegion)
{
iAction = aAction;
iVisual = &aUser;
if (!iVisual)
{
return;
}
// Update area is in screen coordinates so we must convert it
iDefaultClipRegion.Clear();
for (TInt i=0; i < aUpdateRegion.Count(); i++)
{
iDefaultClipRegion.AddRect(AdjustCoordinates(aUpdateRegion[i]));
}
TSize size = RoundedDisplayRect().Size();
// We create buffer only in drawing phase to reduce memory consumption.
TBool recreateBackbuffer =
( iAction == EDrawBuffer ) &&
( !iBitGc || ( iBitBitmap && iBitBitmap->SizeInPixels() != size ) );
// If this is first draw or size has changed, re-create backbuffer
if (recreateBackbuffer)
{
iBitmapInitialized = EFalse;
if (!iBitBitmap)
{
iBitBitmap = new (ELeave) CFbsBitmap;
iBitBitmap->Create(size, SelectDisplayMode());
}
else
{
iBitBitmap->Resize(size);
}
if (!iBitDevice)
{
iBitDevice = CFbsBitmapDevice::NewL(iBitBitmap);
}
else
{
iBitDevice->Resize(size);
}
delete iBitGc;
iBitGc = NULL;
User::LeaveIfError(iBitDevice->CreateContext(iBitGc));
TRgb clearColor = KRgbWhite;
clearColor.SetAlpha(0x0);
iBitGc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
iBitGc->SetPenColor(clearColor);
iBitGc->SetBrushColor(clearColor);
iBitGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
iBitGc->Clear();
iBitGc->Reset();
iIsReallyDirty = EFalse;
}
if (iBitGc)
{
iBitGc->Reset();
}
iBitmapPrepared = aIsCachePrepared && iBitmapInitialized;
}
// Note that for perfomance reasons we keep iBitBitmap alive in this method
void CHuiCanvasWsBitGc::EndActionL(const TRegion& aUpdateRegion, TBool aUpdateDisplay)
{
if (!iBitBitmap || !iVisual)
{
return;
}
// Update internal state - drawing finished
if ( iAction == EDrawBuffer )
{
iBitmapInitialized = ETrue;
iBitmapPrepared = ETrue;
}
// If capturing is used, then copy content from bitmap.
if (iCapturingBitGc && aUpdateDisplay && iIsReallyDirty && iAction == EDrawBuffer)
{
iCapturingBitGc->Reset();
// blend only transparent windows
if (iVisual->Flags() & EHuiVisualFlagOpaqueHint)
{
iCapturingBitGc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
}
else
{
iCapturingBitGc->SetDrawMode(CGraphicsContext::EDrawModePEN);
}
iCapturingBitGc->SetClippingRegion(aUpdateRegion);
TSize visualSize = iVisual->DisplayRect().Size().Round();
if (iCapturingBitBitmap->SizeInPixels() != visualSize)
{
iCapturingBitGc->BitBlt(iVisual->DisplayRect().iTl.Round(), iBitBitmap);
}
else
{
// Old capturing functionality, althoug not really used we support that as well
iCapturingBitGc->BitBlt(TPoint(0,0), iBitBitmap);
}
iCapturingBitGc->CancelClippingRegion();
}
// Content is not drawn anywhere (except to to capturing bitgc)
}
THuiCanvasWsGcType CHuiCanvasWsBitGc::Type() const
{
return EHuiCanvasWsBit;
}
void CHuiCanvasWsBitGc::ClearCache()
{
// ClearCache is called when we can release,
// e.g. when window is hidden by another opaque window.
// So now we must release bitmaps in order to free
// memory.
iBitmapPrepared = EFalse;
iBitmapInitialized = EFalse;
delete iBitGc;
iBitGc = NULL;
delete iBitDevice;
iBitDevice = NULL;
delete iBitBitmap;
iBitBitmap = NULL;
}
TBool CHuiCanvasWsBitGc::IsRenderBufferEnabled() const
{
return ETrue;
}