--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/javauis/lcdui_akn/lcdgr/src/CMIDGraphicsFactory.cpp Tue Apr 27 16:30:29 2010 +0300
@@ -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 <e32base.h>
+#include <f32file.h>
+#include <barsc.h>
+#include <barsread.h>
+
+#include <lcdgr.h>
+#include <lcdgdrv.h>
+#include <lcdgr.rsg>
+
+
+//
+// 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<TGraphicsMode>& aModeArray, const TLinearOrder<TGraphicsMode>&);
+ 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<TGraphicsMode> modeArray(4, _FOFF(TGraphicsMode, iScreenMode));
+ TLinearOrder<TGraphicsMode> 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<TGraphicsMode>& aModeArray, const TLinearOrder<TGraphicsMode>& 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; i<count; i++)
+ {
+ TGraphicsMode mode;
+ mode.iScreenMode = (TDisplayMode)reader.ReadInt16();
+ mode.iPrimaryMode = (TDisplayMode)reader.ReadInt16();
+ mode.iTransparencyMode = (TDisplayMode)reader.ReadInt16();
+ mode.iUiColorMode = (TDisplayMode)reader.ReadInt16();
+ mode.iUiAlphaMode = (TDisplayMode)reader.ReadInt16();
+ mode.iUiInvertMask = (TBool)reader.ReadInt16();
+ aModeArray.InsertInOrderL(mode, aOrder);
+ }
+
+ iConfig.iUpdateRequired = (TBool)reader.ReadInt16();
+ iConfig.iDoubleBuffer = (TBool)reader.ReadInt16();
+
+ CleanupStack::PopAndDestroy(resourceData);
+
+ CleanupStack::PopAndDestroy(); //configFile
+}
+
+
+void CMIDGraphicsFactory::ConfigureL(TGraphicsMode& aMode)
+{
+ //
+ // Fill in defaulted values.
+ //
+ if (aMode.iPrimaryMode == KDefaultDisplayMode)
+ {
+ aMode.iPrimaryMode = aMode.iScreenMode;
+ }
+
+ if (aMode.iTransparencyMode == KDefaultDisplayMode)
+ {
+ if (aMode.iPrimaryMode == EColor16MA)
+ {
+ aMode.iTransparencyMode = ENone;
+ }
+ else
+ {
+ aMode.iTransparencyMode = EGray2;
+ }
+ }
+
+ //
+ // Validate the configuration.
+ //
+
+ if (aMode.iUiColorMode == KDefaultDisplayMode)
+ {
+ aMode.iUiColorMode = aMode.iPrimaryMode;
+ }
+
+ if (aMode.iUiAlphaMode == KDefaultDisplayMode)
+ {
+ aMode.iUiAlphaMode = EGray2;
+ }
+
+ if (!ValidGraphicsMode(aMode))
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+ iConfig.iGraphicsMode = aMode;
+
+ //
+ // configure opaque image type
+ //
+ iImageTypeArray[MMIDImage::ENone].iColorMode = aMode.iPrimaryMode;
+ iImageTypeArray[MMIDImage::ENone].iAlphaMode = ENone;
+ iImageTypeArray[MMIDImage::ENone].iTransparency = ETransparencyNone;
+
+ //
+ // Configure transparent image type
+ //
+ iImageTypeArray[MMIDImage::EMask].iColorMode = aMode.iPrimaryMode;
+ if (aMode.iPrimaryMode == EColor16MA)
+ {
+ iImageTypeArray[MMIDImage::EMask].iAlphaMode = ENone;
+ iImageTypeArray[MMIDImage::EMask].iTransparency = ETransparencyMaskChannel;
+ }
+ else
+ {
+ iImageTypeArray[MMIDImage::EMask].iAlphaMode = aMode.iTransparencyMode;
+ iImageTypeArray[MMIDImage::EMask].iTransparency = ETransparencyMaskBitmap;
+ }
+
+ //
+ // Configure alpha image type
+ //
+ iImageTypeArray[MMIDImage::EAlpha].iColorMode = aMode.iPrimaryMode;
+ if (aMode.iPrimaryMode == EColor16MA)
+ {
+ iImageTypeArray[MMIDImage::EAlpha].iAlphaMode = ENone;
+ iImageTypeArray[MMIDImage::EAlpha].iTransparency = ETransparencyAlphaChannel;
+ }
+ else
+ {
+ iImageTypeArray[MMIDImage::EAlpha].iAlphaMode = EGray256;
+ iImageTypeArray[MMIDImage::EAlpha].iTransparency = ETransparencyAlphaBitmap;
+ }
+
+ iConfig.iGraphicsMode = aMode;
+
+#ifdef __WINS__
+ iConfig.iUpdateRequired = ETrue;
+#endif
+}
+
+TImageType CMIDGraphicsFactory::MutableImageType() const
+{
+ return iImageTypeArray[MMIDImage::ENone];
+}
+
+TBool ValidGraphicsMode(const TGraphicsMode& aMode)
+{
+ if (aMode.iPrimaryMode == EColor16MA)
+ {
+ if (aMode.iTransparencyMode != ENone)
+ {
+ return EFalse;
+ }
+ }
+ else
+ {
+ // transparency alpha mode must be EGray2 or matched mode.
+ if ((aMode.iTransparencyMode != EGray2) && (aMode.iTransparencyMode != aMode.iPrimaryMode))
+ {
+ return EFalse;
+ }
+ }
+
+ return ETrue;
+}
+
+TBool IsAlpha(CFbsBitmap* aBitmap)
+{
+ TBool alpha = EFalse;
+
+ if (aBitmap->DisplayMode() == 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 ];
+}