37 // Creates CAlfCrpPluginClient instance, returns error code. |
40 // Creates CAlfCrpPluginClient instance, returns error code. |
38 static TInt CreateAlfCrpClient(CAlfCrpPluginClient*& aClient); |
41 static TInt CreateAlfCrpClient(CAlfCrpPluginClient*& aClient); |
39 // Creates CAlfCrpPluginClient instance. |
42 // Creates CAlfCrpPluginClient instance. |
40 static CAlfCrpPluginClient* CreateAlfCrpClientL(); |
43 static CAlfCrpPluginClient* CreateAlfCrpClientL(); |
41 |
44 |
|
45 /** |
|
46 * Misc utility methods for CAlfDrawer. |
|
47 */ |
|
48 NONSHARABLE_CLASS(AlfDrawerUtils) |
|
49 { |
|
50 public: |
|
51 |
|
52 enum TRotation |
|
53 { |
|
54 ERotationNone, |
|
55 ERotation90, |
|
56 ERotation180, |
|
57 ERotation270 |
|
58 }; |
|
59 |
|
60 /** |
|
61 * Inverse rotate. |
|
62 */ |
|
63 static void RotateBack(TInt aVirtualRotation, TRect& aRect, TSize aScreenSize) |
|
64 { |
|
65 if( aVirtualRotation == ERotation90 || aVirtualRotation == ERotation270 ) |
|
66 { |
|
67 RotateRect( aVirtualRotation, aRect, aScreenSize, ETrue ); |
|
68 } |
|
69 else if( aVirtualRotation == ERotation180 ) |
|
70 { |
|
71 RotateRect( aVirtualRotation, aRect, aScreenSize, EFalse ); |
|
72 } |
|
73 } |
|
74 |
|
75 /** |
|
76 * Rotate rect |
|
77 */ |
|
78 static void RotateRect(TInt aDirection, TRect& aRect, TSize aScreenSize, TBool aMirror) |
|
79 { |
|
80 if (aMirror) aDirection = (aDirection+2)%4; // magic |
|
81 for (;aDirection > 0; aDirection--) |
|
82 { |
|
83 TSize rotatedSize(aRect.Size().iHeight, aRect.Size().iWidth); |
|
84 aRect = TRect(TPoint(aRect.iTl.iY, aScreenSize.iWidth - aRect.iTl.iX - rotatedSize.iHeight ), rotatedSize); |
|
85 aScreenSize = TSize(aScreenSize.iHeight, aScreenSize.iWidth); |
|
86 } |
|
87 } |
|
88 |
|
89 /** |
|
90 * Copies screen to bitmap using 'read pixels' operation. |
|
91 */ |
|
92 static void DoCopyScreenToBitmapL( |
|
93 CWsScreenDevice& aDevice, |
|
94 CFbsBitmap* aBitmap, |
|
95 const TRect& aRect ); |
|
96 |
|
97 }; |
42 |
98 |
43 // --------------------------------------------------------------------------- |
99 // --------------------------------------------------------------------------- |
44 // NewL |
100 // NewL |
45 // --------------------------------------------------------------------------- |
101 // --------------------------------------------------------------------------- |
46 // |
102 // |
90 |
146 |
91 return err; |
147 return err; |
92 } |
148 } |
93 |
149 |
94 // --------------------------------------------------------------------------- |
150 // --------------------------------------------------------------------------- |
|
151 // FallbackCopyScreenToBitmap |
|
152 // --------------------------------------------------------------------------- |
|
153 // |
|
154 EXPORT_C TInt CAlfDrawer::FallbackCopyScreenToBitmap( |
|
155 CWsScreenDevice& aDevice, |
|
156 CFbsBitmap* aBitmap, |
|
157 const TRect& aRect) |
|
158 { |
|
159 TRAPD(err, AlfDrawerUtils::DoCopyScreenToBitmapL(aDevice, aBitmap, aRect)); |
|
160 return err; |
|
161 } |
|
162 |
|
163 // --------------------------------------------------------------------------- |
|
164 // DoCopyScreenToBitmapL |
|
165 // --------------------------------------------------------------------------- |
|
166 // |
|
167 void AlfDrawerUtils::DoCopyScreenToBitmapL( |
|
168 CWsScreenDevice& aDevice, |
|
169 CFbsBitmap* aBitmap, |
|
170 const TRect& aRect ) |
|
171 { |
|
172 if (aDevice.GetScreenNumber() != 0) // only screen 0 supported for now |
|
173 { |
|
174 User::Leave(KErrNotSupported); |
|
175 } |
|
176 |
|
177 if ( !aBitmap || |
|
178 !aBitmap->Handle() || |
|
179 aBitmap->IsCompressedInRAM() || |
|
180 aBitmap->ExtendedBitmapType() != KNullUid ) |
|
181 { |
|
182 User::Leave(KErrArgument); |
|
183 } |
|
184 |
|
185 __ALFLOGSTRING("DoCopyScreenToBitmapL begin"); |
|
186 |
|
187 RAlfDirectClient client; |
|
188 CleanupClosePushL(client); |
|
189 |
|
190 // Get size & virtual rotation from ALF side. |
|
191 // GetSizeAndRotation will also create session to server. |
|
192 |
|
193 TInt rotation = 0; |
|
194 TSize size; |
|
195 User::LeaveIfError(client.GetSizeAndRotation(size, rotation)); |
|
196 |
|
197 // Calculate device size in pixels (same as aDevice.SizeInPixels()) |
|
198 TSize deviceSize = size; |
|
199 if (rotation == AlfDrawerUtils::ERotation90 || |
|
200 rotation == AlfDrawerUtils::ERotation270 ) |
|
201 { |
|
202 deviceSize.iWidth = size.iHeight; |
|
203 deviceSize.iHeight = size.iWidth; |
|
204 } |
|
205 |
|
206 // Clip aRect to screen boundaries |
|
207 TRect actualRect(deviceSize); |
|
208 actualRect.Intersection(aRect); |
|
209 |
|
210 __ALFLOGSTRING2("DoCopyScreenToBitmapL - requested rect origin %d x %d", actualRect.iTl.iX, actualRect.iTl.iY ) ; |
|
211 __ALFLOGSTRING2("DoCopyScreenToBitmapL - requested rect %d x %d", actualRect.Size().iWidth, actualRect.Size().iHeight ) ; |
|
212 __ALFLOGSTRING2("DoCopyScreenToBitmapL - bitmap rect %d x %d", aBitmap->SizeInPixels().iWidth, aBitmap->SizeInPixels().iHeight ); |
|
213 __ALFLOGSTRING1("DoCopyScreenToBitmapL - bitmap mode %d", aBitmap->DisplayMode() ); |
|
214 |
|
215 if ( TRect( aBitmap->SizeInPixels() ).IsEmpty() || |
|
216 actualRect.IsEmpty() ) |
|
217 { |
|
218 __ALFLOGSTRING("DoCopyScreenToBitmapL - empty rect or zero bitmap size"); |
|
219 CleanupStack::PopAndDestroy(); // CleanupClosePushL |
|
220 return; |
|
221 } |
|
222 |
|
223 // Select display mode. |
|
224 |
|
225 TDisplayMode surfaceDisplayMode = EColor64K; |
|
226 TDisplayMode bitmapDisplayMode = aBitmap->DisplayMode(); |
|
227 if ( bitmapDisplayMode == EColor16MU || |
|
228 bitmapDisplayMode == EColor16MA || |
|
229 bitmapDisplayMode == EColor16MAP ) |
|
230 { |
|
231 surfaceDisplayMode = bitmapDisplayMode; |
|
232 } |
|
233 |
|
234 __ALFLOGSTRING3("DoCopyScreenToBitmapL - surface size %d x %d, mode %d", |
|
235 size.iWidth, size.iHeight, surfaceDisplayMode ) ; |
|
236 |
|
237 // Read pixels to temporary bitmap |
|
238 CFbsBitmap* surfaceBitmap = new (ELeave) CFbsBitmap; |
|
239 CleanupStack::PushL( surfaceBitmap ); |
|
240 User::LeaveIfError( surfaceBitmap->Create( size, surfaceDisplayMode ) ); |
|
241 |
|
242 TInt err = client.ReadPixels( surfaceBitmap->Handle() ); |
|
243 __ALFLOGSTRING1("DoCopyScreenToBitmapL - ReadPixels returned %d", err); |
|
244 User::LeaveIfError( err ); |
|
245 |
|
246 // Copy data |
|
247 TInt surfaceStride = CFbsBitmap::ScanLineLength(size.iWidth, surfaceDisplayMode); |
|
248 __ALFLOGSTRING2("DoCopyScreenToBitmapL - DisplayMode %d, Stride %d", surfaceDisplayMode, surfaceStride); |
|
249 |
|
250 TDisplayMode displayMode = surfaceDisplayMode; |
|
251 |
|
252 TInt8 bytesPerPixel = 2; |
|
253 switch( displayMode ) |
|
254 { |
|
255 case EColor64K: |
|
256 { |
|
257 bytesPerPixel = 2; |
|
258 break; |
|
259 } |
|
260 case EColor16MU: |
|
261 case EColor16MA: |
|
262 case EColor16MAP: |
|
263 { |
|
264 bytesPerPixel = 4; |
|
265 break; |
|
266 } |
|
267 |
|
268 default: |
|
269 { |
|
270 __ALFLOGSTRING1("DoCopyScreenToBitmapL - display mode not supported %d", displayMode); |
|
271 User::Leave( KErrNotSupported ); |
|
272 } |
|
273 } |
|
274 |
|
275 // actualRect (/aRect) must be converted to correct coordinate system. |
|
276 TRect surfaceRect(actualRect); |
|
277 AlfDrawerUtils::RotateBack(rotation, surfaceRect, deviceSize); |
|
278 surfaceRect.Intersection(TRect(size)); |
|
279 |
|
280 __ALFLOGSTRING2("DoCopyScreenToBitmapL - surface rect tl %d x %d", surfaceRect.iTl.iX, surfaceRect.iTl.iY ) ; |
|
281 __ALFLOGSTRING2("DoCopyScreenToBitmapL - surface rect size %d x %d", surfaceRect.Size().iWidth, surfaceRect.Size().iHeight ) ; |
|
282 |
|
283 CFbsBitmap* bitmap = NULL; |
|
284 TBool needTempBitmap = ETrue; |
|
285 |
|
286 if( aBitmap->DisplayMode() == displayMode && actualRect == aRect && aBitmap->SizeInPixels() == aRect.Size() ) |
|
287 { |
|
288 // Copy data direcly to given bitmap |
|
289 bitmap = aBitmap; |
|
290 needTempBitmap = EFalse; |
|
291 } |
|
292 else |
|
293 { |
|
294 // Create temporary bitmap which maches the sufrace's pixel format and source rect size |
|
295 bitmap = new (ELeave) CFbsBitmap; |
|
296 CleanupStack::PushL( bitmap ); |
|
297 TInt err = bitmap->Create( actualRect.Size(), displayMode ); |
|
298 __ALFLOGSTRING1("DoCopyScreenToBitmapL - Create returned %d", err ); |
|
299 User::LeaveIfError( err ); |
|
300 __ALFLOGSTRING("DoCopyScreenToBitmapL - display mode or size don't mach -> using temp bitmap" ); |
|
301 } |
|
302 |
|
303 surfaceBitmap->BeginDataAccess(); |
|
304 bitmap->BeginDataAccess(); |
|
305 |
|
306 TUint8* surfacePtr = (TUint8*)surfaceBitmap->DataAddress() + surfaceStride * surfaceRect.iTl.iY; |
|
307 |
|
308 TUint8* bitmapPtr = (TUint8*)bitmap->DataAddress(); |
|
309 TInt rowBegin = surfaceRect.iTl.iX * bytesPerPixel; |
|
310 TInt captureBitmapWidth = surfaceRect.Width() * bytesPerPixel; |
|
311 |
|
312 const TSize bitmapSize = bitmap->SizeInPixels(); |
|
313 |
|
314 // Initialize with direct copy case parameters |
|
315 TInt bitmapPtrColumnDelta = bytesPerPixel; |
|
316 TInt bitmapPtrRowDelta = bitmap->DataStride(); |
|
317 |
|
318 const TSize surfaceRectSize(surfaceRect.Size()); |
|
319 if ( rotation == AlfDrawerUtils::ERotationNone ) |
|
320 { |
|
321 __ALFLOGSTRING("DoCopyScreenToBitmapL - direct copy") ; |
|
322 |
|
323 // Direct copy case |
|
324 for ( TInt row = surfaceRectSize.iHeight - 1 ; row >= 0 ; --row ) |
|
325 { |
|
326 // Copy only the desired part of the bitmap |
|
327 memcpy( bitmapPtr, |
|
328 surfacePtr + rowBegin, |
|
329 captureBitmapWidth ); |
|
330 surfacePtr += surfaceStride; |
|
331 bitmapPtr += bitmap->DataStride(); |
|
332 } |
|
333 } |
|
334 else |
|
335 { |
|
336 // Handle rotation cases |
|
337 // |
|
338 // 0 degree case |
|
339 // A B C |
|
340 // 1 2 3 |
|
341 // 90 degrees anti-clockwise |
|
342 // C 3 |
|
343 // B 2 |
|
344 // A 1 |
|
345 // 180 degrees anti-clockwise |
|
346 // 3 2 1 |
|
347 // C B A |
|
348 // 270 degrees anti-clockwise |
|
349 // 1 A |
|
350 // 2 B |
|
351 // 3 C |
|
352 // |
|
353 switch (rotation) |
|
354 { |
|
355 case AlfDrawerUtils::ERotation90: |
|
356 bitmapPtrColumnDelta = -bitmap->DataStride(); |
|
357 bitmapPtrRowDelta = bytesPerPixel; |
|
358 bitmapPtr += ( bitmapSize.iHeight - 1 ) * bitmap->DataStride(); |
|
359 break; |
|
360 case AlfDrawerUtils::ERotation180: |
|
361 bitmapPtrColumnDelta = -bytesPerPixel; |
|
362 bitmapPtrRowDelta = -bitmap->DataStride(); |
|
363 bitmapPtr += ( bitmapSize.iHeight - 1 ) * bitmap->DataStride() + ( bitmapSize.iWidth - 1 ) * bytesPerPixel; |
|
364 break; |
|
365 case AlfDrawerUtils::ERotation270: |
|
366 bitmapPtrColumnDelta = bitmap->DataStride(); |
|
367 bitmapPtrRowDelta = -bytesPerPixel; |
|
368 bitmapPtr += ( bitmapSize.iWidth - 1 ) * bytesPerPixel; |
|
369 break; |
|
370 default: |
|
371 break; |
|
372 } |
|
373 |
|
374 // We go through surface row by row, column by column and |
|
375 // copy pixel data to appropriate place to bitmap |
|
376 if ( bytesPerPixel == 4 ) |
|
377 { |
|
378 __ALFLOGSTRING("DoCopyScreenToBitmapL - four bytes per pixel, rotated copy") ; |
|
379 |
|
380 for ( TInt row = surfaceRectSize.iHeight - 1 ; row >= 0 ; --row ) |
|
381 { |
|
382 TUint8* rowBitmapPtr = bitmapPtr; |
|
383 TUint8* rowSurfacePtr = surfacePtr + rowBegin; |
|
384 for ( TInt column = surfaceRectSize.iWidth - 1 ; column >= 0 ; --column ) |
|
385 { |
|
386 *((TUint32*)rowBitmapPtr) = *((TUint32*)rowSurfacePtr); |
|
387 |
|
388 rowBitmapPtr += bitmapPtrColumnDelta; |
|
389 rowSurfacePtr += bytesPerPixel; |
|
390 } |
|
391 |
|
392 surfacePtr += surfaceStride; |
|
393 bitmapPtr += bitmapPtrRowDelta; |
|
394 } |
|
395 } |
|
396 else |
|
397 { |
|
398 // Now bytesPerPixel == 2 |
|
399 __ALFLOGSTRING("DoCopyScreenToBitmapL - two bytes per pixel, rotated copy") ; |
|
400 for ( TInt row = surfaceRectSize.iHeight - 1 ; row >= 0 ; --row ) |
|
401 { |
|
402 TUint8* rowBitmapPtr = bitmapPtr; |
|
403 TUint8* rowSurfacePtr = surfacePtr + rowBegin; |
|
404 for ( TInt column = surfaceRectSize.iWidth - 1 ; column >= 0 ; --column ) |
|
405 { |
|
406 *((TUint16*)rowBitmapPtr) = *((TUint16*)rowSurfacePtr); |
|
407 |
|
408 rowBitmapPtr += bitmapPtrColumnDelta; |
|
409 rowSurfacePtr += bytesPerPixel; |
|
410 } |
|
411 |
|
412 surfacePtr += surfaceStride; |
|
413 bitmapPtr += bitmapPtrRowDelta; |
|
414 } |
|
415 } |
|
416 } |
|
417 __ALFLOGSTRING("DoCopyScreenToBitmapL - copy finished" ); |
|
418 surfaceBitmap->EndDataAccess(ETrue); |
|
419 bitmap->EndDataAccess(); |
|
420 |
|
421 if( !needTempBitmap ) |
|
422 { |
|
423 bitmap = NULL; |
|
424 } |
|
425 else // bitblit the temporary bitmap to given bitmap |
|
426 { |
|
427 CFbsBitmapDevice* tempBitmapDevice = CFbsBitmapDevice::NewL( aBitmap ); |
|
428 CleanupStack::PushL( tempBitmapDevice ); |
|
429 CFbsBitGc* tempBitmapGc = NULL; |
|
430 User::LeaveIfError( tempBitmapDevice->CreateContext( tempBitmapGc ) ); |
|
431 CleanupStack::PushL( tempBitmapGc ); |
|
432 |
|
433 tempBitmapGc->SetDrawMode( CGraphicsContext::EDrawModeWriteAlpha ); |
|
434 tempBitmapGc->BitBlt( TPoint(), bitmap ); |
|
435 |
|
436 CleanupStack::PopAndDestroy( tempBitmapGc ); |
|
437 CleanupStack::PopAndDestroy( tempBitmapDevice ); |
|
438 CleanupStack::PopAndDestroy( bitmap ); |
|
439 } |
|
440 |
|
441 CleanupStack::PopAndDestroy( surfaceBitmap ); |
|
442 |
|
443 CleanupStack::PopAndDestroy(); // CleanupClosePushL |
|
444 |
|
445 __ALFLOGSTRING("DoCopyScreenToBitmapL - Done"); |
|
446 } |
|
447 |
|
448 // --------------------------------------------------------------------------- |
95 // Constructor |
449 // Constructor |
96 // --------------------------------------------------------------------------- |
450 // --------------------------------------------------------------------------- |
97 // |
451 // |
98 CAlfDrawer::CAlfDrawer() |
452 CAlfDrawer::CAlfDrawer() |
99 { |
453 { |