|
1 // Copyright (c) 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". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include "tsurfacehelper.h" |
|
17 #include <w32std.h> |
|
18 |
|
19 CSurfaceHelper* CSurfaceHelper::NewL() |
|
20 { |
|
21 CSurfaceHelper* helper = new(ELeave)CSurfaceHelper; |
|
22 CleanupStack::PushL(helper); |
|
23 helper->ConstructL(); |
|
24 CleanupStack::Pop(helper); |
|
25 return helper; |
|
26 } |
|
27 |
|
28 CSurfaceHelper::~CSurfaceHelper() |
|
29 { |
|
30 DestroySurfaces(); |
|
31 iSurfaces.Close(); |
|
32 iManager.Close(); |
|
33 } |
|
34 |
|
35 /** |
|
36 * Load logical device and open a surface manager |
|
37 */ |
|
38 void CSurfaceHelper::ConstructL() |
|
39 { |
|
40 TInt res = iManager.Open(); |
|
41 if (res != KErrNone) |
|
42 { |
|
43 User::Leave(res); |
|
44 } |
|
45 } |
|
46 |
|
47 /** |
|
48 * Create the surface with the given parameters. |
|
49 * The surface will be owned by the instance of this class |
|
50 */ |
|
51 TSurfaceId CSurfaceHelper::CreateSurfaceL(const TSize& aSize, TUidPixelFormat aPixelFormat, TInt aStride, TInt aBuffers) |
|
52 { |
|
53 RSurfaceManager::TSurfaceCreationAttributesBuf bf; |
|
54 RSurfaceManager::TSurfaceCreationAttributes& b = bf(); |
|
55 |
|
56 b.iSize.iWidth = aSize.iWidth; |
|
57 b.iSize.iHeight = aSize.iHeight; |
|
58 b.iBuffers = aBuffers; // number of buffers in the surface |
|
59 b.iPixelFormat = aPixelFormat; |
|
60 b.iStride = aStride; // Number of bytes between start of one line and start of next |
|
61 b.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data |
|
62 b.iAlignment = 4; // alignment, 1,2,4,8 byte aligned |
|
63 b.iContiguous = EFalse; |
|
64 b.iMappable = ETrue; |
|
65 |
|
66 TSurfaceId surface = TSurfaceId::CreateNullId(); |
|
67 |
|
68 User::LeaveIfError(iManager.CreateSurface(bf, surface)); |
|
69 iSurfaces.AppendL(surface); |
|
70 return surface; |
|
71 } |
|
72 |
|
73 /** |
|
74 * Destroy all surfaces wich have been created by the instance of this class |
|
75 */ |
|
76 void CSurfaceHelper::DestroySurfaces() |
|
77 { |
|
78 TInt numSurfaces = iSurfaces.Count(); |
|
79 for (TInt index = 0; index < numSurfaces; index++) |
|
80 { |
|
81 TSurfaceId surfaceId = iSurfaces[index]; |
|
82 TInt err = iManager.CloseSurface(surfaceId); |
|
83 __ASSERT_DEBUG(err ==KErrNone, User::Panic(_L("CSurfaceHelper::DestroySurfaces"), err)); |
|
84 } |
|
85 iSurfaces.Reset(); |
|
86 } |
|
87 |
|
88 /** |
|
89 Fill a rectangle on the given surface. |
|
90 |
|
91 @param aSurface The surface to be filled. |
|
92 @param aStartPos Where to place the rectangle. |
|
93 @param aSize Size of the rectangle. |
|
94 @param aColor The colour to fill it with. |
|
95 */ |
|
96 void CSurfaceHelper::FillRectangleL(const TSurfaceId& aSurface, const TPoint& aStartPos, const TSize& aSize, const TRgb& aColor) |
|
97 { |
|
98 RSurfaceManager::TInfoBuf infoBuf; |
|
99 RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); |
|
100 User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf)); |
|
101 TUint32 color = 0; |
|
102 |
|
103 if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0) |
|
104 { |
|
105 User::Leave(KErrCorrupt); |
|
106 } |
|
107 if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0) |
|
108 { |
|
109 User::Leave(KErrNotReady); |
|
110 } |
|
111 |
|
112 switch (info.iPixelFormat) |
|
113 { |
|
114 case EUidPixelFormatXRGB_8888: |
|
115 { |
|
116 color = aColor.Color16MU(); |
|
117 #ifdef ALPHA_FIX_24BIT |
|
118 color |= ((ALPHA_FIX_24BIT)&0xff)<<24; |
|
119 #endif |
|
120 break; |
|
121 } |
|
122 case EUidPixelFormatARGB_8888: |
|
123 { |
|
124 color = aColor.Color16MA(); |
|
125 break; |
|
126 } |
|
127 case EUidPixelFormatARGB_8888_PRE: |
|
128 { |
|
129 color = aColor.Color16MAP(); |
|
130 break; |
|
131 } |
|
132 case EUidPixelFormatRGB_565: |
|
133 { |
|
134 color = aColor.Color64K(); |
|
135 break; |
|
136 } |
|
137 default: |
|
138 { |
|
139 User::Leave(KErrNotSupported); |
|
140 break; |
|
141 } |
|
142 } |
|
143 |
|
144 RChunk chunk; |
|
145 User::LeaveIfError(iManager.MapSurface(aSurface, chunk)); |
|
146 CleanupClosePushL(chunk); |
|
147 TUint8* surfacePtr = chunk.Base(); |
|
148 |
|
149 // Check for out of bounds |
|
150 TBool validRect = ETrue; |
|
151 TInt surfaceWidth = info.iSize.iWidth; |
|
152 TInt surfaceHeight = info.iSize.iHeight; |
|
153 |
|
154 // Width and Height |
|
155 if ((aStartPos.iX + aSize.iWidth) > surfaceWidth) |
|
156 { |
|
157 validRect = EFalse; |
|
158 } |
|
159 |
|
160 if ((aStartPos.iY + aSize.iHeight) > surfaceHeight) |
|
161 { |
|
162 validRect = EFalse; |
|
163 } |
|
164 |
|
165 // Starting position |
|
166 if ((aStartPos.iX < 0) || (aStartPos.iY < 0)) |
|
167 { |
|
168 validRect = EFalse; |
|
169 } |
|
170 |
|
171 if (!validRect) |
|
172 { |
|
173 User::Leave(KErrOverflow); |
|
174 } |
|
175 |
|
176 if (info.iPixelFormat == EUidPixelFormatRGB_565) |
|
177 {//2 bytes per pixel |
|
178 if ( info.iSize.iWidth*2>info.iStride) |
|
179 { |
|
180 User::Leave(KErrOverflow); |
|
181 } |
|
182 |
|
183 TInt offset; |
|
184 User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offset)); |
|
185 TUint16* ptr = reinterpret_cast<TUint16*>(surfacePtr + offset); |
|
186 |
|
187 // Fill the rectangle |
|
188 TInt yPos = aStartPos.iY; |
|
189 TInt xPos = aStartPos.iX; |
|
190 for (TInt yy = 0; yy < aSize.iHeight; ++yy) |
|
191 { |
|
192 ptr = reinterpret_cast<TUint16*>(surfacePtr + (yPos*info.iStride)); |
|
193 for (TInt xx = 0; xx < aSize.iWidth; ++xx) |
|
194 { |
|
195 ptr[xPos] = color; |
|
196 xPos++; |
|
197 } |
|
198 xPos = aStartPos.iX; |
|
199 yPos++; |
|
200 } |
|
201 } |
|
202 else |
|
203 { |
|
204 if ( info.iSize.iWidth*4>info.iStride) |
|
205 { |
|
206 User::Leave(KErrOverflow); |
|
207 } |
|
208 |
|
209 TInt offset; |
|
210 User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offset)); |
|
211 TUint32* ptr = reinterpret_cast<TUint32*>(surfacePtr + offset); |
|
212 |
|
213 // Fill the rectangle |
|
214 TInt yPos = aStartPos.iY; |
|
215 TInt xPos = aStartPos.iX; |
|
216 for (TInt yy = 0; yy < aSize.iHeight; ++yy) |
|
217 { |
|
218 ptr = reinterpret_cast<TUint32*>(surfacePtr+(yPos*info.iStride)); |
|
219 for (TInt xx = 0; xx < aSize.iWidth; ++xx) |
|
220 { |
|
221 ptr[xPos] = color; |
|
222 xPos++; |
|
223 } |
|
224 xPos = aStartPos.iX; |
|
225 yPos++; |
|
226 } |
|
227 } |
|
228 CleanupStack::PopAndDestroy(&chunk); |
|
229 } |