uiacceltk/hitchcock/coretoolkit/src/huicanvasalfpainter.cpp
changeset 0 15bf7259bb7c
--- /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;
+    }