--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/coretoolkit/src/huicanvasalfpainter.cpp Tue Feb 02 07:56:43 2010 +0200
@@ -0,0 +1,614 @@
+/*
+* Copyright (c) 2007-2008 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 CHuiCanvasAlfPainter.
+*
+*/
+
+
+
+
+#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 <graphics/wsgraphicscontext.h>
+#include <e32cmn.h>
+#include <AknLayoutFont.h>
+#include "huicanvasalfpainter.h"
+
+
+
+
+template <class T>
+void HuiCanavasGcInternalizeL( const TDesC8& aDes, RArray<T>& aArray )
+ {
+ aArray.Reset();
+ if ( !aDes.Length() )
+ {
+ return;
+ }
+
+ TInt itemCount = 0;
+ memcpy(&itemCount, &aDes[0], sizeof(TInt));
+
+ TPtrC8 buffer( &aDes[4], itemCount*sizeof(T) );
+
+ for ( TInt i = 0 ; i < itemCount ; i++ )
+ {
+ T* itemPtr = (T*)&buffer[i*sizeof(T)];
+ T item = *itemPtr;
+ User::LeaveIfError( aArray.Append( item ) );
+ }
+ }
+
+
+CHuiCanvasAlfPainter* CHuiCanvasAlfPainter::NewL()
+ {
+ CHuiCanvasAlfPainter* self = new ( ELeave ) CHuiCanvasAlfPainter;
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+
+ return self;
+ }
+
+
+CHuiCanvasAlfPainter::CHuiCanvasAlfPainter()
+ {
+ }
+
+void CHuiCanvasAlfPainter::ConstructL()
+ {
+ iPartialCommandBuffer = NULL;
+ iCanvasGc = CHuiStatic::Renderer().CreateCanvasGcL();
+ }
+
+
+CHuiCanvasAlfPainter::~CHuiCanvasAlfPainter()
+ {
+ iCachedTexts.Close();
+ iPointCords.Close();
+ delete iCanvasGc;
+ iCanvasGc = NULL;
+ }
+
+
+void CHuiCanvasAlfPainter::HandleBufferL(TRect& aDisplayRect, TInt aAction, const CHuiCanvasVisual& aUser, CHuiGc* aGc, TPoint/* aPos*/ )
+ {
+ TInt commandNumber = 0;
+ TInt currentText = -1;
+ TInt bufferCount = iCommandBuffers.Count();
+ iCanvasGc->SetVisual(aUser);
+ if ( aGc )
+ {
+ iCanvasGc->SetGc(*aGc);
+ }
+ iCanvasGc->SetDefaults();
+
+ for (TInt cb = 0; cb < bufferCount; cb++)
+ {
+ TPtrC8 ptr = *iCommandBuffers[cb]->iCommands;
+ while ( ptr.Length() )
+ {
+ TInt command = 0;
+ memcpy(&command, &ptr[0], sizeof(TInt));
+
+ ptr.Set( ptr.Right( ptr.Length() - 4 ) );
+
+ TInt bufferLength = 0;
+ memcpy(&bufferLength, &ptr[0], sizeof(TInt));
+
+ // Make sure we are aligned by 4 bytes
+ TInt padding = 0;
+ if (bufferLength % 4)
+ {
+ padding = 4 - (bufferLength % 4);
+ }
+ bufferLength += padding;
+
+ ptr.Set( ptr.Right( ptr.Length() - 4 ) );
+
+ TPtrC8 buffer( ptr.Left( bufferLength ).Ptr(), bufferLength );
+
+ ptr.Set( ptr.Right( ptr.Length() - bufferLength) );
+
+ commandNumber++;
+ switch( command )
+ {
+ case EHuiCanvasDrawImage:
+ {
+ const THuiCanvasDrawImageParams* const params = (THuiCanvasDrawImageParams*)buffer.Ptr();
+
+ CHuiTexture* texture = (CHuiTexture*)(params->iTexture);
+
+ THuiRealPoint topLeft = THuiRealPoint(params->iDestinationRectTopLeftX,
+ params->iDestinationRectTopLeftY);
+
+ THuiRealPoint bottomRight = THuiRealPoint(params->iDestinationRectBottomRightX,
+ params->iDestinationRectBottomRightY);
+
+ // Conversion to pixels (if needed) and to screen coordinates from visual coordinates
+ THuiRealRect destRect = THuiRealRect(aUser.ConvertPoint(topLeft), aUser.ConvertPoint(bottomRight));
+
+ if (aAction == EDrawBuffer)
+ {
+ iCanvasGc->DrawImage(*texture, destRect);
+ }
+ else
+ {
+ aUser.ExpandRect(aDisplayRect, destRect);
+ }
+ break;
+ }
+ case EHuiCanvasPrepareDrawText:
+ {
+ TPtrC text((const TUint16*)buffer.Ptr(), buffer.Length()/2);
+
+ // Check if we already have created a rasterized version of text into cache...
+ TInt cachedEntry = -1;
+ for (TInt i=0; i < iCachedTexts.Count(); i++)
+ {
+ if (iCachedTexts[i].iId == commandNumber)
+ {
+ cachedEntry = i;
+ }
+ }
+
+ // ...no, this is first drawing time so we need to rasterize text
+ if (cachedEntry == -1)
+ {
+ // Create new text mesh
+ CHuiTextMesh* mesh = CHuiStatic::Renderer().CreateTextMeshL();
+ CleanupStack::PushL(mesh);
+ mesh->SetTextStyle(iCanvasGc->TextStyle());
+ mesh->SetTextL(text, ETrue);
+
+ THuiCanvasDrawTextCachedTextEntry newEntry;
+ newEntry.iId = commandNumber;
+ newEntry.iTextMesh = mesh;
+ iCachedTexts.AppendL(newEntry);
+ CleanupStack::Pop(mesh);
+ cachedEntry = iCachedTexts.Count() - 1;
+ }
+
+ currentText = commandNumber;
+ break;
+ }
+ case EHuiCanvasDrawText:
+ {
+ const THuiCanvasDrawTextParams* const params = (THuiCanvasDrawTextParams*)buffer.Ptr();
+
+ THuiRealPoint topLeft = THuiRealPoint(params->iDestinationRectTopLeftX,
+ params->iDestinationRectTopLeftY);
+
+ THuiRealPoint bottomRight = THuiRealPoint(params->iDestinationRectBottomRightX,
+ params->iDestinationRectBottomRightY);
+
+ // Conversion to pixels (if needed) and to screen coordinates from visual coordinates
+ THuiRealRect destRect = THuiRealRect(aUser.ConvertPoint(topLeft), aUser.ConvertPoint(bottomRight));
+
+ // Check if we already have created a rasterized version of text into cache...
+ TInt cachedEntry = -1;
+ for (TInt i=0; i < iCachedTexts.Count(); i++)
+ {
+ if (iCachedTexts[i].iId == currentText)
+ {
+ cachedEntry = i;
+ }
+ }
+
+ if (cachedEntry != -1 && iCachedTexts[cachedEntry].iTextMesh)
+ {
+ if (aAction == EDrawBuffer)
+ {
+ iCanvasGc->DrawText(*iCachedTexts[cachedEntry].iTextMesh, destRect);
+ }
+ else if (aAction == EScanBuffer)
+ {
+ TSize extents = iCachedTexts[cachedEntry].iTextMesh->Extents();
+ TRect destinationRect = destRect;
+ TPoint tl = destinationRect.Center();
+ switch( iCanvasGc->TextHorizontalAlign() )
+ {
+ case EHuiAlignHLeft:
+ tl.iX = destinationRect.iTl.iX;
+ break;
+ case EHuiAlignHCenter:
+ tl.iX -= extents.iWidth/2;
+ break;
+ case EHuiAlignHRight:
+ tl.iX = destinationRect.iBr.iX - extents.iWidth;
+ break;
+ default:
+ break;
+ }
+
+ // check top left Y
+ switch( iCanvasGc->TextVerticalAlign() )
+ {
+ case EHuiAlignVTop:
+ tl.iY = destinationRect.iTl.iY;
+ break;
+ case EHuiAlignVCenter:
+ tl.iY -= extents.iHeight/2;
+ break;
+ case EHuiAlignVBottom:
+ tl.iY = destinationRect.iBr.iY - extents.iHeight;
+ break;
+ default:
+ break;
+ }
+
+ TRect textExtendsRect(tl, extents);
+ aUser.ExpandRect(aDisplayRect, textExtendsRect);
+ }
+ }
+
+ break;
+ }
+ case EHuiCanvasDrawLines:
+ {
+ iPointCords.Reset();
+ TRAP_IGNORE(HuiCanavasGcInternalizeL(buffer, iPointCords))
+ TInt linecount = iPointCords.Count()/4;
+ RArray<THuiRealLine> lines;
+ for(TInt i=0, j=0; i<linecount; i++)
+ {
+ THuiRealPoint start(iPointCords[j], iPointCords[j+1]);
+ THuiRealPoint end(iPointCords[j+2], iPointCords[j+3]);
+ THuiRealLine line(aUser.ConvertPoint(start), aUser.ConvertPoint(end));
+ lines.Append(line);
+ j += 4;
+ }
+
+ if (aAction == EDrawBuffer)
+ {
+ iCanvasGc->DrawLines(lines);
+ }
+ else
+ {
+ for (TInt i=0;i<lines.Count();i++)
+ {
+ TRect pointRect = TRect(lines[i].iStart,lines[i].iStart );
+ pointRect.Grow(iCanvasGc->PenWidth(), iCanvasGc->PenWidth());
+ aUser.ExpandRect(aDisplayRect, pointRect);
+
+ pointRect = TRect(lines[i].iEnd,lines[i].iEnd );
+ pointRect.Grow(iCanvasGc->PenWidth(), iCanvasGc->PenWidth());
+ aUser.ExpandRect(aDisplayRect, pointRect);
+ }
+ }
+ lines.Close();
+ break;
+ }
+
+ case EHuiCanvasDrawEllipse:
+ {
+ const THuiCanvasDrawEllipseParams* const params = (THuiCanvasDrawEllipseParams*)buffer.Ptr();
+
+ THuiRealPoint topLeft = THuiRealPoint(params->iDestinationRectTopLeftX, params->iDestinationRectTopLeftY);
+
+ THuiRealPoint bottomRight = THuiRealPoint(params->iDestinationRectBottomRightX, params->iDestinationRectBottomRightY);
+
+ // Conversion to pixels (if needed) and to screen coordinates from visual coordinates
+ THuiRealRect destRect = THuiRealRect(aUser.ConvertPoint(topLeft), aUser.ConvertPoint(bottomRight));
+
+ if (aAction == EDrawBuffer)
+ {
+ iCanvasGc->DrawEllipse(destRect);
+ }
+ else
+ {
+ aUser.ExpandRect(aDisplayRect, destRect);
+ }
+ break;
+ }
+ case EHuiCanvasDrawPoints:
+ {
+ iPointCords.Reset();
+ TRAP_IGNORE(HuiCanavasGcInternalizeL(buffer, iPointCords))
+ TInt pointcount = iPointCords.Count()/2;
+ RArray<THuiRealPoint> points;
+ for(TInt i=0, j=0; i<pointcount; i++)
+ {
+ THuiRealPoint point(iPointCords[j], iPointCords[j+1]);
+ points.Append(aUser.ConvertPoint(point));
+ j += 2;
+ }
+
+ if (aAction == EDrawBuffer)
+ {
+ iCanvasGc->DrawPoints(points);
+ }
+ else
+ {
+ for (TInt i=0;i<points.Count();i++)
+ {
+ TRect pointRect = TRect(points[i],points[i]);
+ pointRect.Grow(iCanvasGc->PenWidth(), iCanvasGc->PenWidth());
+ aUser.ExpandRect(aDisplayRect, pointRect);
+ }
+ }
+ points.Close();
+ break;
+ }
+ case EHuiCanvasDrawPolygon:
+ {
+ iPointCords.Reset();
+ TRAP_IGNORE(HuiCanavasGcInternalizeL(buffer, iPointCords))
+ TInt pointcount = iPointCords.Count()/2;
+ RArray<THuiRealPoint> points;
+ for(TInt i=0, j=0; i<pointcount; i++)
+ {
+ THuiRealPoint point(iPointCords[j], iPointCords[j+1]);
+ points.Append(aUser.ConvertPoint(point));
+ j += 2;
+ }
+
+ if (aAction == EDrawBuffer)
+ {
+ iCanvasGc->DrawPolygon(points);
+ }
+ else
+ {
+ for (TInt i=0;i<points.Count();i++)
+ {
+ TRect pointRect = TRect(points[i],points[i]);
+ pointRect.Grow(iCanvasGc->PenWidth(), iCanvasGc->PenWidth());
+ aUser.ExpandRect(aDisplayRect, pointRect);
+ }
+ }
+
+ points.Close();
+ break;
+ }
+ case EHuiCanvasDrawRects:
+ {
+ iPointCords.Reset();
+ TRAP_IGNORE(HuiCanavasGcInternalizeL(buffer, iPointCords))
+ TInt rectcount = iPointCords.Count()/4;
+ RArray<THuiRealRect> rects;
+ for(TInt i=0, j=0; i<rectcount; i++)
+ {
+ THuiRealPoint topleft(iPointCords[j], iPointCords[j+1]);
+ THuiRealPoint bottomright(iPointCords[j+2], iPointCords[j+3]);
+ THuiRealRect rect(aUser.ConvertPoint(topleft), aUser.ConvertPoint(bottomright));
+ rects.Append(rect);
+ j += 4;
+ }
+
+ if (aAction == EDrawBuffer)
+ {
+ iCanvasGc->DrawRects(rects);
+ }
+ else
+ {
+ for (TInt i=0;i<rects.Count();i++)
+ {
+ TRect pointRect = rects[i];
+ pointRect.Grow(iCanvasGc->PenWidth(), iCanvasGc->PenWidth());
+ aUser.ExpandRect(aDisplayRect, pointRect);
+ }
+ }
+
+ rects.Close();
+ break;
+ }
+
+ case EHuiCanvasSetTextStyle:
+ {
+ const THuiCanvasSetTextStyleParams* const params = (THuiCanvasSetTextStyleParams*)buffer.Ptr();
+ iCanvasGc->SetTextStyle(params->iTextStyleId);
+ break;
+ }
+
+ case EHuiCanvasSetPenColor:
+ {
+ const THuiCanvasSetPenColorParams* const params = (THuiCanvasSetPenColorParams*)buffer.Ptr();
+ iCanvasGc->SetPenColor(params->iPenColor);
+ break;
+ }
+ case EHuiCanvasSetPenWidth:
+ {
+ const THuiCanvasSetPenWidthParams* const params = (THuiCanvasSetPenWidthParams*)buffer.Ptr();
+ iCanvasGc->SetPenWidth(params->iPenWidth);
+ break;
+ }
+ case EHuiCanvasSetOpacity:
+ {
+ const THuiCanvasSetOpacityParams* const params = (THuiCanvasSetOpacityParams*)buffer.Ptr();
+ iCanvasGc->SetOpacity(params->iOpacity);
+ break;
+ }
+ case EHuiCanvasSetPolygonDrawMode:
+ {
+ const THuiCanvasSetPolygonDrawModeParams* const params = (THuiCanvasSetPolygonDrawModeParams*)buffer.Ptr();
+ iCanvasGc->SetPolygonDrawMode(params->iPolygonDrawMode);
+ break;
+ }
+ case EHuiCanvasSetTextAlign:
+ {
+ const THuiCanvasSetTextAlignParams* const params = (THuiCanvasSetTextAlignParams*)buffer.Ptr();
+ iCanvasGc->SetTextAlign(THuiAlignHorizontal(params->iTextAlignHorizontal), THuiAlignVertical(params->iTextAlignVertical));
+ break;
+ }
+
+ case EHuiCanvasLoadIdentity:
+ {
+ if (aAction == EDrawBuffer)
+ {
+ iCanvasGc->LoadIdentity();
+ }
+ break;
+ }
+ case EHuiCanvasTranslate:
+ {
+ const THuiCanvasTranslateParams* const params = (THuiCanvasTranslateParams*)buffer.Ptr();
+ if (aAction == EDrawBuffer)
+ {
+ iCanvasGc->Translate(aUser.ConvertPoint(THuiRealPoint(params->iX,0)).iX,
+ aUser.ConvertPoint(THuiRealPoint(params->iY,0)).iX,
+ aUser.ConvertPoint(THuiRealPoint(params->iZ,0)).iX);
+ }
+ else
+ {
+ // Calculating transformations may be too difficult, so just set largest possible rect
+ if (aUser.Clipping() || !aUser.Display())
+ {
+ aUser.ExpandRect(aDisplayRect, aUser.DisplayRect());
+ }
+ else
+ {
+ aUser.ExpandRect(aDisplayRect, aUser.Display()->VisibleArea());
+ }
+ }
+ break;
+ }
+ case EHuiCanvasScale:
+ {
+ const THuiCanvasScaleParams* const params = (THuiCanvasScaleParams*)buffer.Ptr();
+ if (aAction == EDrawBuffer)
+ {
+ iCanvasGc->Scale(params->iX, params->iY, params->iZ);
+ }
+ else
+ {
+ // Calculating transformations may be too difficult, so just set largest possible rect
+ if (aUser.Clipping() || !aUser.Display())
+ {
+ aUser.ExpandRect(aDisplayRect, aUser.DisplayRect());
+ }
+ else
+ {
+ aUser.ExpandRect(aDisplayRect, aUser.Display()->VisibleArea());
+ }
+ }
+ break;
+ }
+ case EHuiCanvasRotate:
+ {
+ const THuiCanvasRotateParams* const params = (THuiCanvasRotateParams*)buffer.Ptr();
+ if (aAction == EDrawBuffer)
+ {
+ iCanvasGc->Rotate(params->iAngle, params->iX, params->iY, params->iZ);
+ }
+ else
+ {
+ // Calculating transformations may be too difficult, so just set largest possible rect
+ if (aUser.Clipping() || !aUser.Display())
+ {
+ aUser.ExpandRect(aDisplayRect, aUser.DisplayRect());
+ }
+ else
+ {
+ aUser.ExpandRect(aDisplayRect, aUser.Display()->VisibleArea());
+ }
+ }
+ break;
+ }
+ default:
+ {
+ __ASSERT_DEBUG(EFalse, THuiPanic::Panic(THuiPanic::EUnknown));
+ break;
+ }
+ }
+ }
+ }
+ iPaintedRect = aUser.DisplayRect();
+ }
+
+
+
+void CHuiCanvasAlfPainter::SetCommandSetL( const TDesC8& aCommands )
+ {
+ CHuiCanvasPainter::SetCommandSetL(aCommands);
+ }
+
+void CHuiCanvasAlfPainter::ClearCommandSet()
+ {
+ CHuiCanvasPainter::ClearCommandSet();
+ }
+
+void CHuiCanvasAlfPainter::AddCommandSetL( const TDesC8& aMoreCommands )
+ {
+ CHuiCanvasPainter::AddCommandSetL(aMoreCommands);
+ }
+
+void CHuiCanvasAlfPainter::AddPartialCommandSetL( const TDesC8& aMoreCommands, TBool aLastPart )
+ {
+ CHuiCanvasPainter::AddPartialCommandSetL(aMoreCommands,aLastPart);
+ }
+
+#ifdef HUI_DEBUG_TRACK_DRAWING
+void CHuiCanvasAlfPainter::SetTrackCommandSet( TFileName& aFileName, TBool aTrack )
+ {
+ CHuiCanvasPainter::SetTrackCommandSet( aFileName, aTrack );
+ }
+#endif
+
+void CHuiCanvasAlfPainter::ClearCache()
+ {
+ ClearHuiTextCache();
+ }
+
+void CHuiCanvasAlfPainter::ClearHuiTextCache()
+ {
+ // Hui text meshes
+ for (TInt i=0; i < iCachedTexts.Count(); i++)
+ {
+ delete iCachedTexts[i].iTextMesh;
+ iCachedTexts[i].iTextMesh = NULL;
+ }
+ iCachedTexts.Reset();
+ }
+
+CHuiCanvasGc& CHuiCanvasAlfPainter::CanvasGc() const
+ {
+ return *iCanvasGc;
+ }
+
+TInt CHuiCanvasAlfPainter::PaintedAreaCount() const
+ {
+ return 1;
+ }
+
+THuiCanvasPaintedArea CHuiCanvasAlfPainter::PaintedArea(TInt /*aIndex*/)
+ {
+ THuiCanvasPaintedArea area;
+ area.iPaintedRect = iPaintedRect;
+ area.iPaintType = EHuiCanvasPaintTypeTransparent;
+ area.iFlags = 0;
+ return area;
+ }
+
+TInt CHuiCanvasAlfPainter::SetCapturingBufferL(CFbsBitmap* /*aTarget*/)
+ {
+ return KErrNotSupported;
+ }
+
+TInt CHuiCanvasAlfPainter::EnableRenderBuffer(TBool /*aEnable*/)
+ {
+ return KErrNotSupported;
+ }