Update contrib.
1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
21 #include <imageconversion.h>
22 #include "surfaceutility.h"
23 #include <BitmapTransforms.h>
25 //_LIT(KFileName,"surfacemanager");
27 CSurfaceUtility::CSurfaceUtility(CSurfaceUtility* aClone/*=NULL*/)
28 : iSurfaces(aClone?&(aClone->iSurfaces):NULL)
32 CSurfaceUtility* CSurfaceUtility::NewL(CSurfaceUtility* aClone/*=NULL*/)
34 CSurfaceUtility* utility = new (ELeave)CSurfaceUtility(aClone);
35 CleanupStack::PushL(utility);
36 utility->ConstructL();
37 CleanupStack::Pop(utility);
41 void CSurfaceUtility::ConstructL()
43 TInt r = iManager.Open();
46 LOG(("Surface manager failed to open: %d", r));
50 r = iSurfaceUpdateSession.Connect();
53 LOG(("Failed to connect to update server: %d", r));
58 CSurfaceUtility::~CSurfaceUtility()
66 iSurfaceUpdateSession.Close();
68 // the following call is needed because of a bug in CImageDecoder that
70 REComSession::FinalClose();
73 TBool CSurfaceUtility::DestroyAll()
76 TInt jj = iSurfaces.Count() - 1;
81 err = iManager.CloseSurface(iSurfaces[jj]);
84 LOG(("Error closing surface: 0x%X\n", err));
91 /***************************************
92 * The aim of the THeapSurfaceArray is to locally switch in the specified heap for any array operation
93 ***************************************/
95 CSurfaceUtility::RHeapSurfaceArray::RHeapSurfaceArray(RHeapSurfaceArray* aUseExternalArray)
96 : iUseArray(aUseExternalArray?aUseExternalArray->iUseArray:&this->iLocalArray),
97 iExternalHeapRef(aUseExternalArray?aUseExternalArray->iExternalHeapRef:User::Heap())
101 /************************************
102 * The following methods have been used by the surfaceutility... some require the heap wrapping, and some don't
103 * I actually need three different startegies (count em) for 7 methods...
104 * Some methods only read the existing objects, so don't need a heap swap at all
105 * Leaving methods have to use PopAndDestroy strategy to restore the heap on leaving or success
106 * Non-leaving methods must not call PushL, so directly make SwitchHeap calls!
107 ************************************/
109 // PopAndDestroy method to restore the heap
110 /*static*/ void CSurfaceUtility::RHeapSurfaceArray::PopHeap(void* aHeapPtr)
112 RHeap* heapPtr=(RHeap*)aHeapPtr;
113 User::SwitchHeap(heapPtr);
116 // Switches and pushes the previous heap so it can be restored with PopAndDestroy
117 /*static*/ void CSurfaceUtility::RHeapSurfaceArray::SwitchHeapLC(RHeap* aNewHeap)
119 CleanupStack::PushL(TCleanupItem(PopHeap,NULL));
120 CleanupStack::PushL(TCleanupItem(PopHeap,NULL));
121 CleanupStack::PushL(TCleanupItem(PopHeap,NULL));
122 CleanupStack::Pop(3);
123 RHeap* oldHeap=User::SwitchHeap(aNewHeap);
125 CleanupStack::PushL(TCleanupItem(PopHeap,oldHeap));
129 TSurfaceId& CSurfaceUtility::RHeapSurfaceArray::operator[](TUint aIndex)
131 return iUseArray->operator[](aIndex);
133 // Close only closes the local array, while Reset resets the active array (may be external)
134 void CSurfaceUtility::RHeapSurfaceArray::Close()
136 RHeap* oldHeap=User::SwitchHeap(&iExternalHeapRef);
138 User::SwitchHeap(oldHeap);
140 TInt CSurfaceUtility::RHeapSurfaceArray::Count() const
142 return iUseArray->Count();
144 // Close only closes the local array, while Reset resets the active array (may be external)
145 inline void CSurfaceUtility::RHeapSurfaceArray::Reset()
147 RHeap* oldHeap=User::SwitchHeap(&iExternalHeapRef);
149 User::SwitchHeap(oldHeap);
151 void CSurfaceUtility::RHeapSurfaceArray::AppendL(const TSurfaceId &anEntry)
153 SwitchHeapLC(&iExternalHeapRef);
154 iUseArray->AppendL(anEntry);
155 CleanupStack::PopAndDestroy();
157 TInt CSurfaceUtility::RHeapSurfaceArray::Find(const TSurfaceId &anEntry) const
159 return iUseArray->Find(anEntry);
161 void CSurfaceUtility::RHeapSurfaceArray::Remove(TInt anIndex)
163 RHeap* oldHeap=User::SwitchHeap(&iExternalHeapRef);
164 iUseArray->Remove(anIndex);
165 User::SwitchHeap(oldHeap);
172 Cleanup stack helper object, holding references to both utility and surface, so
173 that the standard Close() semantics can be used.
175 class TSurfaceCleanup
178 TSurfaceCleanup(CSurfaceUtility& aUtility, TSurfaceId& aSurface)
179 : iUtility(aUtility), iSurface(aSurface)
183 // Removes the surface from the list of surfaces to clean up, and closes
184 // the surface reference.
185 iUtility.DestroySurface(iSurface);
188 CSurfaceUtility& iUtility;
189 TSurfaceId& iSurface;
193 Read the given image file into a new surface.
195 @param aFileName The name of the image file.
196 @param aSurface Filled with the surface ID for the surface containing the pixels.
198 void CSurfaceUtility::CreateSurfaceFromFileL(const TDesC& aFileName, TSurfaceId& aSurface)
202 User::LeaveIfError(fs.Connect());
203 CleanupClosePushL(fs);
204 CImageDecoder* decoder = CImageDecoder::FileNewL(fs, aFileName, CImageDecoder::EOptionAlwaysThread);
205 CleanupStack::PushL(decoder);
207 const TFrameInfo& info = decoder->FrameInfo();
209 TSize size = info.iOverallSizeInPixels;
210 TInt stride = size.iWidth << 2; // Default to four bytes per pixel
211 TDisplayMode bmpFormat = info.iFrameDisplayMode;
212 TUidPixelFormat pixelFormat = EUidPixelFormatUnknown;
225 bmpFormat = EColor16MU;
226 pixelFormat = EUidPixelFormatXRGB_8888;
231 stride = size.iWidth << 1;
232 pixelFormat = EUidPixelFormatXRGB_4444;
237 stride = size.iWidth << 1;
238 pixelFormat = EUidPixelFormatRGB_565;
243 pixelFormat = EUidPixelFormatARGB_8888;
248 pixelFormat = EUidPixelFormatARGB_8888_PRE;
253 LOG(("Unsupported display mode: %d", bmpFormat));
254 User::Leave(KErrNotSupported);
259 // Create an intermediary bitmap for decoding into
260 CFbsBitmap* bitmap = new (ELeave) CFbsBitmap();
261 CleanupStack::PushL(bitmap);
262 User::LeaveIfError(bitmap->Create(size, info.iFrameDisplayMode));
264 // Create the final surface.
265 aSurface = CreateSurfaceL(size, pixelFormat, stride);
266 TSurfaceCleanup surfaceCleanup(*this, aSurface);
267 CleanupClosePushL(surfaceCleanup);
270 User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
271 CleanupClosePushL(chunk);
273 // Convert the image file into a Symbian bitmap
274 TRequestStatus status;
275 decoder->Convert(&status, *bitmap);
276 User::WaitForRequest(status);
277 User::LeaveIfError(status.Int());
279 // Copy the data from the bitmap into the surface.
281 for (start.iY = 0; start.iY < size.iHeight; start.iY++)
283 // Set up a descriptor for the current line in the surface and get pixels.
284 TPtr8 ptr(chunk.Base() + start.iY * stride, stride);
285 bitmap->GetScanLine(ptr, start, size.iWidth, bmpFormat);
288 CleanupStack::PopAndDestroy(/* chunk */);
289 CleanupStack::Pop(/* surfaceCleanup */);
290 CleanupStack::PopAndDestroy(bitmap);
291 CleanupStack::PopAndDestroy(decoder);
292 CleanupStack::PopAndDestroy(/* fs */);
295 void CSurfaceUtility::CopyBitmapSurfaceL(const CFbsBitmap* aBitmap, TSurfaceId& aSurface)
298 User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
299 CleanupClosePushL(chunk);
300 TSize bitmapSize = aBitmap->SizeInPixels();
301 TSize size = SurfaceSize(aSurface);
302 TInt stride = size.iWidth*4; // Default to four bytes per pixel
304 // Copy the data from the bitmap into the surface.
306 for (start.iY = 0; start.iY < bitmapSize.iHeight; start.iY++)
308 // Set up a descriptor for the current line in the surface and get pixels.
309 TPtr8 ptr(chunk.Base() + start.iY * stride, stride);
310 aBitmap->GetScanLine(ptr, start, bitmapSize.iWidth, EColor16MU);
312 CleanupStack::PopAndDestroy(/* chunk */);
316 Copy the bitmap from a file to a surface.
318 @param aFileName The name of the image file.
319 @param aSurface Filled with the surface ID for the surface containing the pixels.
321 void CSurfaceUtility::CopyBitmapFromFileToSurfaceL(const TDesC& aFileName, const TSurfaceId& aSurface)
325 User::LeaveIfError(fs.Connect());
326 CleanupClosePushL(fs);
327 CImageDecoder* decoder = CImageDecoder::FileNewL(fs, aFileName, CImageDecoder::EOptionAlwaysThread);
328 CleanupStack::PushL(decoder);
330 const TFrameInfo& info = decoder->FrameInfo();
332 TSize size = SurfaceSize(aSurface);
333 TDisplayMode bmpFormat = info.iFrameDisplayMode;
334 TInt stride = size.iWidth << 2; // Default to four bytes per pixel
336 // Create an intermediary bitmap for decoding into
337 CFbsBitmap* bitmap = new (ELeave) CFbsBitmap();
338 CleanupStack::PushL(bitmap);
339 User::LeaveIfError(bitmap->Create(size, info.iFrameDisplayMode));
342 User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
343 CleanupClosePushL(chunk);
345 // Convert the image file into a Symbian bitmap
346 TRequestStatus status;
347 decoder->Convert(&status, *bitmap);
348 User::WaitForRequest(status);
349 User::LeaveIfError(status.Int());
351 // Copy the data from the bitmap into the surface.
353 for (start.iY = 0; start.iY < size.iHeight; start.iY++)
355 // Set up a descriptor for the current line in the surface and get pixels.
356 TPtr8 ptr(chunk.Base() + start.iY * stride, stride);
357 bitmap->GetScanLine(ptr, start, size.iWidth, bmpFormat);
360 CleanupStack::PopAndDestroy(/* chunk */);
361 CleanupStack::PopAndDestroy(bitmap);
362 CleanupStack::PopAndDestroy(decoder);
363 CleanupStack::PopAndDestroy(/* fs */);
367 Copy the bitmap from a file to a surface scaling the original image to cover the entire surface.
369 @param aFileName The name of the image file.
370 @param aSurface Filled with the surface ID for the surface containing the pixels.
372 void CSurfaceUtility::ScaleBitmapFromFileToSurfaceL(const TDesC& aFileName, const TSurfaceId& aSurface)
376 User::LeaveIfError(fs.Connect());
377 CleanupClosePushL(fs);
378 CImageDecoder* decoder = CImageDecoder::FileNewL(fs, aFileName, CImageDecoder::EOptionAlwaysThread);
379 CleanupStack::PushL(decoder);
381 const TFrameInfo& info = decoder->FrameInfo();
383 TSize size = SurfaceSize(aSurface);
384 TInt stride = size.iWidth << 2; // Default to four bytes per pixel
386 // Create an intermediary bitmap for decoding into
387 CFbsBitmap* bitmap = new (ELeave) CFbsBitmap();
388 CleanupStack::PushL(bitmap);
389 User::LeaveIfError(bitmap->Create(info.iOverallSizeInPixels, info.iFrameDisplayMode));
392 User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
393 CleanupClosePushL(chunk);
394 TUint8* surfacePixelData = chunk.Base() + PixelDataOffet(aSurface);
396 // Convert the image file into a Symbian bitmap
397 // CImageDecoder::EOptionAlwaysThread setting above avoids need for Active Object
398 TRequestStatus status;
399 decoder->Convert(&status, *bitmap);
400 User::WaitForRequest(status);
401 User::LeaveIfError(status.Int());
403 // scale to fit surface
404 CBitmapScaler* scaler = CBitmapScaler::NewL();
405 CleanupStack::PushL(scaler);
406 scaler->SetQualityAlgorithm(CBitmapScaler::EMaximumQuality);
408 CActiveListener* activeListener = CActiveListener::NewLC();
409 activeListener->Initialize();
410 scaler->Scale(&activeListener->iStatus, *bitmap, size, EFalse);
411 CActiveScheduler::Start();
413 User::LeaveIfError(activeListener->iStatus.Int());
415 // Copy the data from the bitmap into the surface.
417 for (start.iY = 0; start.iY < size.iHeight; start.iY++)
419 // Set up a descriptor for the current line in the surface and get pixels.
420 TPtr8 ptr(surfacePixelData + start.iY * stride, stride);
421 bitmap->GetScanLine(ptr, start, size.iWidth, EColor16MA);
423 CleanupStack::PopAndDestroy(activeListener);
424 CleanupStack::PopAndDestroy(scaler);
425 CleanupStack::PopAndDestroy(/* chunk */);
426 CleanupStack::PopAndDestroy(bitmap);
427 CleanupStack::PopAndDestroy(decoder);
428 CleanupStack::PopAndDestroy(/* fs */);
432 Get the size of a surface.
434 @param aSurface The surface to get the size for.
435 @return The size in pixels, or empty on failure.
437 TSize CSurfaceUtility::SurfaceSize(const TSurfaceId& aSurface)
439 RSurfaceManager::TInfoBuf infoBuf;
440 RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
442 if (iManager.SurfaceInfo(aSurface, infoBuf) == KErrNone)
451 Get the offset into the chunk of the start of pixel data.
453 @param aSurface The surface to get the size for.
454 @return The offset bytes, or empty on failure.
456 TInt CSurfaceUtility::PixelDataOffet(const TSurfaceId& aSurface)
458 TInt offsetToFirstBuffer = 0;
459 iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer);
461 return offsetToFirstBuffer;
466 Create a surface using the surface manager.
468 Stores the ID for tear down, as well as returning it.
470 @param aSize Dimensions of the surface.
471 @param aPixelFormat UID of the pixel format.
472 @param aStride Stride value for the surface (usually bytes per pixel * width)
473 @leave May leave due to lack of memory.
474 @return New surface's ID.
476 TSurfaceId CSurfaceUtility::CreateSurfaceL(const TSize& aSize, TUidPixelFormat aPixelFormat, TInt aStride, TInt aBuffers)
478 RSurfaceManager::TSurfaceCreationAttributesBuf bf;
479 RSurfaceManager::TSurfaceCreationAttributes& b = bf();
481 b.iSize.iWidth = aSize.iWidth;
482 b.iSize.iHeight = aSize.iHeight;
483 b.iBuffers = aBuffers; // number of buffers in the surface
484 b.iPixelFormat = aPixelFormat;
485 b.iStride = aStride; // Number of bytes between start of one line and start of next
486 b.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data
487 b.iAlignment = 4; // alignment, 1,2,4,8 byte aligned
488 b.iContiguous=EFalse;
490 TSurfaceId surface = TSurfaceId::CreateNullId();
492 User::LeaveIfError(iManager.CreateSurface(bf, surface));
493 iSurfaces.AppendL(surface);
499 Fill the given surface with a color.
501 @param aSurface The surface to be filled.
502 @param aColor The color to fill it with.
504 void CSurfaceUtility::FillSurfaceL(TSurfaceId& aSurface, const TRgb& aColor)
506 RSurfaceManager::TInfoBuf infoBuf;
507 RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
509 User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
511 TBool use16 = EFalse;
513 if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0)
515 User::Leave(KErrCorrupt);
517 if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0)
519 User::Leave(KErrNotReady);
522 switch (info.iPixelFormat)
524 case EUidPixelFormatXRGB_8888:
526 color = aColor.Color16MU();
527 #ifdef ALPHA_FIX_24BIT
528 color |= ((ALPHA_FIX_24BIT)&0xff)<<24;
532 case EUidPixelFormatARGB_8888:
534 color = aColor.Color16MA();
537 case EUidPixelFormatARGB_8888_PRE:
539 color = aColor.Color16MAP();
542 case EUidPixelFormatXRGB_4444:
543 case EUidPixelFormatARGB_4444:
545 color = aColor.Color4K();
549 case EUidPixelFormatRGB_565:
551 color = aColor.Color64K();
557 User::Leave(KErrNotSupported);
563 User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
565 TUint8* surfacePtr = chunk.Base();
566 TUint8* linePtr = surfacePtr;
570 if ( info.iSize.iWidth*2>info.iStride)
572 User::Leave(KErrOverflow);
574 TUint16* ptr = reinterpret_cast<TUint16*>(surfacePtr);
577 for (TInt xx = 0; xx < info.iSize.iWidth; xx++)
579 ptr[xx] = (TUint16)color;
584 if ( info.iSize.iWidth*4>info.iStride)
586 User::Leave(KErrOverflow);
588 TUint32* ptr = reinterpret_cast<TUint32*>(surfacePtr);
591 for (TInt xx = 0; xx < info.iSize.iWidth; xx++)
597 // Now copy that to the other lines
598 for (TInt yy = 1; yy < info.iSize.iHeight; yy++)
600 linePtr += info.iStride;
601 Mem::Move(linePtr, surfacePtr, info.iStride);
606 TInt err = iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL);
608 LOG(("Error submitting update: 0x%X\n", err));
612 Fill the given memory chunk with a color.
614 @param aSurface The surface to be filled.
615 @param aChunk The surface to be filled.
616 @param aColor The color to fill it with.
618 void CSurfaceUtility::FillChunkL(TSurfaceId& aSurface, RChunk& aChunk, const TRgb& aColor, TInt aBufferNumber)
620 RSurfaceManager::TInfoBuf infoBuf;
621 RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
623 User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
625 TBool use16 = EFalse;
627 if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0)
629 User::Leave(KErrCorrupt);
631 if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0)
633 User::Leave(KErrNotReady);
636 switch (info.iPixelFormat)
638 case EUidPixelFormatXRGB_8888:
640 color = aColor.Color16MU();
641 #ifdef ALPHA_FIX_24BIT
642 color |= ((ALPHA_FIX_24BIT)&0xff)<<24;
646 case EUidPixelFormatARGB_8888:
648 color = aColor.Color16MA();
651 case EUidPixelFormatARGB_8888_PRE:
653 color = aColor.Color16MAP();
656 case EUidPixelFormatXRGB_4444:
657 case EUidPixelFormatARGB_4444:
659 color = aColor.Color4K();
663 case EUidPixelFormatRGB_565:
665 color = aColor.Color64K();
671 User::Leave(KErrNotSupported);
676 User::LeaveIfError(iManager.MapSurface(aSurface, aChunk));
678 TInt offsetToFirstBuffer;
679 User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer));
680 TInt offsetToBufferNumber;
681 User::LeaveIfError(iManager.GetBufferOffset(aSurface, aBufferNumber, offsetToBufferNumber));
683 TUint8* chunkPtr = aChunk.Base() + offsetToFirstBuffer;
684 TUint8* linePtr = aChunk.Base() + offsetToBufferNumber;
685 TUint8* surfPlanePtr = linePtr;
689 if ( info.iSize.iWidth*2>info.iStride)
692 User::Leave(KErrOverflow);
694 TUint16* ptr = reinterpret_cast<TUint16*>(surfPlanePtr);
697 for (TInt xx = 0; xx < info.iSize.iWidth; xx++)
699 ptr[xx] = (TUint16)color;
704 if ( info.iSize.iWidth*4>info.iStride)
707 User::Leave(KErrOverflow);
709 TUint32* ptr = reinterpret_cast<TUint32*>(surfPlanePtr);
712 for (TInt xx = 0; xx < info.iSize.iWidth; xx++)
718 // Now copy that to the other lines
719 for (TInt yy = 1; yy < info.iSize.iHeight; yy++)
721 linePtr += info.iStride;
722 Mem::Copy(linePtr, surfPlanePtr, info.iSize.iWidth * BytesPerPixelL(info.iPixelFormat));
729 Fill a rectangle on the given surface.
731 @param aSurface The surface to be filled.
732 @param aStartPos Where to place the rectangle.
733 @param aSize Size of the rectangle.
734 @param aColor The colour to fill it with.
736 void CSurfaceUtility::FillRectangleL(TSurfaceId& aSurface, TPoint& aStartPos, TSize& aSize, const TRgb& aColor)
738 RSurfaceManager::TInfoBuf infoBuf;
739 RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
741 User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
743 TBool use16 = EFalse;
745 if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0)
747 User::Leave(KErrCorrupt);
749 if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0)
751 User::Leave(KErrNotReady);
754 switch (info.iPixelFormat)
756 case EUidPixelFormatXRGB_8888:
758 color = aColor.Color16MU();
759 #ifdef ALPHA_FIX_24BIT
760 color |= ((ALPHA_FIX_24BIT)&0xff)<<24;
764 case EUidPixelFormatARGB_8888:
766 color = aColor.Color16MA();
769 case EUidPixelFormatARGB_8888_PRE:
771 color = aColor.Color16MAP();
774 case EUidPixelFormatXRGB_4444:
775 case EUidPixelFormatARGB_4444:
777 color = aColor.Color4K();
781 case EUidPixelFormatRGB_565:
783 color = aColor.Color64K();
789 User::Leave(KErrNotSupported);
795 User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
797 TUint8* surfacePtr = chunk.Base();
799 // Check for out of bounds
800 TBool validRect = ETrue;
801 TInt surfaceWidth = info.iSize.iWidth;
802 TInt surfaceHeight = info.iSize.iHeight;
805 if ((aStartPos.iX + aSize.iWidth) > surfaceWidth)
808 if ((aStartPos.iY + aSize.iHeight) > surfaceHeight)
812 if ((aStartPos.iX < 0) || (aStartPos.iY < 0))
816 User::Leave(KErrOverflow);
820 if ( info.iSize.iWidth*2>info.iStride)
822 User::Leave(KErrOverflow);
825 TUint16* ptr = reinterpret_cast<TUint16*>(surfacePtr);
827 // Fill the rectangle
828 TInt yPos = aStartPos.iY;
829 TInt xPos = aStartPos.iX;
830 for (TInt yy = 0; yy < aSize.iHeight; ++yy)
832 ptr = reinterpret_cast<TUint16*>(surfacePtr+(yPos*info.iStride));
833 for (TInt xx = 0; xx < aSize.iWidth; ++xx)
844 if ( info.iSize.iWidth*4>info.iStride)
846 User::Leave(KErrOverflow);
849 TUint32* ptr = reinterpret_cast<TUint32*>(surfacePtr);
851 // Fill the rectangle
852 TInt yPos = aStartPos.iY;
853 TInt xPos = aStartPos.iX;
854 for (TInt yy = 0; yy < aSize.iHeight; ++yy)
856 ptr = reinterpret_cast<TUint32*>(surfacePtr+(yPos*info.iStride));
857 for (TInt xx = 0; xx < aSize.iWidth; ++xx)
869 TInt err = iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL);
871 LOG(("Error submitting update: 0x%X\n", err));
875 Fill a rectangle on the given surface - does not submit update.
877 @param aSurface The surface to be filled.
878 @param aStartPos Where to place the rectangle.
879 @param aSize Size of the rectangle.
880 @param aColor The colour to fill it with.
882 void CSurfaceUtility::FillRectangleNoUpdateL(TSurfaceId& aSurface, TPoint& aStartPos, TSize& aSize, const TRgb& aColor)
884 RSurfaceManager::TInfoBuf infoBuf;
885 RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
887 User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
889 TBool use16 = EFalse;
891 if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0)
893 User::Leave(KErrCorrupt);
895 if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0)
897 User::Leave(KErrNotReady);
900 switch (info.iPixelFormat)
902 case EUidPixelFormatXRGB_8888:
904 color = aColor.Color16MU();
905 #ifdef ALPHA_FIX_24BIT
906 color |= ((ALPHA_FIX_24BIT)&0xff)<<24;
910 case EUidPixelFormatARGB_8888:
912 color = aColor.Color16MA();
915 case EUidPixelFormatARGB_8888_PRE:
917 color = aColor.Color16MAP();
920 case EUidPixelFormatXRGB_4444:
921 case EUidPixelFormatARGB_4444:
923 color = aColor.Color4K();
927 case EUidPixelFormatRGB_565:
929 color = aColor.Color64K();
935 User::Leave(KErrNotSupported);
941 User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
943 TUint8* surfacePtr = chunk.Base();
945 // Check for out of bounds
946 TBool validRect = ETrue;
947 TInt surfaceWidth = info.iSize.iWidth;
948 TInt surfaceHeight = info.iSize.iHeight;
951 if ((aStartPos.iX + aSize.iWidth) > surfaceWidth)
954 if ((aStartPos.iY + aSize.iHeight) > surfaceHeight)
958 if ((aStartPos.iX < 0) || (aStartPos.iY < 0))
962 User::Leave(KErrOverflow);
966 if ( info.iSize.iWidth*2>info.iStride)
968 User::Leave(KErrOverflow);
971 TUint16* ptr = reinterpret_cast<TUint16*>(surfacePtr);
973 // Fill the rectangle
974 TInt yPos = aStartPos.iY;
975 TInt xPos = aStartPos.iX;
976 for (TInt yy = 0; yy < aSize.iHeight; ++yy)
978 ptr = reinterpret_cast<TUint16*>(surfacePtr+(yPos*info.iStride));
979 for (TInt xx = 0; xx < aSize.iWidth; ++xx)
990 if ( info.iSize.iWidth*4>info.iStride)
992 User::Leave(KErrOverflow);
995 TUint32* ptr = reinterpret_cast<TUint32*>(surfacePtr);
997 // Fill the rectangle
998 TInt yPos = aStartPos.iY;
999 TInt xPos = aStartPos.iX;
1000 for (TInt yy = 0; yy < aSize.iHeight; ++yy)
1002 ptr = reinterpret_cast<TUint32*>(surfacePtr+(yPos*info.iStride));
1003 for (TInt xx = 0; xx < aSize.iWidth; ++xx)
1008 xPos = aStartPos.iX;
1018 Fill the given surface with a grid over a solid color.
1020 Similar to FillSurfaceL(), but with a grid overlayed. The pitch of the grid is
1023 @param aSurface The surface to be filled.
1024 @param aColor The color to fill it with.
1025 @param aLines The color of the grid lines.
1027 void CSurfaceUtility::GridFillSurfaceL(TSurfaceId& aSurface, const TRgb& aColor, const TRgb& aLines)
1029 RSurfaceManager::TInfoBuf infoBuf;
1030 RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
1032 User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
1035 TBool use16 = EFalse;
1037 if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0)
1039 User::Leave(KErrCorrupt);
1041 if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0)
1043 User::Leave(KErrNotReady);
1046 switch (info.iPixelFormat)
1048 case EUidPixelFormatXRGB_8888:
1050 color = aColor.Color16MU();
1051 lines = aLines.Color16MU();
1052 #ifdef ALPHA_FIX_24BIT
1053 color |= ((ALPHA_FIX_24BIT)&0xff)<<24;
1054 lines |= ((ALPHA_FIX_24BIT)&0xff)<<24;
1058 case EUidPixelFormatARGB_8888:
1060 color = aColor.Color16MA();
1061 lines = aLines.Color16MA();
1064 case EUidPixelFormatARGB_8888_PRE:
1066 color = aColor.Color16MAP();
1067 lines = aLines.Color16MAP();
1070 case EUidPixelFormatXRGB_4444:
1071 case EUidPixelFormatARGB_4444:
1073 color = aColor.Color4K();
1074 lines = aLines.Color4K();
1078 case EUidPixelFormatRGB_565:
1080 color = aColor.Color64K();
1081 lines = aLines.Color64K();
1087 User::Leave(KErrNotSupported);
1093 User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
1095 TUint8* surfacePtr = chunk.Base();
1096 TUint8* linePtr = surfacePtr;
1100 if ( info.iSize.iWidth*2>info.iStride)
1102 User::Leave(KErrOverflow);
1104 TUint16* ptr = reinterpret_cast<TUint16*>(surfacePtr);
1107 for (TInt xx1 = 0; xx1 < info.iSize.iWidth; xx1++)
1109 ptr[xx1] = (TUint16)lines;
1113 ptr = reinterpret_cast<TUint16*>(surfacePtr + info.iStride);
1114 for (TInt xx2 = 0; xx2 < info.iSize.iWidth; xx2++)
1116 // Vertical line every 8 pixels across
1117 ptr[xx2] = (TUint16)((xx2 & 7) ? color : lines);
1122 if ( info.iSize.iWidth*4>info.iStride)
1124 User::Leave(KErrOverflow);
1126 TUint32* ptr = reinterpret_cast<TUint32*>(surfacePtr);
1129 for (TInt xx3 = 0; xx3 < info.iSize.iWidth; xx3++)
1135 ptr = reinterpret_cast<TUint32*>(surfacePtr + info.iStride);
1136 for (TInt xx4 = 0; xx4 < info.iSize.iWidth; xx4++)
1138 // Vertical line every 8 pixels across
1139 ptr[xx4] = (xx4 & 7) ? color : lines;
1142 linePtr += info.iStride;
1144 // Now copy that to the other lines
1145 for (TInt yy = 2; yy < info.iSize.iHeight; yy++)
1147 linePtr += info.iStride;
1151 Mem::Move(linePtr, surfacePtr + info.iStride, info.iStride);
1156 Mem::Move(linePtr, surfacePtr, info.iStride);
1161 TInt err =iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL);
1163 LOG(("Error submitting update: 0x%X\n", err));
1169 Fill the given surface with a pattern suitable for automated testing.
1171 @param aSurface The surface to be filled.
1173 void CSurfaceUtility::PatternFillSurfaceL(TSurfaceId& aSurface)
1175 RSurfaceManager::TInfoBuf infoBuf;
1176 RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
1178 User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
1180 // Fill the background
1181 FillSurfaceL(aSurface, TRgb(0x00000000));
1183 TInt surfaceWidth = info.iSize.iWidth;
1184 TInt surfaceHeight = info.iSize.iHeight;
1186 // Create the 4 rectangles in the corners
1187 TPoint startPos(0,0);
1189 TInt rectWidth = size.iWidth;
1190 TInt rectHeight = size.iHeight;
1192 FillRectangleL(aSurface, startPos, size, TRgb(0x0000ff));
1195 startPos.iX = surfaceWidth - rectWidth;
1197 FillRectangleL(aSurface, startPos, size, TRgb(0x00ff00));
1201 startPos.iY = surfaceHeight - rectHeight;
1202 FillRectangleL(aSurface, startPos, size, TRgb(0x00ffff));
1205 startPos.iX = surfaceWidth - rectWidth;
1206 startPos.iY = surfaceHeight - rectHeight;
1207 FillRectangleL(aSurface, startPos, size, TRgb(0xffffff));
1209 // Create the 4 side bars
1213 size.iHeight = surfaceHeight - 12;
1215 FillRectangleL(aSurface, startPos, size, TRgb(0x808000));
1217 startPos.iX = surfaceWidth - size.iWidth;
1220 FillRectangleL(aSurface, startPos, size, TRgb(0xff00ff));
1223 startPos.iY = surfaceHeight - size.iWidth;
1224 size.iWidth = surfaceWidth - 12;
1227 FillRectangleL(aSurface, startPos, size, TRgb(0xaaaaaa));
1232 FillRectangleL(aSurface, startPos, size, TRgb(0x000080));
1236 template <class TIntType> void
1237 DdaLine(TUint aX1, TUint aY1,TUint aX2,TUint aY2, TUint aPixPerScan, TIntType* aBuffer, TIntType aColor)
1243 { adx=-adx; sdx=-1; }
1244 TInt ady=dy,sdy=aPixPerScan;
1246 { ady=-ady; sdy=-aPixPerScan; }
1247 //This is simplistic integert DDA.
1248 //The vertical cases are handled by this 1/2 accumulator:
1249 // If adx is zero then we step in sdy indefinitely
1250 // If ady is zero then we step in sdx indefinitely
1253 TIntType* bufferend=aBuffer+aX2+aY2*aPixPerScan;
1254 aBuffer+=aX1+aY1*aPixPerScan;
1256 while (aBuffer!=bufferend)
1273 template <class TIntType> void
1274 FanFill(const TPoint& aInnerXY,TUint aPixPerScan, TIntType* aSurfacePtr, TIntType aLinesTL,
1275 TIntType aLinesBR, TIntType aLinesTR, TIntType aLinesBL)
1278 DdaLine(aInnerXY.iX,0,aInnerXY.iX-aInnerXY.iX*180/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTR);
1279 DdaLine(aInnerXY.iX,0,aInnerXY.iX-aInnerXY.iX*372/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTR);
1280 DdaLine(aInnerXY.iX,0,aInnerXY.iX-aInnerXY.iX*591/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTR);
1281 DdaLine(aInnerXY.iX,0,aInnerXY.iX-aInnerXY.iX*859/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTR);
1283 DdaLine(aInnerXY.iX,0,0,aInnerXY.iY*180/1024,aPixPerScan,aSurfacePtr,aLinesTR);
1284 DdaLine(aInnerXY.iX,0,0,aInnerXY.iY*372/1024,aPixPerScan,aSurfacePtr,aLinesTR);
1285 DdaLine(aInnerXY.iX,0,0,aInnerXY.iY*591/1024,aPixPerScan,aSurfacePtr,aLinesTR);
1286 DdaLine(aInnerXY.iX,0,0,aInnerXY.iY*859/1024,aPixPerScan,aSurfacePtr,aLinesTR);
1288 DdaLine(0,aInnerXY.iY,aInnerXY.iX*180/1024,0,aPixPerScan,aSurfacePtr,aLinesBL);
1289 DdaLine(0,aInnerXY.iY,aInnerXY.iX*372/1024,0,aPixPerScan,aSurfacePtr,aLinesBL);
1290 DdaLine(0,aInnerXY.iY,aInnerXY.iX*591/1024,0,aPixPerScan,aSurfacePtr,aLinesBL);
1291 DdaLine(0,aInnerXY.iY,aInnerXY.iX*859/1024,0,aPixPerScan,aSurfacePtr,aLinesBL);
1293 DdaLine(0,aInnerXY.iY,aInnerXY.iX,aInnerXY.iY-aInnerXY.iY*180/1024,aPixPerScan,aSurfacePtr,aLinesBL);
1294 DdaLine(0,aInnerXY.iY,aInnerXY.iX,aInnerXY.iY-aInnerXY.iY*372/1024,aPixPerScan,aSurfacePtr,aLinesBL);
1295 DdaLine(0,aInnerXY.iY,aInnerXY.iX,aInnerXY.iY-aInnerXY.iY*591/1024,aPixPerScan,aSurfacePtr,aLinesBL);
1296 DdaLine(0,aInnerXY.iY,aInnerXY.iX,aInnerXY.iY-aInnerXY.iY*859/1024,aPixPerScan,aSurfacePtr,aLinesBL);
1298 DdaLine(0,0,aInnerXY.iX*180/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTL);
1299 DdaLine(0,0,aInnerXY.iX*372/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTL);
1300 DdaLine(0,0,aInnerXY.iX*591/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTL);
1301 DdaLine(0,0,aInnerXY.iX*859/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTL);
1303 DdaLine(0,0,aInnerXY.iX,aInnerXY.iY*180/1024,aPixPerScan,aSurfacePtr,aLinesTL);
1304 DdaLine(0,0,aInnerXY.iX,aInnerXY.iY*372/1024,aPixPerScan,aSurfacePtr,aLinesTL);
1305 DdaLine(0,0,aInnerXY.iX,aInnerXY.iY*591/1024,aPixPerScan,aSurfacePtr,aLinesTL);
1306 DdaLine(0,0,aInnerXY.iX,aInnerXY.iY*859/1024,aPixPerScan,aSurfacePtr,aLinesTL);
1308 DdaLine(0,aInnerXY.iY-aInnerXY.iY*180/1024,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR);
1309 DdaLine(0,aInnerXY.iY-aInnerXY.iY*372/1024,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR);
1310 DdaLine(0,aInnerXY.iY-aInnerXY.iY*591/1024,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR);
1311 DdaLine(0,aInnerXY.iY-aInnerXY.iY*859/1024,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR);
1313 DdaLine(aInnerXY.iX-aInnerXY.iX*180/1024,0,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR);
1314 DdaLine(aInnerXY.iX-aInnerXY.iX*372/1024,0,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR);
1315 DdaLine(aInnerXY.iX-aInnerXY.iX*591/1024,0,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR);
1316 DdaLine(aInnerXY.iX-aInnerXY.iX*859/1024,0,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR);
1320 Fill the given surface with a fan of lines over a solid color.
1322 Similar to FillSurfaceL(), but with a fan of lines overlayed.
1323 One fan is drawn about the top-left, and second fan at bottom-right.
1324 The fan contains 8 segments.
1326 @param aSurface The surface to be filled.
1327 @param aColor The color to fill it with.
1328 @param aLines The color of the grid lines.
1330 void CSurfaceUtility::FanFillSurfaceL(TSurfaceId& aSurface, const TRgb& aColor, const TRgb& aLinesTL, const TRgb& aLinesBR)
1332 FillSurfaceL(aSurface,aColor);
1333 RSurfaceManager::TInfoBuf infoBuf;
1334 RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
1336 User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
1337 TUint32 linesTL = 0;
1338 TUint32 linesBR = 0;
1339 TUint32 linesTR = 0;
1340 TUint32 linesBL = 0;
1341 TBool use16 = EFalse;
1342 TRgb rgbLinesTR(0,0,0);
1343 TRgb rgbLinesBL(255,255,255);
1345 switch (info.iPixelFormat)
1347 case EUidPixelFormatXRGB_8888:
1349 linesBR = aLinesBR.Color16MU();
1350 linesTL = aLinesTL.Color16MU();
1351 linesTR = rgbLinesTR.Color16MU();
1352 linesBL = rgbLinesBL.Color16MU();
1353 #ifdef ALPHA_FIX_24BIT
1354 linesBR |= ((ALPHA_FIX_24BIT)&0xff)<<24;
1355 linesTL |= ((ALPHA_FIX_24BIT)&0xff)<<24;
1356 linesTR |= ((ALPHA_FIX_24BIT)&0xff)<<24;
1357 linesBL |= ((ALPHA_FIX_24BIT)&0xff)<<24;
1361 case EUidPixelFormatARGB_8888:
1363 linesBR = aLinesBR.Color16MA();
1364 linesTL = aLinesTL.Color16MA();
1365 linesTR = rgbLinesTR.Color16MA();
1366 linesBL = rgbLinesBL.Color16MA();
1369 case EUidPixelFormatARGB_8888_PRE:
1371 linesBR = aLinesBR.Color16MAP();
1372 linesTL = aLinesTL.Color16MAP();
1373 linesTR = rgbLinesTR.Color16MAP();
1374 linesBL = rgbLinesBL.Color16MAP();
1377 case EUidPixelFormatXRGB_4444:
1378 case EUidPixelFormatARGB_4444:
1380 linesBR = aLinesBR.Color4K();
1381 linesTL = aLinesTL.Color4K();
1382 linesTR = rgbLinesTR.Color4K();
1383 linesBL = rgbLinesBL.Color4K();
1387 case EUidPixelFormatRGB_565:
1389 linesBR = aLinesBR.Color64K();
1390 linesTL = aLinesTL.Color64K();
1391 linesTR = rgbLinesTR.Color64K();
1392 linesBL = rgbLinesBL.Color64K();
1398 User::Leave(KErrNotSupported);
1402 if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0)
1404 User::Leave(KErrCorrupt);
1406 if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0)
1408 User::Leave(KErrNotReady);
1411 User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
1412 TUint8* surfacePtr = chunk.Base();
1413 TPoint innerXY(info.iSize.iWidth-1,info.iSize.iHeight-1);
1416 if ( info.iSize.iWidth*2>info.iStride)
1418 User::Leave(KErrOverflow);
1420 FanFill<TUint16>(innerXY,info.iStride/2,(TUint16*)surfacePtr,linesTL,linesBR,linesBL,linesTR);
1424 if ( info.iSize.iWidth*4>info.iStride)
1426 User::Leave(KErrOverflow);
1428 FanFill<TUint>(innerXY,info.iStride/4,(TUint*)surfacePtr,linesTL,linesBR,linesBL,linesTR);
1433 iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL);
1436 Fill the given surface with vertical line at the given position
1438 Similar to FillSurfaceL(), but with a vertical line overlayed.
1439 The position along the surface is given as a percentage from the left
1441 @param aSurface The surface to be filled.
1442 @param aColor The color to fill it with.
1443 @param aLine The color of the line.
1444 @param aPosition Position of the vertical line given as a percentage across the surface from the left edge
1446 void CSurfaceUtility::LineFillSurfaceL(TSurfaceId& aSurface, const TRgb& aBackColor, const TRgb& aLineColor, TInt aPosition)
1448 if (aPosition<0 || aPosition>100)
1452 FillSurfaceL(aSurface,aBackColor);
1453 RSurfaceManager::TInfoBuf infoBuf;
1454 RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
1456 User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
1457 TUint32 lineColor = 0;
1458 TBool use16 = EFalse;
1460 switch (info.iPixelFormat)
1462 case EUidPixelFormatXRGB_8888:
1464 lineColor = aLineColor.Color16MU();
1465 #ifdef ALPHA_FIX_24BIT
1466 lineColor |= ((ALPHA_FIX_24BIT)&0xff)<<24;
1470 case EUidPixelFormatARGB_8888:
1472 lineColor = aLineColor.Color16MA();
1475 case EUidPixelFormatARGB_8888_PRE:
1477 lineColor = aLineColor.Color16MAP();
1480 case EUidPixelFormatXRGB_4444:
1481 case EUidPixelFormatARGB_4444:
1483 lineColor = aLineColor.Color4K();
1487 case EUidPixelFormatRGB_565:
1489 lineColor = aLineColor.Color64K();
1495 User::Leave(KErrNotSupported);
1500 User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
1502 TUint8* surfacePtr = chunk.Base();
1505 DdaLine<TUint16>((info.iSize.iWidth*aPosition)/100,0,(info.iSize.iWidth*aPosition)/100,
1506 info.iSize.iHeight-1,info.iStride/2,(TUint16*)surfacePtr,lineColor);
1510 DdaLine<TUint>((info.iSize.iWidth*aPosition)/100,0,(info.iSize.iWidth*aPosition)/100,
1511 info.iSize.iHeight-1,info.iStride/4,(TUint*)surfacePtr,lineColor);
1514 iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL);
1517 * Generates a bitmap equivalent to the surface.
1518 * Can reuse an existing bitmap or create a new bitmap.
1519 * The existing bitmap must be an exact match (eg previously generated by this method)
1521 CFbsBitmap* CSurfaceUtility::EquivalentBitmapL(TSurfaceId& aSurface,CFbsBitmap* aCopyToMayBeNull)
1523 RSurfaceManager::TInfoBuf infoBuf;
1524 RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
1526 User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
1527 TInt bytesPerPixel=0;
1528 TDisplayMode bitmapMode = ENone;
1529 switch (info.iPixelFormat)
1531 case EUidPixelFormatXRGB_8888:
1533 bitmapMode = EColor16MU;
1537 case EUidPixelFormatARGB_8888:
1539 bitmapMode=EColor16MA;
1543 case EUidPixelFormatARGB_8888_PRE:
1545 bitmapMode=EColor16MAP;
1549 case EUidPixelFormatXRGB_4444:
1550 case EUidPixelFormatARGB_4444:
1552 bitmapMode=EColor4K;
1556 case EUidPixelFormatRGB_565:
1558 bitmapMode=EColor64K;
1564 User::Leave(KErrNotSupported);
1568 CFbsBitmap* retVal=NULL;
1569 if (aCopyToMayBeNull)
1571 retVal=aCopyToMayBeNull;
1572 if (retVal->SizeInPixels()!=info.iSize)
1573 User::Leave(KErrCorrupt);
1574 if (retVal->DisplayMode()!=bitmapMode)
1575 User::Leave(KErrCorrupt);
1579 retVal=new CFbsBitmap;
1580 CleanupStack::PushL(retVal);
1581 User::LeaveIfError(retVal->Create(info.iSize,bitmapMode));
1584 CleanupClosePushL(chunk);
1585 User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
1586 TUint8* surfacePtr = chunk.Base();
1587 TUint8* bitmapPtr = (TUint8*)retVal->DataAddress();
1588 TInt copyBytes=info.iSize.iWidth*bytesPerPixel;
1589 for (TInt y=0;y<info.iSize.iHeight;y++)
1591 Mem::Copy(bitmapPtr,surfacePtr,copyBytes);
1592 surfacePtr+=info.iStride;
1593 bitmapPtr+=retVal->DataStride();
1595 CleanupStack::PopAndDestroy(&chunk);
1596 if (!aCopyToMayBeNull)
1597 CleanupStack::Pop(retVal);
1604 As well as destroying the surface, it is removed from the set held for
1605 destruction during tear down.
1607 @param aSurface The surface to be destroyed.
1609 void CSurfaceUtility::DestroySurface(TSurfaceId& aSurface)
1611 TInt index = iSurfaces.Find(aSurface);
1613 if (index != KErrNotFound)
1615 iSurfaces.Remove(index);
1618 TInt err = iManager.CloseSurface(aSurface);
1620 LOG(("Error closing surfaces: 0x%X\n", err));
1625 Submit an update to a surface to the update server.
1627 @param aScreenNumber The screen to be updated where the surface is shown.
1628 @param aSurface The surface which has been updated.
1629 @param aRegion The area of the surface affected, or NULL for all of it.*/
1630 void CSurfaceUtility::SubmitUpdate(TInt /* aScreenNumber */, const TSurfaceId& aSurface, const TRegion* aRegion,TInt aBufferNumber)
1632 TInt err =iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, aBufferNumber, aRegion);
1634 LOG(("Error submitting update: 0x%X\n", err));
1638 Map and submit an update to a surface to the update server.
1640 @param aChunk The chunk of memory to be mapped
1641 @param aScreenNumber The screen to be updated where the surface is shown.
1642 @param aSurface The surface which has been updated.
1643 @param aRegion The area of the surface affected, or NULL for all of it.*/
1644 void CSurfaceUtility::MapAndSubmitUpdateL(RChunk& aChunk,
1645 TInt /* aScreenNumber */,
1646 const TSurfaceId& aSurface,
1647 const TRegion* aRegion)
1649 User::LeaveIfError(iManager.MapSurface(aSurface, aChunk));
1651 TInt err =iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, aRegion);
1653 LOG(("Error submitting update: 0x%X\n", err));
1656 void CSurfaceUtility::MapSurfaceL(const TSurfaceId& aSurface, RChunk& aChunk)
1658 User::LeaveIfError(iManager.MapSurface(aSurface, aChunk));
1661 void CSurfaceUtility::CopyBitmapToSurfaceL(TSurfaceId& aSurface, const CFbsBitmap& aBitmap)
1663 TSize size = SurfaceSize(aSurface);
1665 TDisplayMode bmpFormat = aBitmap.DisplayMode();
1666 TInt stride = size.iWidth * 4; // Default to four bytes per pixel
1669 User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
1670 CleanupClosePushL(chunk);
1672 // Copy the data from the bitmap into the surface.
1674 for (start.iY = 0; start.iY < size.iHeight; start.iY++)
1676 // Set up a descriptor for the current line in the surface and get pixels.
1677 TPtr8 ptr(chunk.Base() + start.iY * stride, stride);
1678 aBitmap.GetScanLine(ptr, start, size.iWidth, bmpFormat);
1681 TInt err =iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL);
1684 LOG(("Error submitting update: 0x%X\n", err));
1687 CleanupStack::PopAndDestroy(/* chunk */);
1691 CActiveListener factory function
1692 @return A CActiveListener object
1694 CActiveListener* CActiveListener::NewLC()
1696 CActiveListener* self = new(ELeave) CActiveListener();
1697 CleanupStack::PushL(self);
1702 Constructor for class CActiveListener
1704 CActiveListener::CActiveListener() : CActive(EPriorityLow)
1706 CActiveScheduler::Add(this);
1712 CActiveListener::~CActiveListener()
1717 Handles the request.
1718 This function is derived from CActive
1720 void CActiveListener::RunL()
1722 CActiveScheduler::Stop();
1726 Cancels the outstanding request.
1727 This function is derived from CActive
1729 void CActiveListener::DoCancel()
1734 Initializes the CActiveListener
1736 void CActiveListener::Initialize()
1738 iStatus = KRequestPending;
1743 Check that the request has been cancelled.
1744 @return A boolean indicating whether the request has been cancelled or not
1746 TBool CActiveListener::IsRequestCancelled()
1748 return (iStatus == KErrCancel);
1752 A helper function that returns the bytes per pixel for a given pixel format uid
1754 @param aPixelFormat Pixel format UID to convert
1755 @return The bytes per pixel
1757 TInt CSurfaceUtility::BytesPerPixelL(TUidPixelFormat aPixelFormat)
1759 TInt bytesPerPixel = 0;
1760 switch (aPixelFormat)
1762 case EUidPixelFormatXRGB_8888:
1763 case EUidPixelFormatARGB_8888:
1764 case EUidPixelFormatARGB_8888_PRE:
1769 case EUidPixelFormatXRGB_4444:
1770 case EUidPixelFormatARGB_4444:
1771 case EUidPixelFormatRGB_565:
1778 User::Leave(KErrNotSupported);
1782 return bytesPerPixel;