diff -r 000000000000 -r 15bf7259bb7c uiacceltk/hitchcock/coretoolkit/src/huicanvaswshwgc.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uiacceltk/hitchcock/coretoolkit/src/huicanvaswshwgc.cpp Tue Feb 02 07:56:43 2010 +0200 @@ -0,0 +1,2248 @@ +/* +* 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 CHuiCanvasWsHwGc. +* +*/ + + + +#include "huicanvaswshwgc.h" + +#include "uiacceltk/HuiCanvasVisual.h" +#include "HuiRenderPlugin.h" +#include "uiacceltk/HuiGc.h" +#include "uiacceltk/HuiPanic.h" +#include "uiacceltk/HuiUtil.h" +#include "uiacceltk/HuiStatic.h" +#include "uiacceltk/HuiEnv.h" +#include "uiacceltk/HuiControl.h" +#include "uiacceltk/HuiVisual.h" +#include "uiacceltk/HuiTextMesh.h" +#include "uiacceltk/HuiCanvasCmdBufferReader.h" +#include "huicanvasgc.h" +#include "HuiRenderSurface.h" +#include "huicanvastexturecache.h" +#include "huicanvasbackground.h" +#include +#include +#include +#include + +//#define HUI_DEBUG_PRINT_PERFORMANCE_INTERVAL + +CHuiCanvasWsHwGc* CHuiCanvasWsHwGc::NewL() + { + CHuiCanvasWsHwGc* self = new ( ELeave ) CHuiCanvasWsHwGc; + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + + return self; + } + +void CHuiCanvasWsHwGc::AdjustCoordinates(TPoint& aPoint, TBool aUseWsOrigin ) + { + aPoint += iPosDelta; + if ( aUseWsOrigin ) + { + aPoint += iWsOrigin; + } + } + +void CHuiCanvasWsHwGc::AdjustCoordinates(TRect& aRect, TBool aUseWsOrigin ) + { + aRect.Move( iPosDelta ); + if ( aUseWsOrigin ) + { + aRect.Move( iWsOrigin ); + } + } + +void CHuiCanvasWsHwGc::DrawTextBrush( THuiRealRect& aRect ) + { + if( iWsBrushStyle == CGraphicsContext::ESolidBrush ) + { + TRgb oldPenColor = iCanvasGc->PenColor(); + TReal32 oldOpacity = iCanvasGc->Opacity(); + THuiFillMode oldFillMode = iCanvasGc->PolygonDrawMode(); + + iCanvasGc->SetPenColor(iWsBrushColor); + iCanvasGc->SetOpacity(TReal32(iWsBrushColor.Alpha() / 255.f)); + iCanvasGc->SetPolygonDrawMode(EHuiFillEvenOdd); + + RArray rects; + rects.Append(aRect); + iCanvasGc->DrawRects(rects); + rects.Close(); + + iCanvasGc->SetPolygonDrawMode(oldFillMode); + iCanvasGc->SetOpacity(oldOpacity); + iCanvasGc->SetPenColor(oldPenColor); + } + } + +CHuiCanvasWsHwGc::CHuiCanvasWsHwGc() + { + } + +void CHuiCanvasWsHwGc::ConstructL() + { + iCanvasGc = CHuiStatic::Renderer().CreateCanvasGcL(); + + // Set delayed clipping mode, this is supposed to reduce unnecessary + // clipping which may cause bad performance on hw renderers + iCanvasGc->SetClippingMode(EHuiCanvasClipModeDelayed); + WsResetL(); +#ifdef __WINS__ + iPushCount = 0; +#endif + } + +CHuiCanvasWsHwGc::~CHuiCanvasWsHwGc() + { + if (iVisual) + { + iVisual->Env().CanvasTextureCache().ReleaseCachedRenderBuffer(*iVisual); + } + + iTempRegion.Close(); + iWsClipRegion.Close(); + delete iCanvasGc; + iCanvasGc = NULL; + } + +void CHuiCanvasWsHwGc::WsBitBltL(TInt aBitmapHandle, TPoint aPoint) + { + THuiCachedImageParams cachedImageParams; + cachedImageParams.iBitmapHandle = aBitmapHandle; + cachedImageParams.iGcParams = CachedGcParams(); + + const CHuiCanvasGraphicImage* cachedImage = iVisual->Env().CanvasTextureCache().CreateCachedImageL(cachedImageParams,*iVisual); + + if (IsRenderingEnabled()) + { + const CHuiTexture* texture = cachedImage->Texture(); + if (texture) + { + AdjustCoordinates( aPoint ); + THuiRealRect destinationRect = TRect(aPoint, texture->Size()); + + THuiCanvasDrawMode oldDrawMode = iCanvasGc->DrawMode(); + iCanvasGc->SetDrawMode(SelectCanvasDrawMode(iWsDrawMode)); + // Draw + iCanvasGc->DrawImage(*texture, destinationRect, TRect(TPoint(0,0), texture->Size()), CHuiGc::EStretchNone); + iCanvasGc->SetDrawMode(oldDrawMode); + } + } + } + + + + +void CHuiCanvasWsHwGc::WsBitBltRectL(TInt aBitmapHandle, TPoint aPoint, TRect aRect) + { + THuiCachedImageParams cachedImageParams; + cachedImageParams.iBitmapHandle = aBitmapHandle; + cachedImageParams.iGcParams = CachedGcParams(); + + const CHuiCanvasGraphicImage* cachedImage = iVisual->Env().CanvasTextureCache().CreateCachedImageL(cachedImageParams,*iVisual); + + if (IsRenderingEnabled()) + { + const CHuiTexture* texture = cachedImage->Texture(); + if (texture) + { + AdjustCoordinates( aPoint ); + THuiRealRect destinationRect = TRect(aPoint, texture->Size()); + + THuiCanvasDrawMode oldDrawMode = iCanvasGc->DrawMode(); + iCanvasGc->SetDrawMode(SelectCanvasDrawMode(iWsDrawMode)); + + // Draw + iCanvasGc->DrawImage(*texture, destinationRect, aRect, CHuiGc::EStretchNone); + iCanvasGc->SetDrawMode(oldDrawMode); + } + } + } + + + +void CHuiCanvasWsHwGc::WsBitBltMaskedL(TInt aBitmapHandle, TInt aMaskHandle, TInt aInvertMask, TPoint aPoint, TRect aRect) + { + THuiCachedImageParams cachedImageParams; + cachedImageParams.iBitmapHandle = aBitmapHandle; + cachedImageParams.iMaskHandle = aMaskHandle; + cachedImageParams.iInvertedMask = aInvertMask; + cachedImageParams.iGcParams = CachedGcParams(); + + + const CHuiCanvasGraphicImage* cachedImage = iVisual->Env().CanvasTextureCache().CreateCachedImageL(cachedImageParams,*iVisual); + + if (IsRenderingEnabled()) + { + const CHuiTexture* texture = cachedImage->Texture(); + if (texture) + { + AdjustCoordinates( aPoint ); + THuiRealRect destinationRect = TRect(aPoint, texture->Size()); + + // Draw + iCanvasGc->DrawImage(*texture, destinationRect, aRect, CHuiGc::EStretchNone); + } + } + } + + +void CHuiCanvasWsHwGc::WsCombinedBitBltMaskedL(TRect aDestinationRect, const RArray& aBlits ) + { + THuiCachedCombinedImageParams cachedCombinedImageParams; + THuiCachedGcParams gcParams = CachedGcParams(); + TSize imageSize = aDestinationRect.Size(); + + // Must convert points relative to the image itself + RArray convertedBlits; + for (TInt i=0; iEnv().CanvasTextureCache().CreateCombinedCachedImageL( + convertedBlits, + gcParams, + imageSize, + *iVisual); + + convertedBlits.Close(); + + if (IsRenderingEnabled()) + { + const CHuiTexture* texture = cachedImage->Texture(); + if (texture) + { + TPoint point = aDestinationRect.iTl; + AdjustCoordinates( point ); + + THuiRealRect destinationRect = TRect(point, texture->Size()); + + // Draw + iCanvasGc->DrawImage(*texture, destinationRect, TRect(TPoint(0,0), texture->Size()), CHuiGc::EStretchNone); + } + } + } + + +void CHuiCanvasWsHwGc::WsBitBltMaskedPointL(TInt aBitmapHandle, TInt aMaskHandle, TPoint aPoint1, TPoint aPoint2, TRect aRect) + { + THuiCachedImageParams cachedImageParams; + cachedImageParams.iBitmapHandle = aBitmapHandle; + cachedImageParams.iMaskHandle = aMaskHandle; + cachedImageParams.iMaskOriginPoint = aPoint2; + cachedImageParams.iGcParams = CachedGcParams(); + + const CHuiCanvasGraphicImage* cachedImage = iVisual->Env().CanvasTextureCache().CreateCachedImageL(cachedImageParams,*iVisual); + + if (IsRenderingEnabled()) + { + const CHuiTexture* texture = cachedImage->Texture(); + if (texture) + { + AdjustCoordinates( aPoint1 ); + THuiRealRect destinationRect = TRect(aPoint1, texture->Size()); + + // Draw + iCanvasGc->DrawImage(*texture, destinationRect, aRect, CHuiGc::EStretchNone); + } + } + } + +void CHuiCanvasWsHwGc::WsResetClippingRegionL() + { + if (IsRenderingEnabled()) + { + // Reset clip region + iWsClipRegion.Clear(); + iCanvasGc->CancelClipping(); + } + } + +void CHuiCanvasWsHwGc::WsClearL() + { + if (IsRenderingEnabled()) + { + THuiRealRect rect(iVisual->DisplayRect()); + DoWsClearRectL(rect); + } + } + +void CHuiCanvasWsHwGc::WsClearRectL(TRect& aRect) + { + if (IsRenderingEnabled()) + { + AdjustCoordinates( aRect ); + DoWsClearRectL(aRect); + } + } + + +void CHuiCanvasWsHwGc::DoWsClearRectL(const THuiRealRect& aRect ) + { + if (IsRenderingEnabled()) + { + RArray rects; + rects.Append(aRect); + + // Store current gc params + UseWsState(); + + CHuiTexture* oldPolygonFillTexture = iCanvasGc->PolygonFillTexture(); + + // Clear + iCanvasGc->SetPolygonFillTexture(NULL); + iCanvasGc->SetPolygonDrawMode(EHuiFillNonZero); + iCanvasGc->SetPenWidth(1); + iCanvasGc->SetPenColor(iWsBrushColor); + iCanvasGc->SetOpacity(TReal32(iWsBrushColor.Alpha() / 255.f)); + iCanvasGc->SetDrawMode(SelectCanvasDrawMode(iWsDrawMode)); + iCanvasGc->DrawRects(rects); + + // Restore gc params etc. + rects.Close(); + UseCanvasState(); + iCanvasGc->SetPolygonFillTexture(oldPolygonFillTexture); + } + } + +void CHuiCanvasWsHwGc::WsResetBrushPatternL() + { + iWsBrushPattern = 0; + } + +void CHuiCanvasWsHwGc::WsResetFontL() + { + iWsCurrentFont = 0; + } + +void CHuiCanvasWsHwGc::WsDrawArcL(TPoint aPoint1, TPoint aPoint2, TRect aRect) + { + // If penstyle is ENullPen, then nothign is drawn + if (!iWsPenStyle) + { + return; + } + + if (IsRenderingEnabled()) + { + UseWsState(); + + AdjustCoordinates( aRect ); + AdjustCoordinates( aPoint1 ); + AdjustCoordinates( aPoint2 ); + + iCanvasGc->DrawArc( THuiRealRect(aRect), THuiRealPoint(aPoint1), THuiRealPoint(aPoint2) ); + + UseCanvasState(); + } + } + +void CHuiCanvasWsHwGc::WsDrawPieL(TPoint aPoint1, TPoint aPoint2, TRect aRect) + { + // If penstyle is ENullPen, then nothign is drawn + if (!iWsPenStyle && !iWsBrushStyle) + { + return; + } + + if (IsRenderingEnabled()) + { + UseWsState(); + + AdjustCoordinates( aRect ); + AdjustCoordinates( aPoint1 ); + AdjustCoordinates( aPoint2 ); + + if (iWsBrushStyle == MWsGraphicsContext::ENullBrush) + { + iCanvasGc->SetPolygonDrawMode( EHuiNoFill ); + iCanvasGc->SetPenColor(iWsPenColor); + iCanvasGc->SetOpacity(TReal32(iWsPenColor.Alpha() / 255.f)); + iCanvasGc->DrawPie(THuiRealRect(aRect),THuiRealPoint(aPoint1),THuiRealPoint(aPoint2)); + } + else if (iWsBrushStyle == MWsGraphicsContext::ESolidBrush) + { + iCanvasGc->SetPolygonDrawMode( EHuiFillEvenOdd ); + iCanvasGc->SetPenColor(iWsBrushColor); + iCanvasGc->SetOpacity(TReal32(iWsBrushColor.Alpha() / 255.f)); + iCanvasGc->DrawPie(THuiRealRect(aRect),THuiRealPoint(aPoint1),THuiRealPoint(aPoint2)); + + // Border should be drawn if pencolor is different than solid fill + if (IsDifferent(iWsBrushColor, iWsPenColor, ETrue) && iWsPenStyle && iWsPenSize.iHeight >= 1 && iWsPenSize.iWidth >= 1) + { + iCanvasGc->SetPolygonDrawMode( EHuiNoFill ); + iCanvasGc->SetPenColor(iWsPenColor); + iCanvasGc->SetOpacity(TReal32(iWsPenColor.Alpha() / 255.f)); + iCanvasGc->DrawPie(THuiRealRect(aRect),THuiRealPoint(aPoint1),THuiRealPoint(aPoint2)); + } + } + else if (iWsBrushStyle == MWsGraphicsContext::EPatternedBrush) + { + iCanvasGc->SetPolygonDrawMode( EHuiFillEvenOdd ); + iCanvasGc->SetPenColor(iWsPenColor); + iCanvasGc->SetOpacity(TReal32(iWsPenColor.Alpha() / 255.f)); + UseBrushPattern(); + iCanvasGc->SetDrawMode(SelectCanvasDrawMode(iWsDrawMode)); + iCanvasGc->DrawPie(THuiRealRect(aRect),THuiRealPoint(aPoint1),THuiRealPoint(aPoint2)); + DiscardBrushPattern(); + + if (iWsPenStyle && iWsPenSize.iHeight >= 1 && iWsPenSize.iWidth >= 1) + { + iCanvasGc->SetPolygonDrawMode( EHuiNoFill ); + iCanvasGc->SetPenColor(iWsPenColor); + iCanvasGc->SetOpacity(TReal32(iWsPenColor.Alpha() / 255.f)); + iCanvasGc->DrawPie(THuiRealRect(aRect),THuiRealPoint(aPoint1),THuiRealPoint(aPoint2)); + } + } + else + { + // We should never get here because fallbackmode should be used in this case ! + RDebug::Print(_L("CHuiCanvasWsHwGc::WsDrawPieL - Unsupported brush mode %i"), iWsBrushStyle); + } + + UseCanvasState(); + } + } + +void CHuiCanvasWsHwGc::WsDrawBitmap1L(TInt aBitmapHandle, TRect aRect) + { + THuiCachedImageParams cachedImageParams; + cachedImageParams.iBitmapHandle = aBitmapHandle; + cachedImageParams.iGcParams = CachedGcParams(); + + const CHuiCanvasGraphicImage* cachedImage = iVisual->Env().CanvasTextureCache().CreateCachedImageL(cachedImageParams,*iVisual); + if (IsRenderingEnabled()) + { + const CHuiTexture* texture = cachedImage->Texture(); + if (texture) + { + AdjustCoordinates( aRect ); + THuiRealRect destinationRect = aRect; + + // Draw + // This should stretch ! + iCanvasGc->DrawImage(*texture, destinationRect, TRect(TPoint(0,0), texture->Size()), CHuiGc::EStretchFull); + } + } + } + +void CHuiCanvasWsHwGc::WsDrawBitmap2L(TInt aBitmapHandle, TRect aRect1, TRect aRect2) + { + THuiCachedImageParams cachedImageParams; + cachedImageParams.iBitmapHandle = aBitmapHandle; + cachedImageParams.iGcParams = CachedGcParams(); + + const CHuiCanvasGraphicImage* cachedImage = iVisual->Env().CanvasTextureCache().CreateCachedImageL(cachedImageParams,*iVisual); + + if (IsRenderingEnabled()) + { + const CHuiTexture* texture = cachedImage->Texture(); + if (texture) + { + AdjustCoordinates( aRect1 ); + THuiRealRect destinationRect = aRect1; + + // Draw + iCanvasGc->DrawImage(*texture, destinationRect, aRect2, CHuiGc::EStretchFull); + } + } + } + +void CHuiCanvasWsHwGc::WsDrawBitmap3L(TInt aBitmapHandle, TPoint aPoint) + { + THuiCachedImageParams cachedImageParams; + cachedImageParams.iBitmapHandle = aBitmapHandle; + cachedImageParams.iGcParams = CachedGcParams(); + + const CHuiCanvasGraphicImage* cachedImage = iVisual->Env().CanvasTextureCache().CreateCachedImageL(cachedImageParams,*iVisual); + + if (IsRenderingEnabled()) + { + const CHuiTexture* texture = cachedImage->Texture(); + if (texture) + { + AdjustCoordinates( aPoint ); + THuiRealRect destinationRect = TRect(aPoint, texture->Size()); + + // Draw + // TODO: Actually we should check the bitmap size in twips here are decide destinationRect based on that ! + iCanvasGc->DrawImage(*texture, destinationRect, TRect(TPoint(0,0), texture->Size()), CHuiGc::EStretchNone); + } + } + } + +void CHuiCanvasWsHwGc::WsDrawBitmapMaskedL(TInt aBitmapHandle, TInt aMaskHandle, TInt aInvertMask, TRect& aRect1, TRect& aRect2) + { + THuiCachedImageParams cachedImageParams; + cachedImageParams.iBitmapHandle = aBitmapHandle; + cachedImageParams.iMaskHandle = aMaskHandle; + cachedImageParams.iInvertedMask = aInvertMask; + cachedImageParams.iGcParams = CachedGcParams(); + + const CHuiCanvasGraphicImage* cachedImage = iVisual->Env().CanvasTextureCache().CreateCachedImageL(cachedImageParams,*iVisual); + + if (IsRenderingEnabled()) + { + const CHuiTexture* texture = cachedImage->Texture(); + if (texture) + { + AdjustCoordinates( aRect1 ); + THuiRealRect destinationRect = aRect1; + + // Draw + iCanvasGc->DrawImage(*texture, destinationRect, aRect2, CHuiGc::EStretchFull); + } + } + } + +void CHuiCanvasWsHwGc::WsDrawRoundRectL(TPoint aPoint, TRect& aRect) + { + // If penstyle is ENullPen, then nothign is drawn + if (!iWsPenStyle && !iWsBrushStyle) + { + return; + } + + if (IsRenderingEnabled()) + { + UseWsState(); + + AdjustCoordinates( aRect ); + iCanvasGc->SetDrawMode(SelectCanvasDrawMode(iWsDrawMode)); + + if (iWsBrushStyle == MWsGraphicsContext::ENullBrush) + { + iCanvasGc->SetPolygonDrawMode( EHuiNoFill ); + iCanvasGc->SetPenColor(iWsPenColor); + iCanvasGc->SetOpacity(TReal32(iWsPenColor.Alpha() / 255.f)); + iCanvasGc->DrawRoundRect( THuiRealRect(aRect), THuiRealSize( aPoint.iX*2, aPoint.iY*2 )); + } + else if (iWsBrushStyle == MWsGraphicsContext::ESolidBrush) + { + iCanvasGc->SetPolygonDrawMode( EHuiFillEvenOdd ); + iCanvasGc->SetPenColor(iWsBrushColor); + iCanvasGc->SetOpacity(TReal32(iWsBrushColor.Alpha() / 255.f)); + iCanvasGc->DrawRoundRect( THuiRealRect(aRect), THuiRealSize( aPoint.iX*2, aPoint.iY*2 )); + + // Border should be drawn if pencolor is different than solid fill + if (IsDifferent(iWsBrushColor,iWsPenColor, ETrue) && iWsPenStyle && iWsPenSize.iHeight >= 1 && iWsPenSize.iWidth >= 1) + { + iCanvasGc->SetPolygonDrawMode( EHuiNoFill ); + iCanvasGc->SetPenColor(iWsPenColor); + iCanvasGc->SetOpacity(TReal32(iWsPenColor.Alpha() / 255.f)); + iCanvasGc->DrawRoundRect( THuiRealRect(aRect), THuiRealSize( aPoint.iX*2, aPoint.iY*2 )); + } + } + else if (iWsBrushStyle == MWsGraphicsContext::EPatternedBrush) + { + iCanvasGc->SetPolygonDrawMode( EHuiFillEvenOdd ); + iCanvasGc->SetPenColor(iWsPenColor); + iCanvasGc->SetOpacity(TReal32(iWsPenColor.Alpha() / 255.f)); + UseBrushPattern(); + iCanvasGc->SetDrawMode(SelectCanvasDrawMode(iWsDrawMode)); + iCanvasGc->DrawRoundRect( THuiRealRect(aRect), THuiRealSize( aPoint.iX*2, aPoint.iY*2 )); + DiscardBrushPattern(); + + if (iWsPenStyle && iWsPenSize.iHeight >= 1 && iWsPenSize.iWidth >= 1) + { + iCanvasGc->SetPolygonDrawMode( EHuiNoFill ); + iCanvasGc->SetPenColor(iWsPenColor); + iCanvasGc->SetOpacity(TReal32(iWsPenColor.Alpha() / 255.f)); + iCanvasGc->DrawRoundRect( THuiRealRect(aRect), THuiRealSize( aPoint.iX*2, aPoint.iY*2 )); + } + } + else + { + // We should never get here because fallbackmode should be used in this case ! + RDebug::Print(_L("CHuiCanvasWsHwGc::WsDrawRoundRectL - Unsupported brush mode %i"), iWsBrushStyle); + } + UseCanvasState(); + } + } + +void CHuiCanvasWsHwGc::WsDrawPolyLineL(CArrayFix* aPointerArray) + { + // If penstyle is ENullPen, then nothign is drawn + if (!iWsPenStyle) + { + return; + } + + if (IsRenderingEnabled()) + { + if ( aPointerArray ) + { + UseWsState(); + + RArray lines; + TPoint finalDeltaPos = iWsOrigin + iPosDelta; + for(TInt j=0; jCount()-1; j++) + { + THuiRealLine line(aPointerArray->At(j) + finalDeltaPos, aPointerArray->At(j+1) + finalDeltaPos); + lines.Append(line); + } + iCanvasGc->DrawLines(lines); + lines.Close(); + + UseCanvasState(); + } + } + } + +void CHuiCanvasWsHwGc::WsDrawPolyLineNoEndPointL(TPoint* aPointerArray, TInt aCount) + { + // If penstyle is ENullPen, then nothign is drawn + if (!iWsPenStyle) + { + return; + } + + if (IsRenderingEnabled()) + { + if ( aPointerArray ) + { + UseWsState(); + + RArray lines; + TPoint finalDeltaPos = iWsOrigin + iPosDelta; + for(TInt j=0; j< aCount-1; j++) + { + THuiRealLine line(aPointerArray[j] + finalDeltaPos, aPointerArray[j+1] + finalDeltaPos );// TODO: TEST + lines.Append(line); + } + iCanvasGc->DrawLines(lines); + + RArray rects; + THuiRealRect pointRect = THuiRealRect(aPointerArray[aCount],aPointerArray[aCount]); + rects.AppendL(pointRect); + iCanvasGc->SetPenWidth(0); + iCanvasGc->DrawRects(rects); + rects.Close(); + lines.Close(); + + UseCanvasState(); + } + } + } + +void CHuiCanvasWsHwGc::WsDrawPolygonL(CArrayFix* aPointerArray, TInt aFillRule) + { + if (IsRenderingEnabled()) + { + RArray points; + for(TInt j=0; jCount(); j++) + { + points.Append( THuiRealPoint( aPointerArray->At(j) + iWsOrigin + iPosDelta) ); + } + UseWsState(); + + if ( aFillRule == MWsGraphicsContext::EAlternate ) + { + iCanvasGc->SetPolygonDrawMode( EHuiFillEvenOdd ); + } + if ( aFillRule == MWsGraphicsContext::EWinding ) + { + iCanvasGc->SetPolygonDrawMode( EHuiFillNonZero ); + } + iCanvasGc->SetPenColor(iWsPenColor); + iCanvasGc->SetOpacity(TReal32(iWsPenColor.Alpha() / 255.f)); + iCanvasGc->SetDrawMode(SelectCanvasDrawMode(iWsDrawMode)); + + iCanvasGc->DrawPolygon( points ); + + UseCanvasState(); + + points.Close(); + } + } + +void CHuiCanvasWsHwGc::WsDrawEllipseL(TRect& aRect) + { + // If penstyle is ENullPen, then nothign is drawn + if (!iWsPenStyle && !iWsBrushStyle) + { + return; + } + + if (IsRenderingEnabled()) + { + AdjustCoordinates( aRect ); + THuiRealRect destRect = aRect; + UseWsState(); + + if (iWsBrushStyle == MWsGraphicsContext::ENullBrush) + { + iCanvasGc->SetPolygonDrawMode( EHuiNoFill ); + iCanvasGc->SetPenColor(iWsPenColor); + iCanvasGc->SetOpacity(TReal32(iWsPenColor.Alpha() / 255.f)); + iCanvasGc->DrawEllipse(destRect); + } + else if (iWsBrushStyle == MWsGraphicsContext::ESolidBrush) + { + iCanvasGc->SetPolygonDrawMode( EHuiFillEvenOdd ); + iCanvasGc->SetPenColor(iWsBrushColor); + iCanvasGc->SetOpacity(TReal32(iWsBrushColor.Alpha() / 255.f)); + iCanvasGc->DrawEllipse(destRect); + + // Border should be drawn if pencolor is different than solid fill + if (IsDifferent(iWsBrushColor,iWsPenColor, ETrue) && iWsPenStyle && iWsPenSize.iHeight >= 1 && iWsPenSize.iWidth >= 1) + { + iCanvasGc->SetPolygonDrawMode( EHuiNoFill ); + iCanvasGc->SetPenColor(iWsPenColor); + iCanvasGc->SetOpacity(TReal32(iWsPenColor.Alpha() / 255.f)); + iCanvasGc->DrawEllipse(destRect); + } + } + else if (iWsBrushStyle == MWsGraphicsContext::EPatternedBrush) + { + iCanvasGc->SetPolygonDrawMode( EHuiFillEvenOdd ); + iCanvasGc->SetPenColor(iWsPenColor); + iCanvasGc->SetOpacity(TReal32(iWsPenColor.Alpha() / 255.f)); + UseBrushPattern(); + iCanvasGc->SetDrawMode(SelectCanvasDrawMode(iWsDrawMode)); + iCanvasGc->DrawEllipse(destRect); + DiscardBrushPattern(); + + if (iWsPenStyle && iWsPenSize.iHeight >= 1 && iWsPenSize.iWidth >= 1) + { + iCanvasGc->SetPolygonDrawMode( EHuiNoFill ); + iCanvasGc->SetPenColor(iWsPenColor); + iCanvasGc->SetOpacity(TReal32(iWsPenColor.Alpha() / 255.f)); + iCanvasGc->DrawEllipse(destRect); + } + } + else + { + // We should never get here because fallbackmode should be used in this case ! + RDebug::Print(_L("CHuiCanvasWsHwGc::WsDrawEllipseL - Unsupported brush mode %i"), iWsBrushStyle); + } + + UseCanvasState(); + } + } + +void CHuiCanvasWsHwGc::WsDrawLineL(TPoint& aStart, TPoint& aEnd) + { + // If penstyle is ENullPen, then nothign is drawn + if (!iWsPenStyle) + { + return; + } + + if (IsRenderingEnabled()) + { + AdjustCoordinates( aStart ); + AdjustCoordinates( aEnd ); + + THuiRealLine line(aStart, aEnd); + RArray lines; + lines.Append(line); + + UseWsState(); + + iCanvasGc->DrawLines( lines ); + lines.Close(); + + UseCanvasState(); + } + } + +void CHuiCanvasWsHwGc::WsDrawLineToL(TPoint& aPoint) + { + // If penstyle is ENullPen, then nothign is drawn + if (!iWsPenStyle) + { + return; + } + + if (IsRenderingEnabled()) + { + AdjustCoordinates( aPoint ); + TPoint currentPosition = iWsPenPosition; + THuiRealLine line(currentPosition, aPoint); + RArray lines; + lines.Append(line); + + UseWsState(); + + iCanvasGc->DrawLines( lines ); + + iWsPenPosition = aPoint; + lines.Close(); + + UseCanvasState(); + } + } + +void CHuiCanvasWsHwGc::WsDrawLineByL(TPoint& aPoint) + { + // If penstyle is ENullPen, then nothign is drawn + if (!iWsPenStyle) + { + return; + } + + if (IsRenderingEnabled()) + { + AdjustCoordinates( aPoint ); + TPoint currentPosition = iWsPenPosition; + TPoint endPoint = currentPosition + aPoint; + THuiRealLine line(currentPosition, endPoint); + RArray lines; + lines.Append(line); + + UseWsState(); + + iCanvasGc->DrawLines( lines ); + + iWsPenPosition = endPoint; + lines.Close(); + + UseCanvasState(); + } + } + +void CHuiCanvasWsHwGc::WsDrawRectL(TRect& aRect) + { + // If penstyle is ENullPen, then nothign is drawn + if (!iWsPenStyle && !iWsBrushStyle) + { + return; + } + + if (IsRenderingEnabled()) + { + AdjustCoordinates( aRect ); + RArray rects; + rects.AppendL(aRect); + + UseWsState(); + + if (iWsBrushStyle == MWsGraphicsContext::ENullBrush) + { + iCanvasGc->SetPenColor(iWsPenColor); + iCanvasGc->SetOpacity(TReal32(iWsPenColor.Alpha() / 255.f)); + iCanvasGc->SetDrawMode(SelectCanvasDrawMode(iWsDrawMode)); + iCanvasGc->DrawRects(rects); + } + else if (iWsBrushStyle == MWsGraphicsContext::ESolidBrush) + { + iCanvasGc->SetPolygonDrawMode( EHuiFillEvenOdd ); + iCanvasGc->SetPenColor(iWsBrushColor); + iCanvasGc->SetOpacity(TReal32(iWsBrushColor.Alpha() / 255.f)); + iCanvasGc->SetDrawMode(SelectCanvasDrawMode(iWsDrawMode)); + iCanvasGc->DrawRects(rects); + + + // Border should be drawn if pencolor is different than solid fill + if (IsDifferent(iWsBrushColor,iWsPenColor, ETrue) && iWsPenStyle && iWsPenSize.iHeight >= 1 && iWsPenSize.iWidth >= 1) + { + iCanvasGc->SetPolygonDrawMode( EHuiNoFill ); + iCanvasGc->SetPenColor(iWsPenColor); + iCanvasGc->SetOpacity(TReal32(iWsPenColor.Alpha() / 255.f)); + iCanvasGc->DrawRects(rects); + } + } + else if (iWsBrushStyle == MWsGraphicsContext::EPatternedBrush) + { + iCanvasGc->SetPolygonDrawMode( EHuiFillEvenOdd ); + iCanvasGc->SetPenColor(iWsPenColor); + iCanvasGc->SetOpacity(TReal32(iWsPenColor.Alpha() / 255.f)); + UseBrushPattern(); + iCanvasGc->SetDrawMode(SelectCanvasDrawMode(iWsDrawMode)); + iCanvasGc->DrawRects(rects); + DiscardBrushPattern(); + + if (iWsPenStyle && iWsPenSize.iHeight >= 1 && iWsPenSize.iWidth >= 1) + { + iCanvasGc->SetPolygonDrawMode( EHuiNoFill ); + iCanvasGc->SetPenColor(iWsPenColor); + iCanvasGc->SetOpacity(TReal32(iWsPenColor.Alpha() / 255.f)); + iCanvasGc->DrawRects(rects); + } + } + else + { + // We should never get here because fallbackmode should be used in this case ! + RDebug::Print(_L("CHuiCanvasWsHwGc::WsDrawRectL - Unsupported brush mode %i"), iWsBrushStyle); + } + + rects.Close(); + + UseCanvasState(); + } + } + +const TUint8 color_s_to_lin[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, + 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a, + 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0c, 0x0d, + 0x0d, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x10, + 0x11, 0x11, 0x12, 0x12, 0x12, 0x13, 0x13, 0x14, + 0x15, 0x15, 0x16, 0x16, 0x17, 0x17, 0x18, 0x18, + 0x19, 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1d, 0x1d, + 0x1e, 0x1f, 0x1f, 0x20, 0x21, 0x21, 0x22, 0x23, + 0x23, 0x24, 0x25, 0x26, 0x26, 0x27, 0x28, 0x29, + 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x33, 0x34, 0x35, 0x36, + 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, + 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, + 0x47, 0x48, 0x49, 0x4a, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x5a, 0x5b, 0x5c, 0x5d, 0x5f, 0x60, 0x61, 0x63, + 0x64, 0x65, 0x67, 0x68, 0x69, 0x6b, 0x6c, 0x6d, + 0x6f, 0x70, 0x72, 0x73, 0x74, 0x76, 0x77, 0x79, + 0x7a, 0x7c, 0x7d, 0x7f, 0x80, 0x82, 0x83, 0x85, + 0x86, 0x88, 0x8a, 0x8b, 0x8d, 0x8e, 0x90, 0x92, + 0x93, 0x95, 0x97, 0x98, 0x9a, 0x9c, 0x9d, 0x9f, + 0xa1, 0xa3, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xad, + 0xaf, 0xb1, 0xb3, 0xb5, 0xb7, 0xb8, 0xba, 0xbc, + 0xbe, 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, + 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, + 0xde, 0xe0, 0xe2, 0xe5, 0xe7, 0xe9, 0xeb, 0xed, + 0xef, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfd, 0xff }; + +inline TRgb ConvertToLinear(TRgb aColor) + { + // perform sRGB->linear color conversion if the renderer is + // openvg + // NOTE: For emulator depending on the OpenVG SW version mapping may + // be needed or not. Use/unuse ifdefs below if text colors are too dark/light. +//#ifndef __WINSCW__ + if (CHuiStatic::Env().Renderer() == EHuiRendererVg10) + { + TUint32 color = aColor.Internal(); + return + ((TUint32)color_s_to_lin[(color >> 0) & 0xff] << 16) | + ((TUint32)color_s_to_lin[(color >> 8) & 0xff] << 8) | + ((TUint32)color_s_to_lin[(color >> 16) & 0xff] << 0) | + (color & 0xff000000); + } +//#endif + return aColor; + } + +void CHuiCanvasWsHwGc::WsDrawText1L(TPtr& aTextValue, THuiCanvasTextParameters& aTextParameters) + { + TPoint point = iWsPenPosition; + AdjustCoordinates( point ); + THuiCachedTextParams cachedtextParams; + cachedtextParams.iFindTextPtr = &aTextValue; + cachedtextParams.iFontHandle = iWsCurrentFont; + cachedtextParams.iTextParams = aTextParameters; + cachedtextParams.iGcParams = CachedGcParams(); + + const CHuiCanvasTextImage* cachedImage = iVisual->Env().CanvasTextureCache().CreateCachedTextL(cachedtextParams,*iVisual); + + if (IsRenderingEnabled()) + { + const CHuiTexture* texture = cachedImage->Texture(); + if (texture) + { + THuiRealRect destinationRect = TRect(point, texture->Size()); + + // Adjust destination rect according to the point where text was rasterised in the image + TInt dx = cachedImage->iRasterizationOffset.iX; + TInt dy = cachedImage->iRasterizationOffset.iY; + destinationRect.Move(-dx,-dy); + + TRgb oldPenColor = iCanvasGc->PenColor(); + if (cachedImage->iUseColorModulation) + { + iCanvasGc->SetPenColor(ConvertToLinear(iWsPenColor)); + } + + // Draw + iCanvasGc->DrawImage(*texture, destinationRect, TRect(TPoint(0,0), texture->Size()), CHuiGc::EStretchNone); + + if (cachedImage->iUseColorModulation) + { + iCanvasGc->SetPenColor(oldPenColor); + } + } + } + } + +void CHuiCanvasWsHwGc::WsDrawText2L(TPtr& aTextValue, TPoint& aPoint,THuiCanvasTextParameters& aTextParameters) + { + THuiCachedTextParams cachedtextParams; + cachedtextParams.iFindTextPtr = &aTextValue; + cachedtextParams.iFontHandle = iWsCurrentFont; + cachedtextParams.iTextParams = aTextParameters; + cachedtextParams.iGcParams = CachedGcParams(); + + const CHuiCanvasTextImage* cachedImage = iVisual->Env().CanvasTextureCache().CreateCachedTextL(cachedtextParams,*iVisual); + + if (IsRenderingEnabled()) + { + const CHuiTexture* texture = cachedImage->Texture(); + if (texture) + { + AdjustCoordinates( aPoint ); + THuiRealRect destinationRect = TRect(aPoint, texture->Size()); + + // Adjust destination rect according to the point where text was rasterised in the image + TInt dx = cachedImage->iRasterizationOffset.iX; + TInt dy = cachedImage->iRasterizationOffset.iY; + destinationRect.Move(-dx,-dy); + + TRgb oldPenColor = iCanvasGc->PenColor(); + if (cachedImage->iUseColorModulation) + { + iCanvasGc->SetPenColor(ConvertToLinear(iWsPenColor)); + } + + // Draw + iCanvasGc->DrawImage(*texture, destinationRect, TRect(TPoint(0,0), texture->Size()), CHuiGc::EStretchNone); + + if (cachedImage->iUseColorModulation) + { + iCanvasGc->SetPenColor(oldPenColor); + } + } + } + } + +void CHuiCanvasWsHwGc::WsDrawText3L(TPtr& aTextValue, TRect& aRect, THuiCanvasTextParameters& aTextParameters) + { + THuiCachedTextParams cachedtextParams; + cachedtextParams.iFindTextPtr = &aTextValue; + cachedtextParams.iFontHandle = iWsCurrentFont; + cachedtextParams.iTextParams = aTextParameters; + cachedtextParams.iTextBoxMaxSize = aRect.Size(); + cachedtextParams.iGcParams = CachedGcParams(); + + const CHuiCanvasTextImage* cachedImage = iVisual->Env().CanvasTextureCache().CreateCachedTextL(cachedtextParams,*iVisual); + + if (IsRenderingEnabled()) + { + const CHuiTexture* texture = cachedImage->Texture(); + if (texture) + { + AdjustCoordinates( aRect ); + THuiRealRect destinationRect = aRect; + + // Adjust destination rect according to the point where text was rasterised in the image + TInt dx = cachedImage->iRasterizationOffset.iX; + TInt dy = cachedImage->iRasterizationOffset.iY; + destinationRect.Move(-dx,-dy); + + TRgb oldPenColor = iCanvasGc->PenColor(); + if (cachedImage->iUseColorModulation) + { + DrawTextBrush( destinationRect ); + iCanvasGc->SetPenColor(ConvertToLinear(iWsPenColor)); + } + + // Draw + iCanvasGc->DrawImage(*texture, destinationRect, TRect(TPoint(0,0), texture->Size()), CHuiGc::EStretchNone); + + if (cachedImage->iUseColorModulation) + { + iCanvasGc->SetPenColor(oldPenColor); + } + } + } + } + + +void CHuiCanvasWsHwGc::WsDrawText4L(TPtr& aTextValue, TRect& aRect, TInt aBaselineOffset, TInt aTextAlign, TInt aTextMargin,THuiCanvasTextParameters& aTextParameters) + { + THuiCachedTextParams cachedtextParams; + cachedtextParams.iFindTextPtr = &aTextValue; + cachedtextParams.iFontHandle = iWsCurrentFont; + cachedtextParams.iTextParams = aTextParameters; + cachedtextParams.iTextBoxMaxSize = aRect.Size(); + cachedtextParams.iBaseLineOffset = aBaselineOffset; + cachedtextParams.iTextAlign = aTextAlign; + cachedtextParams.iMargin = aTextMargin; + cachedtextParams.iGcParams = CachedGcParams(); + + const CHuiCanvasTextImage* cachedImage = iVisual->Env().CanvasTextureCache().CreateCachedTextL(cachedtextParams,*iVisual); + + if (IsRenderingEnabled()) + { + const CHuiTexture* texture = cachedImage->Texture(); + if (texture) + { + AdjustCoordinates( aRect ); + THuiRealRect destinationRect = aRect; + + // Adjust destination rect according to the point where text was rasterised in the image + TInt dx = cachedImage->iRasterizationOffset.iX; + TInt dy = cachedImage->iRasterizationOffset.iY; + destinationRect.Move(-dx,-dy); + + TRgb oldPenColor = iCanvasGc->PenColor(); + if (cachedImage->iUseColorModulation) + { + DrawTextBrush( destinationRect ); + iCanvasGc->SetPenColor(ConvertToLinear(iWsPenColor)); + } + + // Draw + iCanvasGc->DrawImage(*texture, destinationRect, TRect(TPoint(0,0), texture->Size()), CHuiGc::EStretchNone); + + if (cachedImage->iUseColorModulation) + { + iCanvasGc->SetPenColor(oldPenColor); + } + } + } + } + +void CHuiCanvasWsHwGc::WsDrawText5L( TPtr& aTextValue, TRect& aRect, TInt aBaselineOffset, TInt aTextAlign, TInt aTextMargin,TInt aTextWidth, THuiCanvasTextParameters& aTextParameters) + { + THuiCachedTextParams cachedtextParams; + cachedtextParams.iFindTextPtr = &aTextValue; + cachedtextParams.iFontHandle = iWsCurrentFont; + cachedtextParams.iTextParams = aTextParameters; + cachedtextParams.iTextBoxMaxSize = aRect.Size(); + cachedtextParams.iBaseLineOffset = aBaselineOffset; + cachedtextParams.iTextAlign = aTextAlign; + cachedtextParams.iMargin = aTextMargin; + cachedtextParams.iTextWidth = aTextWidth; + cachedtextParams.iGcParams = CachedGcParams(); + + const CHuiCanvasTextImage* cachedImage = iVisual->Env().CanvasTextureCache().CreateCachedTextL(cachedtextParams,*iVisual); + + if (IsRenderingEnabled()) + { + const CHuiTexture* texture = cachedImage->Texture(); + if (texture) + { + AdjustCoordinates( aRect ); + THuiRealRect destinationRect = aRect; + + // Adjust destination rect according to the point where text was rasterised in the image + TInt dx = cachedImage->iRasterizationOffset.iX; + TInt dy = cachedImage->iRasterizationOffset.iY; + destinationRect.Move(-dx,-dy); + + TRgb oldPenColor = iCanvasGc->PenColor(); + if (cachedImage->iUseColorModulation) + { + DrawTextBrush( destinationRect ); + iCanvasGc->SetPenColor(ConvertToLinear(iWsPenColor)); + } + + // Draw + iCanvasGc->DrawImage(*texture, destinationRect, TRect(TPoint(0,0), texture->Size()), CHuiGc::EStretchNone); + + if (cachedImage->iUseColorModulation) + { + iCanvasGc->SetPenColor(oldPenColor); + } + } + } + } + +void CHuiCanvasWsHwGc::WsDrawTextVertical1L(TPtr& aTextValue, TInt aTextUp, THuiCanvasTextParameters& aTextParameters) + { + TPoint point = iWsPenPosition; + TInt angle = aTextUp ? -90 : 90; + + THuiCachedTextParams cachedtextParams; + cachedtextParams.iFindTextPtr = &aTextValue; + cachedtextParams.iFontHandle = iWsCurrentFont; + cachedtextParams.iTextParams = aTextParameters; + cachedtextParams.iAngle = angle; + cachedtextParams.iGcParams = CachedGcParams(); + + const CHuiCanvasTextImage* cachedImage = iVisual->Env().CanvasTextureCache().CreateCachedTextL(cachedtextParams,*iVisual); + + if (IsRenderingEnabled()) + { + const CHuiTexture* texture = cachedImage->Texture(); + if (texture) + { + AdjustCoordinates( point ); + THuiRealRect destinationRect = TRect(point, texture->Size()); + + // Adjust destination rect according to the point where text was rasterised in the image + TInt dx = cachedImage->iRasterizationOffset.iX; + TInt dy = cachedImage->iRasterizationOffset.iY; + destinationRect.Move(-dx,-dy); + + TRgb oldPenColor = iCanvasGc->PenColor(); + if (cachedImage->iUseColorModulation) + { + iCanvasGc->SetPenColor(ConvertToLinear(iWsPenColor)); + } + + // Draw + iCanvasGc->DrawImage(*texture, destinationRect, TRect(TPoint(0,0), texture->Size()), CHuiGc::EStretchNone); + + if (cachedImage->iUseColorModulation) + { + iCanvasGc->SetPenColor(oldPenColor); + } + } + } + } + +void CHuiCanvasWsHwGc::WsDrawTextVertical2L(TPtr& aTextValue, TInt aTextUp,TPoint& aPoint, THuiCanvasTextParameters& aTextParameters) + { + TInt angle = aTextUp ? -90 : 90; + + THuiCachedTextParams cachedtextParams; + cachedtextParams.iFindTextPtr = &aTextValue; + cachedtextParams.iFontHandle = iWsCurrentFont; + cachedtextParams.iTextParams = aTextParameters; + cachedtextParams.iAngle = angle; + cachedtextParams.iGcParams = CachedGcParams(); + + const CHuiCanvasTextImage* cachedImage = iVisual->Env().CanvasTextureCache().CreateCachedTextL(cachedtextParams,*iVisual); + + if (IsRenderingEnabled()) + { + const CHuiTexture* texture = cachedImage->Texture(); + if (texture) + { + AdjustCoordinates( aPoint ); + THuiRealRect destinationRect = TRect(aPoint, texture->Size()); + + // Adjust destination rect according to the point where text was rasterised in the image + TInt dx = cachedImage->iRasterizationOffset.iX; + TInt dy = cachedImage->iRasterizationOffset.iY; + destinationRect.Move(-dx,-dy); + + TRgb oldPenColor = iCanvasGc->PenColor(); + if (cachedImage->iUseColorModulation) + { + iCanvasGc->SetPenColor(ConvertToLinear(iWsPenColor)); + } + + // Draw + iCanvasGc->DrawImage(*texture, destinationRect, TRect(TPoint(0,0), texture->Size()), CHuiGc::EStretchNone); + + if (cachedImage->iUseColorModulation) + { + iCanvasGc->SetPenColor(oldPenColor); + } + } + } + } + +void CHuiCanvasWsHwGc::WsDrawTextVertical3L(TPtr& aTextValue, TInt aTextUp, TRect& aRect, THuiCanvasTextParameters& aTextParameters) + { + TInt angle = aTextUp ? -90 : 90; + + THuiCachedTextParams cachedtextParams; + cachedtextParams.iFindTextPtr = &aTextValue; + cachedtextParams.iFontHandle = iWsCurrentFont; + cachedtextParams.iTextParams = aTextParameters; + cachedtextParams.iTextBoxMaxSize = aRect.Size(); + cachedtextParams.iAngle = angle; + cachedtextParams.iGcParams = CachedGcParams(); + + const CHuiCanvasTextImage* cachedImage = iVisual->Env().CanvasTextureCache().CreateCachedTextL(cachedtextParams,*iVisual); + + if (IsRenderingEnabled()) + { + const CHuiTexture* texture = cachedImage->Texture(); + if (texture) + { + AdjustCoordinates( aRect ); + THuiRealRect destinationRect = aRect; + + // Adjust destination rect according to the point where text was rasterised in the image + TInt dx = cachedImage->iRasterizationOffset.iX; + TInt dy = cachedImage->iRasterizationOffset.iY; + destinationRect.Move(-dx,-dy); + + TRgb oldPenColor = iCanvasGc->PenColor(); + if (cachedImage->iUseColorModulation) + { + DrawTextBrush( destinationRect ); + iCanvasGc->SetPenColor(ConvertToLinear(iWsPenColor)); + } + + // Draw + iCanvasGc->DrawImage(*texture, destinationRect, TRect(TPoint(0,0), texture->Size()), CHuiGc::EStretchNone); + + if (cachedImage->iUseColorModulation) + { + iCanvasGc->SetPenColor(oldPenColor); + } + } + } + } + +void CHuiCanvasWsHwGc::WsDrawTextVertical4L(TPtr& aTextValue, TRect& aRect, TInt aBaselineOffset, TInt aTextUp, TInt aTextAlign, TInt aTextMargin,THuiCanvasTextParameters& aTextParameters) + { + TInt angle = aTextUp ? -90 : 90; + + + THuiCachedTextParams cachedtextParams; + cachedtextParams.iFindTextPtr = &aTextValue; + cachedtextParams.iFontHandle = iWsCurrentFont; + cachedtextParams.iTextParams = aTextParameters; + cachedtextParams.iTextBoxMaxSize = aRect.Size(); + cachedtextParams.iAngle = angle; + cachedtextParams.iBaseLineOffset = aBaselineOffset; + cachedtextParams.iTextAlign = aTextAlign; + cachedtextParams.iMargin = aTextMargin; + cachedtextParams.iGcParams = CachedGcParams(); + + const CHuiCanvasTextImage* cachedImage = iVisual->Env().CanvasTextureCache().CreateCachedTextL(cachedtextParams,*iVisual); + + if (IsRenderingEnabled()) + { + const CHuiTexture* texture = cachedImage->Texture(); + if (texture) + { + AdjustCoordinates( aRect ); + THuiRealRect destinationRect = aRect; + + // Adjust destination rect according to the point where text was rasterised in the image + TInt dx = cachedImage->iRasterizationOffset.iX; + TInt dy = cachedImage->iRasterizationOffset.iY; + destinationRect.Move(-dx,-dy); + + TRgb oldPenColor = iCanvasGc->PenColor(); + if (cachedImage->iUseColorModulation) + { + DrawTextBrush( destinationRect ); + iCanvasGc->SetPenColor(ConvertToLinear(iWsPenColor)); + } + + // Draw + iCanvasGc->DrawImage(*texture, destinationRect, TRect(TPoint(0,0), texture->Size()), CHuiGc::EStretchNone); + + if (cachedImage->iUseColorModulation) + { + iCanvasGc->SetPenColor(oldPenColor); + } + } + } + } + +void CHuiCanvasWsHwGc::WsDrawTextVertical5L(TPtr& aTextValue, TRect& aRect, TInt aBaselineOffset, TInt aTextUp, TInt aTextAlign, TInt aTextMargin, TInt aTextWidth, THuiCanvasTextParameters& aTextParameters) + { + TInt angle = aTextUp ? -90 : 90; + + THuiCachedTextParams cachedtextParams; + cachedtextParams.iFindTextPtr = &aTextValue; + cachedtextParams.iFontHandle = iWsCurrentFont; + cachedtextParams.iTextParams = aTextParameters; + cachedtextParams.iTextBoxMaxSize = aRect.Size(); + cachedtextParams.iAngle = angle; + cachedtextParams.iTextWidth = aTextWidth; + cachedtextParams.iBaseLineOffset = aBaselineOffset; + cachedtextParams.iTextAlign = aTextAlign; + cachedtextParams.iMargin = aTextMargin; + cachedtextParams.iGcParams = CachedGcParams(); + + const CHuiCanvasTextImage* cachedImage = iVisual->Env().CanvasTextureCache().CreateCachedTextL(cachedtextParams,*iVisual); + + if (IsRenderingEnabled()) + { + const CHuiTexture* texture = cachedImage->Texture(); + if (texture) + { + AdjustCoordinates( aRect ); + THuiRealRect destinationRect = aRect; + + // Adjust destination rect according to the point where text was rasterised in the image + TInt dx = cachedImage->iRasterizationOffset.iX; + TInt dy = cachedImage->iRasterizationOffset.iY; + destinationRect.Move(-dx,-dy); + + TRgb oldPenColor = iCanvasGc->PenColor(); + if (cachedImage->iUseColorModulation) + { + DrawTextBrush( destinationRect ); + iCanvasGc->SetPenColor(ConvertToLinear(iWsPenColor)); + } + + // Draw + iCanvasGc->DrawImage(*texture, destinationRect, TRect(TPoint(0,0), texture->Size()), CHuiGc::EStretchNone); + + if (cachedImage->iUseColorModulation) + { + iCanvasGc->SetPenColor(oldPenColor); + } + } + } + } + +void CHuiCanvasWsHwGc::WsMoveToL( TPoint& aPoint) + { + iWsPenPosition = aPoint; + } + +void CHuiCanvasWsHwGc::WsMoveByL( TPoint& aPoint) + { + iWsPenPosition += aPoint; + } + +void CHuiCanvasWsHwGc::WsPlotL(TPoint& aPoint) + { + if (IsRenderingEnabled()) + { + AdjustCoordinates( aPoint ); + UseWsState(); + // Draw + RArray points; + CleanupClosePushL(points); + points.AppendL(THuiRealPoint(aPoint)); + iCanvasGc->DrawPoints(points); + CleanupStack::PopAndDestroy(); + UseCanvasState(); + } + } + +void CHuiCanvasWsHwGc::WsResetL() + { + iWsClipRegion.Clear(); + iWsCurrentFont = 0; + iWsOrigin = KHuiWsDefaultOrigin; + iWsPenSize = KHuiWsDefaultPenSize; + + iWsPenPosition = TPoint(0,0); + iWsFadeColor = KHuiWsDefaultFadeColor; + + iWsPenColor = KHuiWsDefaultPenColor; + iWsBrushColor = KHuiWsDefaultBrushColor; + iWsPenStyle = KHuiWsDefaultPenStyle; + iWsDrawMode = KHuiWsDefaultDrawMode; + iWsBrushStyle = KHuiWsDefaultBrushStyle; + iWsShadowMode = KHuiWsDefaultShadowMode; + iWsStrikethrough = KHuiWsDefaultStrikethrough; + iWsUnderline = KHuiWsDefaultUnderline; + iWsUserDisplayMode = KHuiWsDefaultUserDisplayMode; + iWsShadowColor = KHuiWsDefaultShadowColor; + iWsBrushPattern = 0; + iWsBrushOrigin = TPoint(0,0); + + + iCanvasGc->CancelClipping(); + iCanvasGc->SetPenColor(KRgbWhite); + iCanvasGc->SetOpacity(1.0); + iCanvasGc->SetPenWidth(1); + } + + + +void CHuiCanvasWsHwGc::WsSetBrushColorL( TRgb aColor) + { + iWsBrushColor = aColor; + } + +void CHuiCanvasWsHwGc::WsSetBrushOriginL( TPoint& aPoint) + { + iWsBrushOrigin = aPoint; + } + +void CHuiCanvasWsHwGc::WsSetBrushStyleL( TInt aStyle) + { + iWsBrushStyle = aStyle; + } + +void CHuiCanvasWsHwGc::WsSetClippingRegionL( RRegion& aRegion) + { + if (IsRenderingEnabled()) + { + iWsClipRegion.Clear(); + for (TInt i=0;iClipRegion(iWsClipRegion); + } + } + +void CHuiCanvasWsHwGc::WsSetDrawModeL( TInt aDrawMode) + { + iWsDrawMode = aDrawMode; + } + +void CHuiCanvasWsHwGc::WsSetOriginL( TPoint& aOrigin) + { + iWsOrigin = aOrigin; + } + +void CHuiCanvasWsHwGc::WsSetPenColorL( TRgb aColor) + { + iWsPenColor = aColor; + } + +void CHuiCanvasWsHwGc::WsSetPenStyleL( TInt aStyle) + { + iWsPenStyle = aStyle; + } + +void CHuiCanvasWsHwGc::WsSetPenSizeL( TInt aWidth, TInt aHeight) + { + iWsPenSize.iWidth = aWidth; + // Note, that only width is supported by HW renderer. Canvas should be draw in fallback mode, if width and height are not the same + iWsPenSize.iHeight = aHeight; + } + +void CHuiCanvasWsHwGc::WsSetTextShadowColorL( TRgb aColor) + { + iWsShadowColor = aColor; + } + +void CHuiCanvasWsHwGc::WsSetCharJustificationL( TInt /*aExcessiveWidth*/, TInt /*aNumGap*/) + { + // This is not supported by this CHuiCanvasWsGc implementation + iAllCommandsSupported = EFalse; + } + +void CHuiCanvasWsHwGc::WsSetWordJustificationL( TInt /*aExcessiveWidth*/, TInt /*aNumGap*/) + { + // This is not supported by this CHuiCanvasWsGc implementation + iAllCommandsSupported = EFalse; + } + +void CHuiCanvasWsHwGc::WsSetUnderlineStyleL( TInt aValue ) + { + if (aValue < 1000) // magic, we recycle the same function for both underline and strike through + { + iWsUnderline = aValue; + } + else + { + iWsStrikethrough=aValue-1000; + } + } + +void CHuiCanvasWsHwGc::WsSetBrushPatternL( TInt aValue ) + { + iWsBrushPattern = aValue; + } + +void CHuiCanvasWsHwGc::WsSetFontL( TInt aFontId) + { + iWsCurrentFont = aFontId; + } + +void CHuiCanvasWsHwGc::WsCopyRectL( TPoint& /*aPoint*/, TRect& /*aRect*/) + { + // This is not supported by this CHuiCanvasWsGc implementation + iAllCommandsSupported = EFalse; + } + +void CHuiCanvasWsHwGc::WsUpdateJustificationL( TPtr& /*aTextValue*/) + { + // This is not supported by this CHuiCanvasWsGc implementation + iAllCommandsSupported = EFalse; + } + +void CHuiCanvasWsHwGc::WsUpdateJustificationVerticalL( TInt /*aValue*/, TPtr& /*aTextValue*/) + { + // This is not supported by this CHuiCanvasWsGc implementation + iAllCommandsSupported = EFalse; + } + +void CHuiCanvasWsHwGc::WsSetFontNoDuplicateL( TInt aCurrentFont) + { + iWsCurrentFont = aCurrentFont; + } + +void CHuiCanvasWsHwGc::WsCopySettingsL() + { + // This is not supported by this CHuiCanvasWsGc implementation + iAllCommandsSupported = EFalse; + } + +void CHuiCanvasWsHwGc::WsSetClippingRectL( TRect& aRect) + { + if (IsRenderingEnabled()) + { + // Symbian SetClippingRect takes ws origin into account, + // but setClippingRegion does not. + AdjustCoordinates( aRect, ETrue ); + iTempRegion.Clear(); + iTempRegion.AddRect( aRect ); + iCanvasGc->ClipRegion( iTempRegion ); + } + } + +void CHuiCanvasWsHwGc::WsCancelClippingRectL() + { + if (IsRenderingEnabled()) + { + WsResetClippingRegionL(); + iCanvasGc->CancelClipping(); + } + } + +void CHuiCanvasWsHwGc::WsSetFadedL( TInt& /*aFaded*/) + { + // Nothing to do, we should get FadeArea commands if window is faded. + } + +void CHuiCanvasWsHwGc::WsSetFadingParametersL( TInt aBlackMap, TInt aWhiteMap) + { + if (IsRenderingEnabled()) + { + if (aBlackMap > aWhiteMap) + { + TInt oldMap = aBlackMap; + aBlackMap = aWhiteMap; + aWhiteMap = oldMap; + } + + const TUint16* lut = PtrTo16BitNormalisationTable(); + + //CFbsBitGc::FadeArea() does the following per color component: + // dst = dst * (aWhiteMap - aBlackMap) + aBlackMap; + + //To achieve the same effect using MWsGraphicsContext we draw a rectangle + //with specific intensity and alpha values: + // dst = dst * (1 - alpha) + intensity * alpha; + //Thus: + // alpha = 1 - aWhiteMap + aBlackMap; + // intensity = aBlackMap / alpha; + + // alpha = 1 - aWhiteMap + aBlackMap; + TInt alpha = 255 - aWhiteMap + aBlackMap; + // intensity = aBlackMap / alpha; + TInt i = (aBlackMap * lut[alpha]) >> 8; + + iWsFadeColor.SetInternal(i << 16 | i << 8 | i | alpha << 24); + } + } + +void CHuiCanvasWsHwGc::WsFadeAreaL( RRegion& aRegion) + { + if (IsRenderingEnabled()) + { + RArray realRects; + for (TInt i=0; iSetPenColor(fadeColor); + iCanvasGc->SetOpacity(opacity); + iCanvasGc->SetPolygonDrawMode(EHuiFillNonZero); + iCanvasGc->SetDrawMode(SelectCanvasDrawMode(iWsDrawMode)); + + iCanvasGc->DrawRects(realRects); + + UseCanvasState(); + + realRects.Close(); + aRegion.Close(); + } + } + +void CHuiCanvasWsHwGc::WsMapColorsL() + { + // This is not supported by this CHuiCanvasWsGc implementation + iAllCommandsSupported = EFalse; + } + +void CHuiCanvasWsHwGc::WsSetUserDisplayModeL( TInt aMode ) + { + iWsUserDisplayMode = aMode; + } + +void CHuiCanvasWsHwGc::WsUseFontL(TInt aCurrentFont) + { + iWsCurrentFont = aCurrentFont; + } + +void CHuiCanvasWsHwGc::BeginActionL(TInt aAction, TRect aDisplayRect, const CHuiCanvasVisual& aUser, TBool aIsCachePrepared, const TRegion& aUpdateRegion) + { + iAction = aAction; + iVisual = (CHuiCanvasVisual*)&aUser; + iAllCommandsSupported = ETrue; + + if (aAction == EDrawBuffer) + { + BeginDrawL(aDisplayRect, aUser, aIsCachePrepared, aUpdateRegion); + } + else if (aAction == EScanBuffer) + { + BeginScanL(aDisplayRect, aUser, aIsCachePrepared, aUpdateRegion); + } + else + { + // Should not happen + } + } + +void CHuiCanvasWsHwGc::EndActionL(const TRegion& aUpdateRegion, TBool aUpdateDisplay) + { + if (iAction == EDrawBuffer) + { + EndDrawL(aUpdateRegion, aUpdateDisplay); + } + else if (iAction == EScanBuffer) + { + EndScanL(aUpdateRegion, aUpdateDisplay); + } + else + { + // Should not happen + } + } + +void CHuiCanvasWsHwGc::BeginDrawL(TRect aDisplayRect,const CHuiCanvasVisual& aUser, TBool aIsCachePrepared, const TRegion& aUpdateRegion) + { + CHuiCanvasRenderBuffer* renderbuffer = NULL; + TRect updatedRect = aUpdateRegion.BoundingRect(); + TBool renderBufferCreated = EFalse; + + // Try to get render buffer if it has been enabled + if (iRenderBufferEnabled && updatedRect.Size() != TSize(0,0)) + { + renderbuffer = iVisual->Env().CanvasTextureCache().FindCachedRenderBuffer(aUser); + if (!renderbuffer) + { + renderbuffer = iVisual->Env().CanvasTextureCache().CreateCachedRenderBufferL(aUser, updatedRect.Size()); + renderBufferCreated = ETrue; + } + } + + if (renderbuffer) + { + // If renderbuffer is not initialized, set the internal flag to EFalse. It will be set + // to ETrue after drawing has been done. + if (!renderbuffer->IsInitialized() || renderbuffer->Size() != updatedRect.Size() || renderBufferCreated) + { + iRenderBufferInitialized = EFalse; + } + + // We can access render buffer, mark it to be available. + iRenderBufferAvailable = ETrue; + + // Render buffer is prepared if caller says that cache is prepared and renderbuffer has been initialized. + iRenderBufferPrepared = aIsCachePrepared && iRenderBufferInitialized; + } + else + { + // We could not access render buffer, mark it to be unavailable. + iRenderBufferAvailable = EFalse; + } + + // If render buffer is not prepared, we must prepare it. We will set the flag at EndActionL when + // we really have prepared it. + if (IsRenderBufferUpdateOngoing()) + { + // Init render buffer (it only really initializes if needed) + renderbuffer->InitializeL(updatedRect.Size()); + + // Bind render buffer + BindRenderBuffer(renderbuffer, aUpdateRegion); + } + iCanvasGc->RestoreFlaggedState(); + } + +void CHuiCanvasWsHwGc::BeginScanL(TRect aDisplayRect,const CHuiCanvasVisual& aUser, TBool aIsCachePrepared, const TRegion& aUpdateRegion) + { + CHuiCanvasRenderBuffer* renderbuffer = NULL; + TRect updatedRect = aUpdateRegion.BoundingRect(); + TBool renderBufferCreated = EFalse; + + // Try to get render buffer if it has been enabled + if (iRenderBufferEnabled && updatedRect.Size() != TSize(0,0)) + { + renderbuffer = iVisual->Env().CanvasTextureCache().FindCachedRenderBuffer(aUser); + if (!renderbuffer) + { + renderbuffer = iVisual->Env().CanvasTextureCache().CreateCachedRenderBufferL(aUser, updatedRect.Size()); + renderBufferCreated = ETrue; + } + } + + if (renderbuffer) + { + // If renderbuffer is not initialized, set the internal flag to EFalse. It will be set + // to ETrue after drawing has been done. + if (!renderbuffer->IsInitialized() || renderbuffer->Size() != updatedRect.Size() || renderBufferCreated) + { + iRenderBufferInitialized = EFalse; + } + + // We can access render buffer, mark it to be available. + iRenderBufferAvailable = ETrue; + + // Render buffer is prepared if caller says that cache is prepared and renderbuffer has been initialized. + iRenderBufferPrepared = aIsCachePrepared && iRenderBufferInitialized; + } + else + { + // We could not access render buffer, mark it to be unavailable. + iRenderBufferAvailable = EFalse; + } + + // If render buffer is not prepared, we must prepare it. We will set the flag at EndActionL when + // we really have prepared it. + if (IsRenderBufferUpdateOngoing()) + { + // Init render buffer (it only really initializes if needed) + renderbuffer->InitializeL(updatedRect.Size()); + } + + iCanvasGc->RestoreFlaggedState(); + } + +void CHuiCanvasWsHwGc::EndDrawL(const TRegion& aUpdateRegion, TBool aUpdateDisplay) + { + CHuiCanvasRenderBuffer* renderbuffer = NULL; + + // Check if we have cached render buffer available + if (IsRenderBufferEnabled()) + { + renderbuffer = iVisual->Env().CanvasTextureCache().FindCachedRenderBuffer(*iVisual); + } + + if (renderbuffer) + { + // We can access render buffer, mark it to be available. + iRenderBufferAvailable = ETrue; + } + else + { + // We could not access render buffer, mark it to be unavailable. + iRenderBufferAvailable = EFalse; + } + + // Are we updating into render buffer + if (IsRenderBufferUpdateOngoing()) + { + // Are we rendering + UnBindRenderBuffer(renderbuffer); + // If we really did draw to the renderbuffer, then set it "prepared". + if (iCanvasGc->Gc()) + { + iRenderBufferInitialized = ETrue; + iRenderBufferPrepared = ETrue; + } + } + + iCanvasGc->RestoreFlaggedState(); + + // Cancel clipping if still active etc... + iCanvasGc->SetDefaults(); + + // If render buffer is used, draw its content to display here + if (aUpdateDisplay && renderbuffer && iCanvasGc->Gc()) + { + THuiRealRect updatedRect = aUpdateRegion.BoundingRect(); + + // Handle relative rotation + TRect displayArea = iVisual->Display()->VisibleArea(); + TInt w = displayArea.Width(); + TInt h = displayArea.Height(); + + // ...select right rotation... + if (iRelativeOrientation == CHuiGc::EOrientationCW90) + { + // Rotate around origo and move back to displayarea + iCanvasGc->Rotate(-90, 0, 0, 1.f); + iCanvasGc->Translate(-h, 0, 0); + } + else if (iRelativeOrientation == CHuiGc::EOrientationCCW90) + { + // Rotate around origo and move back to displayarea + iCanvasGc->Rotate(90, 0, 0, 1.f); + iCanvasGc->Translate(0, -w, 0); + } + else if (iRelativeOrientation == CHuiGc::EOrientation180) + { + // Rotate around origo and move back to displayarea + iCanvasGc->Rotate(180, 0, 0, 1.f); + iCanvasGc->Translate(-w, -h, 0); + } + else + { + // Nothing + } + + iCanvasGc->ClipRegion(aUpdateRegion); + THuiCanvasDrawMode dmode = iCanvasGc->DrawMode(); + // blend only transparent windows + if ((iVisual->Flags() & EHuiVisualFlagOpaqueHint) && !(iVisual->EffectiveOpacity() < 1.0f)) + { + iCanvasGc->SetDrawMode(EHuiCanvasDrawModeNormal); + } + else + { + iCanvasGc->SetDrawMode(EHuiCanvasDrawModeBlend); + } + + iCanvasGc->DrawImage(*renderbuffer, updatedRect.iTl); + iCanvasGc->CancelClipping(); + iCanvasGc->SetDrawMode(dmode); + } + } + +void CHuiCanvasWsHwGc::EndScanL(const TRegion& aUpdateRegion, TBool aUpdateDisplay) + { + CHuiCanvasRenderBuffer* renderbuffer = NULL; + + // Check if we have cached render buffer available + if (IsRenderBufferEnabled()) + { + renderbuffer = iVisual->Env().CanvasTextureCache().FindCachedRenderBuffer(*iVisual); + } + + if (renderbuffer) + { + // We can access render buffer, mark it to be available. + iRenderBufferAvailable = ETrue; + } + else + { + // We could not access render buffer, mark it to be unavailable. + iRenderBufferAvailable = EFalse; + } + + // Cancel clipping if still active etc... + iCanvasGc->RestoreFlaggedState(); + iCanvasGc->SetDefaults(); + } + + +CHuiCanvasGc& CHuiCanvasWsHwGc::CanvasGc() const + { + return *iCanvasGc; + } + +THuiCachedGcParams CHuiCanvasWsHwGc::CachedGcParams() + { + THuiCachedGcParams params; + params.iPenColor = iWsPenColor; + params.iBrushColor = iWsBrushColor; + params.iPenStyle = iWsPenStyle; + params.iDrawMode = iWsDrawMode; + params.iBrushColor = iWsBrushColor; + params.iBrushStyle = iWsBrushStyle; + params.iShadowMode = iWsShadowMode; + params.iStrikethrough = iWsStrikethrough; + params.iUnderline = iWsUnderline; + params.iUserDisplayMode = iWsUserDisplayMode; + params.iShadowColor = iWsShadowColor; + return params; + } + +TInt CHuiCanvasWsHwGc::SetCapturingBufferL(CFbsBitmap* /*aTarget*/) + { + // This implementation does not support capturing + return KErrNotSupported; + } + +void CHuiCanvasWsHwGc::SetPositionDelta( TPoint& aPoint ) + { + iPosDelta = aPoint; + } + +TRect CHuiCanvasWsHwGc::RoundedDisplayRect() + { + if (iVisual) + { + return iVisual->DisplayRect().Round(); + } + else + { + return TRect(0,0,0,0); + } + } + +void CHuiCanvasWsHwGc::ClearCache() + { + if (iVisual) + { + iVisual->Env().CanvasTextureCache().ReleaseCachedRenderBuffer(*iVisual); + } + } + +TBool CHuiCanvasWsHwGc::IsRenderBufferEnabled() const + { + return iRenderBufferEnabled && iRenderBufferAvailable; + } + +TBool CHuiCanvasWsHwGc::IsRenderBufferPrepared() const + { + return iRenderBufferEnabled && iRenderBufferAvailable && iRenderBufferPrepared; + } + +TBool CHuiCanvasWsHwGc::IsRenderBufferInitialized() const + { + return iRenderBufferEnabled && iRenderBufferAvailable && iRenderBufferInitialized; + } + + +TBool CHuiCanvasWsHwGc::IsRenderingEnabled() const + { + if (iAction == EDrawBuffer) + { + return ETrue; + } + else if (iAction == EScanBuffer) + { + return EFalse; + } + else + { + return EFalse; + } + } + +TBool CHuiCanvasWsHwGc::IsRenderBufferUpdateOngoing() const + { + return iRenderBufferEnabled && iRenderBufferAvailable && !iRenderBufferPrepared; + } + + +TInt CHuiCanvasWsHwGc::EnableRenderbuffer(TBool aEnable) + { + // TODO: Some renderers should return KErrNotSupported + TInt retVal = KErrNone; + iRenderBufferEnabled = aEnable; + return retVal; + } + +THuiCanvasWsGcType CHuiCanvasWsHwGc::Type() const + { + return EHuiCanvasWsHw; + } + +THuiCanvasDrawMode CHuiCanvasWsHwGc::SelectCanvasDrawMode(TInt aWsDrawMode) + { + if (aWsDrawMode == MWsGraphicsContext::EDrawModeWriteAlpha) + { + return EHuiCanvasDrawModeNormal; + } + else + { + return EHuiCanvasDrawModeBlend; + } + } + +void CHuiCanvasWsHwGc::EnableUpdateRegion(const TRegion& aUpdateRegion, TBool aClear) + { + CHuiGc* gc = iCanvasGc->Gc(); + if (gc && IsRenderingEnabled()) + { + gc->Enable(CHuiGc::EFeatureClipping); + gc->PushClip(); + gc->Clip(aUpdateRegion); + if (aClear) + { + TInt oldAlpha = gc->PenAlpha(); + TRgb oldColor = gc->PenColor(); + gc->SetPenAlpha(0); + gc->SetPenColor(KRgbBlue); + gc->Clear(); + gc->SetPenAlpha(oldAlpha); + gc->SetPenColor(oldColor); + } + } + } + +void CHuiCanvasWsHwGc::DisableUpdateRegion() + { + CHuiGc* gc = iCanvasGc->Gc(); + if (gc && IsRenderingEnabled()) + { + gc->PopClip(); + } + } + +void CHuiCanvasWsHwGc::BindRenderBuffer(CHuiCanvasRenderBuffer* aRenderbuffer, const TRegion& aUpdateRegion) + { + // Disable effective opacity when rendering to a buffer + iCanvasGc->EnableEffectiveOpacity(EFalse); + + THuiRealRect updatedRect = aUpdateRegion.BoundingRect(); + + // Bind render buffer as rendering target (further drawing will be redirected to render buffer) + aRenderbuffer->Bind(); + + // Restore gc state after render target bind/unbind ops + iCanvasGc->RestoreState(); + + // Translation values + TReal32 x = -updatedRect.iTl.iX; + TReal32 y = -updatedRect.iTl.iY; + + // Push clipping so that we can restore it after we have done drawing into render buffer. + iCanvasGc->Gc()->PushClip(); + + // Set new clipping region which does not clip anything. + // We want always draw aUpdateRegion fully to the aRenderbuffer. + TRect displayArea = iCanvasGc->Gc()->DisplayArea(); + iCanvasGc->Gc()->SetClip(displayArea); // this call does not transform region anymore + + // We use translation to get screen coordinates to match render buffer coordinates + iCanvasGc->PushTransformationMatrix(); + iCanvasGc->Translate(x, y, 0.f); + + // Handle relative rotation + TInt w = displayArea.Width(); + TInt h = displayArea.Height(); + + // ...select right rotation... + if (iRelativeOrientation == CHuiGc::EOrientationCW90) + { + // Rotate around origo and move back to displayarea + iCanvasGc->Rotate(-90, 0, 0, 1.f); + iCanvasGc->Translate(-h, 0, 0); + } + else if (iRelativeOrientation == CHuiGc::EOrientationCCW90) + { + // Rotate around origo and move back to displayarea + iCanvasGc->Rotate(90, 0, 0, 1.f); + iCanvasGc->Translate(0, -w, 0); + } + else if (iRelativeOrientation == CHuiGc::EOrientation180) + { + // Rotate around origo and move back to displayarea + iCanvasGc->Rotate(180, 0, 0, 1.f); + iCanvasGc->Translate(-w, -h, 0); + } + else + { + // Nothing + } + + // Set needed clip region + iCanvasGc->Gc()->Clip(aUpdateRegion); + } + +void CHuiCanvasWsHwGc::UnBindRenderBuffer(CHuiCanvasRenderBuffer* aRenderbuffer) + { + // Enable effective opacity again when no more rendering to buffer + iCanvasGc->EnableEffectiveOpacity(ETrue); + + // Restore translation (screen coordinates to match render buffer coordinates) + iCanvasGc->PopTransformationMatrix(); + + // Restore clipping + iCanvasGc->Gc()->PopClip(); + + // Unbind render buffer as rendering target (further drawing will be done to display normally) + aRenderbuffer->UnBind(); + + // Restore gc state after render target bind/unbind ops + iCanvasGc->RestoreState(); + } + +void CHuiCanvasWsHwGc::SetRelativeOrientation(CHuiGc::TOrientation aOrientation) + { + iRelativeOrientation = aOrientation; + } + + +void CHuiCanvasWsHwGc::UseBrushPattern() + { + THuiCachedImageParams cachedImageParams; + cachedImageParams.iBitmapHandle = iWsBrushPattern; + cachedImageParams.iGcParams = CachedGcParams(); + + const CHuiCanvasGraphicImage* cachedImage = iVisual->Env().CanvasTextureCache().CreateCachedImageL(cachedImageParams,*iVisual); + if (IsRenderingEnabled()) + { + iCanvasGc->SetPolygonFillTexture(cachedImage->Texture()); + // Symbian implementation for CWindowGc is different from CFbsBitGc. Latter + // adds iWsOrigin to iWsBrushOrigin, but because we are implementing + // CWindowGc, we do not take iWsOrigin into account here. + iCanvasGc->SetPolygonFillTextureOrigin(iWsBrushOrigin); + } + } + +void CHuiCanvasWsHwGc::DiscardBrushPattern() + { + if (IsRenderingEnabled()) + { + iCanvasGc->SetPolygonFillTexture(NULL); + iCanvasGc->SetPolygonFillTextureOrigin(TPoint(0,0)); + } + } + +TBool CHuiCanvasWsHwGc::IsDifferent(const TRgb& aFirst, const TRgb& aSecond, TBool aIgnoreAlpha) + { + if (aIgnoreAlpha) + { + const TUint32 mask = 0x00FFFFFF; + return ((aFirst.Internal() & mask) != (aSecond.Internal() & mask)); + } + else + { + return (aFirst.Internal() != aSecond.Internal()); + } + } + +void CHuiCanvasWsHwGc::UseWsState() + { +#ifdef __WINS__ + iPushCount++; + if(iPushCount>1) + { + // This function cannot be called recursively. Fix your code. + USER_INVARIANT(); + } +#endif + iOldColor = iCanvasGc->PenColor(); + iOldOpacity = iCanvasGc->Opacity(); + iOldDrawMode = iCanvasGc->DrawMode(); + iOldPenWidth = iCanvasGc->PenWidth(); + iOldPolygonDrawMode = iCanvasGc->PolygonDrawMode(); + + iCanvasGc->SetPenColor(iWsPenColor); + iCanvasGc->SetOpacity(TReal32(iWsPenColor.Alpha() / 255.f)); + iCanvasGc->SetDrawMode(SelectCanvasDrawMode(iWsDrawMode)); + iCanvasGc->SetPenWidth(iWsPenSize.iWidth); + iCanvasGc->PolygonDrawMode(); + } + +void CHuiCanvasWsHwGc::UseCanvasState() + { +#ifdef __WINS__ + iPushCount--; + if(iPushCount!=0) + { + // This function cannot be called recursively. Fix your code. + USER_INVARIANT(); + } +#endif + iCanvasGc->SetPenColor(iOldColor); + iCanvasGc->SetOpacity(iOldOpacity); + iCanvasGc->SetDrawMode(iOldDrawMode); + iCanvasGc->SetPenWidth(iOldPenWidth); + iCanvasGc->SetPolygonDrawMode(iOldPolygonDrawMode); + }