diff -r ae942d28ec0e -r 2455ef1f5bbc javauis/lcdui_akn/lcdgr/src/CMIDGraphicsFactory.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javauis/lcdui_akn/lcdgr/src/CMIDGraphicsFactory.cpp Wed Sep 01 12:33:18 2010 +0100 @@ -0,0 +1,623 @@ +/* +* Copyright (c) 2005 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: +* +*/ + +#include +#include +#include +#include + +#include +#include +#include + + +// +// Proxies +// +#include "CMIDImage.h" +#include "CMIDGraphics.h" +#include "CMIDImageDecoder.h" +#include "MMIDCanvasGraphicsItemPainter.h" + +// +// Implementation +// +#include "MidProxyMap.h" +#include "LcdImage.h" +#include "LcdGraphics.h" +#include "LcdFbsImage.h" +#include "LcdFbsImageCache.h" + +#include "s60commonutils.h" + +struct TGraphicsMode +{ + TDisplayMode iScreenMode; + TDisplayMode iPrimaryMode; + TDisplayMode iTransparencyMode; + TDisplayMode iUiColorMode; + TDisplayMode iUiAlphaMode; + TBool iUiInvertMask; +}; + +struct TGraphicsConfig +{ + TGraphicsMode iGraphicsMode; + TBool iUpdateRequired; + TBool iDoubleBuffer; +}; + +TBool ValidGraphicsMode(const TGraphicsMode& aConfig); + +TBool IsAlpha(CFbsBitmap* aBitmap); + +TInt CompareScreenMode(const TGraphicsMode& aLhs, const TGraphicsMode& aRhs) +{ + return aLhs.iScreenMode - aRhs.iScreenMode; +} + +NONSHARABLE_CLASS(CMIDGraphicsFactory) : public CBase + , public MMIDGraphicsFactory + , private MImageTypeMap +{ +public: + CMIDGraphicsFactory(RFs&); + void ConstructL(TDisplayMode); + ~CMIDGraphicsFactory(); + + virtual void Dispose(); + virtual TDisplayMode DisplayMode() const; + virtual TBool DoubleBuffer() const; + virtual MMIDImage* NewMutableImageL(const TSize& aSize); + virtual MMIDImage* NewImageL(const TSize& aSize, TInt aTransparency); + virtual MMIDImage* NewImageL(MMIDImageDecoder* aDecoder); + virtual MMIDImage* NewImageL(MMIDCanvas* aCanvas); + virtual MMIDGraphics* NewGraphicsL(MMIDCanvas* aCanvas); + virtual MMIDGraphics* NewGraphicsL(MMIDCustomItem* aCustomItem); + virtual MMIDGraphics* NewGraphicsL(MMIDImage* aImage); + virtual MMIDGraphics* NewGraphicsL(MMIDCanvasGraphicsItemPainter* aCanvasGraphicsPainter); + virtual MMIDImageDecoder* NewImageDecoderL(); + +private: + virtual TImageType GetImageType(MMIDImage::TTransparencyType aType); + +private: + void LoadConfigL(RArray& aModeArray, const TLinearOrder&); + void ConfigureL(TGraphicsMode& aMode); + TImageType MutableImageType() const; + + virtual MMIDGraphics* NewGraphicsL( + const CFbsBitmap* aBitmap, TBool aIsImageTarget, TBool aIsCanvasGraphicsItem); + +private: + RFs& iFsSession; + CLcdGraphicsDriver* iDriver; + CLcdFbsImageCache* iBitmapCache; + CMIDProxyMap* iProxyMap; + TGraphicsConfig iConfig; + TInt iConfigError; // indicates an error when loading config from resource file + TImageType iImageTypeArray[3]; +}; + +// +// Configuration resource file and constants. +// +_LIT(KLcdgrResourceFileName, "lcdgr.rsc"); +const TInt KDefaultDisplayMode = MMIDBitmapImage::EDefaultDisplayMode; + +// +// The one and only export. +// +EXPORT_C MMIDGraphicsFactory* NewFactoryL(RFs& aFsSession, TDisplayMode aScreenMode) +{ + CMIDGraphicsFactory* factory = new(ELeave) CMIDGraphicsFactory(aFsSession); + CleanupStack::PushL(factory); + factory->ConstructL(aScreenMode); + CleanupStack::Pop(factory); + return factory; +} + +CMIDGraphicsFactory::CMIDGraphicsFactory(RFs& aFsSession) + : iFsSession(aFsSession) +{ + // + // initialize default configuration. + // + iConfig.iGraphicsMode.iPrimaryMode = (TDisplayMode)KDefaultDisplayMode; + iConfig.iGraphicsMode.iTransparencyMode = (TDisplayMode)KDefaultDisplayMode; + iConfig.iGraphicsMode.iUiColorMode = (TDisplayMode)KDefaultDisplayMode; + iConfig.iGraphicsMode.iUiAlphaMode = (TDisplayMode)KDefaultDisplayMode; + iConfig.iGraphicsMode.iUiInvertMask = EFalse; + iConfig.iUpdateRequired = EFalse; + iConfig.iDoubleBuffer = EFalse; +} + +void CMIDGraphicsFactory::ConstructL(TDisplayMode aScreenMode) +{ + // + // Array of graphics modes sorted on screen mode. + // + RArray modeArray(4, _FOFF(TGraphicsMode, iScreenMode)); + TLinearOrder screenModeOrder(CompareScreenMode); + CleanupClosePushL(modeArray); + TGraphicsMode mode; + + // + // Load config from resource file. + // + TRAP(iConfigError, LoadConfigL(modeArray, screenModeOrder)); // ignore error - we'll just use defaults + if (iConfigError) + { + modeArray.Reset(); + mode.iScreenMode = aScreenMode; + mode.iPrimaryMode = aScreenMode; + mode.iTransparencyMode = EGray2; + mode.iUiColorMode = aScreenMode; + mode.iUiAlphaMode = EGray2; + mode.iUiInvertMask = EFalse; + modeArray.AppendL(mode); + } + else + { + mode.iScreenMode = aScreenMode; + TInt index = modeArray.FindInOrder(mode, screenModeOrder); + if (index < 0) + { + // + // Configuration file does not list screen mode. + // + User::Leave(KErrNotSupported); + } + mode = modeArray[index]; + } + ASSERT(mode.iScreenMode == aScreenMode); + + // + // Evaluate configuration, validating any loaded values and filling + // in defaults. This also populates the image type array. + // + ConfigureL(mode); + CleanupStack::PopAndDestroy(); // modes + + iDriver = CLcdGraphicsDriver::NewL(iConfig.iGraphicsMode.iPrimaryMode); + + // + // Construct bitmap cache for UI controls. + // + iBitmapCache = CLcdFbsImageCache::NewL(*iDriver, + iConfig.iGraphicsMode.iUiColorMode, + iConfig.iGraphicsMode.iUiAlphaMode, + iConfig.iGraphicsMode.iUiInvertMask); + + iProxyMap = new(ELeave) CMIDProxyMap; +} + +CMIDGraphicsFactory::~CMIDGraphicsFactory() +{ + if (iBitmapCache) + { + delete iBitmapCache; + iBitmapCache = NULL; + } + if (iProxyMap) + { + delete iProxyMap; + iProxyMap = NULL; + } + if (iDriver) + { + delete iDriver; + iDriver = NULL; + } +} + +void CMIDGraphicsFactory::Dispose() +{ + delete this; +} + +TDisplayMode CMIDGraphicsFactory::DisplayMode() const +{ + return iConfig.iGraphicsMode.iPrimaryMode; +} + +TBool CMIDGraphicsFactory::DoubleBuffer() const +{ + return iConfig.iDoubleBuffer; +} + +MMIDImage* CMIDGraphicsFactory::NewMutableImageL(const TSize& aSize) +{ + CLcdImage* image = new(ELeave) CLcdImage(*iDriver, ETrue); + CleanupStack::PushL(image); + image->ConstructL(aSize, MutableImageType()); + CMIDImage* proxy = new(ELeave) CMIDImage(*iBitmapCache, *this, image); + CleanupStack::Pop(image); + CleanupStack::PushL(proxy); + proxy->ConstructL(); + CleanupStack::Pop(proxy); + return proxy; +} + +MMIDImage* CMIDGraphicsFactory::NewImageL(const TSize& aSize, TInt aTransparency) +{ + CLcdImage* image = new(ELeave) CLcdImage(*iDriver, EFalse); + CleanupStack::PushL(image); + image->ConstructL(aSize, iImageTypeArray[aTransparency]); + CMIDImage* proxy = new(ELeave) CMIDImage(*iBitmapCache, *this, image); + CleanupStack::Pop(image); + CleanupStack::PushL(proxy); + proxy->ConstructL(); + CleanupStack::Pop(proxy); + return proxy; +} + +MMIDImage* CMIDGraphicsFactory::NewImageL(MMIDImageDecoder* aDecoder) +{ + MMIDBitmapImage* bitmapImage = aDecoder->BitmapImage(); + if (!bitmapImage) + { + User::Leave(KErrArgument); + } + + CFbsBitmap* colorBitmap = bitmapImage->ColorBitmap(); + CFbsBitmap* alphaBitmap = bitmapImage->AlphaBitmap(); + + TInt index = MMIDImage::ENone; + if (alphaBitmap) + { + if (IsAlpha(alphaBitmap)) + { + index = MMIDImage::EAlpha; + } + else + { + index = MMIDImage::EMask; + } + } + + CLcdImage* image = new(ELeave) CLcdImage(*iDriver, EFalse); + CleanupStack::PushL(image); + image->ConstructL(colorBitmap, alphaBitmap, iImageTypeArray[index]); + CMIDImage* proxy = new(ELeave) CMIDImage(*iBitmapCache, *this, image); + CleanupStack::Pop(image); + CleanupStack::PushL(proxy); + proxy->ConstructL(); + CleanupStack::Pop(proxy); + return proxy; +} + +/** + * Create a framebuffer image + */ +MMIDImage* CMIDGraphicsFactory::NewImageL(MMIDCanvas* aCanvas) +{ + CFbsBitmap* colorBitmap = aCanvas->FrameBuffer(); + CFbsBitmap* alphaBitmap = NULL; + + if (NULL == colorBitmap) + { + User::Leave(KErrNotSupported); + } + + CLcdImage* image = new(ELeave) CLcdImage(*iDriver, ETrue); + CleanupStack::PushL(image); + image->ConstructL(colorBitmap, alphaBitmap, MutableImageType()); + CMIDImage* proxy = new(ELeave) CMIDImage(*iBitmapCache, *this, image); + CleanupStack::Pop(image); + CleanupStack::PushL(proxy); + proxy->ConstructL(); + CleanupStack::Pop(proxy); + return proxy; +} + + +#ifdef RD_JAVA_NGA_ENABLED +// --------------------------------------------------------------------------- +// NGA extension +// --------------------------------------------------------------------------- +// +MMIDGraphics* CMIDGraphicsFactory::NewGraphicsL(MMIDCanvas* aCanvas) +{ + CLcdGraphics* graphics = CLcdGraphics::NewL(*iDriver, aCanvas->FrameBuffer()); + CleanupStack::PushL(graphics); + CMIDGraphics* proxy = new(ELeave) CMIDGraphics(*iProxyMap, graphics, EFalse, aCanvas); + CleanupStack::Pop(graphics); + return proxy; +} + +#else // !RD_JAVA_NGA_ENABLED + +MMIDGraphics* CMIDGraphicsFactory::NewGraphicsL(MMIDCanvas* aCanvas) +{ + CCoeControl& window = aCanvas->Control(); + MDirectContainer& container = aCanvas->DirectContainer(); + + CLcdGraphics* graphics = CLcdGraphics::NewL(*iDriver, window, container, iConfig.iUpdateRequired); + CleanupStack::PushL(graphics); + CMIDGraphics* proxy = new(ELeave) CMIDGraphics(*iProxyMap, graphics, EFalse); + CleanupStack::Pop(graphics); + return proxy; +} +#endif // RD_JAVA_NGA_ENABLED + +MMIDGraphics* CMIDGraphicsFactory::NewGraphicsL(MMIDCustomItem* aCustomItem) +{ + return NewGraphicsL(aCustomItem->FrameBuffer(), EFalse, EFalse); +} + +MMIDGraphics* CMIDGraphicsFactory::NewGraphicsL(MMIDImage* aImage) +{ + // + // All mutable images must be registered bitmap images as we currently + // rely on BITGDI to render many primitives. + // + // We could have a separate map for mutable images if necessary. + // + MMIDBitmapImage* image = iBitmapCache->GetBitmapImage(aImage); + ASSERT(image); + MMIDGraphics* graphics = NewGraphicsL(image->ColorBitmap(), ETrue, EFalse); + + //Graphics duplicates the fbs handle. + image->RemoveRef(); + return graphics; +} + +MMIDGraphics* CMIDGraphicsFactory::NewGraphicsL(MMIDCanvasGraphicsItemPainter* aCanvasGraphicsItemPainter) +{ + return NewGraphicsL(aCanvasGraphicsItemPainter->FrameBuffer(), EFalse, ETrue); +} + +MMIDGraphics* CMIDGraphicsFactory::NewGraphicsL( + const CFbsBitmap* aBitmap, TBool aIsImageTarget, TBool aIsCanvasGraphicsItem) + +{ + if (NULL == aBitmap) + { + User::Leave(KErrArgument); + } + + if (aBitmap->DisplayMode() != iConfig.iGraphicsMode.iPrimaryMode) + { + User::Leave(KErrArgument); + } + + CLcdGraphics* graphics = CLcdGraphics::NewL(*iDriver, aBitmap); + CleanupStack::PushL(graphics); + CMIDGraphics* proxy = new(ELeave) CMIDGraphics(*iProxyMap, graphics, aIsImageTarget); + CleanupStack::Pop(graphics); + + // CLcdGraphics instance has to know that rendering target bitmap is framebuffer + // of CanavsGraphicsItem. Its because drawing images its not allowed to + // transparent target and CanvasGraphicsItem is transparent by default. + graphics->SetCanvasGraphicsItemtarget(aIsCanvasGraphicsItem); + + return proxy; +} + +MMIDImageDecoder* CMIDGraphicsFactory::NewImageDecoderL() +{ + CMIDImageDecoder* decoder = new(ELeave) CMIDImageDecoder(iFsSession, DisplayMode()); + CleanupStack::PushL(decoder); + decoder->ConstructL(); + CleanupStack::Pop(decoder); + return decoder; +} + +void CMIDGraphicsFactory::LoadConfigL(RArray& aModeArray, const TLinearOrder& aOrder) +{ + TFileName fileName; + + fileName.Append(KLcdgrResourceFileName); + fileName = java::util::S60CommonUtils::ResourceLanguageFileNameL(fileName); + + RResourceFile configFile; + configFile.OpenL(iFsSession, fileName); + CleanupClosePushL(configFile); + configFile.ConfirmSignatureL(); + + // + // read R_GRAPHICS_CONFIG + // + + // + // WARNING! TResourceReader will panic or endless loop on error + // (e.g. if the config file is corrupt). + // + + HBufC8* resourceData = configFile.AllocReadLC(R_GRAPHICS_CONFIG); + TResourceReader reader; + reader.SetBuffer(resourceData); + + int count = reader.ReadInt16(); + for (int i=0; iDisplayMode() == EGray256) + { + TSize size = aBitmap->SizeInPixels(); + TInt scan = CFbsBitmap::ScanLineLength(size.iWidth, EGray256); + + aBitmap->LockHeap(); + + TUint8* address = (TUint8*)aBitmap->DataAddress(); + for (TInt h = size.iHeight; --h>=0;) + { + TUint8* pix = address; + TUint8* end = address + size.iWidth; + while (pix < end) + { + TUint8 value = *pix++; + if ((value > 0) && (value < 255)) + { + alpha = ETrue; + goto endLoop; + } + } + address += scan; + } + +endLoop: + + aBitmap->UnlockHeap(); + } + + return alpha; +} + +#define TYPE_ARRAY_SIZE (sizeof(iImageTypeArray)/sizeof(iImageTypeArray[0])) + +TImageType CMIDGraphicsFactory::GetImageType(MMIDImage::TTransparencyType aType) +{ + ASSERT((0 <= aType) && (aType < TYPE_ARRAY_SIZE)); + return iImageTypeArray[ aType ]; +}