sl@0: // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: /** sl@0: * @file sl@0: */ sl@0: sl@0: #include sl@0: #include sl@0: #include "surfaceutility.h" sl@0: #include sl@0: sl@0: //_LIT(KFileName,"surfacemanager"); sl@0: sl@0: CSurfaceUtility::CSurfaceUtility(CSurfaceUtility* aClone/*=NULL*/) sl@0: : iSurfaces(aClone?&(aClone->iSurfaces):NULL) sl@0: { sl@0: } sl@0: sl@0: CSurfaceUtility* CSurfaceUtility::NewL(CSurfaceUtility* aClone/*=NULL*/) sl@0: { sl@0: CSurfaceUtility* utility = new (ELeave)CSurfaceUtility(aClone); sl@0: CleanupStack::PushL(utility); sl@0: utility->ConstructL(); sl@0: CleanupStack::Pop(utility); sl@0: return utility; sl@0: } sl@0: sl@0: void CSurfaceUtility::ConstructL() sl@0: { sl@0: TInt r = iManager.Open(); sl@0: if (r != KErrNone) sl@0: { sl@0: LOG(("Surface manager failed to open: %d", r)); sl@0: User::Leave(r); sl@0: } sl@0: sl@0: r = iSurfaceUpdateSession.Connect(); sl@0: if (r != KErrNone) sl@0: { sl@0: LOG(("Failed to connect to update server: %d", r)); sl@0: User::Leave(r); sl@0: } sl@0: } sl@0: sl@0: CSurfaceUtility::~CSurfaceUtility() sl@0: { sl@0: DestroyAll(); sl@0: sl@0: iSurfaces.Close(); sl@0: sl@0: iManager.Close(); sl@0: sl@0: iSurfaceUpdateSession.Close(); sl@0: sl@0: // the following call is needed because of a bug in CImageDecoder that sl@0: // leaks heap memory sl@0: REComSession::FinalClose(); sl@0: } sl@0: sl@0: TBool CSurfaceUtility::DestroyAll() sl@0: { sl@0: TInt err = KErrNone; sl@0: TInt jj = iSurfaces.Count() - 1; sl@0: if (jj<0) sl@0: return EFalse; sl@0: for (; jj >= 0; jj--) sl@0: { sl@0: err = iManager.CloseSurface(iSurfaces[jj]); sl@0: if (err!=KErrNone) sl@0: { sl@0: LOG(("Error closing surface: 0x%X\n", err)); sl@0: } sl@0: } sl@0: iSurfaces.Reset(); sl@0: return ETrue; sl@0: } sl@0: sl@0: /*************************************** sl@0: * The aim of the THeapSurfaceArray is to locally switch in the specified heap for any array operation sl@0: ***************************************/ sl@0: sl@0: CSurfaceUtility::RHeapSurfaceArray::RHeapSurfaceArray(RHeapSurfaceArray* aUseExternalArray) sl@0: : iUseArray(aUseExternalArray?aUseExternalArray->iUseArray:&this->iLocalArray), sl@0: iExternalHeapRef(aUseExternalArray?aUseExternalArray->iExternalHeapRef:User::Heap()) sl@0: { sl@0: sl@0: } sl@0: /************************************ sl@0: * The following methods have been used by the surfaceutility... some require the heap wrapping, and some don't sl@0: * I actually need three different startegies (count em) for 7 methods... sl@0: * Some methods only read the existing objects, so don't need a heap swap at all sl@0: * Leaving methods have to use PopAndDestroy strategy to restore the heap on leaving or success sl@0: * Non-leaving methods must not call PushL, so directly make SwitchHeap calls! sl@0: ************************************/ sl@0: sl@0: // PopAndDestroy method to restore the heap sl@0: /*static*/ void CSurfaceUtility::RHeapSurfaceArray::PopHeap(void* aHeapPtr) sl@0: { sl@0: RHeap* heapPtr=(RHeap*)aHeapPtr; sl@0: User::SwitchHeap(heapPtr); sl@0: } sl@0: sl@0: // Switches and pushes the previous heap so it can be restored with PopAndDestroy sl@0: /*static*/ void CSurfaceUtility::RHeapSurfaceArray::SwitchHeapLC(RHeap* aNewHeap) sl@0: { sl@0: CleanupStack::PushL(TCleanupItem(PopHeap,NULL)); sl@0: CleanupStack::PushL(TCleanupItem(PopHeap,NULL)); sl@0: CleanupStack::PushL(TCleanupItem(PopHeap,NULL)); sl@0: CleanupStack::Pop(3); sl@0: RHeap* oldHeap=User::SwitchHeap(aNewHeap); sl@0: delete new char; sl@0: CleanupStack::PushL(TCleanupItem(PopHeap,oldHeap)); sl@0: } sl@0: sl@0: sl@0: TSurfaceId& CSurfaceUtility::RHeapSurfaceArray::operator[](TUint aIndex) sl@0: { sl@0: return iUseArray->operator[](aIndex); sl@0: } sl@0: // Close only closes the local array, while Reset resets the active array (may be external) sl@0: void CSurfaceUtility::RHeapSurfaceArray::Close() sl@0: { sl@0: RHeap* oldHeap=User::SwitchHeap(&iExternalHeapRef); sl@0: iLocalArray.Close(); sl@0: User::SwitchHeap(oldHeap); sl@0: } sl@0: TInt CSurfaceUtility::RHeapSurfaceArray::Count() const sl@0: { sl@0: return iUseArray->Count(); sl@0: } sl@0: // Close only closes the local array, while Reset resets the active array (may be external) sl@0: inline void CSurfaceUtility::RHeapSurfaceArray::Reset() sl@0: { sl@0: RHeap* oldHeap=User::SwitchHeap(&iExternalHeapRef); sl@0: iUseArray->Reset(); sl@0: User::SwitchHeap(oldHeap); sl@0: } sl@0: void CSurfaceUtility::RHeapSurfaceArray::AppendL(const TSurfaceId &anEntry) sl@0: { sl@0: SwitchHeapLC(&iExternalHeapRef); sl@0: iUseArray->AppendL(anEntry); sl@0: CleanupStack::PopAndDestroy(); sl@0: } sl@0: TInt CSurfaceUtility::RHeapSurfaceArray::Find(const TSurfaceId &anEntry) const sl@0: { sl@0: return iUseArray->Find(anEntry); sl@0: } sl@0: void CSurfaceUtility::RHeapSurfaceArray::Remove(TInt anIndex) sl@0: { sl@0: RHeap* oldHeap=User::SwitchHeap(&iExternalHeapRef); sl@0: iUseArray->Remove(anIndex); sl@0: User::SwitchHeap(oldHeap); sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: /** sl@0: Cleanup stack helper object, holding references to both utility and surface, so sl@0: that the standard Close() semantics can be used. sl@0: */ sl@0: class TSurfaceCleanup sl@0: { sl@0: public: sl@0: TSurfaceCleanup(CSurfaceUtility& aUtility, TSurfaceId& aSurface) sl@0: : iUtility(aUtility), iSurface(aSurface) sl@0: {} sl@0: void Close() sl@0: { sl@0: // Removes the surface from the list of surfaces to clean up, and closes sl@0: // the surface reference. sl@0: iUtility.DestroySurface(iSurface); sl@0: } sl@0: private: sl@0: CSurfaceUtility& iUtility; sl@0: TSurfaceId& iSurface; sl@0: }; sl@0: sl@0: /** sl@0: Read the given image file into a new surface. sl@0: sl@0: @param aFileName The name of the image file. sl@0: @param aSurface Filled with the surface ID for the surface containing the pixels. sl@0: */ sl@0: void CSurfaceUtility::CreateSurfaceFromFileL(const TDesC& aFileName, TSurfaceId& aSurface) sl@0: { sl@0: RFs fs; sl@0: sl@0: User::LeaveIfError(fs.Connect()); sl@0: CleanupClosePushL(fs); sl@0: CImageDecoder* decoder = CImageDecoder::FileNewL(fs, aFileName, CImageDecoder::EOptionAlwaysThread); sl@0: CleanupStack::PushL(decoder); sl@0: sl@0: const TFrameInfo& info = decoder->FrameInfo(); sl@0: sl@0: TSize size = info.iOverallSizeInPixels; sl@0: TInt stride = size.iWidth << 2; // Default to four bytes per pixel sl@0: TDisplayMode bmpFormat = info.iFrameDisplayMode; sl@0: TUidPixelFormat pixelFormat = EUidPixelFormatUnknown; sl@0: sl@0: switch (bmpFormat) sl@0: { sl@0: case EGray2: sl@0: case EGray4: sl@0: case EGray16: sl@0: case EGray256: sl@0: case EColor16: sl@0: case EColor256: sl@0: case EColor16M: sl@0: case EColor16MU: sl@0: { sl@0: bmpFormat = EColor16MU; sl@0: pixelFormat = EUidPixelFormatXRGB_8888; sl@0: break; sl@0: } sl@0: case EColor4K: sl@0: { sl@0: stride = size.iWidth << 1; sl@0: pixelFormat = EUidPixelFormatXRGB_4444; sl@0: break; sl@0: } sl@0: case EColor64K: sl@0: { sl@0: stride = size.iWidth << 1; sl@0: pixelFormat = EUidPixelFormatRGB_565; sl@0: break; sl@0: } sl@0: case EColor16MA: sl@0: { sl@0: pixelFormat = EUidPixelFormatARGB_8888; sl@0: break; sl@0: } sl@0: case EColor16MAP: sl@0: { sl@0: pixelFormat = EUidPixelFormatARGB_8888_PRE; sl@0: break; sl@0: } sl@0: default: sl@0: { sl@0: LOG(("Unsupported display mode: %d", bmpFormat)); sl@0: User::Leave(KErrNotSupported); sl@0: break; sl@0: } sl@0: } sl@0: sl@0: // Create an intermediary bitmap for decoding into sl@0: CFbsBitmap* bitmap = new (ELeave) CFbsBitmap(); sl@0: CleanupStack::PushL(bitmap); sl@0: User::LeaveIfError(bitmap->Create(size, info.iFrameDisplayMode)); sl@0: sl@0: // Create the final surface. sl@0: aSurface = CreateSurfaceL(size, pixelFormat, stride); sl@0: TSurfaceCleanup surfaceCleanup(*this, aSurface); sl@0: CleanupClosePushL(surfaceCleanup); sl@0: sl@0: RChunk chunk; sl@0: User::LeaveIfError(iManager.MapSurface(aSurface, chunk)); sl@0: CleanupClosePushL(chunk); sl@0: sl@0: // Convert the image file into a Symbian bitmap sl@0: TRequestStatus status; sl@0: decoder->Convert(&status, *bitmap); sl@0: User::WaitForRequest(status); sl@0: User::LeaveIfError(status.Int()); sl@0: sl@0: // Copy the data from the bitmap into the surface. sl@0: TPoint start; sl@0: for (start.iY = 0; start.iY < size.iHeight; start.iY++) sl@0: { sl@0: // Set up a descriptor for the current line in the surface and get pixels. sl@0: TPtr8 ptr(chunk.Base() + start.iY * stride, stride); sl@0: bitmap->GetScanLine(ptr, start, size.iWidth, bmpFormat); sl@0: } sl@0: sl@0: CleanupStack::PopAndDestroy(/* chunk */); sl@0: CleanupStack::Pop(/* surfaceCleanup */); sl@0: CleanupStack::PopAndDestroy(bitmap); sl@0: CleanupStack::PopAndDestroy(decoder); sl@0: CleanupStack::PopAndDestroy(/* fs */); sl@0: } sl@0: sl@0: void CSurfaceUtility::CopyBitmapSurfaceL(const CFbsBitmap* aBitmap, TSurfaceId& aSurface) sl@0: { sl@0: RChunk chunk; sl@0: User::LeaveIfError(iManager.MapSurface(aSurface, chunk)); sl@0: CleanupClosePushL(chunk); sl@0: TSize bitmapSize = aBitmap->SizeInPixels(); sl@0: TSize size = SurfaceSize(aSurface); sl@0: TInt stride = size.iWidth*4; // Default to four bytes per pixel sl@0: sl@0: // Copy the data from the bitmap into the surface. sl@0: TPoint start; sl@0: for (start.iY = 0; start.iY < bitmapSize.iHeight; start.iY++) sl@0: { sl@0: // Set up a descriptor for the current line in the surface and get pixels. sl@0: TPtr8 ptr(chunk.Base() + start.iY * stride, stride); sl@0: aBitmap->GetScanLine(ptr, start, bitmapSize.iWidth, EColor16MU); sl@0: } sl@0: CleanupStack::PopAndDestroy(/* chunk */); sl@0: sl@0: } sl@0: /** sl@0: Copy the bitmap from a file to a surface. sl@0: sl@0: @param aFileName The name of the image file. sl@0: @param aSurface Filled with the surface ID for the surface containing the pixels. sl@0: */ sl@0: void CSurfaceUtility::CopyBitmapFromFileToSurfaceL(const TDesC& aFileName, const TSurfaceId& aSurface) sl@0: { sl@0: RFs fs; sl@0: sl@0: User::LeaveIfError(fs.Connect()); sl@0: CleanupClosePushL(fs); sl@0: CImageDecoder* decoder = CImageDecoder::FileNewL(fs, aFileName, CImageDecoder::EOptionAlwaysThread); sl@0: CleanupStack::PushL(decoder); sl@0: sl@0: const TFrameInfo& info = decoder->FrameInfo(); sl@0: sl@0: TSize size = SurfaceSize(aSurface); sl@0: TDisplayMode bmpFormat = info.iFrameDisplayMode; sl@0: TInt stride = size.iWidth << 2; // Default to four bytes per pixel sl@0: sl@0: // Create an intermediary bitmap for decoding into sl@0: CFbsBitmap* bitmap = new (ELeave) CFbsBitmap(); sl@0: CleanupStack::PushL(bitmap); sl@0: User::LeaveIfError(bitmap->Create(size, info.iFrameDisplayMode)); sl@0: sl@0: RChunk chunk; sl@0: User::LeaveIfError(iManager.MapSurface(aSurface, chunk)); sl@0: CleanupClosePushL(chunk); sl@0: sl@0: // Convert the image file into a Symbian bitmap sl@0: TRequestStatus status; sl@0: decoder->Convert(&status, *bitmap); sl@0: User::WaitForRequest(status); sl@0: User::LeaveIfError(status.Int()); sl@0: sl@0: // Copy the data from the bitmap into the surface. sl@0: TPoint start; sl@0: for (start.iY = 0; start.iY < size.iHeight; start.iY++) sl@0: { sl@0: // Set up a descriptor for the current line in the surface and get pixels. sl@0: TPtr8 ptr(chunk.Base() + start.iY * stride, stride); sl@0: bitmap->GetScanLine(ptr, start, size.iWidth, bmpFormat); sl@0: } sl@0: sl@0: CleanupStack::PopAndDestroy(/* chunk */); sl@0: CleanupStack::PopAndDestroy(bitmap); sl@0: CleanupStack::PopAndDestroy(decoder); sl@0: CleanupStack::PopAndDestroy(/* fs */); sl@0: } sl@0: sl@0: /** sl@0: Copy the bitmap from a file to a surface scaling the original image to cover the entire surface. sl@0: sl@0: @param aFileName The name of the image file. sl@0: @param aSurface Filled with the surface ID for the surface containing the pixels. sl@0: */ sl@0: void CSurfaceUtility::ScaleBitmapFromFileToSurfaceL(const TDesC& aFileName, const TSurfaceId& aSurface) sl@0: { sl@0: sl@0: RFs fs; sl@0: User::LeaveIfError(fs.Connect()); sl@0: CleanupClosePushL(fs); sl@0: CImageDecoder* decoder = CImageDecoder::FileNewL(fs, aFileName, CImageDecoder::EOptionAlwaysThread); sl@0: CleanupStack::PushL(decoder); sl@0: sl@0: const TFrameInfo& info = decoder->FrameInfo(); sl@0: sl@0: TSize size = SurfaceSize(aSurface); sl@0: TInt stride = size.iWidth << 2; // Default to four bytes per pixel sl@0: sl@0: // Create an intermediary bitmap for decoding into sl@0: CFbsBitmap* bitmap = new (ELeave) CFbsBitmap(); sl@0: CleanupStack::PushL(bitmap); sl@0: User::LeaveIfError(bitmap->Create(info.iOverallSizeInPixels, info.iFrameDisplayMode)); sl@0: sl@0: RChunk chunk; sl@0: User::LeaveIfError(iManager.MapSurface(aSurface, chunk)); sl@0: CleanupClosePushL(chunk); sl@0: TUint8* surfacePixelData = chunk.Base() + PixelDataOffet(aSurface); sl@0: sl@0: // Convert the image file into a Symbian bitmap sl@0: // CImageDecoder::EOptionAlwaysThread setting above avoids need for Active Object sl@0: TRequestStatus status; sl@0: decoder->Convert(&status, *bitmap); sl@0: User::WaitForRequest(status); sl@0: User::LeaveIfError(status.Int()); sl@0: sl@0: // scale to fit surface sl@0: CBitmapScaler* scaler = CBitmapScaler::NewL(); sl@0: CleanupStack::PushL(scaler); sl@0: scaler->SetQualityAlgorithm(CBitmapScaler::EMaximumQuality); sl@0: sl@0: CActiveListener* activeListener = CActiveListener::NewLC(); sl@0: activeListener->Initialize(); sl@0: scaler->Scale(&activeListener->iStatus, *bitmap, size, EFalse); sl@0: CActiveScheduler::Start(); sl@0: sl@0: User::LeaveIfError(activeListener->iStatus.Int()); sl@0: sl@0: // Copy the data from the bitmap into the surface. sl@0: TPoint start; sl@0: for (start.iY = 0; start.iY < size.iHeight; start.iY++) sl@0: { sl@0: // Set up a descriptor for the current line in the surface and get pixels. sl@0: TPtr8 ptr(surfacePixelData + start.iY * stride, stride); sl@0: bitmap->GetScanLine(ptr, start, size.iWidth, EColor16MA); sl@0: } sl@0: CleanupStack::PopAndDestroy(activeListener); sl@0: CleanupStack::PopAndDestroy(scaler); sl@0: CleanupStack::PopAndDestroy(/* chunk */); sl@0: CleanupStack::PopAndDestroy(bitmap); sl@0: CleanupStack::PopAndDestroy(decoder); sl@0: CleanupStack::PopAndDestroy(/* fs */); sl@0: } sl@0: sl@0: /** sl@0: Get the size of a surface. sl@0: sl@0: @param aSurface The surface to get the size for. sl@0: @return The size in pixels, or empty on failure. sl@0: */ sl@0: TSize CSurfaceUtility::SurfaceSize(const TSurfaceId& aSurface) sl@0: { sl@0: RSurfaceManager::TInfoBuf infoBuf; sl@0: RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); sl@0: sl@0: if (iManager.SurfaceInfo(aSurface, infoBuf) == KErrNone) sl@0: { sl@0: return info.iSize; sl@0: } sl@0: sl@0: return TSize(); sl@0: } sl@0: sl@0: /** sl@0: Get the offset into the chunk of the start of pixel data. sl@0: sl@0: @param aSurface The surface to get the size for. sl@0: @return The offset bytes, or empty on failure. sl@0: */ sl@0: TInt CSurfaceUtility::PixelDataOffet(const TSurfaceId& aSurface) sl@0: { sl@0: TInt offsetToFirstBuffer = 0; sl@0: iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer); sl@0: sl@0: return offsetToFirstBuffer; sl@0: } sl@0: sl@0: sl@0: /** sl@0: Create a surface using the surface manager. sl@0: sl@0: Stores the ID for tear down, as well as returning it. sl@0: sl@0: @param aSize Dimensions of the surface. sl@0: @param aPixelFormat UID of the pixel format. sl@0: @param aStride Stride value for the surface (usually bytes per pixel * width) sl@0: @leave May leave due to lack of memory. sl@0: @return New surface's ID. sl@0: */ sl@0: TSurfaceId CSurfaceUtility::CreateSurfaceL(const TSize& aSize, TUidPixelFormat aPixelFormat, TInt aStride, TInt aBuffers) sl@0: { sl@0: RSurfaceManager::TSurfaceCreationAttributesBuf bf; sl@0: RSurfaceManager::TSurfaceCreationAttributes& b = bf(); sl@0: sl@0: b.iSize.iWidth = aSize.iWidth; sl@0: b.iSize.iHeight = aSize.iHeight; sl@0: b.iBuffers = aBuffers; // number of buffers in the surface sl@0: b.iPixelFormat = aPixelFormat; sl@0: b.iStride = aStride; // Number of bytes between start of one line and start of next sl@0: b.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data sl@0: b.iAlignment = 4; // alignment, 1,2,4,8 byte aligned sl@0: b.iContiguous=EFalse; sl@0: sl@0: TSurfaceId surface = TSurfaceId::CreateNullId(); sl@0: sl@0: User::LeaveIfError(iManager.CreateSurface(bf, surface)); sl@0: iSurfaces.AppendL(surface); sl@0: return surface; sl@0: } sl@0: sl@0: sl@0: /** sl@0: Fill the given surface with a color. sl@0: sl@0: @param aSurface The surface to be filled. sl@0: @param aColor The color to fill it with. sl@0: */ sl@0: void CSurfaceUtility::FillSurfaceL(TSurfaceId& aSurface, const TRgb& aColor) sl@0: { sl@0: RSurfaceManager::TInfoBuf infoBuf; sl@0: RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); sl@0: sl@0: User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf)); sl@0: TUint32 color = 0; sl@0: TBool use16 = EFalse; sl@0: sl@0: if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0) sl@0: { sl@0: User::Leave(KErrCorrupt); sl@0: } sl@0: if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0) sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: sl@0: switch (info.iPixelFormat) sl@0: { sl@0: case EUidPixelFormatXRGB_8888: sl@0: { sl@0: color = aColor.Color16MU(); sl@0: #ifdef ALPHA_FIX_24BIT sl@0: color |= ((ALPHA_FIX_24BIT)&0xff)<<24; sl@0: #endif sl@0: break; sl@0: } sl@0: case EUidPixelFormatARGB_8888: sl@0: { sl@0: color = aColor.Color16MA(); sl@0: break; sl@0: } sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: { sl@0: color = aColor.Color16MAP(); sl@0: break; sl@0: } sl@0: case EUidPixelFormatXRGB_4444: sl@0: case EUidPixelFormatARGB_4444: sl@0: { sl@0: color = aColor.Color4K(); sl@0: use16 = ETrue; sl@0: break; sl@0: } sl@0: case EUidPixelFormatRGB_565: sl@0: { sl@0: color = aColor.Color64K(); sl@0: use16 = ETrue; sl@0: break; sl@0: } sl@0: default: sl@0: { sl@0: User::Leave(KErrNotSupported); sl@0: break; sl@0: } sl@0: } sl@0: sl@0: RChunk chunk; sl@0: User::LeaveIfError(iManager.MapSurface(aSurface, chunk)); sl@0: sl@0: TUint8* surfacePtr = chunk.Base(); sl@0: TUint8* linePtr = surfacePtr; sl@0: sl@0: if (use16) sl@0: { sl@0: if ( info.iSize.iWidth*2>info.iStride) sl@0: { sl@0: User::Leave(KErrOverflow); sl@0: } sl@0: TUint16* ptr = reinterpret_cast(surfacePtr); sl@0: sl@0: // Fill first line sl@0: for (TInt xx = 0; xx < info.iSize.iWidth; xx++) sl@0: { sl@0: ptr[xx] = (TUint16)color; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: if ( info.iSize.iWidth*4>info.iStride) sl@0: { sl@0: User::Leave(KErrOverflow); sl@0: } sl@0: TUint32* ptr = reinterpret_cast(surfacePtr); sl@0: sl@0: // Fill first line sl@0: for (TInt xx = 0; xx < info.iSize.iWidth; xx++) sl@0: { sl@0: ptr[xx] = color; sl@0: } sl@0: } sl@0: sl@0: // Now copy that to the other lines sl@0: for (TInt yy = 1; yy < info.iSize.iHeight; yy++) sl@0: { sl@0: linePtr += info.iStride; sl@0: Mem::Move(linePtr, surfacePtr, info.iStride); sl@0: } sl@0: sl@0: chunk.Close(); sl@0: sl@0: TInt err = iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL); sl@0: if (err!=KErrNone) sl@0: LOG(("Error submitting update: 0x%X\n", err)); sl@0: } sl@0: sl@0: /** sl@0: Fill the given memory chunk with a color. sl@0: sl@0: @param aSurface The surface to be filled. sl@0: @param aChunk The surface to be filled. sl@0: @param aColor The color to fill it with. sl@0: */ sl@0: void CSurfaceUtility::FillChunkL(TSurfaceId& aSurface, RChunk& aChunk, const TRgb& aColor, TInt aBufferNumber) sl@0: { sl@0: RSurfaceManager::TInfoBuf infoBuf; sl@0: RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); sl@0: sl@0: User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf)); sl@0: TUint32 color = 0; sl@0: TBool use16 = EFalse; sl@0: sl@0: if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0) sl@0: { sl@0: User::Leave(KErrCorrupt); sl@0: } sl@0: if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0) sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: sl@0: switch (info.iPixelFormat) sl@0: { sl@0: case EUidPixelFormatXRGB_8888: sl@0: { sl@0: color = aColor.Color16MU(); sl@0: #ifdef ALPHA_FIX_24BIT sl@0: color |= ((ALPHA_FIX_24BIT)&0xff)<<24; sl@0: #endif sl@0: break; sl@0: } sl@0: case EUidPixelFormatARGB_8888: sl@0: { sl@0: color = aColor.Color16MA(); sl@0: break; sl@0: } sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: { sl@0: color = aColor.Color16MAP(); sl@0: break; sl@0: } sl@0: case EUidPixelFormatXRGB_4444: sl@0: case EUidPixelFormatARGB_4444: sl@0: { sl@0: color = aColor.Color4K(); sl@0: use16 = ETrue; sl@0: break; sl@0: } sl@0: case EUidPixelFormatRGB_565: sl@0: { sl@0: color = aColor.Color64K(); sl@0: use16 = ETrue; sl@0: break; sl@0: } sl@0: default: sl@0: { sl@0: User::Leave(KErrNotSupported); sl@0: break; sl@0: } sl@0: } sl@0: sl@0: User::LeaveIfError(iManager.MapSurface(aSurface, aChunk)); sl@0: sl@0: TInt offsetToFirstBuffer; sl@0: User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer)); sl@0: TInt offsetToBufferNumber; sl@0: User::LeaveIfError(iManager.GetBufferOffset(aSurface, aBufferNumber, offsetToBufferNumber)); sl@0: sl@0: TUint8* chunkPtr = aChunk.Base() + offsetToFirstBuffer; sl@0: TUint8* linePtr = aChunk.Base() + offsetToBufferNumber; sl@0: TUint8* surfPlanePtr = linePtr; sl@0: sl@0: if (use16) sl@0: { sl@0: if ( info.iSize.iWidth*2>info.iStride) sl@0: { sl@0: aChunk.Close(); sl@0: User::Leave(KErrOverflow); sl@0: } sl@0: TUint16* ptr = reinterpret_cast(surfPlanePtr); sl@0: sl@0: // Fill first line sl@0: for (TInt xx = 0; xx < info.iSize.iWidth; xx++) sl@0: { sl@0: ptr[xx] = (TUint16)color; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: if ( info.iSize.iWidth*4>info.iStride) sl@0: { sl@0: aChunk.Close(); sl@0: User::Leave(KErrOverflow); sl@0: } sl@0: TUint32* ptr = reinterpret_cast(surfPlanePtr); sl@0: sl@0: // Fill first line sl@0: for (TInt xx = 0; xx < info.iSize.iWidth; xx++) sl@0: { sl@0: ptr[xx] = color; sl@0: } sl@0: } sl@0: sl@0: // Now copy that to the other lines sl@0: for (TInt yy = 1; yy < info.iSize.iHeight; yy++) sl@0: { sl@0: linePtr += info.iStride; sl@0: Mem::Copy(linePtr, surfPlanePtr, info.iSize.iWidth * BytesPerPixelL(info.iPixelFormat)); sl@0: } sl@0: sl@0: aChunk.Close(); sl@0: } sl@0: sl@0: /** sl@0: Fill a rectangle on the given surface. sl@0: sl@0: @param aSurface The surface to be filled. sl@0: @param aStartPos Where to place the rectangle. sl@0: @param aSize Size of the rectangle. sl@0: @param aColor The colour to fill it with. sl@0: */ sl@0: void CSurfaceUtility::FillRectangleL(TSurfaceId& aSurface, TPoint& aStartPos, TSize& aSize, const TRgb& aColor) sl@0: { sl@0: RSurfaceManager::TInfoBuf infoBuf; sl@0: RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); sl@0: sl@0: User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf)); sl@0: TUint32 color = 0; sl@0: TBool use16 = EFalse; sl@0: sl@0: if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0) sl@0: { sl@0: User::Leave(KErrCorrupt); sl@0: } sl@0: if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0) sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: sl@0: switch (info.iPixelFormat) sl@0: { sl@0: case EUidPixelFormatXRGB_8888: sl@0: { sl@0: color = aColor.Color16MU(); sl@0: #ifdef ALPHA_FIX_24BIT sl@0: color |= ((ALPHA_FIX_24BIT)&0xff)<<24; sl@0: #endif sl@0: break; sl@0: } sl@0: case EUidPixelFormatARGB_8888: sl@0: { sl@0: color = aColor.Color16MA(); sl@0: break; sl@0: } sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: { sl@0: color = aColor.Color16MAP(); sl@0: break; sl@0: } sl@0: case EUidPixelFormatXRGB_4444: sl@0: case EUidPixelFormatARGB_4444: sl@0: { sl@0: color = aColor.Color4K(); sl@0: use16 = ETrue; sl@0: break; sl@0: } sl@0: case EUidPixelFormatRGB_565: sl@0: { sl@0: color = aColor.Color64K(); sl@0: use16 = ETrue; sl@0: break; sl@0: } sl@0: default: sl@0: { sl@0: User::Leave(KErrNotSupported); sl@0: break; sl@0: } sl@0: } sl@0: sl@0: RChunk chunk; sl@0: User::LeaveIfError(iManager.MapSurface(aSurface, chunk)); sl@0: sl@0: TUint8* surfacePtr = chunk.Base(); sl@0: sl@0: // Check for out of bounds sl@0: TBool validRect = ETrue; sl@0: TInt surfaceWidth = info.iSize.iWidth; sl@0: TInt surfaceHeight = info.iSize.iHeight; sl@0: sl@0: // Width and Height sl@0: if ((aStartPos.iX + aSize.iWidth) > surfaceWidth) sl@0: validRect = EFalse; sl@0: sl@0: if ((aStartPos.iY + aSize.iHeight) > surfaceHeight) sl@0: validRect = EFalse; sl@0: sl@0: // Starting position sl@0: if ((aStartPos.iX < 0) || (aStartPos.iY < 0)) sl@0: validRect = EFalse; sl@0: sl@0: if (!validRect) sl@0: User::Leave(KErrOverflow); sl@0: sl@0: if (use16) sl@0: { sl@0: if ( info.iSize.iWidth*2>info.iStride) sl@0: { sl@0: User::Leave(KErrOverflow); sl@0: } sl@0: sl@0: TUint16* ptr = reinterpret_cast(surfacePtr); sl@0: sl@0: // Fill the rectangle sl@0: TInt yPos = aStartPos.iY; sl@0: TInt xPos = aStartPos.iX; sl@0: for (TInt yy = 0; yy < aSize.iHeight; ++yy) sl@0: { sl@0: ptr = reinterpret_cast(surfacePtr+(yPos*info.iStride)); sl@0: for (TInt xx = 0; xx < aSize.iWidth; ++xx) sl@0: { sl@0: ptr[xPos] = color; sl@0: xPos++; sl@0: } sl@0: xPos = aStartPos.iX; sl@0: yPos++; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: if ( info.iSize.iWidth*4>info.iStride) sl@0: { sl@0: User::Leave(KErrOverflow); sl@0: } sl@0: sl@0: TUint32* ptr = reinterpret_cast(surfacePtr); sl@0: sl@0: // Fill the rectangle sl@0: TInt yPos = aStartPos.iY; sl@0: TInt xPos = aStartPos.iX; sl@0: for (TInt yy = 0; yy < aSize.iHeight; ++yy) sl@0: { sl@0: ptr = reinterpret_cast(surfacePtr+(yPos*info.iStride)); sl@0: for (TInt xx = 0; xx < aSize.iWidth; ++xx) sl@0: { sl@0: ptr[xPos] = color; sl@0: xPos++; sl@0: } sl@0: xPos = aStartPos.iX; sl@0: yPos++; sl@0: } sl@0: } sl@0: sl@0: chunk.Close(); sl@0: sl@0: TInt err = iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL); sl@0: if (err!=KErrNone) sl@0: LOG(("Error submitting update: 0x%X\n", err)); sl@0: } sl@0: sl@0: /** sl@0: Fill a rectangle on the given surface - does not submit update. sl@0: sl@0: @param aSurface The surface to be filled. sl@0: @param aStartPos Where to place the rectangle. sl@0: @param aSize Size of the rectangle. sl@0: @param aColor The colour to fill it with. sl@0: */ sl@0: void CSurfaceUtility::FillRectangleNoUpdateL(TSurfaceId& aSurface, TPoint& aStartPos, TSize& aSize, const TRgb& aColor) sl@0: { sl@0: RSurfaceManager::TInfoBuf infoBuf; sl@0: RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); sl@0: sl@0: User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf)); sl@0: TUint32 color = 0; sl@0: TBool use16 = EFalse; sl@0: sl@0: if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0) sl@0: { sl@0: User::Leave(KErrCorrupt); sl@0: } sl@0: if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0) sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: sl@0: switch (info.iPixelFormat) sl@0: { sl@0: case EUidPixelFormatXRGB_8888: sl@0: { sl@0: color = aColor.Color16MU(); sl@0: #ifdef ALPHA_FIX_24BIT sl@0: color |= ((ALPHA_FIX_24BIT)&0xff)<<24; sl@0: #endif sl@0: break; sl@0: } sl@0: case EUidPixelFormatARGB_8888: sl@0: { sl@0: color = aColor.Color16MA(); sl@0: break; sl@0: } sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: { sl@0: color = aColor.Color16MAP(); sl@0: break; sl@0: } sl@0: case EUidPixelFormatXRGB_4444: sl@0: case EUidPixelFormatARGB_4444: sl@0: { sl@0: color = aColor.Color4K(); sl@0: use16 = ETrue; sl@0: break; sl@0: } sl@0: case EUidPixelFormatRGB_565: sl@0: { sl@0: color = aColor.Color64K(); sl@0: use16 = ETrue; sl@0: break; sl@0: } sl@0: default: sl@0: { sl@0: User::Leave(KErrNotSupported); sl@0: break; sl@0: } sl@0: } sl@0: sl@0: RChunk chunk; sl@0: User::LeaveIfError(iManager.MapSurface(aSurface, chunk)); sl@0: sl@0: TUint8* surfacePtr = chunk.Base(); sl@0: sl@0: // Check for out of bounds sl@0: TBool validRect = ETrue; sl@0: TInt surfaceWidth = info.iSize.iWidth; sl@0: TInt surfaceHeight = info.iSize.iHeight; sl@0: sl@0: // Width and Height sl@0: if ((aStartPos.iX + aSize.iWidth) > surfaceWidth) sl@0: validRect = EFalse; sl@0: sl@0: if ((aStartPos.iY + aSize.iHeight) > surfaceHeight) sl@0: validRect = EFalse; sl@0: sl@0: // Starting position sl@0: if ((aStartPos.iX < 0) || (aStartPos.iY < 0)) sl@0: validRect = EFalse; sl@0: sl@0: if (!validRect) sl@0: User::Leave(KErrOverflow); sl@0: sl@0: if (use16) sl@0: { sl@0: if ( info.iSize.iWidth*2>info.iStride) sl@0: { sl@0: User::Leave(KErrOverflow); sl@0: } sl@0: sl@0: TUint16* ptr = reinterpret_cast(surfacePtr); sl@0: sl@0: // Fill the rectangle sl@0: TInt yPos = aStartPos.iY; sl@0: TInt xPos = aStartPos.iX; sl@0: for (TInt yy = 0; yy < aSize.iHeight; ++yy) sl@0: { sl@0: ptr = reinterpret_cast(surfacePtr+(yPos*info.iStride)); sl@0: for (TInt xx = 0; xx < aSize.iWidth; ++xx) sl@0: { sl@0: ptr[xPos] = color; sl@0: xPos++; sl@0: } sl@0: xPos = aStartPos.iX; sl@0: yPos++; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: if ( info.iSize.iWidth*4>info.iStride) sl@0: { sl@0: User::Leave(KErrOverflow); sl@0: } sl@0: sl@0: TUint32* ptr = reinterpret_cast(surfacePtr); sl@0: sl@0: // Fill the rectangle sl@0: TInt yPos = aStartPos.iY; sl@0: TInt xPos = aStartPos.iX; sl@0: for (TInt yy = 0; yy < aSize.iHeight; ++yy) sl@0: { sl@0: ptr = reinterpret_cast(surfacePtr+(yPos*info.iStride)); sl@0: for (TInt xx = 0; xx < aSize.iWidth; ++xx) sl@0: { sl@0: ptr[xPos] = color; sl@0: xPos++; sl@0: } sl@0: xPos = aStartPos.iX; sl@0: yPos++; sl@0: } sl@0: } sl@0: sl@0: chunk.Close(); sl@0: sl@0: } sl@0: sl@0: /** sl@0: Fill the given surface with a grid over a solid color. sl@0: sl@0: Similar to FillSurfaceL(), but with a grid overlayed. The pitch of the grid is sl@0: eight pixels. sl@0: sl@0: @param aSurface The surface to be filled. sl@0: @param aColor The color to fill it with. sl@0: @param aLines The color of the grid lines. sl@0: */ sl@0: void CSurfaceUtility::GridFillSurfaceL(TSurfaceId& aSurface, const TRgb& aColor, const TRgb& aLines) sl@0: { sl@0: RSurfaceManager::TInfoBuf infoBuf; sl@0: RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); sl@0: sl@0: User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf)); sl@0: TUint32 color = 0; sl@0: TUint32 lines = 0; sl@0: TBool use16 = EFalse; sl@0: sl@0: if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0) sl@0: { sl@0: User::Leave(KErrCorrupt); sl@0: } sl@0: if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0) sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: sl@0: switch (info.iPixelFormat) sl@0: { sl@0: case EUidPixelFormatXRGB_8888: sl@0: { sl@0: color = aColor.Color16MU(); sl@0: lines = aLines.Color16MU(); sl@0: #ifdef ALPHA_FIX_24BIT sl@0: color |= ((ALPHA_FIX_24BIT)&0xff)<<24; sl@0: lines |= ((ALPHA_FIX_24BIT)&0xff)<<24; sl@0: #endif sl@0: break; sl@0: } sl@0: case EUidPixelFormatARGB_8888: sl@0: { sl@0: color = aColor.Color16MA(); sl@0: lines = aLines.Color16MA(); sl@0: break; sl@0: } sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: { sl@0: color = aColor.Color16MAP(); sl@0: lines = aLines.Color16MAP(); sl@0: break; sl@0: } sl@0: case EUidPixelFormatXRGB_4444: sl@0: case EUidPixelFormatARGB_4444: sl@0: { sl@0: color = aColor.Color4K(); sl@0: lines = aLines.Color4K(); sl@0: use16 = ETrue; sl@0: break; sl@0: } sl@0: case EUidPixelFormatRGB_565: sl@0: { sl@0: color = aColor.Color64K(); sl@0: lines = aLines.Color64K(); sl@0: use16 = ETrue; sl@0: break; sl@0: } sl@0: default: sl@0: { sl@0: User::Leave(KErrNotSupported); sl@0: break; sl@0: } sl@0: } sl@0: sl@0: RChunk chunk; sl@0: User::LeaveIfError(iManager.MapSurface(aSurface, chunk)); sl@0: sl@0: TUint8* surfacePtr = chunk.Base(); sl@0: TUint8* linePtr = surfacePtr; sl@0: sl@0: if (use16) sl@0: { sl@0: if ( info.iSize.iWidth*2>info.iStride) sl@0: { sl@0: User::Leave(KErrOverflow); sl@0: } sl@0: TUint16* ptr = reinterpret_cast(surfacePtr); sl@0: sl@0: // Fill first line sl@0: for (TInt xx1 = 0; xx1 < info.iSize.iWidth; xx1++) sl@0: { sl@0: ptr[xx1] = (TUint16)lines; sl@0: } sl@0: sl@0: // Fill second line sl@0: ptr = reinterpret_cast(surfacePtr + info.iStride); sl@0: for (TInt xx2 = 0; xx2 < info.iSize.iWidth; xx2++) sl@0: { sl@0: // Vertical line every 8 pixels across sl@0: ptr[xx2] = (TUint16)((xx2 & 7) ? color : lines); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: if ( info.iSize.iWidth*4>info.iStride) sl@0: { sl@0: User::Leave(KErrOverflow); sl@0: } sl@0: TUint32* ptr = reinterpret_cast(surfacePtr); sl@0: sl@0: // Fill first line sl@0: for (TInt xx3 = 0; xx3 < info.iSize.iWidth; xx3++) sl@0: { sl@0: ptr[xx3] = lines; sl@0: } sl@0: sl@0: // Fill second line sl@0: ptr = reinterpret_cast(surfacePtr + info.iStride); sl@0: for (TInt xx4 = 0; xx4 < info.iSize.iWidth; xx4++) sl@0: { sl@0: // Vertical line every 8 pixels across sl@0: ptr[xx4] = (xx4 & 7) ? color : lines; sl@0: } sl@0: } sl@0: linePtr += info.iStride; sl@0: sl@0: // Now copy that to the other lines sl@0: for (TInt yy = 2; yy < info.iSize.iHeight; yy++) sl@0: { sl@0: linePtr += info.iStride; sl@0: if (yy & 7) sl@0: { sl@0: // Copy second line sl@0: Mem::Move(linePtr, surfacePtr + info.iStride, info.iStride); sl@0: } sl@0: else sl@0: { sl@0: // Copy first line sl@0: Mem::Move(linePtr, surfacePtr, info.iStride); sl@0: } sl@0: } sl@0: chunk.Close(); sl@0: sl@0: TInt err =iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL); sl@0: if (err!=KErrNone) sl@0: LOG(("Error submitting update: 0x%X\n", err)); sl@0: sl@0: } sl@0: sl@0: sl@0: /** sl@0: Fill the given surface with a pattern suitable for automated testing. sl@0: sl@0: @param aSurface The surface to be filled. sl@0: */ sl@0: void CSurfaceUtility::PatternFillSurfaceL(TSurfaceId& aSurface) sl@0: { sl@0: RSurfaceManager::TInfoBuf infoBuf; sl@0: RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); sl@0: sl@0: User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf)); sl@0: sl@0: // Fill the background sl@0: FillSurfaceL(aSurface, TRgb(0x00000000)); sl@0: sl@0: TInt surfaceWidth = info.iSize.iWidth; sl@0: TInt surfaceHeight = info.iSize.iHeight; sl@0: sl@0: // Create the 4 rectangles in the corners sl@0: TPoint startPos(0,0); sl@0: TSize size(15,15); sl@0: TInt rectWidth = size.iWidth; sl@0: TInt rectHeight = size.iHeight; sl@0: // Top left sl@0: FillRectangleL(aSurface, startPos, size, TRgb(0x0000ff)); sl@0: sl@0: // Top right sl@0: startPos.iX = surfaceWidth - rectWidth; sl@0: startPos.iY = 0; sl@0: FillRectangleL(aSurface, startPos, size, TRgb(0x00ff00)); sl@0: sl@0: // Bottom left sl@0: startPos.iX = 0; sl@0: startPos.iY = surfaceHeight - rectHeight; sl@0: FillRectangleL(aSurface, startPos, size, TRgb(0x00ffff)); sl@0: sl@0: // Bottom right sl@0: startPos.iX = surfaceWidth - rectWidth; sl@0: startPos.iY = surfaceHeight - rectHeight; sl@0: FillRectangleL(aSurface, startPos, size, TRgb(0xffffff)); sl@0: sl@0: // Create the 4 side bars sl@0: startPos.iX = 0; sl@0: startPos.iY = 6; sl@0: size.iWidth = 5; sl@0: size.iHeight = surfaceHeight - 12; sl@0: // Left sl@0: FillRectangleL(aSurface, startPos, size, TRgb(0x808000)); sl@0: sl@0: startPos.iX = surfaceWidth - size.iWidth; sl@0: startPos.iY = 6; sl@0: // Right sl@0: FillRectangleL(aSurface, startPos, size, TRgb(0xff00ff)); sl@0: sl@0: startPos.iX = 6; sl@0: startPos.iY = surfaceHeight - size.iWidth; sl@0: size.iWidth = surfaceWidth - 12; sl@0: size.iHeight = 5; sl@0: // Top sl@0: FillRectangleL(aSurface, startPos, size, TRgb(0xaaaaaa)); sl@0: sl@0: startPos.iX = 6; sl@0: startPos.iY = 0; sl@0: // Bottom sl@0: FillRectangleL(aSurface, startPos, size, TRgb(0x000080)); sl@0: } sl@0: sl@0: sl@0: template void sl@0: DdaLine(TUint aX1, TUint aY1,TUint aX2,TUint aY2, TUint aPixPerScan, TIntType* aBuffer, TIntType aColor) sl@0: { sl@0: TInt dx=aX2-aX1; sl@0: TInt dy=aY2-aY1; sl@0: TInt adx=dx,sdx=1; sl@0: if (adx<0) sl@0: { adx=-adx; sdx=-1; } sl@0: TInt ady=dy,sdy=aPixPerScan; sl@0: if (ady<0) sl@0: { ady=-ady; sdy=-aPixPerScan; } sl@0: //This is simplistic integert DDA. sl@0: //The vertical cases are handled by this 1/2 accumulator: sl@0: // If adx is zero then we step in sdy indefinitely sl@0: // If ady is zero then we step in sdx indefinitely sl@0: TInt accum=adx/2; sl@0: sl@0: TIntType* bufferend=aBuffer+aX2+aY2*aPixPerScan; sl@0: aBuffer+=aX1+aY1*aPixPerScan; sl@0: *aBuffer=aColor; sl@0: while (aBuffer!=bufferend) sl@0: { sl@0: if (accum>0) sl@0: { sl@0: accum-=ady; sl@0: aBuffer+=sdx; sl@0: } sl@0: else sl@0: { sl@0: accum+=adx; sl@0: aBuffer+=sdy; sl@0: } sl@0: *aBuffer=aColor; sl@0: } sl@0: sl@0: sl@0: } sl@0: template void sl@0: FanFill(const TPoint& aInnerXY,TUint aPixPerScan, TIntType* aSurfacePtr, TIntType aLinesTL, sl@0: TIntType aLinesBR, TIntType aLinesTR, TIntType aLinesBL) sl@0: { sl@0: sl@0: DdaLine(aInnerXY.iX,0,aInnerXY.iX-aInnerXY.iX*180/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTR); sl@0: DdaLine(aInnerXY.iX,0,aInnerXY.iX-aInnerXY.iX*372/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTR); sl@0: DdaLine(aInnerXY.iX,0,aInnerXY.iX-aInnerXY.iX*591/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTR); sl@0: DdaLine(aInnerXY.iX,0,aInnerXY.iX-aInnerXY.iX*859/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTR); sl@0: sl@0: DdaLine(aInnerXY.iX,0,0,aInnerXY.iY*180/1024,aPixPerScan,aSurfacePtr,aLinesTR); sl@0: DdaLine(aInnerXY.iX,0,0,aInnerXY.iY*372/1024,aPixPerScan,aSurfacePtr,aLinesTR); sl@0: DdaLine(aInnerXY.iX,0,0,aInnerXY.iY*591/1024,aPixPerScan,aSurfacePtr,aLinesTR); sl@0: DdaLine(aInnerXY.iX,0,0,aInnerXY.iY*859/1024,aPixPerScan,aSurfacePtr,aLinesTR); sl@0: sl@0: DdaLine(0,aInnerXY.iY,aInnerXY.iX*180/1024,0,aPixPerScan,aSurfacePtr,aLinesBL); sl@0: DdaLine(0,aInnerXY.iY,aInnerXY.iX*372/1024,0,aPixPerScan,aSurfacePtr,aLinesBL); sl@0: DdaLine(0,aInnerXY.iY,aInnerXY.iX*591/1024,0,aPixPerScan,aSurfacePtr,aLinesBL); sl@0: DdaLine(0,aInnerXY.iY,aInnerXY.iX*859/1024,0,aPixPerScan,aSurfacePtr,aLinesBL); sl@0: sl@0: DdaLine(0,aInnerXY.iY,aInnerXY.iX,aInnerXY.iY-aInnerXY.iY*180/1024,aPixPerScan,aSurfacePtr,aLinesBL); sl@0: DdaLine(0,aInnerXY.iY,aInnerXY.iX,aInnerXY.iY-aInnerXY.iY*372/1024,aPixPerScan,aSurfacePtr,aLinesBL); sl@0: DdaLine(0,aInnerXY.iY,aInnerXY.iX,aInnerXY.iY-aInnerXY.iY*591/1024,aPixPerScan,aSurfacePtr,aLinesBL); sl@0: DdaLine(0,aInnerXY.iY,aInnerXY.iX,aInnerXY.iY-aInnerXY.iY*859/1024,aPixPerScan,aSurfacePtr,aLinesBL); sl@0: sl@0: DdaLine(0,0,aInnerXY.iX*180/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTL); sl@0: DdaLine(0,0,aInnerXY.iX*372/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTL); sl@0: DdaLine(0,0,aInnerXY.iX*591/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTL); sl@0: DdaLine(0,0,aInnerXY.iX*859/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTL); sl@0: sl@0: DdaLine(0,0,aInnerXY.iX,aInnerXY.iY*180/1024,aPixPerScan,aSurfacePtr,aLinesTL); sl@0: DdaLine(0,0,aInnerXY.iX,aInnerXY.iY*372/1024,aPixPerScan,aSurfacePtr,aLinesTL); sl@0: DdaLine(0,0,aInnerXY.iX,aInnerXY.iY*591/1024,aPixPerScan,aSurfacePtr,aLinesTL); sl@0: DdaLine(0,0,aInnerXY.iX,aInnerXY.iY*859/1024,aPixPerScan,aSurfacePtr,aLinesTL); sl@0: sl@0: DdaLine(0,aInnerXY.iY-aInnerXY.iY*180/1024,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR); sl@0: DdaLine(0,aInnerXY.iY-aInnerXY.iY*372/1024,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR); sl@0: DdaLine(0,aInnerXY.iY-aInnerXY.iY*591/1024,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR); sl@0: DdaLine(0,aInnerXY.iY-aInnerXY.iY*859/1024,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR); sl@0: sl@0: DdaLine(aInnerXY.iX-aInnerXY.iX*180/1024,0,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR); sl@0: DdaLine(aInnerXY.iX-aInnerXY.iX*372/1024,0,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR); sl@0: DdaLine(aInnerXY.iX-aInnerXY.iX*591/1024,0,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR); sl@0: DdaLine(aInnerXY.iX-aInnerXY.iX*859/1024,0,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR); sl@0: sl@0: } sl@0: /** sl@0: Fill the given surface with a fan of lines over a solid color. sl@0: sl@0: Similar to FillSurfaceL(), but with a fan of lines overlayed. sl@0: One fan is drawn about the top-left, and second fan at bottom-right. sl@0: The fan contains 8 segments. sl@0: sl@0: @param aSurface The surface to be filled. sl@0: @param aColor The color to fill it with. sl@0: @param aLines The color of the grid lines. sl@0: */ sl@0: void CSurfaceUtility::FanFillSurfaceL(TSurfaceId& aSurface, const TRgb& aColor, const TRgb& aLinesTL, const TRgb& aLinesBR) sl@0: { sl@0: FillSurfaceL(aSurface,aColor); sl@0: RSurfaceManager::TInfoBuf infoBuf; sl@0: RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); sl@0: sl@0: User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf)); sl@0: TUint32 linesTL = 0; sl@0: TUint32 linesBR = 0; sl@0: TUint32 linesTR = 0; sl@0: TUint32 linesBL = 0; sl@0: TBool use16 = EFalse; sl@0: TRgb rgbLinesTR(0,0,0); sl@0: TRgb rgbLinesBL(255,255,255); sl@0: sl@0: switch (info.iPixelFormat) sl@0: { sl@0: case EUidPixelFormatXRGB_8888: sl@0: { sl@0: linesBR = aLinesBR.Color16MU(); sl@0: linesTL = aLinesTL.Color16MU(); sl@0: linesTR = rgbLinesTR.Color16MU(); sl@0: linesBL = rgbLinesBL.Color16MU(); sl@0: #ifdef ALPHA_FIX_24BIT sl@0: linesBR |= ((ALPHA_FIX_24BIT)&0xff)<<24; sl@0: linesTL |= ((ALPHA_FIX_24BIT)&0xff)<<24; sl@0: linesTR |= ((ALPHA_FIX_24BIT)&0xff)<<24; sl@0: linesBL |= ((ALPHA_FIX_24BIT)&0xff)<<24; sl@0: #endif sl@0: break; sl@0: } sl@0: case EUidPixelFormatARGB_8888: sl@0: { sl@0: linesBR = aLinesBR.Color16MA(); sl@0: linesTL = aLinesTL.Color16MA(); sl@0: linesTR = rgbLinesTR.Color16MA(); sl@0: linesBL = rgbLinesBL.Color16MA(); sl@0: break; sl@0: } sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: { sl@0: linesBR = aLinesBR.Color16MAP(); sl@0: linesTL = aLinesTL.Color16MAP(); sl@0: linesTR = rgbLinesTR.Color16MAP(); sl@0: linesBL = rgbLinesBL.Color16MAP(); sl@0: break; sl@0: } sl@0: case EUidPixelFormatXRGB_4444: sl@0: case EUidPixelFormatARGB_4444: sl@0: { sl@0: linesBR = aLinesBR.Color4K(); sl@0: linesTL = aLinesTL.Color4K(); sl@0: linesTR = rgbLinesTR.Color4K(); sl@0: linesBL = rgbLinesBL.Color4K(); sl@0: use16 = ETrue; sl@0: break; sl@0: } sl@0: case EUidPixelFormatRGB_565: sl@0: { sl@0: linesBR = aLinesBR.Color64K(); sl@0: linesTL = aLinesTL.Color64K(); sl@0: linesTR = rgbLinesTR.Color64K(); sl@0: linesBL = rgbLinesBL.Color64K(); sl@0: use16 = ETrue; sl@0: break; sl@0: } sl@0: default: sl@0: { sl@0: User::Leave(KErrNotSupported); sl@0: break; sl@0: } sl@0: } sl@0: if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0) sl@0: { sl@0: User::Leave(KErrCorrupt); sl@0: } sl@0: if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0) sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: RChunk chunk; sl@0: User::LeaveIfError(iManager.MapSurface(aSurface, chunk)); sl@0: TUint8* surfacePtr = chunk.Base(); sl@0: TPoint innerXY(info.iSize.iWidth-1,info.iSize.iHeight-1); sl@0: if (use16) sl@0: { sl@0: if ( info.iSize.iWidth*2>info.iStride) sl@0: { sl@0: User::Leave(KErrOverflow); sl@0: } sl@0: FanFill(innerXY,info.iStride/2,(TUint16*)surfacePtr,linesTL,linesBR,linesBL,linesTR); sl@0: } sl@0: else sl@0: { sl@0: if ( info.iSize.iWidth*4>info.iStride) sl@0: { sl@0: User::Leave(KErrOverflow); sl@0: } sl@0: FanFill(innerXY,info.iStride/4,(TUint*)surfacePtr,linesTL,linesBR,linesBL,linesTR); sl@0: } sl@0: sl@0: chunk.Close(); sl@0: sl@0: iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL); sl@0: } sl@0: /** sl@0: Fill the given surface with vertical line at the given position sl@0: sl@0: Similar to FillSurfaceL(), but with a vertical line overlayed. sl@0: The position along the surface is given as a percentage from the left sl@0: sl@0: @param aSurface The surface to be filled. sl@0: @param aColor The color to fill it with. sl@0: @param aLine The color of the line. sl@0: @param aPosition Position of the vertical line given as a percentage across the surface from the left edge sl@0: */ sl@0: void CSurfaceUtility::LineFillSurfaceL(TSurfaceId& aSurface, const TRgb& aBackColor, const TRgb& aLineColor, TInt aPosition) sl@0: { sl@0: if (aPosition<0 || aPosition>100) sl@0: { sl@0: aPosition=0; sl@0: } sl@0: FillSurfaceL(aSurface,aBackColor); sl@0: RSurfaceManager::TInfoBuf infoBuf; sl@0: RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); sl@0: sl@0: User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf)); sl@0: TUint32 lineColor = 0; sl@0: TBool use16 = EFalse; sl@0: sl@0: switch (info.iPixelFormat) sl@0: { sl@0: case EUidPixelFormatXRGB_8888: sl@0: { sl@0: lineColor = aLineColor.Color16MU(); sl@0: #ifdef ALPHA_FIX_24BIT sl@0: lineColor |= ((ALPHA_FIX_24BIT)&0xff)<<24; sl@0: #endif sl@0: break; sl@0: } sl@0: case EUidPixelFormatARGB_8888: sl@0: { sl@0: lineColor = aLineColor.Color16MA(); sl@0: break; sl@0: } sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: { sl@0: lineColor = aLineColor.Color16MAP(); sl@0: break; sl@0: } sl@0: case EUidPixelFormatXRGB_4444: sl@0: case EUidPixelFormatARGB_4444: sl@0: { sl@0: lineColor = aLineColor.Color4K(); sl@0: use16 = ETrue; sl@0: break; sl@0: } sl@0: case EUidPixelFormatRGB_565: sl@0: { sl@0: lineColor = aLineColor.Color64K(); sl@0: use16 = ETrue; sl@0: break; sl@0: } sl@0: default: sl@0: { sl@0: User::Leave(KErrNotSupported); sl@0: break; sl@0: } sl@0: } sl@0: RChunk chunk; sl@0: User::LeaveIfError(iManager.MapSurface(aSurface, chunk)); sl@0: sl@0: TUint8* surfacePtr = chunk.Base(); sl@0: if (use16) sl@0: { sl@0: DdaLine((info.iSize.iWidth*aPosition)/100,0,(info.iSize.iWidth*aPosition)/100, sl@0: info.iSize.iHeight-1,info.iStride/2,(TUint16*)surfacePtr,lineColor); sl@0: } sl@0: else sl@0: { sl@0: DdaLine((info.iSize.iWidth*aPosition)/100,0,(info.iSize.iWidth*aPosition)/100, sl@0: info.iSize.iHeight-1,info.iStride/4,(TUint*)surfacePtr,lineColor); sl@0: } sl@0: chunk.Close(); sl@0: iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL); sl@0: } sl@0: /** sl@0: * Generates a bitmap equivalent to the surface. sl@0: * Can reuse an existing bitmap or create a new bitmap. sl@0: * The existing bitmap must be an exact match (eg previously generated by this method) sl@0: **/ sl@0: CFbsBitmap* CSurfaceUtility::EquivalentBitmapL(TSurfaceId& aSurface,CFbsBitmap* aCopyToMayBeNull) sl@0: { sl@0: RSurfaceManager::TInfoBuf infoBuf; sl@0: RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); sl@0: sl@0: User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf)); sl@0: TInt bytesPerPixel=0; sl@0: TDisplayMode bitmapMode = ENone; sl@0: switch (info.iPixelFormat) sl@0: { sl@0: case EUidPixelFormatXRGB_8888: sl@0: { sl@0: bitmapMode = EColor16MU; sl@0: bytesPerPixel = 4; sl@0: break; sl@0: } sl@0: case EUidPixelFormatARGB_8888: sl@0: { sl@0: bitmapMode=EColor16MA; sl@0: bytesPerPixel = 4; sl@0: break; sl@0: } sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: { sl@0: bitmapMode=EColor16MAP; sl@0: bytesPerPixel = 4; sl@0: break; sl@0: } sl@0: case EUidPixelFormatXRGB_4444: sl@0: case EUidPixelFormatARGB_4444: sl@0: { sl@0: bitmapMode=EColor4K; sl@0: bytesPerPixel = 2; sl@0: break; sl@0: } sl@0: case EUidPixelFormatRGB_565: sl@0: { sl@0: bitmapMode=EColor64K; sl@0: bytesPerPixel = 2; sl@0: break; sl@0: } sl@0: default: sl@0: { sl@0: User::Leave(KErrNotSupported); sl@0: break; sl@0: } sl@0: } sl@0: CFbsBitmap* retVal=NULL; sl@0: if (aCopyToMayBeNull) sl@0: { sl@0: retVal=aCopyToMayBeNull; sl@0: if (retVal->SizeInPixels()!=info.iSize) sl@0: User::Leave(KErrCorrupt); sl@0: if (retVal->DisplayMode()!=bitmapMode) sl@0: User::Leave(KErrCorrupt); sl@0: } sl@0: else sl@0: { sl@0: retVal=new CFbsBitmap; sl@0: CleanupStack::PushL(retVal); sl@0: User::LeaveIfError(retVal->Create(info.iSize,bitmapMode)); sl@0: } sl@0: RChunk chunk; sl@0: CleanupClosePushL(chunk); sl@0: User::LeaveIfError(iManager.MapSurface(aSurface, chunk)); sl@0: TUint8* surfacePtr = chunk.Base(); sl@0: TUint8* bitmapPtr = (TUint8*)retVal->DataAddress(); sl@0: TInt copyBytes=info.iSize.iWidth*bytesPerPixel; sl@0: for (TInt y=0;yDataStride(); sl@0: } sl@0: CleanupStack::PopAndDestroy(&chunk); sl@0: if (!aCopyToMayBeNull) sl@0: CleanupStack::Pop(retVal); sl@0: return retVal; sl@0: } sl@0: sl@0: /** sl@0: Destroy a surface. sl@0: sl@0: As well as destroying the surface, it is removed from the set held for sl@0: destruction during tear down. sl@0: sl@0: @param aSurface The surface to be destroyed. sl@0: */ sl@0: void CSurfaceUtility::DestroySurface(TSurfaceId& aSurface) sl@0: { sl@0: TInt index = iSurfaces.Find(aSurface); sl@0: sl@0: if (index != KErrNotFound) sl@0: { sl@0: iSurfaces.Remove(index); sl@0: } sl@0: sl@0: TInt err = iManager.CloseSurface(aSurface); sl@0: if (err!=KErrNone) sl@0: LOG(("Error closing surfaces: 0x%X\n", err)); sl@0: } sl@0: sl@0: sl@0: /** sl@0: Submit an update to a surface to the update server. sl@0: sl@0: @param aScreenNumber The screen to be updated where the surface is shown. sl@0: @param aSurface The surface which has been updated. sl@0: @param aRegion The area of the surface affected, or NULL for all of it.*/ sl@0: void CSurfaceUtility::SubmitUpdate(TInt /* aScreenNumber */, const TSurfaceId& aSurface, const TRegion* aRegion,TInt aBufferNumber) sl@0: { sl@0: TInt err =iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, aBufferNumber, aRegion); sl@0: if (err!=KErrNone) sl@0: LOG(("Error submitting update: 0x%X\n", err)); sl@0: } sl@0: sl@0: /** sl@0: Map and submit an update to a surface to the update server. sl@0: sl@0: @param aChunk The chunk of memory to be mapped sl@0: @param aScreenNumber The screen to be updated where the surface is shown. sl@0: @param aSurface The surface which has been updated. sl@0: @param aRegion The area of the surface affected, or NULL for all of it.*/ sl@0: void CSurfaceUtility::MapAndSubmitUpdateL(RChunk& aChunk, sl@0: TInt /* aScreenNumber */, sl@0: const TSurfaceId& aSurface, sl@0: const TRegion* aRegion) sl@0: { sl@0: User::LeaveIfError(iManager.MapSurface(aSurface, aChunk)); sl@0: aChunk.Close(); sl@0: TInt err =iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, aRegion); sl@0: if (err!=KErrNone) sl@0: LOG(("Error submitting update: 0x%X\n", err)); sl@0: } sl@0: sl@0: void CSurfaceUtility::MapSurfaceL(const TSurfaceId& aSurface, RChunk& aChunk) sl@0: { sl@0: User::LeaveIfError(iManager.MapSurface(aSurface, aChunk)); sl@0: } sl@0: sl@0: void CSurfaceUtility::CopyBitmapToSurfaceL(TSurfaceId& aSurface, const CFbsBitmap& aBitmap) sl@0: { sl@0: TSize size = SurfaceSize(aSurface); sl@0: sl@0: TDisplayMode bmpFormat = aBitmap.DisplayMode(); sl@0: TInt stride = size.iWidth * 4; // Default to four bytes per pixel sl@0: sl@0: RChunk chunk; sl@0: User::LeaveIfError(iManager.MapSurface(aSurface, chunk)); sl@0: CleanupClosePushL(chunk); sl@0: sl@0: // Copy the data from the bitmap into the surface. sl@0: TPoint start; sl@0: for (start.iY = 0; start.iY < size.iHeight; start.iY++) sl@0: { sl@0: // Set up a descriptor for the current line in the surface and get pixels. sl@0: TPtr8 ptr(chunk.Base() + start.iY * stride, stride); sl@0: aBitmap.GetScanLine(ptr, start, size.iWidth, bmpFormat); sl@0: } sl@0: sl@0: TInt err =iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL); sl@0: if (err!=KErrNone) sl@0: { sl@0: LOG(("Error submitting update: 0x%X\n", err)); sl@0: } sl@0: sl@0: CleanupStack::PopAndDestroy(/* chunk */); sl@0: } sl@0: sl@0: /** sl@0: CActiveListener factory function sl@0: @return A CActiveListener object sl@0: */ sl@0: CActiveListener* CActiveListener::NewLC() sl@0: { sl@0: CActiveListener* self = new(ELeave) CActiveListener(); sl@0: CleanupStack::PushL(self); sl@0: return self; sl@0: } sl@0: sl@0: /** sl@0: Constructor for class CActiveListener sl@0: */ sl@0: CActiveListener::CActiveListener() : CActive(EPriorityLow) sl@0: { sl@0: CActiveScheduler::Add(this); sl@0: } sl@0: sl@0: /** sl@0: Destructor sl@0: */ sl@0: CActiveListener::~CActiveListener() sl@0: { sl@0: } sl@0: sl@0: /** sl@0: Handles the request. sl@0: This function is derived from CActive sl@0: */ sl@0: void CActiveListener::RunL() sl@0: { sl@0: CActiveScheduler::Stop(); sl@0: } sl@0: sl@0: /** sl@0: Cancels the outstanding request. sl@0: This function is derived from CActive sl@0: */ sl@0: void CActiveListener::DoCancel() sl@0: { sl@0: } sl@0: sl@0: /** sl@0: Initializes the CActiveListener sl@0: */ sl@0: void CActiveListener::Initialize() sl@0: { sl@0: iStatus = KRequestPending; sl@0: SetActive(); sl@0: } sl@0: sl@0: /** sl@0: Check that the request has been cancelled. sl@0: @return A boolean indicating whether the request has been cancelled or not sl@0: */ sl@0: TBool CActiveListener::IsRequestCancelled() sl@0: { sl@0: return (iStatus == KErrCancel); sl@0: } sl@0: sl@0: /** sl@0: A helper function that returns the bytes per pixel for a given pixel format uid sl@0: sl@0: @param aPixelFormat Pixel format UID to convert sl@0: @return The bytes per pixel sl@0: */ sl@0: TInt CSurfaceUtility::BytesPerPixelL(TUidPixelFormat aPixelFormat) sl@0: { sl@0: TInt bytesPerPixel = 0; sl@0: switch (aPixelFormat) sl@0: { sl@0: case EUidPixelFormatXRGB_8888: sl@0: case EUidPixelFormatARGB_8888: sl@0: case EUidPixelFormatARGB_8888_PRE: sl@0: { sl@0: bytesPerPixel = 4; sl@0: break; sl@0: } sl@0: case EUidPixelFormatXRGB_4444: sl@0: case EUidPixelFormatARGB_4444: sl@0: case EUidPixelFormatRGB_565: sl@0: { sl@0: bytesPerPixel = 2; sl@0: break; sl@0: } sl@0: default: sl@0: { sl@0: User::Leave(KErrNotSupported); sl@0: break; sl@0: } sl@0: } sl@0: return bytesPerPixel; sl@0: } sl@0: