--- a/imagehandlinglib/Src/CIHLImageViewer.cpp Fri Sep 03 10:29:37 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1369 +0,0 @@
-/*
-* Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description: Implementation of Image Viewer class.
-*
-*/
-
-
-// INCLUDE FILES
-#include "CIHLImageViewer.h"
-
-#include "CIHLBitmap.h"
-#include "CIHLBitmapProcessor.h"
-#include "IHLImplementationIds.h"
-#include "IHLDebugPrint.h" // Debug print
-#include <IHLInterfaceIds.h>
-#include <MIHLViewerObserver.h>
-#include <MIHLFileImage.h>
-#include <fbs.h>
-#include <e32math.h>
-
-// Private namespace for constants and functions
-namespace
- {
- // Panic function
- _LIT( KIHLPanicString, "IHLImageViewer" );
- void Panic( TInt aPanicCode ) { User::Panic( KIHLPanicString, aPanicCode ); }
- }
-
-// ============================ MEMBER FUNCTIONS ===============================
-// -----------------------------------------------------------------------------
-//
-// C++ constructor can NOT contain any code, that might leave.
-// -----------------------------------------------------------------------------
-CIHLImageViewer::CIHLImageViewer( const TSize& aViewerSize,
- MIHLFileImage& aSource,
- MIHLBitmap& aDestination,
- MIHLViewerObserver& aObserver,
- const TUint32 aOptions )
-:CTimer( EPriorityNormal ), iObserver( aObserver ),
-iSource( aSource ), iDestination( aDestination ),
-iOptions( aOptions ), iViewerSize( aViewerSize ), iSrcBitmapScaleFactor(1)
- {
- CActiveScheduler::Add( this );
- iAnimDelay = 0;
- iAnimLastFrameDrawTime = 0;
- iAnimDrawStartFastTime = 0;
- }
-
-// -----------------------------------------------------------------------------
-//
-// Two-phased constructor.
-// -----------------------------------------------------------------------------
-CIHLImageViewer* CIHLImageViewer::NewL( const TSize& aViewerSize,
- MIHLFileImage& aSource,
- MIHLBitmap& aDestination,
- MIHLViewerObserver& aObserver,
- const TUint32 aOptions )
- {
- CIHLImageViewer* self = new( ELeave ) CIHLImageViewer(
- aViewerSize, aSource, aDestination, aObserver, aOptions );
- CleanupStack::PushL( self );
- self->ConstructL();
- CleanupStack::Pop(); // self
- return self;
- }
-
-// -----------------------------------------------------------------------------
-//
-// Symbian constructor can leave.
-// -----------------------------------------------------------------------------
-void CIHLImageViewer::ConstructL()
- {
- CTimer::ConstructL();
-
- HAL::Get(HALData::EFastCounterFrequency, iTickPeriod);
-
- iCacheSource = CIHLBitmap::NewL();
- iCacheDestination = CIHLBitmap::NewL();
- iProcessor = CIHLBitmapProcessor::NewL( iOptions );
-
- // Initialize settings and start load (default is zoom to fit)
- iSourceSize = iSource.Size();
- CalculateZoomToFitRatio();
- User::LeaveIfError( SetZoomRatio( iZoomToFitRatio ) );
- }
-
-// -----------------------------------------------------------------------------
-// Destructor
-// -----------------------------------------------------------------------------
-CIHLImageViewer::~CIHLImageViewer()
- {
- Cancel();
- delete iProcessor;
- delete iCacheDestination;
- delete iCacheSource;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::Id
-// -----------------------------------------------------------------------------
-TIHLInterfaceType CIHLImageViewer::Type() const
- {
- return TIHLInterfaceType( KIHLInterfaceIdImageViewer, KIHLImplementationIdImageViewer );
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::IsAnimation
-// -----------------------------------------------------------------------------
-TBool CIHLImageViewer::IsAnimation() const
- {
- return iSource.IsAnimation();
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::SheduleNextFrame
-// -----------------------------------------------------------------------------
-void CIHLImageViewer::SheduleNextFrame(TTimeIntervalMicroSeconds32 aDelay)
- {
- TInt delay=aDelay.Int();
-
- if (delay == 0) // 0 second deleay set in GIF file
- {
- iAnimDelay = TTimeIntervalMicroSeconds32(100000-iAnimLastFrameDrawTime);
- }
- else
- {
- iAnimDelay = delay - iAnimLastFrameDrawTime;
- }
-
- if (iAnimDelay.Int() <=0) //last frame drawn longer than animation frame interval.
- {
- iAnimDelay = KMinimumInterval;
- }
- iAnimInitFastTime=User::FastCounter(); //store the start time
- HighRes(iAnimDelay);
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::Play
-// -----------------------------------------------------------------------------
-void CIHLImageViewer::Play()
- {
- if( iSource.IsAnimation() )
- {
- iIsPlaying = ETrue;
- if( iViewerState == EInactive)
- {
- iViewerState = EAnimation;
- SheduleNextFrame( iSource.AnimationFrameDelay( iAnimationIndex ) );
- }
- }
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::Stop
-// -----------------------------------------------------------------------------
-void CIHLImageViewer::Stop()
- {
- iIsPlaying = EFalse;
- if( iViewerState == EAnimation )
- {
- Cancel();
- }
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::IsPlaying
-// -----------------------------------------------------------------------------
-TBool CIHLImageViewer::IsPlaying() const
- {
- return iIsPlaying;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::AnimationFrameCount
-// -----------------------------------------------------------------------------
-TInt CIHLImageViewer::AnimationFrameCount() const
- {
- return iSource.AnimationFrameCount();
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::AnimationFrame
-// -----------------------------------------------------------------------------
-TInt CIHLImageViewer::AnimationFrame() const
- {
- return iAnimationIndex;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::SetAnimationFrame
-// -----------------------------------------------------------------------------
-TInt CIHLImageViewer::SetAnimationFrame( TInt aFrameIndex )
- {
- // Public API, boundary check -> panic also on hardware
- __ASSERT_ALWAYS( aFrameIndex >= 0 &&
- aFrameIndex < iSource.AnimationFrameCount(), Panic( KErrArgument ) );
-
- // Save new index and clear old source cache to force load new frame
- iAnimationIndex = aFrameIndex;
- iCacheSource->Reset();
-
- // Start load
- return ApplySettings();
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::SetViewerSize
-// -----------------------------------------------------------------------------
-TInt CIHLImageViewer::SetViewerSize( const TSize& aViewerSize, int aSrcBitmapScaleFactor )
- {
- // Public API, negative value check -> panic also on hardware
- __ASSERT_ALWAYS( aViewerSize.iWidth >= 0 &&
- aViewerSize.iHeight >= 0, Panic( KErrArgument ) );
-
- iSrcBitmapScaleFactor = aSrcBitmapScaleFactor;
-
- // Save new viewer size
- iViewerSize = aViewerSize;
-
- // Recalculate source rect and destination size
- CalculateSourceRectAndDestinationSize();
-
- // Recalculate zoom to fit ratio
- CalculateZoomToFitRatio();
-
- // Start load
- return ApplySettings();
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::ViewerSize
-// -----------------------------------------------------------------------------
-TSize CIHLImageViewer::ViewerSize() const
- {
- return iViewerSize;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::MoveSourceRect
-// -----------------------------------------------------------------------------
-TInt CIHLImageViewer::MoveSourceRect( TInt aDx, TInt aDy )
- {
- TInt dx( aDx );
- TInt dy( aDy );
- switch( iRotationAngle )
- {
- case ERotationAngle0:
- {
- break;
- }
- case ERotationAngle90:
- {
- dx = aDy;
- dy = -aDx;
- break;
- }
- case ERotationAngle180:
- {
- dx = -aDx;
- dy = -aDy;
- break;
- }
- case ERotationAngle270:
- {
- dx = -aDy;
- dy = aDx;
- break;
- }
- default:
- {
- // Internal state error, debug panic only
- #ifdef _DEBUG
- Panic( KErrGeneral );
- #endif
- }
- }
- if( iHorizontalMirroring )
- {
- dx = -dx;
- }
- if( iVerticalMirroring )
- {
- dy = -dy;
- }
-
- if( iSourceRect.iTl.iX + dx < 0 ||
- iSourceRect.iBr.iX + dx > iSourceSize.iWidth ||
- iSourceRect.iTl.iY + dy < 0 ||
- iSourceRect.iBr.iY + dy > iSourceSize.iHeight )
- {
- return KErrArgument;
- }
-
- iSourceRect.Move( dx, dy );
-
- // Start load
- return ApplySettings();
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::SetSourceRectPosition
-// -----------------------------------------------------------------------------
-TInt CIHLImageViewer::SetSourceRectPosition( const TPoint& aPosition )
- {
- TPoint newPosition( aPosition );
- TSize sourceRectSize( iSourceRect.Size() );
- switch( iRotationAngle )
- {
- case ERotationAngle0:
- {
- break;
- }
- case ERotationAngle90:
- {
- newPosition.iX = aPosition.iY;
- newPosition.iY = iSourceSize.iHeight - sourceRectSize.iHeight - aPosition.iX;
- break;
- }
- case ERotationAngle180:
- {
- newPosition.iX = iSourceSize.iWidth - sourceRectSize.iWidth - aPosition.iX;
- newPosition.iY = iSourceSize.iHeight - sourceRectSize.iHeight - aPosition.iY;
- break;
- }
- case ERotationAngle270:
- {
- newPosition.iX = iSourceSize.iWidth - sourceRectSize.iWidth - aPosition.iY;
- newPosition.iY = aPosition.iX;
- break;
- }
- default:
- {
- // Internal state error, debug panic only
- #ifdef _DEBUG
- Panic( KErrGeneral );
- #endif
- }
- }
- if( iHorizontalMirroring )
- {
- newPosition.iX = iSourceSize.iWidth - sourceRectSize.iWidth - newPosition.iX;
- }
- if( iVerticalMirroring )
- {
- newPosition.iY = iSourceSize.iHeight - sourceRectSize.iHeight - newPosition.iY;
- }
-
- if( newPosition.iX < 0 ||
- newPosition.iX > ( iSourceSize.iWidth - sourceRectSize.iWidth ) ||
- newPosition.iY < 0 ||
- newPosition.iY > ( iSourceSize.iHeight - sourceRectSize.iHeight ) )
- {
- return KErrArgument;
- }
-
- iSourceRect = TRect( newPosition, sourceRectSize );
-
- // Start load
- return ApplySettings();
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::SourceRect
-// -----------------------------------------------------------------------------
-TRect CIHLImageViewer::SourceRect() const
- {
- TRect mirroredSourceRect( iSourceRect );
- if( iHorizontalMirroring )
- {
- mirroredSourceRect.iTl.iX = iSourceSize.iWidth - iSourceRect.iBr.iX;
- mirroredSourceRect.iBr.iX = iSourceSize.iWidth - iSourceRect.iTl.iX;
- }
- if( iVerticalMirroring )
- {
- mirroredSourceRect.iTl.iY = iSourceSize.iHeight - iSourceRect.iBr.iY;
- mirroredSourceRect.iBr.iY = iSourceSize.iHeight - iSourceRect.iTl.iY;
- }
-
- TRect rotatedSourceRect( mirroredSourceRect );
- switch( iRotationAngle )
- {
- case ERotationAngle0:
- {
- break;
- }
- case ERotationAngle90:
- {
- rotatedSourceRect.iTl.iX = iSourceSize.iHeight - mirroredSourceRect.iBr.iY;
- rotatedSourceRect.iTl.iY = mirroredSourceRect.iTl.iX;
- rotatedSourceRect.iBr.iX = iSourceSize.iHeight - mirroredSourceRect.iTl.iY;
- rotatedSourceRect.iBr.iY = mirroredSourceRect.iBr.iX;
- break;
- }
- case ERotationAngle180:
- {
- rotatedSourceRect.iTl.iX = iSourceSize.iWidth - mirroredSourceRect.iBr.iX;
- rotatedSourceRect.iTl.iY = iSourceSize.iHeight - mirroredSourceRect.iBr.iY;
- rotatedSourceRect.iBr.iX = iSourceSize.iWidth - mirroredSourceRect.iTl.iX;
- rotatedSourceRect.iBr.iY = iSourceSize.iHeight - mirroredSourceRect.iTl.iY;
- break;
- }
- case ERotationAngle270:
- {
- rotatedSourceRect.iTl.iX = mirroredSourceRect.iTl.iY;
- rotatedSourceRect.iTl.iY = iSourceSize.iWidth - mirroredSourceRect.iBr.iX;
- rotatedSourceRect.iBr.iX = mirroredSourceRect.iBr.iY;
- rotatedSourceRect.iBr.iY = iSourceSize.iWidth - mirroredSourceRect.iTl.iX;
- break;
- }
- default:
- {
- // Internal state error, debug panic only
- #ifdef _DEBUG
- Panic( KErrGeneral );
- #endif
- }
- }
-
- return rotatedSourceRect;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::SourceSize
-// -----------------------------------------------------------------------------
-TSize CIHLImageViewer::SourceSize() const
- {
- if( iRotationAngle == ERotationAngle90 ||
- iRotationAngle == ERotationAngle270 )
- {
- return TSize( iSourceSize.iHeight, iSourceSize.iWidth );
- }
- else
- {
- return iSourceSize;
- }
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::SetZoomRatio
-// -----------------------------------------------------------------------------
-TInt CIHLImageViewer::SetZoomRatio( TReal aZoomRatio )
- {
- if( aZoomRatio <= 0 || Math::IsInfinite( aZoomRatio ) )
- {
- return KErrArgument;
- }
-
- iZoomRatio = aZoomRatio;
-
- // Recalculate source rect and destination size
- CalculateSourceRectAndDestinationSize();
-
- // Start load
- return ApplySettings();
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::ZoomRatio
-// -----------------------------------------------------------------------------
-TReal CIHLImageViewer::ZoomRatio() const
- {
- return iZoomRatio;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::ZoomToFitRatio
-// -----------------------------------------------------------------------------
-TReal CIHLImageViewer::ZoomToFitRatio() const
- {
- return iZoomToFitRatio;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::RotateClockwise
-// -----------------------------------------------------------------------------
-TInt CIHLImageViewer::RotateClockwise()
- {
- TInt rotationAngle( iRotationAngle + ERotationAngle90 );
- if( rotationAngle > ERotationAngle270 )
- {
- rotationAngle = ERotationAngle0;
- }
-
- return SetRotationAngle( rotationAngle );
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::RotateCounterClockwise
-// -----------------------------------------------------------------------------
-TInt CIHLImageViewer::RotateCounterClockwise()
- {
- TInt rotationAngle( iRotationAngle - ERotationAngle90 );
- if( rotationAngle < ERotationAngle0 )
- {
- rotationAngle = ERotationAngle270;
- }
-
- return SetRotationAngle( rotationAngle );
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::SetRotationAngle
-// -----------------------------------------------------------------------------
-TInt CIHLImageViewer::SetRotationAngle( TInt aRotationAngle )
- {
- if( aRotationAngle != ERotationAngle0 &&
- aRotationAngle != ERotationAngle90 &&
- aRotationAngle != ERotationAngle180 &&
- aRotationAngle != ERotationAngle270 )
- {
- return KErrArgument;
- }
-
- iRotationAngle = aRotationAngle;
-
- // Recalculate source rect and destination size
- CalculateSourceRectAndDestinationSize();
-
- // Recalculate zoom to fit ratio
- CalculateZoomToFitRatio();
-
- // Start load
- return ApplySettings();
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::RotationAngle
-// -----------------------------------------------------------------------------
-TInt CIHLImageViewer::RotationAngle() const
- {
- return iRotationAngle;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::SetVerticalMirroring
-// -----------------------------------------------------------------------------
-TInt CIHLImageViewer::SetVerticalMirroring( TBool aValue )
- {
- if( iVerticalMirroring != aValue )
- {
- iVerticalMirroring = aValue;
-
- // Start load
- return ApplySettings();
- }
- return KErrNone;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::VerticalMirroring
-// -----------------------------------------------------------------------------
-TBool CIHLImageViewer::VerticalMirroring() const
- {
- return iVerticalMirroring;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::SetHorizontalMirroring
-// -----------------------------------------------------------------------------
-TInt CIHLImageViewer::SetHorizontalMirroring( TBool aValue )
- {
- if( iHorizontalMirroring != aValue )
- {
- iHorizontalMirroring = aValue;
- return ApplySettings();
- }
- return KErrNone;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::HorizontalMirroring
-// -----------------------------------------------------------------------------
-TBool CIHLImageViewer::HorizontalMirroring() const
- {
- return iHorizontalMirroring;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::SetFilter
-// -----------------------------------------------------------------------------
-void CIHLImageViewer::SetFilter( MIHLFilter* /*aFilter*/ )
- {
- // Not in use
- }
-
-
-
-// Private methods
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::DoCancel
-// -----------------------------------------------------------------------------
-void CIHLImageViewer::DoCancel()
- {
- CTimer::DoCancel();
- switch( iViewerState )
- {
- case ELoad:
- {
- // Cancel asynchronous source loading
- iSource.CancelLoad();
- iCacheSource->Reset();
- break;
- }
- case EProcess:
- {
- // Cancel asynchronous processing
- iProcessor->CancelProcess();
- iCacheDestination->Reset();
- break;
- }
- default:
- {
- break;
- }
- }
-
- // Set state to inactive
- iViewerState = EInactive;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::RunL
-// -----------------------------------------------------------------------------
-void CIHLImageViewer::RunL()
- {
- User::LeaveIfError( iStatus.Int() );
-
-
- TInt err( KErrNone );
- switch( iViewerState )
- {
- case ELoad:
- {
- // Async load successful; start async processing if needed
- if( NeedAsyncProcess() )
- {
- err = AsyncProcess();
- if( !err )
- {
- iViewerState = EProcess;
- SetActive();
- }
- break;
- }
- else
- {
- iViewerState=EInactive;
- // Flowtrough to EProcess if no error
- err = SyncProcess();
- if( err )
- {
- break;
- }
- }
- }
- case EProcess:
- {
- // Process successful; finish and check if animation is needed
- err = Finish();
- if( !err )
- {
- TInt64 currentTime = User::FastCounter();
- if(iAnimDrawStartFastTime > 0)
- {
- iAnimLastFrameDrawTime=(currentTime-iAnimDrawStartFastTime)*1000000/iTickPeriod;
- }
-
- if( iIsPlaying )
- {
- iViewerState = EAnimation;
- SheduleNextFrame(iSource.AnimationFrameDelay( iAnimationIndex ));
- }
- else
- {
- iViewerState = EInactive;
- }
- // Notify client
- // NOTE! client may call any API method in this point!
- iObserver.ViewerBitmapChangedL();
- }
- break;
- }
- case EAnimation:
- {
- // Check if still playing..
- iAnimDrawStartFastTime = User::FastCounter();
- if( iIsPlaying )
- {
- // Change animation frame + 1
- UpdateAnimationIndex();
- err = AsyncLoad();
- if( !err )
- {
- iViewerState = ELoad;
- SetActive();
- }
- else
- {
- iViewerState = EInactive;
- }
- }
- else
- {
- iViewerState = EInactive;
- }
- break;
- }
- default:
- {
- // Internal state error, debug panic only
- #ifdef _DEBUG
- Panic( KErrGeneral );
- #endif
- }
- }
-
-
- User::LeaveIfError( err );
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::RunError
-// -----------------------------------------------------------------------------
-TInt CIHLImageViewer::RunError( TInt aError )
- {
- switch( iViewerState )
- {
- case ELoad:
- {
- // Cleanup cached source if load has been failed
- iCacheSource->Reset();
- break;
- }
- case EProcess:
- {
- // Cleanup cached destination if process has been failed
- iCacheDestination->Reset();
- break;
- }
- default:
- {
- break;
- }
- }
-
- iViewerState = EInactive;
- iObserver.ViewerError( aError );
- return KErrNone;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::Set
-// -----------------------------------------------------------------------------
-TInt CIHLImageViewer::ApplySettings()
- {
- // Assert source rect and destination, debug build only
-#ifdef _DEBUG
- AssertSourceRectAndDestinationSize();
-#endif
-
- // Cancel current process if any
- Cancel();
-
- // Check if cached source bitmap is already valid for processing..
- TBool validSourceCache( EFalse );
- const CFbsBitmap& cacheSource = iCacheSource->Bitmap();
- if( cacheSource.Handle() )
- {
- const TSize cacheSize( cacheSource.SizeInPixels() );
- const TSize minLoadSize( MinimumSourceLoadSize() );
- if( cacheSize.iWidth >= minLoadSize.iWidth &&
- cacheSize.iHeight >= minLoadSize.iHeight )
- {
- validSourceCache = ETrue;
- }
- }
-
- // Start async load/process..
- TInt err( KErrNone );
- if( validSourceCache )
- {
- if( NeedAsyncProcess() )
- {
- err = AsyncProcess();
- if( !err )
- {
- iViewerState = EProcess;
- SetActive();
- }
- }
- else
- {
- err = SyncProcess();
- if( !err )
- {
- iViewerState = EProcess;
- SelfComplete();
- }
- }
- }
- else
- {
- err = AsyncLoad();
- if( !err )
- {
- iViewerState = ELoad;
- SetActive();
- }
- }
-
- return err;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::AsyncLoad
-// -----------------------------------------------------------------------------
-TInt CIHLImageViewer::AsyncLoad()
- {
- // Internal state check, debug panic only
- __ASSERT_DEBUG( !iCacheDestination->Bitmap().Handle(), Panic( KErrGeneral ) );
-
- TInt err( KErrNone );
- if( !iSource.IsAnimation() )
- {
- // Do not reset animation frame because loading
- // might be faster if previous frame can be utilized
- iCacheSource->Reset();
- }
- if( !iCacheSource->Bitmap().Handle() )
- {
- TDisplayMode transparency( iSource.MaskDisplayMode() );
- if( transparency )
- {
- err = iCacheSource->Create( MinimumSourceLoadSize(),
- iSource.DisplayMode(),
- transparency );
- }
- else
- {
- err = iCacheSource->Create( MinimumSourceLoadSize(),
- iSource.DisplayMode() );
- }
- }
-
- // Load source bitmap
- if( !err )
- {
- if( iSource.IsAnimation() )
- {
- err = iSource.LoadAnimation( iStatus, *iCacheSource, iAnimationIndex );
- }
- else
- {
- err = iSource.Load( iStatus, *iCacheSource, iSource.ImageIndex() );
- }
-
- }
-
- // Error cleanup if needed
- if( err )
- {
- iCacheSource->Reset();
- }
- return err;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::NeedAsyncProcess
-// -----------------------------------------------------------------------------
-TBool CIHLImageViewer::NeedAsyncProcess()
- {
- // Internal state check, debug panic only
- __ASSERT_DEBUG( iCacheSource->Bitmap().Handle(), Panic( KErrGeneral ) );
- __ASSERT_DEBUG( !iCacheDestination->Bitmap().Handle(), Panic( KErrGeneral ) );
-
- // First check if destination size differs from source size
- // (=scaling needed)
- TSize scaledSrcSize( iCacheSource->Bitmap().SizeInPixels() );
- if( scaledSrcSize.iWidth != iDestinationSize.iWidth ||
- scaledSrcSize.iHeight != iDestinationSize.iHeight )
- {
- return ETrue;
- }
-
- // Then check if source rect and source size differs
- // (=clipping needed)
- if( iSourceRect.iTl != TPoint( 0,0 ) ||
- iSourceRect.iBr != iSource.Size().AsPoint() )
- {
- return ETrue;
- }
-
- // Finally check rotation and mirroring
- if( iRotationAngle == ERotationAngle0 &&
- !iHorizontalMirroring &&
- !iVerticalMirroring )
- {
- return EFalse;
- }
- else if( iRotationAngle == ERotationAngle180 &&
- iHorizontalMirroring &&
- iVerticalMirroring )
- {
- return EFalse;
- }
- else
- {
- return ETrue;
- }
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::AsyncProcess
-// -----------------------------------------------------------------------------
-TInt CIHLImageViewer::AsyncProcess()
- {
- IHL_DEBUG1( KIHLDebug, "IHL - CIHLImageViewer - AsyncProcess" );
-
- // Internal state check, debug panic only
- __ASSERT_DEBUG( iCacheSource->Bitmap().Handle(), Panic( KErrGeneral ) );
- __ASSERT_DEBUG( !iCacheDestination->Bitmap().Handle(), Panic( KErrGeneral ) );
-
- const CFbsBitmap& srcBitmap = iCacheSource->Bitmap();
- const CFbsBitmap& srcMask = iCacheSource->Mask();
- TInt err( KErrNone );
-
- // Create new cached destination
- if( srcMask.Handle() )
- {
- err = iCacheDestination->Create( iDestinationSize,
- srcBitmap.DisplayMode(), srcMask.DisplayMode() );
- }
- else
- {
- err = iCacheDestination->Create( iDestinationSize, srcBitmap.DisplayMode() );
- }
-
- // Scale and clip bitmap from cached source to new cached destination
- if( !err )
- {
- TRect scaledSourceRect(
- CalculateProcessSourceRect( srcBitmap.SizeInPixels() ) );
-
- TRect destinationRect( CalculateProcessDestinationRect() );
-
- err = iProcessor->Process( iStatus, *iCacheSource, scaledSourceRect,
- *iCacheDestination, destinationRect );
- }
-
- // Error cleanup if needed
- if( err )
- {
- iCacheDestination->Reset();
- }
-
- return err;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::SyncProcess
-// -----------------------------------------------------------------------------
-TInt CIHLImageViewer::SyncProcess()
- {
- IHL_DEBUG1( KIHLDebug, "IHL - CIHLImageViewer - SyncProcess" );
-
- // Internal state check, debug panic only
- __ASSERT_DEBUG( iCacheSource->Bitmap().Handle(), Panic( KErrGeneral ) );
- __ASSERT_DEBUG( !iCacheDestination->Bitmap().Handle(), Panic( KErrGeneral ) );
-
- // Duplicate destination cache to destination bitmap
- TInt err( iCacheDestination->Copy( *iCacheSource, EFalse ) );
- return err;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::Finish
-// -----------------------------------------------------------------------------
-TInt CIHLImageViewer::Finish()
- {
- // Internal state check, debug panic only
- __ASSERT_DEBUG( iCacheDestination->Bitmap().Handle(), Panic( KErrGeneral ) );
-
- // Duplicate destination cache to destination bitmap
- TInt err( iDestination.Copy( *iCacheDestination, ETrue ) );
- iCacheDestination->Reset();
-
- // Error cleanup if needed
- if( err )
- {
- iDestination.Reset();
- }
- return err;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::UpdateAnimationIndex
-// -----------------------------------------------------------------------------
-void CIHLImageViewer::UpdateAnimationIndex()
- {
- // Internal state check, debug panic only
- __ASSERT_DEBUG( iIsPlaying, Panic( KErrGeneral ) );
-
- // Check if animation is in last frame
- if( iAnimationIndex == iSource.AnimationFrameCount() - 1 )
- {
- iAnimationIndex = 0;
- }
- else
- {
- // Not in last frame; move to next frame
- iAnimationIndex++;
- }
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::SelfComplete
-// -----------------------------------------------------------------------------
-void CIHLImageViewer::SelfComplete()
- {
- SetActive();
- iStatus = KRequestPending;
- TRequestStatus* status = &iStatus;
- User::RequestComplete( status, KErrNone );
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::MinimumSourceLoadSize
-// -----------------------------------------------------------------------------
-TSize CIHLImageViewer::MinimumSourceLoadSize()
- {
- TSize minumumLoadSize( iSource.Size() );
-
- if( iSource.IsFullyScaleable() )
- {
- const TSize originalSize( iSource.Size() );
- switch( iRotationAngle )
- {
- case ERotationAngle0:
- case ERotationAngle180:
- {
- minumumLoadSize.iWidth = originalSize.iWidth * iDestinationSize.iWidth / Abs( iSourceRect.Width() );
- minumumLoadSize.iHeight = originalSize.iHeight * iDestinationSize.iHeight / Abs( iSourceRect.Height() );
- break;
- }
- case ERotationAngle90:
- case ERotationAngle270:
- {
- minumumLoadSize.iWidth = originalSize.iWidth * iDestinationSize.iWidth / Abs( iSourceRect.Height() );
- minumumLoadSize.iHeight = originalSize.iHeight * iDestinationSize.iHeight / Abs( iSourceRect.Width() );
- break;
- }
- default:
- {
- // Internal state error, debug panic only
- #ifdef _DEBUG
- Panic( KErrGeneral );
- #endif
- }
- }
-
- // Limit fully scaleable loadsize to original size
- if( minumumLoadSize.iWidth > originalSize.iWidth ||
- minumumLoadSize.iHeight > originalSize.iHeight )
- {
- minumumLoadSize = originalSize;
- }
- }
- else
- {
- const RArray<TSize>& loadSizeArray = iSource.CustomLoadSizeArray();
- const TInt count( loadSizeArray.Count() );
-
- if( count )
- {
- TRect loadRect;
- TSize loadRectSize;
- TBool indexFound( EFalse );
- for( TInt i( 0 ); ( i < count ) && !indexFound; ++i )
- {
- loadRect = CalculateProcessSourceRect( loadSizeArray[ i ] );
- loadRectSize = loadRect.Size();
- loadRectSize.iWidth = Abs( loadRectSize.iWidth );
- loadRectSize.iHeight = Abs( loadRectSize.iHeight );
-
- if( iDestinationSize.iWidth <= loadRectSize.iWidth &&
- iDestinationSize.iHeight <= loadRectSize.iHeight )
- {
- minumumLoadSize = loadSizeArray[ i ];
- indexFound = ETrue;
- }
- }
- }
- }
-
- return minumumLoadSize;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::CalculateProcessSourceRect
-// -----------------------------------------------------------------------------
-TRect CIHLImageViewer::CalculateProcessSourceRect( const TSize& aLoadSize )
- {
- const TSize originalSize( iSource.Size() );
- TRect loadRect;
- if ( aLoadSize.iWidth > KErrNone && aLoadSize.iHeight > KErrNone )
- {
- loadRect.iTl.iX = iSourceRect.iTl.iX * aLoadSize.iWidth / originalSize.iWidth;
- loadRect.iTl.iY = iSourceRect.iTl.iY * aLoadSize.iHeight / originalSize.iHeight;
- loadRect.iBr.iX = iSourceRect.iBr.iX * aLoadSize.iWidth / originalSize.iWidth;
- loadRect.iBr.iY = iSourceRect.iBr.iY * aLoadSize.iHeight / originalSize.iHeight;
- }
- else
- {
- loadRect.SetRect(0,0,0,0);
- return loadRect;
- }
-
- switch( iRotationAngle )
- {
- case ERotationAngle0:
- {
- break;
- }
- case ERotationAngle90:
- {
- TInt tmp( loadRect.iTl.iY );
- loadRect.iTl.iY = loadRect.iBr.iY;
- loadRect.iBr.iY = tmp;
- break;
- }
- case ERotationAngle180:
- {
- TPoint tmp( loadRect.iTl );
- loadRect.iTl = loadRect.iBr;
- loadRect.iBr = tmp;
- break;
- }
- case ERotationAngle270:
- {
- TInt tmp( loadRect.iTl.iX );
- loadRect.iTl.iX = loadRect.iBr.iX;
- loadRect.iBr.iX = tmp;
- break;
- }
- default:
- {
- // Internal state error, debug panic only
- #ifdef _DEBUG
- Panic( KErrGeneral );
- #endif
- }
- }
-
- return loadRect;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::CalculateProcessDestinationRect
-// -----------------------------------------------------------------------------
-TRect CIHLImageViewer::CalculateProcessDestinationRect()
- {
- TRect dstRect( iDestinationSize );
- switch( iRotationAngle )
- {
- case ERotationAngle0:
- case ERotationAngle180:
- {
- if( iHorizontalMirroring )
- {
- TInt tmp( dstRect.iTl.iX );
- dstRect.iTl.iX = dstRect.iBr.iX;
- dstRect.iBr.iX = tmp;
- }
- if( iVerticalMirroring )
- {
- TInt tmp( dstRect.iTl.iY );
- dstRect.iTl.iY = dstRect.iBr.iY;
- dstRect.iBr.iY = tmp;
- }
- break;
- }
- case ERotationAngle90:
- case ERotationAngle270:
- {
- if( iHorizontalMirroring )
- {
- TInt tmp( dstRect.iTl.iY );
- dstRect.iTl.iY = dstRect.iBr.iY;
- dstRect.iBr.iY = tmp;
- }
- if( iVerticalMirroring )
- {
- TInt tmp( dstRect.iTl.iX );
- dstRect.iTl.iX = dstRect.iBr.iX;
- dstRect.iBr.iX = tmp;
- }
- break;
- }
- default:
- {
- // Internal state error, debug panic only
- #ifdef _DEBUG
- Panic( KErrGeneral );
- #endif
- }
- }
- return dstRect;
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::CalculateZoomToFitRatio
-// -----------------------------------------------------------------------------
-void CIHLImageViewer::CalculateZoomToFitRatio()
- {
- TSize sourceSize( SourceSize() );
- TReal widthRatio( TReal( iViewerSize.iWidth ) / TReal( sourceSize.iWidth ) );
- TReal heightRatio( TReal( iViewerSize.iHeight ) / TReal( sourceSize.iHeight ) );
-
- if( iOptions & MIHLImageViewer::EOptionIgnoreAspectRatio )
- {
- iZoomToFitRatio = ( widthRatio > heightRatio ) ? widthRatio : heightRatio;
- }
- else
- {
- iZoomToFitRatio = ( widthRatio < heightRatio ) ? widthRatio : heightRatio;
- }
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::CalculateSourceRectAndDestinationSize
-// -----------------------------------------------------------------------------
-void CIHLImageViewer::CalculateSourceRectAndDestinationSize()
- {
- // Calculate new source rect
- TSize oldSourceRectSize( iSourceRect.Size() );
-
- TReal newSourceRectWidth;
- TReal newSourceRectHeight;
- TReal widthZoomRatio( iZoomRatio );
- TReal heightZoomRatio( iZoomRatio );
-
- if( iOptions & MIHLImageViewer::EOptionIgnoreAspectRatio )
- {
- TReal widthRatio( TReal( iViewerSize.iWidth ) / TReal( iSourceSize.iWidth ) );
- TReal heightRatio( TReal( iViewerSize.iHeight ) / TReal( iSourceSize.iHeight ) );
- if( widthRatio < heightRatio )
- {
- widthZoomRatio = widthZoomRatio * widthRatio / heightRatio;
- }
- else
- {
- heightZoomRatio = heightZoomRatio * heightRatio / widthRatio;
- }
- }
-
- if( iRotationAngle == ERotationAngle90 ||
- iRotationAngle == ERotationAngle270 )
- {
- newSourceRectWidth = iSrcBitmapScaleFactor * iViewerSize.iHeight / heightZoomRatio; //widthZoomRatio
- newSourceRectHeight = iSrcBitmapScaleFactor * iViewerSize.iWidth / widthZoomRatio; //heightZoomRatio
- }
- else
- {
- newSourceRectWidth = iSrcBitmapScaleFactor * iViewerSize.iWidth / widthZoomRatio;
- newSourceRectHeight = iSrcBitmapScaleFactor * iViewerSize.iHeight / heightZoomRatio;
- }
-
- // Check if source rect is not larger than source area
- if( newSourceRectWidth > iSourceSize.iWidth )
- {
- newSourceRectWidth = iSourceSize.iWidth;
- }
- if( newSourceRectHeight > iSourceSize.iHeight )
- {
- newSourceRectHeight = iSourceSize.iHeight;
- }
-
- // Rounding the results
- TReal roundedWidth;
- Math::Round( roundedWidth, newSourceRectWidth, 0 );
- TReal roundedHeight;
- Math::Round( roundedHeight, newSourceRectHeight, 0 );
-
- iSourceRect.SetWidth( (TInt)roundedWidth );
- iSourceRect.SetHeight( (TInt)roundedHeight );
-
- // Calculate actual destination size (always same or smaller than iViewerSize !)
- if( iRotationAngle == ERotationAngle90 ||
- iRotationAngle == ERotationAngle270 )
- {
- iDestinationSize.iWidth = (TInt)( newSourceRectHeight * widthZoomRatio ); //heightZoomRatio
- iDestinationSize.iHeight = (TInt)( newSourceRectWidth * heightZoomRatio ); //widthZoomRatio
- }
- else
- {
- iDestinationSize.iWidth = (TInt)( newSourceRectWidth * widthZoomRatio );
- iDestinationSize.iHeight = (TInt)( newSourceRectHeight * heightZoomRatio );
- }
- // Check that destination size is not rounded to zero
- if( iDestinationSize.iWidth == 0 )
- {
- iDestinationSize.iWidth = 1;
- }
- if( iDestinationSize.iHeight == 0 )
- {
- iDestinationSize.iHeight = 1;
- }
-
- // Move source rect keeping center point in same location
- iSourceRect.Move( ( oldSourceRectSize.iWidth - (TInt)newSourceRectWidth ) / 2,
- ( oldSourceRectSize.iHeight - (TInt)newSourceRectHeight ) / 2 );
-
- // Move rect if partially out of source area
- TPoint moveOffset( 0, 0 );
- if( iSourceRect.iTl.iX < 0 )
- {
- moveOffset.iX = -iSourceRect.iTl.iX;
- }
- else if( iSourceRect.iBr.iX > iSourceSize.iWidth )
- {
- moveOffset.iX = iSourceSize.iWidth - iSourceRect.iBr.iX;
- }
- if( iSourceRect.iTl.iY < 0 ) //lint !e961
- {
- moveOffset.iY = -iSourceRect.iTl.iY;
- }
- else if( iSourceRect.iBr.iY > iSourceSize.iHeight )
- {
- moveOffset.iY = iSourceSize.iHeight - iSourceRect.iBr.iY;
- }
- iSourceRect.Move( moveOffset ); //lint !e961
-
- // Assert that rectangle is valid, debug build only
-#ifdef _DEBUG
- AssertSourceRectAndDestinationSize();
-#endif
- }
-
-// -----------------------------------------------------------------------------
-// CIHLImageViewer::AssertSourceRectAndDestinationSize
-// Used in debug build only
-// -----------------------------------------------------------------------------
-#ifdef _DEBUG
-void CIHLImageViewer::AssertSourceRectAndDestinationSize()
- {
- if( iSourceRect.iTl.iX < 0 ||
- iSourceRect.iBr.iX > iSourceSize.iWidth ||
- iSourceRect.iTl.iY < 0 ||
- iSourceRect.iBr.iY > iSourceSize.iHeight ||
- iDestinationSize.iWidth <= 0 || iDestinationSize.iHeight <= 0 )
- {
- Panic( KErrGeneral );
- }
- }
-#endif
-
-// End of File