diff -r 000000000000 -r 15bf7259bb7c uiacceltk/hitchcock/coretoolkit/src/huicanvasalfpainter.cpp --- /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 +#include +#include +#include "huicanvasalfpainter.h" + + + + +template +void HuiCanavasGcInternalizeL( const TDesC8& aDes, RArray& 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 lines; + for(TInt i=0, j=0; iDrawLines(lines); + } + else + { + for (TInt i=0;iPenWidth(), 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 points; + for(TInt i=0, j=0; iDrawPoints(points); + } + else + { + for (TInt i=0;iPenWidth(), iCanvasGc->PenWidth()); + aUser.ExpandRect(aDisplayRect, pointRect); + } + } + points.Close(); + break; + } + case EHuiCanvasDrawPolygon: + { + iPointCords.Reset(); + TRAP_IGNORE(HuiCanavasGcInternalizeL(buffer, iPointCords)) + TInt pointcount = iPointCords.Count()/2; + RArray points; + for(TInt i=0, j=0; iDrawPolygon(points); + } + else + { + for (TInt i=0;iPenWidth(), iCanvasGc->PenWidth()); + aUser.ExpandRect(aDisplayRect, pointRect); + } + } + + points.Close(); + break; + } + case EHuiCanvasDrawRects: + { + iPointCords.Reset(); + TRAP_IGNORE(HuiCanavasGcInternalizeL(buffer, iPointCords)) + TInt rectcount = iPointCords.Count()/4; + RArray rects; + for(TInt i=0, j=0; iDrawRects(rects); + } + else + { + for (TInt i=0;iPenWidth(), 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; + }