diff -r 058b1fc1663a -r 8a173132b0aa scrsaver/scrsaverplugins/BmpAnimScrPlugin/src/CBmpAnimScrPlugin.cpp --- a/scrsaver/scrsaverplugins/BmpAnimScrPlugin/src/CBmpAnimScrPlugin.cpp Mon Jan 18 20:19:52 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1073 +0,0 @@ -/* -* Copyright (c) 2003 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: Main code file for plugin -* -*/ - - - -#include -#include -#include -#include -#include -#include - -#include "CBmpAnimScrPlugin.h" -#include "BmpAnimUtils.h" - -#include -#include -// "BmpAnimScrPlugin.rsg" - -const TInt KDefaultViewTime = 1000000; - -// -// CBmpAnimSrcPlugin -// - -// Creates and returns a new instance of CBmpAnimScrPlugin -CBmpAnimScrPlugin* CBmpAnimScrPlugin::NewL() - { - CBmpAnimScrPlugin *plugin = new (ELeave) CBmpAnimScrPlugin(); - - // Initialize settings object so that the plugin name can be retrieved - iSettings = CBmpAnimSettings::NewL(); - - return plugin; - } - - -// Default constructor -CBmpAnimScrPlugin::CBmpAnimScrPlugin() - : iState(EPluginStateLoading), - iStopDisplaying(EFalse), - iLoadedAnimation(ENone) - { - BMALOGGER_CREATE; - - } - - -// Destructor -CBmpAnimScrPlugin::~CBmpAnimScrPlugin() - { - delete iModel; - delete iSettings; - - StopDisplayTimer(); - delete iDisplayTimer; - - BMALOGGER_DELETE; - } - - -// --- from Screensaverplugin --- - - -// Initialization function. Must be called before anything but -// name query can be done -TInt CBmpAnimScrPlugin::InitializeL(MScreensaverPluginHost *aHost) - { - ASSERT(aHost); - - // Sanity check - if (!aHost) - { - return KErrArgument; - } - - // Save the host interface - iHost = aHost; - - // Start state - iState = EPluginStateLoading; - - // Initial timing (may be overridden by settings) - iHost->SetRefreshTimerValue(KDefaultViewTime); - - // Lie that we'll show indicators so that host does not prevent - // plugin to be run if there are any to show. We'll stop after a - // while anyway and the indicators are shown by normal Screensaver - iHost->OverrideStandardIndicators(); - - // Grab hold of the environment (this could be in the plugin host interface) - iEikEnv = CEikonEnv::Static(); - - // Create the model to store the animation in - iModel = new(ELeave) CBmpAnimModel(); - iModel->ConstructL(iSettings); - - // Get screen info - UpdateDisplayInfo(); - - // Load the animation (Reload figures out which graphics should be used) - ReloadAnimationL(); - - // Create display timer - iDisplayTimer = CPeriodic::NewL(CActive::EPriorityStandard); - - return KErrNone; - } - - -// Draw function being called repeatedly by the host -TInt CBmpAnimScrPlugin::Draw(CWindowGc& aGc) - { - // If initializing, start the timer and move on to animation state - if (iState == EPluginStateInitializing) - { - BMALOGGER_WRITE("First draw, initializing"); - - StartDisplayTimer(); - HandlePluginState(); - SetDisplayMode(); - TInt nLights = iModel->Settings()->Lights(); - - if (nLights > 0) - { - Lights(nLights); - } - - // Make sure the animation sequence starts from the beginning - iModel->SetCurrentItemIndex(0); - } - - // Retrieve the next image in sequence - TBool endOfSequence = EFalse; - CBmpAnimItem* pItem = iModel->NextItem(endOfSequence); - - if ((endOfSequence) || (!pItem)) - { - // End of sequence reached, see if we've shown enough (1 minute) - if (iStopDisplaying) - { - // Stop the timer - StopDisplayTimer(); - - // Back to square 1 - iState = EPluginStateInitializing; - - // Set a lower refresh rate while plugin is suspended. - // This allows the Screensaver to stop Window Server heartbeat - // and the system is able to sleep normally - // NOTE: Not needed anymore, Screensaver now shuts down - // WSERV heartbeat for suspended plugins - // iHost->SetRefreshTimerValue(KDefaultViewTime); - - TInt suspendTime = iModel->Settings()->SuspendTime(); - - BMALOGGER_WRITEF(_L("BMA: Done drawing, suspending for %d"), - suspendTime); - - iHost->Suspend(suspendTime); - - return KErrNone; - } - } - - if (pItem) - { - // Make sure the window is empty in case the bitmap doesn't - // fill the whole screen - aGc.Clear(); - - DrawCentered(aGc, pItem); - } - -// Activate code if centering INI-controllable -#if 0 - // Retrieve drawing information - CGulIcon* pIcon = pItem->Icon(); - TPoint position = pItem->Position(); - CFbsBitmap* bitmap = pIcon->Bitmap(); - CFbsBitmap* mask = pIcon->Mask(); - - // Draw the whole bitmap at position - TRect rect(position, bitmap->SizeInPixels()); - - if (mask) - { - // Looks like a real icon - draw masked - aGc.BitBltMasked(position, bitmap, rect, mask, ETrue); - } - else - { - // Just the bitmap - no masked draw - aGc.BitBlt(position, bitmap, rect); - } - - // Wait for the specified time until next image - // - // TODO: The new wk28 Screensaver crashes if the next call - // is uncommented. Maybe the timer is not stopped - // before starting again? Hmm... doesn't seem to happen - // anymore. I wonder what changed. Anyway, I'll have it - // commented out for the time being, in order to control - // all frames' rate with the single setting - // - // NOTE: There was a flaw in Screensaver where it would try to - // start refresh timer twice, if plugin changes the value during - // the first draw. The fix is released for 2.6_wk40_FB4 - // iHost->SetRefreshTimerValue(pItem->Timing()); - } -/* - aGc.SetPenColor(TRgb(255,0,0)); - aGc.SetPenStyle(CGraphicsContext::ESolidPen); - aGc.DrawRect(TRect(30, 30, 100, 100)); - - aGc.SetPenColor(TRgb(255,0,0)); - aGc.SetPenSize(TSize(3,3)); - aGc.DrawRect(TRect(120, 100, 200, 150)); -*/ -#endif - return KErrNone; - } - - -// Return the name of the plugin -const TDesC16& CBmpAnimScrPlugin::Name() const - { - if (iSettings) - { - return iSettings->PluginName(); - } - - return KPluginName; - } - - -// Handles events sent by the screensaver -TInt CBmpAnimScrPlugin::HandleScreensaverEventL( - TScreensaverEvent aEvent, - TAny* /* aData */) - { - switch (aEvent) - { - case EScreensaverEventStarting: - BMALOGGER_WRITE("Start event"); - break; - case EScreensaverEventStopping: - BMALOGGER_WRITE("Stop event"); - StopDisplayTimer(); - iState = EPluginStateInitializing; - break; - case EScreensaverEventDisplayChanged: - BMALOGGER_WRITE("Display changed event"); - // Grab current screen info - UpdateDisplayInfo(); - // Reload animation, if needed - ReloadAnimationL(); - break; - default: - break; - } - - return KErrNone; - } - - -// Return plugin capabilities (configurable) -TInt CBmpAnimScrPlugin::Capabilities() - { - return EScpCapsConfigure; - } - - -// Perform a plugin function -TInt CBmpAnimScrPlugin::PluginFunction(TScPluginCaps aFunction, TAny* aParam) - { - switch (aFunction) - { - case EScpCapsConfigure: - { - TRAPD(err, err = ConfigureL(aParam)); - return err; - } - break; - default: - return KErrNotSupported; - break; - } - } - - -// --- private functions --- - -// Draws centered items -void CBmpAnimScrPlugin::DrawCentered(CWindowGc& aGc, CBmpAnimItem* aItem) - { - CGulIcon* pIcon = aItem->Icon(); - CFbsBitmap* bitmap = pIcon->Bitmap(); - CFbsBitmap* mask = pIcon->Mask(); - - if (!bitmap) - return; - - // Center the bitmap horizontally and vertically (crop off excess) - TPoint pos; - TRect rectToDraw; - TSize sizeBmp = bitmap->SizeInPixels(); - TInt screenWidth = iDi.iRect.Width(); - TInt screenHeight = iDi.iRect.Height(); - - // Horizontally - if (sizeBmp.iWidth <= screenWidth) - { - // Width fits on screen - center xpos - pos.iX = (screenWidth - sizeBmp.iWidth) / 2; - - // Whole width of bmp can be drawn - rectToDraw.SetWidth(sizeBmp.iWidth); - } - else - { - // Bmp wider than screen - xpos top left - pos.iX = 0; - - // Adjust draw rect position and width - rectToDraw.iTl.iX = (sizeBmp.iWidth - screenWidth) / 2; - rectToDraw.SetWidth(screenWidth); - } - - // Vertically - if (sizeBmp.iHeight <= screenHeight) - { - // Height fits on screen - center ypos - pos.iY = (screenHeight - sizeBmp.iHeight) / 2; - - // Whole height of bmp can be drawn - rectToDraw.SetHeight(sizeBmp.iHeight); - } - else - { - // Bmp higher than screen - ypos top left - pos.iY = 0; - - // Adjust draw rect position and height - rectToDraw.iTl.iY = (sizeBmp.iHeight - screenHeight) / 2; - rectToDraw.SetHeight(screenHeight); - } - - // Do the drawing - if (mask) - { - // Looks like a real icon - draw masked - aGc.BitBltMasked(pos, bitmap, rectToDraw, mask, ETrue); - } - else - { - // Just the bitmap - no masked draw - aGc.BitBlt(pos, bitmap, rectToDraw); - } - } - - -// Loads the animation into the model -void CBmpAnimScrPlugin::LoadAnimationL(TBool aLandscape, TBool aRotate) - { - // Rotated landscape not supported - ASSERT(!(aLandscape && aRotate)); - - // Start by getting rid of a possible loaded animation - iModel->DeleteAll(); - - // Bitmap index. If negative, loading is finished. - TInt nIndex = KMifIdFirst; - - TFileName fileName; - - if (aLandscape) - { - fileName = iModel->Settings()->BitmapFilenameLandscape(); - } - else - { - fileName = iModel->Settings()->BitmapFilename(); - } - - BMALOGGER_WRITEF(_L("BMA: Loading from: %S"), &(fileName)); - - while (nIndex > 0) - { - CFbsBitmap* pBmp = NULL; - - TRAPD(err, pBmp = AknIconUtils::CreateIconL(fileName, nIndex)); - - if ((pBmp) && (err == KErrNone)) - { - // Got bitmap, push and set size - CleanupStack::PushL(pBmp); - TInt scaleErr = ScaleBitmap(pBmp, aRotate); - if (scaleErr == KErrNone) - { - // Create an item with the bitmap and store it in the model - CBmpAnimItem* pItem = new(ELeave) CBmpAnimItem(); - CleanupStack::PushL(pItem); - - pItem->SetIconL(pBmp); - iModel->AppendItemL(pItem); - - CleanupStack::Pop(2); // pBmp, pItem - - BMALOGGER_WRITEF(_L("BMA: Loaded bmp %d"), nIndex); - - // Try loading next bitmap (skip mask IDs) - nIndex += 2; - } - else - { - BMALOGGER_WRITEF(_L("BMA: Bmp %d scale err %d"), - nIndex, scaleErr); - - // Apparently SVG icon was not found, this is not caught - // in CreateIconL(). Assume last image was loaded. - CleanupStack::PopAndDestroy(); // pBmp - nIndex = -1; - } - } - else - { - // Loading failed - maybe reached end of bitmaps - nIndex = -1; - - BMALOGGER_WRITEF(_L("BMA: Bmp load failed: %d"), err); - } - } - - // Save the type of loaded animation - if (aLandscape) - { - iLoadedAnimation = ELandscape; - } - else if (aRotate) - { - iLoadedAnimation = EPortraitRotated; - } - else - { - iLoadedAnimation = EPortrait; - } - - // On to next state - HandlePluginState(); - - // Start animating, when appropriate - iHost->SetRefreshTimerValue(iModel->Settings()->Timing()); - - BMALOGGER_WRITE("BMA: Animation loaded"); - } - - -// Re-loads the animation into the model, if needed -void CBmpAnimScrPlugin::ReloadAnimationL() - { - // Check if the correct graphics are already loaded - if (!ReloadNeeded()) - { - // Done! That was easy :) - return; - } - - // Load correct graphics - LoadAnimationL(LoadLandscape(), RotateNeeded()); - } - - -// Starts the display timer -void CBmpAnimScrPlugin::StartDisplayTimer() - { - ASSERT(iDisplayTimer); - - TInt time = iModel->Settings()->RunningTime(); - - BMALOGGER_WRITEF(_L("BMA: Start display timer for %d"), time); - - iStopDisplaying = EFalse; - iDisplayTimer->Start( - time, - time, - TCallBack(DisplayTimerCallback, this)); - } - - -// Stops the display timer -void CBmpAnimScrPlugin::StopDisplayTimer() - { - BMALOGGER_WRITE("BMA: Stop display timer"); - - if (iDisplayTimer) - { - iDisplayTimer->Cancel(); - } - - iStopDisplaying = EFalse; - } - - -// Display timer callback - sets animation stop flag -TInt CBmpAnimScrPlugin::DisplayTimerCallback(TAny* aPtr) - { - BMALOGGER_WRITE("BMA: Display timer timeout"); - - CBmpAnimScrPlugin* _this = REINTERPRET_CAST(CBmpAnimScrPlugin*, aPtr); - _this->iStopDisplaying = ETrue; - return KErrNone; - } - - -// Changes the internal state flag -void CBmpAnimScrPlugin::HandlePluginState() - { - switch (iState) - { - case EPluginStateLoading: - iState = EPluginStateInitializing; - break; - case EPluginStateInitializing: - iState = EPluginStateAnimation; - break; - case EPluginStateAnimation: - break; - case EPluginStateStoppingAnimation: - iHost->SetRefreshTimerValue(KDefaultViewTime); - iState = EPluginStateInitializing; - break; - } - } - - -// Requests display mode from host -void CBmpAnimScrPlugin::SetDisplayMode() - { - if (!iHost) - { - return; - } - - // Exit partial mode - iHost->ExitPartialMode(); - } - - -void CBmpAnimScrPlugin::Lights(TInt aSecs) - { - BMALOGGER_WRITEF(_L("BMA: Request lights for %d secs"), aSecs); - iHost->RequestLights(aSecs); - } - - -// Configure the plugin -TInt CBmpAnimScrPlugin::ConfigureL(TAny* aParam) - { - if (!iSettings) - { - return KErrNotFound; - } - - // Grab the parameter (CEikonEnv in this case) - CEikonEnv* eikEnv = NULL; - - if (aParam) - { - // The host was kind enough to provide us with a param - use it - eikEnv = REINTERPRET_CAST(CEikonEnv*, aParam); - } - else if (iEikEnv) - { - // Use own env, if initialized - eikEnv = iEikEnv; - } - - TInt setting = iSettings->Lights(); - - CAknNumberQueryDialog* dlg = CAknNumberQueryDialog::NewL(setting); - CleanupStack::PushL(dlg); - _LIT(KPrompt, "Lights time (sec)"); - dlg->SetPromptL(KPrompt); - dlg->SetMinimumAndMaximum(0, 30); - CleanupStack::Pop(); - - if (dlg->ExecuteLD(R_AVKON_DIALOG_QUERY_VALUE_NUMBER)) - { - iSettings->SetLights(setting); - iSettings->SaveSettingsL(); - } - - // All was swell! - return KErrNone; - } - - -// Scale bitmap to screen size, set size of SVG bitmaps -TInt CBmpAnimScrPlugin::ScaleBitmap(CFbsBitmap* aBmp, TBool aRotate) - { - TInt ret = KErrNone; - - // SVG size always screen size - TSize size = iDi.iRect.Size(); - - if (!AknIconUtils::IsMifIcon(aBmp)) - { - // Bitmaps maintain their original size, unless scaling requested, in which - // case screen size is OK - if (!iSettings->ScaleBmps()) - { - // No scaling, use original size - size = aBmp->SizeInPixels(); - - if (aRotate) - { - // Lie the target size, otherwise IconUitls will think - // the image needs scaling (this won't work perfectly - // either, the image gets clipped a little :( - //size.SetSize(size.iHeight, size.iHeight); - - // Flip size for rotation - size.SetSize(size.iHeight, size.iWidth); - } - } - } - - if (aRotate) - { - // Set image to screen size and rotate 90 deg left (270 right) - // ret = SetSizeAndRotation(aBmp, size, 270); - ret = AknIconUtils::SetSizeAndRotation( - aBmp, size, EAspectRatioPreservedSlice, 270); - } - else - { - // Just set image to size - ret = AknIconUtils::SetSize(aBmp, size, EAspectRatioPreserved); - } - - return ret; - } - - -// Returns ETrue if reload of the animation is needed -TBool CBmpAnimScrPlugin::ReloadNeeded() - { - // Assume reload needed - TBool needed = ETrue; - - switch (iLoadedAnimation) - { - case EPortrait: - // No reload if display portrait - if (!DisplayIsLandscape()) - { - needed = EFalse; - } - break; - - case ELandscape: - case EPortraitRotated: - // No reload if display landscape - if (DisplayIsLandscape()) - { - needed = EFalse; - } - break; - - case ENone: - default: - // Reload - break; - } - - return needed; - } - - -// Returns ETrue if display in landscape -TBool CBmpAnimScrPlugin::DisplayIsLandscape() - { - // Should actually check the rotation and stuff, but what the hey... - return (iDi.iRect.Width() > iDi.iRect.Height()); - } - - -// Returns ETrue if graphics should be rotated -TBool CBmpAnimScrPlugin::RotateNeeded() - { - // Rotate needed, if only portrait graphics are used, and - // display is landscape - return ((!iSettings->UseLandscape()) && (DisplayIsLandscape())); - } - - -// Returns ETrue if landscape graphics should be loaded -TBool CBmpAnimScrPlugin::LoadLandscape() - { - // Landscape, if only available and display is landscape - return ((iSettings->UseLandscape()) && (DisplayIsLandscape())); - } - - -// Updates the saved information about display -void CBmpAnimScrPlugin::UpdateDisplayInfo() - { - iDi.iSize = sizeof(TScreensaverDisplayInfo); - iHost->DisplayInfo(&iDi); - } - -#if 0 -// Rotates and scales a source bitmap into target bitmap (non-leaving wrapper) -TInt CBmpAnimScrPlugin::SetSizeAndRotation( - CFbsBitmap* aBmp, TSize aSize, TInt aAngle) - { - // Anything to do? - if ((aBmp) && (aBmp->SizeInPixels() == aSize) && ((aAngle % 360) == 0)) - { - // Duh, the bitmap is already as requested - return KErrNone; - } - - // Call the actual workhorse - TRAPD(err, SetSizeAndRotationL(aBmp, aSize, aAngle)); - - return err; - } - - -// Rotates and scales a source bitmap into target bitmap (leaving version) -void CBmpAnimScrPlugin::SetSizeAndRotationL( - CFbsBitmap* aBmp, TSize aSize, TInt aAngle) - { - // Make a copy of the source bitmap, and use the original source as target - CFbsBitmap* tmpBmp = new (ELeave) CFbsBitmap; - CleanupStack::PushL(tmpBmp); - - User::LeaveIfError(tmpBmp->Duplicate(aBmp->Handle())); - - // Discard original bitmap - aBmp->Reset(); - - // Create new target bitmap in the original object - User::LeaveIfError(aBmp->Create(aSize, tmpBmp->DisplayMode())); - - // Let the workhorse do its work - RotateAndScaleBitmapL(TRect(aSize), aBmp, tmpBmp, aAngle); - - // Not interested in original anymore - CleanupStack::PopAndDestroy(tmpBmp); - } - - -// Rotates and scales a source bitmap into target bitmap -void CBmpAnimScrPlugin::RotateAndScaleBitmapL( - const TRect& aTrgRect, - CFbsBitmap* aTrgBitmap, - CFbsBitmap* aSrcBitmap, - TInt aAngle) - { - aAngle = aAngle % 360; - if (aAngle < 0) - { - aAngle+=360; - } - - if (!aSrcBitmap) User::Leave(KErrArgument); - if (!aTrgBitmap) User::Leave(KErrArgument); - if (aSrcBitmap->DisplayMode() != aTrgBitmap->DisplayMode()) - User::Leave(KErrArgument); - - TSize trgBitmapSize = aTrgBitmap->SizeInPixels(); - if ((trgBitmapSize.iHeight < aTrgRect.iBr.iY) || - (trgBitmapSize.iWidth < aTrgRect.iBr.iX)) - { - User::Leave(KErrArgument); - } - - if (aTrgRect.IsEmpty()) - return; - - TSize srcSize = aSrcBitmap->SizeInPixels(); - - TInt centerX = srcSize.iWidth / 2; - TInt centerY = srcSize.iHeight / 2; - - TInt trgWidth = aTrgRect.Width(); - TInt trgHeight = aTrgRect.Height(); - - TInt scalefactor = 65536; - TInt xscalefactor = (srcSize.iWidth << 16) / trgWidth; - TInt yscalefactor = (srcSize.iHeight << 16) / trgHeight; - - // Check if rotating 90 left or right, no need to scale - if (((aAngle == 270) || (aAngle == 90)) && - (srcSize.iWidth == trgHeight) && - (srcSize.iHeight == trgWidth)) - { - scalefactor = 65535; - } - else - { - if (xscalefactor < yscalefactor) - { - scalefactor = yscalefactor; - } - else - { - scalefactor = xscalefactor; - } - } - - TBool srcTemporary = EFalse; - TBool hardMask = EFalse; - if (aSrcBitmap->IsRomBitmap()) - { - srcTemporary = ETrue; - } - if (aSrcBitmap->IsCompressedInRAM()) - { - srcTemporary = ETrue; - } - - TBool fallbackOnly = EFalse; - TDisplayMode displayMode = aSrcBitmap->DisplayMode(); - TUint8 fillColor = 0; - - switch(displayMode) - { - case EGray2: - srcTemporary = ETrue; - hardMask = ETrue; - fillColor = 0xff; // white - break; - case EGray4: - case EGray16: - case EColor16: - case EColor16M: - case ERgb: - fallbackOnly = ETrue; - break; - case EColor256: - fillColor = 0xff; // should be black in our indexed palette.... - case EGray256: - case EColor4K: - case EColor64K: - - case EColor16MU: - // These are the supported modes - break; - default: - fallbackOnly = ETrue; - } - - if (fallbackOnly) - { - // Color mode not supported - User::Leave(KErrNotSupported); - } - - CFbsBitmap* realSource = aSrcBitmap; - CFbsBitmap* realTarget = aTrgBitmap; - if (srcTemporary) - { - realSource = new (ELeave) CFbsBitmap(); - CleanupStack::PushL(realSource); - if (hardMask) - { - realTarget = new (ELeave) CFbsBitmap(); - CleanupStack::PushL(realTarget); - User::LeaveIfError(realSource->Create(srcSize, EGray256)); - displayMode = EGray256; - User::LeaveIfError(realTarget->Create( - aTrgBitmap->SizeInPixels(), EGray256)); - } - else - { - User::LeaveIfError(realSource->Create( - srcSize, aSrcBitmap->DisplayMode())); - } - - CFbsBitmapDevice* dev = CFbsBitmapDevice::NewL(realSource); - CleanupStack::PushL(dev); - CFbsBitGc* gc = NULL; - User::LeaveIfError(dev->CreateContext(gc)); - CleanupStack::PushL(gc); - gc->BitBlt(TPoint(0,0), aSrcBitmap); - CleanupStack::PopAndDestroy(2); // dev, gc - } - - // Heap lock for FBServ large chunk is only needed with large bitmaps. - if (realSource->IsLargeBitmap() || realTarget->IsLargeBitmap()) - { - realTarget->LockHeapLC(ETrue); // fbsheaplock - } - else - { - // Bogus push so we can pop() anyway - CleanupStack::PushL((TAny*)NULL); - } - - TUint32* srcAddress = realSource->DataAddress(); - TUint32* trgAddress = realTarget->DataAddress(); - - TReal realsin; - TReal realcos; - TInt sin; - TInt cos; - - User::LeaveIfError(Math::Sin(realsin, ((2*KPi)/360) * aAngle)); - User::LeaveIfError(Math::Cos(realcos, ((2*KPi)/360) * aAngle)); - - sin = ((TInt)(realsin * scalefactor)); - cos = ((TInt)(realcos * scalefactor)); - - TInt xx = ((trgWidth)/2) - ((srcSize.iWidth/2) - centerX); - TInt yy = ((trgHeight)/2) - ((srcSize.iHeight/2) - centerY); - - TInt x = 0; - TInt y = 0; - TInt u = 0; - TInt v = 0; - - if( (displayMode==EGray256) || (displayMode==EColor256) ) - { - TInt srcScanLen8 = CFbsBitmap::ScanLineLength( - srcSize.iWidth, displayMode); - TInt trgScanLen8 = CFbsBitmap::ScanLineLength( - trgBitmapSize.iWidth, displayMode); - TUint8* srcAddr8 = reinterpret_cast(srcAddress); - TUint8* trgAddr8 = reinterpret_cast(trgAddress); - - // skip left and top margins in the beginning - trgAddr8 += trgScanLen8 * aTrgRect.iTl.iY + aTrgRect.iTl.iX; - - for (y = 0; y < trgHeight; y++) - { - u = (-xx) * cos + (y-yy) * sin + (centerX<<16); - v = (y-yy) * cos - (-xx) * sin + (centerY<<16); - for (x = 0; x < trgWidth; x++) - { - if (((u>>16)>=srcSize.iWidth) || - ((v>>16)>=srcSize.iHeight) || - ((u>>16)<0) || - ((v>>16)<0)) - { - *trgAddr8++ = fillColor; - } - else - { - *trgAddr8++ = srcAddr8[(u>>16)+(((v>>16))*srcScanLen8)]; - } - u += cos; - v -= sin; - } - trgAddr8 += trgScanLen8 - trgWidth; - } - } - else if( displayMode == EColor64K || displayMode == EColor4K) - { - TInt srcScanLen16 = CFbsBitmap::ScanLineLength( - srcSize.iWidth, displayMode) / 2; - TInt trgScanLen16 = CFbsBitmap::ScanLineLength( - trgBitmapSize.iWidth, displayMode) / 2; - TUint16* srcAddr16 = reinterpret_cast(srcAddress); - TUint16* trgAddr16 = reinterpret_cast(trgAddress); - - // skip left and top margins in the beginning - trgAddr16 += trgScanLen16 * aTrgRect.iTl.iY + aTrgRect.iTl.iX; - - for (y = 0; y < trgHeight; y++) - { - u = (-xx) * cos + (y-yy) * sin + (centerX<<16); - v = (y-yy) * cos - (-xx) * sin + (centerY<<16); - for (x = 0; x < trgWidth; x++) - { - if (((u>>16)>=srcSize.iWidth) || - ((v>>16)>=srcSize.iHeight) || - ((u>>16)<0) || - ((v>>16)<0)) - { - *trgAddr16++ = 0; - } - else - { - *trgAddr16++ = - srcAddr16[(u>>16)+(((v>>16))*srcScanLen16)]; - } - u += cos; - v -= sin; - } - trgAddr16 += trgScanLen16 - trgWidth; - } - } - else if(displayMode == EColor16MU) - { - TInt srcScanLen32 = CFbsBitmap::ScanLineLength( - srcSize.iWidth, displayMode) / 4; - TInt trgScanLen32 = CFbsBitmap::ScanLineLength( - trgBitmapSize.iWidth, displayMode) / 4; - TUint32* srcAddr32 = srcAddress; - TUint32* trgAddr32 = trgAddress; - - // skip left and top margins in the beginning - trgAddr32 += trgScanLen32 * aTrgRect.iTl.iY + aTrgRect.iTl.iX; - - for (y = 0; y < trgHeight; y++) - { - u = (-xx) * cos + (y-yy) * sin + (centerX<<16); - v = (y-yy) * cos - (-xx) * sin + (centerY<<16); - for (x = 0; x < trgWidth; x++) - { - if (((u>>16)>=srcSize.iWidth) || - ((v>>16)>=srcSize.iHeight) || - ((u>>16)<0) || - ((v>>16)<0)) - { - *trgAddr32++ = 0; - } - else - { - *trgAddr32++ = - srcAddr32[(u>>16)+(((v>>16))*srcScanLen32)]; - } - u += cos; - v -= sin; - } - trgAddr32 += trgScanLen32 - trgWidth; - } - } - else - { - // Display mode not supported - but this should've been caught - // already earlier - User::Leave(KErrUnknown); - } - - CleanupStack::PopAndDestroy(); // fbsheaplock - - if (srcTemporary) - { - if (hardMask) - { - CFbsBitmapDevice* dev = CFbsBitmapDevice::NewL(aTrgBitmap); - CleanupStack::PushL(dev); - CFbsBitGc* gc = NULL; - User::LeaveIfError(dev->CreateContext(gc)); - CleanupStack::PushL(gc); - gc->BitBlt(TPoint(0,0), realTarget); - CleanupStack::PopAndDestroy(3); // dev, gc, realtarget - } - CleanupStack::PopAndDestroy(); // realSource - } - } -#endif - -// End of file