graphicscomposition/surfaceupdate/tsrc/tsurfacehelper.cpp
changeset 0 5d03bc08d59c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicscomposition/surfaceupdate/tsrc/tsurfacehelper.cpp	Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,229 @@
+// Copyright (c) 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:
+//
+
+#include "tsurfacehelper.h"
+#include <w32std.h>
+
+CSurfaceHelper* CSurfaceHelper::NewL()
+	{
+	CSurfaceHelper* helper = new(ELeave)CSurfaceHelper;
+	CleanupStack::PushL(helper);
+	helper->ConstructL();
+	CleanupStack::Pop(helper);
+	return helper;
+	}
+
+CSurfaceHelper::~CSurfaceHelper()
+	{
+	DestroySurfaces();
+	iSurfaces.Close();
+	iManager.Close();
+	}
+
+/**
+ * Load logical device and open a surface manager
+ */
+void CSurfaceHelper::ConstructL()
+	{
+	TInt res = iManager.Open();
+	if (res != KErrNone)
+		{
+		User::Leave(res);
+		}
+	}
+
+/**
+ * Create the surface with the given parameters.
+ * The surface will be owned by the instance of this class  
+ */
+TSurfaceId CSurfaceHelper::CreateSurfaceL(const TSize& aSize, TUidPixelFormat aPixelFormat, TInt aStride, TInt aBuffers)
+	{
+	RSurfaceManager::TSurfaceCreationAttributesBuf bf;
+	RSurfaceManager::TSurfaceCreationAttributes& b = bf();
+	
+	b.iSize.iWidth = aSize.iWidth;
+	b.iSize.iHeight = aSize.iHeight;
+	b.iBuffers = aBuffers;				// number of buffers in the surface
+	b.iPixelFormat = aPixelFormat;
+	b.iStride = aStride;		// Number of bytes between start of one line and start of next
+	b.iOffsetToFirstBuffer = 0;	// way of reserving space before the surface pixel data
+	b.iAlignment = 4;			// alignment, 1,2,4,8 byte aligned
+	b.iContiguous = EFalse;
+	b.iMappable = ETrue;
+
+	TSurfaceId surface = TSurfaceId::CreateNullId();
+
+	User::LeaveIfError(iManager.CreateSurface(bf, surface));
+	iSurfaces.AppendL(surface);
+	return surface;
+	}
+
+/**
+ * Destroy all surfaces wich have been created by the instance of this class
+ */
+void CSurfaceHelper::DestroySurfaces()
+	{
+	TInt numSurfaces = iSurfaces.Count();
+	for (TInt index = 0; index < numSurfaces; index++)
+		{
+		TSurfaceId surfaceId = iSurfaces[index];
+		TInt err = iManager.CloseSurface(surfaceId);
+		__ASSERT_DEBUG(err ==KErrNone, User::Panic(_L("CSurfaceHelper::DestroySurfaces"), err));
+		}
+	iSurfaces.Reset();
+	}
+
+/**
+Fill a rectangle on the given surface.
+
+@param aSurface		The surface to be filled.
+@param aStartPos	Where to place the rectangle.
+@param aSize		Size of the rectangle.
+@param aColor		The colour to fill it with.
+*/
+void CSurfaceHelper::FillRectangleL(const TSurfaceId& aSurface, const TPoint& aStartPos, const TSize& aSize, const TRgb& aColor)
+	{
+	RSurfaceManager::TInfoBuf infoBuf;
+	RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
+	User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
+	TUint32 color = 0;
+
+	if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0)
+		{
+		User::Leave(KErrCorrupt);
+		}
+	if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0)
+		{
+		User::Leave(KErrNotReady);
+		}
+
+	switch (info.iPixelFormat)
+		{
+		case EUidPixelFormatXRGB_8888:
+			{
+			color = aColor.Color16MU();
+#ifdef ALPHA_FIX_24BIT
+			color |= ((ALPHA_FIX_24BIT)&0xff)<<24;
+#endif
+			break;
+			}
+		case EUidPixelFormatARGB_8888:
+			{
+			color = aColor.Color16MA();
+			break;
+			}
+		case EUidPixelFormatARGB_8888_PRE:
+			{
+			color = aColor.Color16MAP();
+			break;
+			}
+		case EUidPixelFormatRGB_565:
+			{
+			color = aColor.Color64K();
+			break;
+			}
+		default:
+			{
+			User::Leave(KErrNotSupported);
+			break;
+			}
+		}
+
+	RChunk chunk;
+	User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
+	CleanupClosePushL(chunk);
+	TUint8* surfacePtr = chunk.Base();
+	
+	// Check for out of bounds
+	TBool validRect = ETrue;
+	TInt surfaceWidth = info.iSize.iWidth;
+	TInt surfaceHeight = info.iSize.iHeight;
+	
+	// Width and Height
+	if ((aStartPos.iX + aSize.iWidth) > surfaceWidth)
+		{
+		validRect = EFalse;
+		}
+	
+	if ((aStartPos.iY + aSize.iHeight) > surfaceHeight)
+		{
+		validRect = EFalse;
+		}
+	
+	// Starting position
+	if ((aStartPos.iX < 0) || (aStartPos.iY < 0))
+		{
+		validRect = EFalse;
+		}
+	
+	if (!validRect)
+		{
+		User::Leave(KErrOverflow);
+		}
+		
+	if (info.iPixelFormat == EUidPixelFormatRGB_565)
+		{//2 bytes per pixel
+		if ( info.iSize.iWidth*2>info.iStride)
+			{
+			User::Leave(KErrOverflow);
+			}
+		
+		TInt offset;
+		User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offset));
+		TUint16* ptr = reinterpret_cast<TUint16*>(surfacePtr + offset);
+		
+		// Fill the rectangle
+		TInt yPos = aStartPos.iY;
+		TInt xPos = aStartPos.iX;
+		for (TInt yy = 0; yy < aSize.iHeight; ++yy)
+			{
+			ptr = reinterpret_cast<TUint16*>(surfacePtr + (yPos*info.iStride));
+			for (TInt xx = 0; xx < aSize.iWidth; ++xx)
+				{
+				ptr[xPos] = color;
+				xPos++;
+				}
+			xPos = aStartPos.iX;
+			yPos++;
+			}
+		}
+	else
+		{
+		if ( info.iSize.iWidth*4>info.iStride)
+			{
+			User::Leave(KErrOverflow);
+			}
+
+		TInt offset;
+		User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offset));
+		TUint32* ptr = reinterpret_cast<TUint32*>(surfacePtr + offset);		
+		
+		// Fill the rectangle
+		TInt yPos = aStartPos.iY;
+		TInt xPos = aStartPos.iX;
+		for (TInt yy = 0; yy < aSize.iHeight; ++yy)
+			{
+			ptr = reinterpret_cast<TUint32*>(surfacePtr+(yPos*info.iStride));
+			for (TInt xx = 0; xx < aSize.iWidth; ++xx)
+				{
+				ptr[xPos] = color;
+				xPos++;
+				}
+			xPos = aStartPos.iX;
+			yPos++;
+			}
+		}
+	CleanupStack::PopAndDestroy(&chunk);
+	}