os/graphics/graphicsdeviceinterface/screendriver/sbit/BMDRAW.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include "BMDRAW.H"
sl@0
    17
#include "BitDrawInterfaceId.h"
sl@0
    18
sl@0
    19
GLDEF_C void Panic(TScreenDriverPanic aPanicCode)
sl@0
    20
	{
sl@0
    21
	_LIT(KSCDVPanicCategory,"SCDV");
sl@0
    22
	User::Panic(KSCDVPanicCategory,aPanicCode);
sl@0
    23
	}
sl@0
    24
sl@0
    25
sl@0
    26
/**
sl@0
    27
Alphablends a pixel.
sl@0
    28
The formula used for that, is:
sl@0
    29
(aPrimary * aAlphaValue + aSecondary * (255 - aAlphaValue)) / 255 - for each color (R,G,B).
sl@0
    30
@param aPrimary RGB color 1.
sl@0
    31
@param aSecondary RGB color 2.
sl@0
    32
@param aAlphaValue Mask.
sl@0
    33
@return Alpha blended value.
sl@0
    34
@internalComponent
sl@0
    35
*/
sl@0
    36
TRgb AlphaBlend(TRgb aPrimary, TRgb aSecondary, TInt aAlphaValue)
sl@0
    37
    {
sl@0
    38
    return ::AlphaBlend(aPrimary.Red(), aPrimary.Green(), aPrimary.Blue(), aSecondary, aAlphaValue);
sl@0
    39
    }
sl@0
    40
sl@0
    41
GLREF_D const TUint8 ditherlutab[16][4];
sl@0
    42
sl@0
    43
const TInt8 xIncArray[4] = { 1, 0, -1, 0 };
sl@0
    44
const TInt8 yIncArray[4] = { 0, 1, 0, -1 };
sl@0
    45
sl@0
    46
static CFbsDrawDevice* CreateBitmapDeviceL(const TSize& aSize, TDisplayMode aDispMode, TInt aDataStride)
sl@0
    47
	{
sl@0
    48
	CFbsDrawDevice* drawDevice = NULL;
sl@0
    49
sl@0
    50
	switch(aDispMode)
sl@0
    51
		{
sl@0
    52
	case EGray2:
sl@0
    53
		drawDevice = new(ELeave) CDrawOneBppBitmap;
sl@0
    54
		CleanupStack::PushL(drawDevice);
sl@0
    55
		User::LeaveIfError(((CDrawOneBppBitmap*)drawDevice)->Construct(aSize, aDataStride));
sl@0
    56
		break;
sl@0
    57
	case EGray4:
sl@0
    58
		drawDevice = new(ELeave) CDrawTwoBppBitmap;
sl@0
    59
		CleanupStack::PushL(drawDevice);
sl@0
    60
		User::LeaveIfError(((CDrawTwoBppBitmap*)drawDevice)->Construct(aSize, aDataStride));
sl@0
    61
		break;
sl@0
    62
	case EGray16:
sl@0
    63
		drawDevice = new(ELeave) CDrawFourBppBitmapGray;
sl@0
    64
		CleanupStack::PushL(drawDevice);
sl@0
    65
		User::LeaveIfError(((CDrawFourBppBitmapGray*)drawDevice)->Construct(aSize, aDataStride));
sl@0
    66
		break;
sl@0
    67
	case EGray256:
sl@0
    68
		drawDevice = new(ELeave) CDrawEightBppBitmapGray;
sl@0
    69
		CleanupStack::PushL(drawDevice);
sl@0
    70
		User::LeaveIfError(((CDrawEightBppBitmapGray*)drawDevice)->Construct(aSize, aDataStride));
sl@0
    71
		break;
sl@0
    72
	case EColor16:
sl@0
    73
		drawDevice = new(ELeave) CDrawFourBppBitmapColor;
sl@0
    74
		CleanupStack::PushL(drawDevice);
sl@0
    75
		User::LeaveIfError(((CDrawFourBppBitmapColor*)drawDevice)->Construct(aSize, aDataStride));
sl@0
    76
		break;
sl@0
    77
	case EColor256:
sl@0
    78
		drawDevice = new(ELeave) CDrawEightBppBitmapColor;
sl@0
    79
		CleanupStack::PushL(drawDevice);
sl@0
    80
		User::LeaveIfError(((CDrawEightBppBitmapColor*)drawDevice)->Construct(aSize, aDataStride));
sl@0
    81
		break;
sl@0
    82
	case EColor4K:
sl@0
    83
		drawDevice = new(ELeave) CDrawTwelveBppBitmap;
sl@0
    84
		CleanupStack::PushL(drawDevice);
sl@0
    85
		User::LeaveIfError(((CDrawTwelveBppBitmap*)drawDevice)->Construct(aSize, aDataStride));
sl@0
    86
		break;
sl@0
    87
	case EColor64K:
sl@0
    88
		drawDevice = new(ELeave) CDrawSixteenBppBitmap;
sl@0
    89
		CleanupStack::PushL(drawDevice);
sl@0
    90
		User::LeaveIfError(((CDrawSixteenBppBitmap*)drawDevice)->Construct(aSize, aDataStride));
sl@0
    91
		break;
sl@0
    92
	case EColor16M:
sl@0
    93
		drawDevice = new(ELeave) CDrawTwentyFourBppBitmap;
sl@0
    94
		CleanupStack::PushL(drawDevice);
sl@0
    95
		User::LeaveIfError(((CDrawTwentyFourBppBitmap*)drawDevice)->Construct(aSize, aDataStride));
sl@0
    96
		break;
sl@0
    97
	case EColor16MU:
sl@0
    98
		drawDevice = new(ELeave) CDrawUTwentyFourBppBitmap;
sl@0
    99
		CleanupStack::PushL(drawDevice);
sl@0
   100
		User::LeaveIfError(((CDrawUTwentyFourBppBitmap*)drawDevice)->Construct(aSize, aDataStride));
sl@0
   101
		break;
sl@0
   102
	case EColor16MA:
sl@0
   103
		drawDevice = new(ELeave) CDrawThirtyTwoBppBitmapAlpha;
sl@0
   104
		CleanupStack::PushL(drawDevice);
sl@0
   105
		User::LeaveIfError(((CDrawThirtyTwoBppBitmapAlpha*)drawDevice)->Construct(aSize, aDataStride));
sl@0
   106
		break;
sl@0
   107
	case EColor16MAP:
sl@0
   108
		drawDevice = new(ELeave) CDrawThirtyTwoBppBitmapAlphaPM;
sl@0
   109
		CleanupStack::PushL(drawDevice);
sl@0
   110
		User::LeaveIfError(((CDrawThirtyTwoBppBitmapAlphaPM*)drawDevice)->Construct(aSize, aDataStride));
sl@0
   111
		break;
sl@0
   112
	default:
sl@0
   113
		Panic(EScreenDriverPanicInvalidDisplayMode);
sl@0
   114
		}
sl@0
   115
	CleanupStack::Pop(drawDevice); // drawDevice
sl@0
   116
	return drawDevice;
sl@0
   117
	}
sl@0
   118
sl@0
   119
/**
sl@0
   120
@deprecated Use NewBitmapDeviceL(const TSize& aSize, TDisplayMode aDispMode, TInt aDataStride)
sl@0
   121
*/
sl@0
   122
EXPORT_C CFbsDrawDevice* CFbsDrawDevice::NewBitmapDeviceL(TScreenInfoV01 aInfo,
sl@0
   123
														  TDisplayMode aDispMode,
sl@0
   124
														  TInt aDataStride)
sl@0
   125
	{
sl@0
   126
	return ::CreateBitmapDeviceL(aInfo.iScreenSize, aDispMode, aDataStride);
sl@0
   127
	}
sl@0
   128
sl@0
   129
/**
sl@0
   130
Creates a new bitmap device instance, which implements CFbsDrawDevice interface.
sl@0
   131
@param aSize Bitmap device size
sl@0
   132
@param aDispMode Requested display mode
sl@0
   133
@return A pointer to just created bitmap device, which implements CFbsDrawDevice interface
sl@0
   134
@leave KErrNoMemory Not enough memory
sl@0
   135
       KErrArgument Invalid aSize value
sl@0
   136
*/
sl@0
   137
EXPORT_C CFbsDrawDevice* CFbsDrawDevice::NewBitmapDeviceL(const TSize& aSize,
sl@0
   138
														  TDisplayMode aDispMode,
sl@0
   139
														  TInt aDataStride)
sl@0
   140
	{
sl@0
   141
	return ::CreateBitmapDeviceL(aSize, aDispMode, aDataStride);
sl@0
   142
	}
sl@0
   143
sl@0
   144
//Logical coordinates will be initialized with the right values, when SetSize() is called.
sl@0
   145
CDrawBitmap::CDrawBitmap()
sl@0
   146
	{
sl@0
   147
	SetDefaults();
sl@0
   148
	TInt err = GetInterface(KAlphaBlendInterfaceID, reinterpret_cast <TAny*&> (iAlphaBlend));
sl@0
   149
    //There must be a support for an interface with KAlphaBlendInterfaceID id.
sl@0
   150
    __ASSERT_ALWAYS(iAlphaBlend && err == KErrNone, User::Invariant());
sl@0
   151
	}
sl@0
   152
sl@0
   153
//Scanline width in pixels.
sl@0
   154
//The return value can be greater or equal than iSize.iWidth, because
sl@0
   155
//the scan line memory is allocated in 32-bit words and can be rounded up, if
sl@0
   156
//the display mode allows more than 1 pixel to be stored in a single byte.
sl@0
   157
TInt CDrawBitmap::LongWidth() const
sl@0
   158
	{
sl@0
   159
	//0 or 180 dgrees
sl@0
   160
	if(!(iOrientation & 1))
sl@0
   161
		{
sl@0
   162
		return iLongWidth;
sl@0
   163
		}
sl@0
   164
	//90 or 270 degrees
sl@0
   165
	return iSize.iWidth == 0 ? 0 : iLongWidth * iSize.iHeight / iSize.iWidth;
sl@0
   166
	}
sl@0
   167
sl@0
   168
TUint32* CDrawBitmap::ScanLineBuffer() const
sl@0
   169
	{
sl@0
   170
	return iScanLineBuffer;
sl@0
   171
	}
sl@0
   172
sl@0
   173
//Scanline width in bytes
sl@0
   174
TInt CDrawBitmap::ScanLineBytes() const
sl@0
   175
	{
sl@0
   176
	register TInt scanLineBytes = iScanLineWords << 2;
sl@0
   177
	//90 or 270 degrees
sl@0
   178
	if(iOrientation & 1)
sl@0
   179
		{
sl@0
   180
		return iSize.iWidth == 0 ? 0 : scanLineBytes * iSize.iHeight / iSize.iWidth;
sl@0
   181
		}
sl@0
   182
	//0 or 180 degrees
sl@0
   183
	return scanLineBytes;
sl@0
   184
	}
sl@0
   185
sl@0
   186
/**
sl@0
   187
The method returns screen size in pixels. The orientation is taken into account.
sl@0
   188
Always prefer GetDrawRect() to SizeInPixels() call.
sl@0
   189
GetDrawRect() will take into account possible non-[0,0] top-left corner of the drawing
sl@0
   190
rectangle if the device is scaled.
sl@0
   191
@return TSize Screen size in pixels
sl@0
   192
*/
sl@0
   193
TSize CDrawBitmap::SizeInPixels() const
sl@0
   194
	{
sl@0
   195
	//90 or 270 degrees
sl@0
   196
	if(iOrientation & 1)
sl@0
   197
		{
sl@0
   198
		return TSize(iDrawRect.Height(), iDrawRect.Width());
sl@0
   199
		}
sl@0
   200
	//0 or 180 degrees
sl@0
   201
	return iDrawRect.Size();
sl@0
   202
	}
sl@0
   203
sl@0
   204
//aPoint - logical coordinates
sl@0
   205
void CDrawBitmap::SetDitherOrigin(const TPoint& aPoint)
sl@0
   206
	{
sl@0
   207
	if (iOrientation&1)
sl@0
   208
		{
sl@0
   209
		iDitherOrigin.iX = ::Log2Phys(aPoint.iX,iOrigin.iX,iScalingSettings.iFactorY,iSize.iHeight);
sl@0
   210
		iDitherOrigin.iY = ::Log2Phys(aPoint.iY,iOrigin.iY,iScalingSettings.iFactorX,iSize.iWidth);
sl@0
   211
		}
sl@0
   212
	else
sl@0
   213
		{
sl@0
   214
		iDitherOrigin.iX = ::Log2Phys(aPoint.iX,iOrigin.iX,iScalingSettings.iFactorX,iSize.iWidth);
sl@0
   215
		iDitherOrigin.iY = ::Log2Phys(aPoint.iY,iOrigin.iY,iScalingSettings.iFactorY,iSize.iHeight);
sl@0
   216
		}
sl@0
   217
	}
sl@0
   218
sl@0
   219
TInt CDrawBitmap::BitsPerPixel(TDisplayMode aDispMode)
sl@0
   220
	{
sl@0
   221
	switch(aDispMode)
sl@0
   222
		{
sl@0
   223
	case EGray2:
sl@0
   224
		return 1;
sl@0
   225
	case EGray4:
sl@0
   226
		return 2;
sl@0
   227
	case EGray16:
sl@0
   228
	case EColor16:
sl@0
   229
		return 4;
sl@0
   230
	case EGray256:
sl@0
   231
	case EColor256:
sl@0
   232
		return 8;
sl@0
   233
	case EColor4K:
sl@0
   234
	case EColor64K:
sl@0
   235
		return 16;
sl@0
   236
	case EColor16M:
sl@0
   237
		return 24;
sl@0
   238
	case EColor16MU:
sl@0
   239
	case EColor16MA:
sl@0
   240
	case EColor16MAP:
sl@0
   241
		return 32;
sl@0
   242
	default:
sl@0
   243
		return 0;
sl@0
   244
		}
sl@0
   245
	}
sl@0
   246
sl@0
   247
void CDrawBitmap::OrientationsAvailable(TBool aOrientation[4])
sl@0
   248
	{
sl@0
   249
	aOrientation[EOrientationNormal] = ETrue;
sl@0
   250
	aOrientation[EOrientationRotated90] = EFalse;
sl@0
   251
	aOrientation[EOrientationRotated180] = EFalse;
sl@0
   252
	aOrientation[EOrientationRotated270] = EFalse;
sl@0
   253
	}
sl@0
   254
sl@0
   255
//Works with logical coordinates
sl@0
   256
void CDrawBitmap::Clear()
sl@0
   257
	{
sl@0
   258
	if(iBits)
sl@0
   259
		{
sl@0
   260
		if(iScalingOff && iOriginIsZero)
sl@0
   261
			{
sl@0
   262
			Mem::Fill(iBits, iScanLineWords * 4 * iSize.iHeight, 0xFF);
sl@0
   263
			}
sl@0
   264
		else
sl@0
   265
			{
sl@0
   266
			TShadowMode storedShadowMode = iShadowMode;
sl@0
   267
			iShadowMode = ENoShadow;
sl@0
   268
			TRect drawRect;
sl@0
   269
			GetDrawRect(drawRect);
sl@0
   270
			WriteRgbMulti(drawRect.iTl.iX, drawRect.iTl.iY, drawRect.Width(), drawRect.Height(), KRgbWhite, CGraphicsContext::EDrawModeWriteAlpha);
sl@0
   271
			iShadowMode = storedShadowMode;
sl@0
   272
			}
sl@0
   273
		}
sl@0
   274
	}
sl@0
   275
sl@0
   276
CDrawBitmap::~CDrawBitmap()
sl@0
   277
	{
sl@0
   278
	if(iScanLineBuffer)
sl@0
   279
		{
sl@0
   280
		User::Free(iScanLineBuffer);
sl@0
   281
		}
sl@0
   282
	}
sl@0
   283
sl@0
   284
//Works with logical sizes
sl@0
   285
//The new device will accept old device scalling&scaling settings
sl@0
   286
//All graphics contexts, already created by the scaled device, should be
sl@0
   287
//re-activated calling CFbsBitGc::Activate().
sl@0
   288
void CDrawBitmap::CopyOldSettings(CFbsDrawDevice* aDrawDevice)
sl@0
   289
	{
sl@0
   290
	__ASSERT_DEBUG(aDrawDevice, User::Invariant());
sl@0
   291
	//Scaling&Origin settings - their values when scaling&origin are off.
sl@0
   292
	const TPoint KDefaultOrigin(0, 0);
sl@0
   293
	const TInt KDefaultFactorX = 1, KDefaultFactorY = 1;
sl@0
   294
	const TInt KDefaultDivisorX = 1, KDefaultDivisorY = 1;
sl@0
   295
	TPoint origin = KDefaultOrigin;//old device origin
sl@0
   296
	TInt factorX = KDefaultFactorX, factorY = KDefaultFactorY;//old device - X and Y scaling factors
sl@0
   297
	TInt divisorX = KDefaultDivisorX, divisorY = KDefaultDivisorY;//old device - X and Y scaling divisors
sl@0
   298
	//Old device - set default scaling setings.
sl@0
   299
	MScalingSettings* scalingSettings = NULL;
sl@0
   300
	TInt err = aDrawDevice->GetInterface(KScalingSettingsInterfaceID, reinterpret_cast <TAny*&> (scalingSettings));
sl@0
   301
	if(err == KErrNone)
sl@0
   302
		{//There is a support for the interface with KScalingSettingsInterfaceID id.
sl@0
   303
		__ASSERT_DEBUG(scalingSettings, User::Invariant());
sl@0
   304
		scalingSettings->Get(factorX, factorY, divisorX, divisorY);
sl@0
   305
		(void)scalingSettings->Set(KDefaultFactorX, KDefaultFactorY, KDefaultDivisorX, KDefaultDivisorY);
sl@0
   306
		}
sl@0
   307
	//Current device - set default scaling setings.
sl@0
   308
	if(CanBeScaled())
sl@0
   309
		{
sl@0
   310
		(void)Set(KDefaultFactorX, KDefaultFactorY, KDefaultDivisorX, KDefaultDivisorY);
sl@0
   311
		}
sl@0
   312
	//Old device - set default origin.
sl@0
   313
	MDrawDeviceOrigin* originInterface = NULL;
sl@0
   314
	err = aDrawDevice->GetInterface(KDrawDeviceOriginInterfaceID, reinterpret_cast <TAny*&> (originInterface));
sl@0
   315
	if(err == KErrNone)
sl@0
   316
		{//There is a support for the interface with KDrawDeviceOriginInterfaceID id.
sl@0
   317
		__ASSERT_DEBUG(originInterface, User::Invariant());
sl@0
   318
		originInterface->Get(origin);
sl@0
   319
		(void)originInterface->Set(KDefaultOrigin);
sl@0
   320
		}
sl@0
   321
	//Current device - set default origin.
sl@0
   322
	if(CanOriginBeMoved())
sl@0
   323
		{
sl@0
   324
		(void)Set(KDefaultOrigin);
sl@0
   325
		}
sl@0
   326
	//Copy setigns
sl@0
   327
	DoCopyOldSettings(aDrawDevice);
sl@0
   328
	//Old device - restore scaling setings.
sl@0
   329
	if(scalingSettings)
sl@0
   330
		{
sl@0
   331
		(void)scalingSettings->Set(factorX, factorY, divisorX, divisorY);
sl@0
   332
		}
sl@0
   333
	//Old device - restore origin.
sl@0
   334
	if(originInterface)
sl@0
   335
		{
sl@0
   336
		(void)originInterface->Set(origin);
sl@0
   337
		}
sl@0
   338
	//Set current device scaling&origin settings to be the same as
sl@0
   339
	//scaling&origin settings of the old device.
sl@0
   340
	if(CanBeScaled())
sl@0
   341
		{
sl@0
   342
		(void)Set(factorX, factorY, divisorX, divisorY);
sl@0
   343
		}
sl@0
   344
	if(CanOriginBeMoved())
sl@0
   345
		{
sl@0
   346
		(void)Set(origin);
sl@0
   347
		}
sl@0
   348
	}
sl@0
   349
sl@0
   350
void CDrawBitmap::DoCopyOldSettings(CFbsDrawDevice* aDrawDevice)
sl@0
   351
	{
sl@0
   352
	CDrawBitmap* oldDevice = (CDrawBitmap*)aDrawDevice;
sl@0
   353
	iDitherOrigin = oldDevice->iDitherOrigin;
sl@0
   354
	iShadowMode = oldDevice->iShadowMode;
sl@0
   355
	SetOrientation(oldDevice->iOrientation);
sl@0
   356
	iFadeMapFactor = oldDevice->iFadeMapFactor;
sl@0
   357
	iFadeMapOffset = oldDevice->iFadeMapOffset;
sl@0
   358
sl@0
   359
	TUint32* destRowPtr = iBits;
sl@0
   360
	TUint32* destRowPtrLimit = iBits;
sl@0
   361
	TInt destRowPtrInc = iScanLineWords;
sl@0
   362
sl@0
   363
	TInt row = 0;
sl@0
   364
	TInt rowInc = 1;
sl@0
   365
sl@0
   366
	if (BitsPerPixel(oldDevice->iDispMode) < BitsPerPixel(iDispMode))
sl@0
   367
		{
sl@0
   368
		destRowPtr += (iSize.iHeight - 1) * iScanLineWords;
sl@0
   369
		destRowPtrInc = -destRowPtrInc;
sl@0
   370
		destRowPtrLimit -= iScanLineWords;
sl@0
   371
		row = iSize.iHeight - 1;
sl@0
   372
		rowInc = -1;
sl@0
   373
		}
sl@0
   374
	else
sl@0
   375
		destRowPtrLimit += iSize.iHeight * iScanLineWords;
sl@0
   376
sl@0
   377
	TOrientation oldOrientation=oldDevice->iOrientation;
sl@0
   378
	oldDevice->SetOrientation(CFbsDrawDevice::EOrientationNormal);
sl@0
   379
	while (destRowPtr != destRowPtrLimit)
sl@0
   380
		{
sl@0
   381
		aDrawDevice->ReadLine(0,row,iSize.iWidth,iScanLineBuffer,iDispMode);
sl@0
   382
		Mem::Copy(destRowPtr,iScanLineBuffer,iScanLineWords << 2);
sl@0
   383
		destRowPtr += destRowPtrInc;
sl@0
   384
		row += rowInc;
sl@0
   385
		}
sl@0
   386
sl@0
   387
	oldDevice->SetOrientation(oldOrientation);
sl@0
   388
	UpdateRegion(TRect(SizeInPixels()));
sl@0
   389
	Update();
sl@0
   390
	}
sl@0
   391
sl@0
   392
TUint32 CDrawBitmap::Hash(TUint32 aGray16,TInt aX,TInt aY) const
sl@0
   393
	{
sl@0
   394
	if (iDitherOrigin.iX & 1)
sl@0
   395
		aX++;
sl@0
   396
	if (iDitherOrigin.iY & 1)
sl@0
   397
		aY++;
sl@0
   398
	aX &= 1;
sl@0
   399
	aY &= 1;
sl@0
   400
	return ditherlutab[aGray16][aX + (aY << 1)];
sl@0
   401
	}
sl@0
   402
sl@0
   403
//aRect - logical coordinates
sl@0
   404
void CDrawBitmap::MapColors(const TRect& aRect, const TRgb* aColors,
sl@0
   405
							TInt aNumPairs, TBool aMapForwards)
sl@0
   406
	{
sl@0
   407
	const TRect rect = DeOrientate(aRect);//deorientation and transformation of coordinates.
sl@0
   408
	//rect - physical coordinates
sl@0
   409
	__ASSERT_DEBUG(rect.iTl.iX >= 0 && rect.iBr.iX <= iSize.iWidth,Panic(EScreenDriverPanicOutOfBounds));
sl@0
   410
	__ASSERT_DEBUG(rect.iTl.iY >= 0 && rect.iBr.iY <= iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds));
sl@0
   411
	__ASSERT_DEBUG(aColors,Panic(EScreenDriverPanicNullPointer));
sl@0
   412
	__ASSERT_DEBUG(aNumPairs > 0,Panic(EScreenDriverPanicZeroLength));
sl@0
   413
sl@0
   414
	TRgb color;
sl@0
   415
sl@0
   416
	TInt offset = aMapForwards ? 0 : 1;
sl@0
   417
	TInt scaleX;
sl@0
   418
	TInt scaleY;
sl@0
   419
	if (iOrientation&1)
sl@0
   420
		{
sl@0
   421
		scaleX=iScalingSettings.iFactorY;
sl@0
   422
		scaleY=iScalingSettings.iFactorX;
sl@0
   423
		}
sl@0
   424
	else
sl@0
   425
		{
sl@0
   426
		scaleX=iScalingSettings.iFactorX;
sl@0
   427
		scaleY=iScalingSettings.iFactorY;
sl@0
   428
		}
sl@0
   429
	for(TInt ycoord = rect.iTl.iY; ycoord < rect.iBr.iY; ycoord+=scaleY)
sl@0
   430
		{
sl@0
   431
		for(TInt xcoord = rect.iTl.iX; xcoord < rect.iBr.iX; xcoord+=scaleX)
sl@0
   432
			{
sl@0
   433
			color = ReadRgbNormal(xcoord,ycoord);
sl@0
   434
			for (TInt rgbcount = 0; rgbcount < aNumPairs; rgbcount++)
sl@0
   435
				{
sl@0
   436
				if (color == aColors[(rgbcount << 1) + offset])
sl@0
   437
					{
sl@0
   438
					WriteRgb(xcoord,ycoord,aColors[(rgbcount << 1) + 1 - offset]);
sl@0
   439
					break;
sl@0
   440
					}
sl@0
   441
				}
sl@0
   442
			}
sl@0
   443
		}
sl@0
   444
	}
sl@0
   445
sl@0
   446
//form an int from the end portion of one and the start portion of another
sl@0
   447
TUint32 CDrawBitmap::PasteInt(TUint32 aFirst,TUint32 aSecond,TInt aOffset) const
sl@0
   448
	{
sl@0
   449
	TUint32 mask=0;
sl@0
   450
	if(aOffset<32) mask=0xffffffff>>aOffset;
sl@0
   451
	aFirst&=mask;
sl@0
   452
	aSecond&=~mask;
sl@0
   453
	return(aFirst|aSecond);
sl@0
   454
	}
sl@0
   455
sl@0
   456
//returns the address of the start of scanline aY
sl@0
   457
//aY- physical coordinate
sl@0
   458
TUint32* CDrawBitmap::ScanLine(TInt aY) const
sl@0
   459
	{
sl@0
   460
	return iBits + (aY * iScanLineWords);
sl@0
   461
	}
sl@0
   462
sl@0
   463
void CDrawBitmap::SetBits(TAny* aBits)
sl@0
   464
	{
sl@0
   465
	iBits = STATIC_CAST(TUint32*,aBits);
sl@0
   466
	}
sl@0
   467
sl@0
   468
TBool CDrawBitmap::SetOrientation(TOrientation aOrientation)
sl@0
   469
	{
sl@0
   470
	if (iOrientation == aOrientation)
sl@0
   471
		return ETrue;
sl@0
   472
sl@0
   473
	return EFalse;
sl@0
   474
	}
sl@0
   475
sl@0
   476
void CDrawBitmap::SetFadingParameters(TUint8 aBlackMap,TUint8 aWhiteMap)
sl@0
   477
	{
sl@0
   478
	iFadeMapFactor = aWhiteMap - aBlackMap + 1;
sl@0
   479
	iFadeMapOffset = aBlackMap;
sl@0
   480
	}
sl@0
   481
sl@0
   482
TRgb CDrawBitmap::FadeRgb(TRgb aColor)
sl@0
   483
	{
sl@0
   484
	TInt value = aColor.Internal();
sl@0
   485
	TInt b = (((value & 0x000000ff) * iFadeMapFactor) >> 8)  + iFadeMapOffset;
sl@0
   486
	TInt g = (((value & 0x0000ff00) * iFadeMapFactor) >> 16) + iFadeMapOffset;
sl@0
   487
	//the multiplication by iFadeMapFactor can overflow into the sign bit, so we shift down in two steps
sl@0
   488
	TInt r = ((((value & 0x00ff0000) >> 16) * iFadeMapFactor) >> 8) + iFadeMapOffset;
sl@0
   489
	TInt a = aColor.Alpha();
sl@0
   490
  	return TRgb(r,g,b,a);
sl@0
   491
	}
sl@0
   492
sl@0
   493
 TUint32 CDrawBitmap::FadeRgb(TUint32 aColor)
sl@0
   494
  	{
sl@0
   495
  	TInt value = aColor;
sl@0
   496
sl@0
   497
  	TInt b = (((value & 0x000000ff) * iFadeMapFactor) >> 8)  + iFadeMapOffset;
sl@0
   498
   	TInt g = (((value & 0x0000ff00) * iFadeMapFactor) >> 16) + iFadeMapOffset;
sl@0
   499
  	//the multiplication by iFadeMapFactor can overflow into the sign bit, so we shift down in two steps
sl@0
   500
   	TInt r = ((((value & 0x00ff0000) >> 16) * iFadeMapFactor) >> 8) + iFadeMapOffset;
sl@0
   501
   	TInt a = aColor >> 24;
sl@0
   502
   	return (a<<24) | ((r&0xff)<<16) | ((g&0xff)<<8) | (b&0xff);
sl@0
   503
    }
sl@0
   504
sl@0
   505
/**
sl@0
   506
The overloaded function for FadeRgb(TRgb) which works directly with
sl@0
   507
the Red, Green and Blue colour components to increase the performance.
sl@0
   508
@param aRed Red component of colour.
sl@0
   509
@param aGreen Green component of colour.
sl@0
   510
@param aBlue Blue component of colour.
sl@0
   511
*/
sl@0
   512
void CDrawBitmap::FadeRgb(TInt& aRed, TInt& aGreen, TInt& aBlue)
sl@0
   513
	{
sl@0
   514
	aRed = ((aRed * iFadeMapFactor) >> 8)  + iFadeMapOffset;
sl@0
   515
	aGreen = ((aGreen * iFadeMapFactor) >> 8)  + iFadeMapOffset;
sl@0
   516
	aBlue = ((aBlue * iFadeMapFactor) >> 8)  + iFadeMapOffset;
sl@0
   517
	}
sl@0
   518
sl@0
   519
TUint8 CDrawBitmap::FadeGray(TInt aGray256)
sl@0
   520
	{
sl@0
   521
	return STATIC_CAST(TUint8,((aGray256 * iFadeMapFactor) >> 8) + iFadeMapOffset);
sl@0
   522
	}
sl@0
   523
sl@0
   524
//aX and aY - logical coordinates
sl@0
   525
//aX and aY - deorientated and transformed to physical coordinates after the call
sl@0
   526
void CDrawBitmap::DeOrientate(TInt& aX,TInt& aY) const
sl@0
   527
	{
sl@0
   528
	register TInt physWidth = iSize.iWidth;
sl@0
   529
	register TInt physHeight = iSize.iHeight;
sl@0
   530
	register TInt originX = iOrigin.iX;
sl@0
   531
	register TInt originY = iOrigin.iY;
sl@0
   532
	register TInt scalingFactorX = iScalingSettings.iFactorX;
sl@0
   533
	register TInt scalingFactorY = iScalingSettings.iFactorY;
sl@0
   534
	if(iOrientation & 0x1)
sl@0
   535
		{
sl@0
   536
		aX = ::Log2Phys(aX, originX, scalingFactorY, physHeight);
sl@0
   537
		aY = ::Log2Phys(aY, originY, scalingFactorX, physWidth);
sl@0
   538
		}
sl@0
   539
	else
sl@0
   540
		{
sl@0
   541
		aX = ::Log2Phys(aX, originX, scalingFactorX, physWidth);
sl@0
   542
		aY = ::Log2Phys(aY, originY, scalingFactorY, physHeight);
sl@0
   543
		}
sl@0
   544
sl@0
   545
	//aX and aY - descaled.
sl@0
   546
	switch(iOrientation)
sl@0
   547
		{
sl@0
   548
		case EOrientationNormal:
sl@0
   549
			{
sl@0
   550
			return;
sl@0
   551
			}
sl@0
   552
		case EOrientationRotated180:
sl@0
   553
			{
sl@0
   554
			aX = physWidth - aX - 1;
sl@0
   555
			aY = physHeight - aY - 1;
sl@0
   556
			break;
sl@0
   557
			}
sl@0
   558
			case EOrientationRotated90:
sl@0
   559
			{
sl@0
   560
			TInt temp = physWidth - aY - 1;
sl@0
   561
			aY = aX;
sl@0
   562
			aX = temp;
sl@0
   563
			break;
sl@0
   564
			}
sl@0
   565
		default: // EOrientationRotated270
sl@0
   566
			{
sl@0
   567
			TInt temp = aY;
sl@0
   568
			aY = physHeight - aX - 1;
sl@0
   569
			aX = temp;
sl@0
   570
			}
sl@0
   571
		}
sl@0
   572
	}
sl@0
   573
sl@0
   574
//aPoint - logical coordinates
sl@0
   575
//The method returns TPoint object with deorientated and transformed to physical coordinates.
sl@0
   576
TPoint CDrawBitmap::DeOrientate(const TPoint& aPoint) const
sl@0
   577
	{
sl@0
   578
	register TInt physWidth = iSize.iWidth;
sl@0
   579
	register TInt physHeight = iSize.iHeight;
sl@0
   580
	register TInt originX = iOrigin.iX;
sl@0
   581
	register TInt originY = iOrigin.iY;
sl@0
   582
	register TInt scalingFactorX = iScalingSettings.iFactorX;
sl@0
   583
	register TInt scalingFactorY = iScalingSettings.iFactorY;
sl@0
   584
	TPoint physPt;
sl@0
   585
	if(iOrientation & 0x1)
sl@0
   586
		{
sl@0
   587
		physPt.iX = ::Log2Phys(aPoint.iX, originX, scalingFactorY, physHeight);
sl@0
   588
		physPt.iY = ::Log2Phys(aPoint.iY, originY, scalingFactorX, physWidth);
sl@0
   589
		}
sl@0
   590
	else
sl@0
   591
		{
sl@0
   592
		physPt.iX = ::Log2Phys(aPoint.iX, originX, scalingFactorX, physWidth);
sl@0
   593
		physPt.iY = ::Log2Phys(aPoint.iY, originY, scalingFactorY, physHeight);
sl@0
   594
		}
sl@0
   595
sl@0
   596
	//physPt - descaled
sl@0
   597
	switch(iOrientation)
sl@0
   598
		{
sl@0
   599
		case EOrientationNormal:
sl@0
   600
			{
sl@0
   601
			return physPt;
sl@0
   602
			}
sl@0
   603
		case EOrientationRotated180:
sl@0
   604
			{
sl@0
   605
			return TPoint(physWidth - physPt.iX - 1, physHeight - physPt.iY - 1);
sl@0
   606
			}
sl@0
   607
		case EOrientationRotated90:
sl@0
   608
			{
sl@0
   609
			return TPoint(physWidth - physPt.iY - 1, physPt.iX);
sl@0
   610
			}
sl@0
   611
		// EOrientationRotated270
sl@0
   612
		default:
sl@0
   613
			return TPoint(physPt.iY, physHeight - physPt.iX - 1);
sl@0
   614
		}
sl@0
   615
	}
sl@0
   616
sl@0
   617
//aRect - logical coordinates
sl@0
   618
//The method returns TRect object with deorientated and transformed to physical coordinates.
sl@0
   619
TRect CDrawBitmap::DeOrientate(const TRect& aRect) const
sl@0
   620
	{
sl@0
   621
	register TInt originX = iOrigin.iX;
sl@0
   622
	register TInt originY = iOrigin.iY;
sl@0
   623
	register TInt scalingFactorX = iScalingSettings.iFactorX;
sl@0
   624
	register TInt scalingFactorY = iScalingSettings.iFactorY;
sl@0
   625
	register TInt physWidth = iSize.iWidth;
sl@0
   626
	register TInt physHeight = iSize.iHeight;
sl@0
   627
	TRect physRect;
sl@0
   628
	if(iOrientation & 0x1)
sl@0
   629
		{
sl@0
   630
		physRect.iTl.iX = ::Log2Phys(aRect.iTl.iX, originX, scalingFactorY, physHeight);
sl@0
   631
		physRect.iTl.iY = ::Log2Phys(aRect.iTl.iY, originY, scalingFactorX, physWidth);
sl@0
   632
		physRect.iBr.iX = ::RBtmLog2Phys(aRect.iBr.iX, originX, scalingFactorY, physHeight);
sl@0
   633
		physRect.iBr.iY = ::RBtmLog2Phys(aRect.iBr.iY, originY, scalingFactorX, physWidth);
sl@0
   634
		}
sl@0
   635
	else
sl@0
   636
		{
sl@0
   637
		physRect.iTl.iX = ::Log2Phys(aRect.iTl.iX, originX, scalingFactorX, physWidth);
sl@0
   638
		physRect.iTl.iY = ::Log2Phys(aRect.iTl.iY, originY, scalingFactorY, physHeight);
sl@0
   639
		physRect.iBr.iX = ::RBtmLog2Phys(aRect.iBr.iX, originX, scalingFactorX, physWidth);
sl@0
   640
		physRect.iBr.iY = ::RBtmLog2Phys(aRect.iBr.iY, originY, scalingFactorY, physHeight);
sl@0
   641
		}
sl@0
   642
sl@0
   643
	//physRect - descaled
sl@0
   644
	if(iOrientation == EOrientationNormal)
sl@0
   645
		{
sl@0
   646
		return physRect;
sl@0
   647
		}
sl@0
   648
	if (iOrientation == EOrientationRotated180)
sl@0
   649
		{
sl@0
   650
		return TRect(TPoint(physWidth - physRect.iBr.iX, physHeight - physRect.iBr.iY), physRect.Size());
sl@0
   651
		}
sl@0
   652
	TSize altSize(physRect.Height(), physRect.Width());
sl@0
   653
	TPoint altPoint;
sl@0
   654
	if (iOrientation == EOrientationRotated90)
sl@0
   655
		{
sl@0
   656
		altPoint.SetXY(physWidth - physRect.iBr.iY, physRect.iTl.iX);
sl@0
   657
		}
sl@0
   658
	else // EOrientationRotated270
sl@0
   659
		{
sl@0
   660
		altPoint.SetXY(physRect.iTl.iY, physHeight - physRect.iBr.iX);
sl@0
   661
		}
sl@0
   662
	return TRect(altPoint, altSize);
sl@0
   663
	}
sl@0
   664
sl@0
   665
//aX and aY - logical coordinates
sl@0
   666
TRgb CDrawBitmap::ReadPixel(TInt aX,TInt aY) const
sl@0
   667
	{
sl@0
   668
	DeOrientate(aX, aY);//aX and aY - physical coordinates
sl@0
   669
sl@0
   670
	__ASSERT_DEBUG(aX >= 0 && aX < iSize.iWidth,Panic(EScreenDriverPanicOutOfBounds));
sl@0
   671
	__ASSERT_DEBUG(aY >= 0 && aY < iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds));
sl@0
   672
sl@0
   673
	return ReadRgbNormal(aX, aY);
sl@0
   674
	}
sl@0
   675
sl@0
   676
//aX and aY - logical coordinates
sl@0
   677
void CDrawBitmap::ReadLine(TInt aX,TInt aY,TInt aLength,
sl@0
   678
						   TAny* aBuffer,TDisplayMode aDispMode) const
sl@0
   679
	{
sl@0
   680
	DeOrientate(aX,aY);//aX and aY - physical coordinates
sl@0
   681
sl@0
   682
	__ASSERT_DEBUG(aX >= 0 && aX < iSize.iWidth,Panic(EScreenDriverPanicOutOfBounds));
sl@0
   683
	__ASSERT_DEBUG(aY >= 0 && aY < iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds));
sl@0
   684
#if defined(_DEBUG)
sl@0
   685
	switch (iOrientation)
sl@0
   686
		{
sl@0
   687
	case EOrientationNormal:
sl@0
   688
		__ASSERT_DEBUG(aX + aLength <= iLongWidth,Panic(EScreenDriverPanicOutOfBounds));
sl@0
   689
		break;
sl@0
   690
	case EOrientationRotated90:
sl@0
   691
		__ASSERT_DEBUG(aY + aLength <= iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds));
sl@0
   692
		break;
sl@0
   693
	case EOrientationRotated180:
sl@0
   694
		__ASSERT_DEBUG(aX - aLength >= -1,Panic(EScreenDriverPanicOutOfBounds));
sl@0
   695
		break;
sl@0
   696
	default: // EOrientationRotated270
sl@0
   697
		__ASSERT_DEBUG(aY - aLength >= -1,Panic(EScreenDriverPanicOutOfBounds));
sl@0
   698
		break;
sl@0
   699
		}
sl@0
   700
#endif
sl@0
   701
	__ASSERT_DEBUG(aLength > 0,Panic(EScreenDriverPanicZeroLength));
sl@0
   702
	__ASSERT_DEBUG(aBuffer,Panic(EScreenDriverPanicNullPointer));
sl@0
   703
sl@0
   704
	if (aDispMode == iDispMode)
sl@0
   705
		{
sl@0
   706
		ReadLine(aX,aY,aLength,aBuffer);
sl@0
   707
		return;
sl@0
   708
		}
sl@0
   709
sl@0
   710
	TInt xInc = xIncArray[iOrientation];
sl@0
   711
	TInt yInc = yIncArray[iOrientation];
sl@0
   712
	if(iOrientation & 0x1)
sl@0
   713
		{
sl@0
   714
		xInc*=iScalingSettings.iFactorY;
sl@0
   715
		yInc*=iScalingSettings.iFactorX;
sl@0
   716
		}
sl@0
   717
	else
sl@0
   718
		{
sl@0
   719
		xInc*=iScalingSettings.iFactorX;
sl@0
   720
		yInc*=iScalingSettings.iFactorY;
sl@0
   721
		}
sl@0
   722
sl@0
   723
	switch (aDispMode)
sl@0
   724
		{
sl@0
   725
		case EGray2:
sl@0
   726
			{
sl@0
   727
			TUint8* bufferPtr = (TUint8*)aBuffer;
sl@0
   728
sl@0
   729
			while (aLength >= 8)
sl@0
   730
				{
sl@0
   731
				bufferPtr[0] = TUint8(ReadRgbNormal(aX,aY)._Gray2());
sl@0
   732
				aX += xInc; aY += yInc;
sl@0
   733
				bufferPtr[0] |= TUint8(ReadRgbNormal(aX,aY)._Gray2() << 1);
sl@0
   734
				aX += xInc; aY += yInc;
sl@0
   735
				bufferPtr[0] |= TUint8(ReadRgbNormal(aX,aY)._Gray2() << 2);
sl@0
   736
				aX += xInc; aY += yInc;
sl@0
   737
				bufferPtr[0] |= TUint8(ReadRgbNormal(aX,aY)._Gray2() << 3);
sl@0
   738
				aX += xInc; aY += yInc;
sl@0
   739
				bufferPtr[0] |= TUint8(ReadRgbNormal(aX,aY)._Gray2() << 4);
sl@0
   740
				aX += xInc; aY += yInc;
sl@0
   741
				bufferPtr[0] |= TUint8(ReadRgbNormal(aX,aY)._Gray2() << 5);
sl@0
   742
				aX += xInc; aY += yInc;
sl@0
   743
				bufferPtr[0] |= TUint8(ReadRgbNormal(aX,aY)._Gray2() << 6);
sl@0
   744
				aX += xInc; aY += yInc;
sl@0
   745
				bufferPtr[0] |= TUint8(ReadRgbNormal(aX,aY)._Gray2() << 7);
sl@0
   746
				aX += xInc; aY += yInc;
sl@0
   747
				bufferPtr++;
sl@0
   748
				aLength -= 8;
sl@0
   749
				}
sl@0
   750
			TInt bitShift = 0;
sl@0
   751
			TInt bitLimit = aLength;
sl@0
   752
			if (bitShift < bitLimit)
sl@0
   753
				bufferPtr[0] = 0;
sl@0
   754
			while (bitShift < bitLimit)
sl@0
   755
				{
sl@0
   756
				bufferPtr[0] |= TUint8(ReadRgbNormal(aX,aY)._Gray2() << bitShift);
sl@0
   757
				aX += xInc; aY += yInc;
sl@0
   758
				bitShift++;
sl@0
   759
				}
sl@0
   760
			}
sl@0
   761
			break;
sl@0
   762
		case EGray4:
sl@0
   763
			{
sl@0
   764
			TUint8* bufferPtr = REINTERPRET_CAST(TUint8*,aBuffer);
sl@0
   765
sl@0
   766
			while (aLength > 3)
sl@0
   767
				{
sl@0
   768
				*bufferPtr = TUint8(ReadRgbNormal(aX,aY)._Gray4());
sl@0
   769
				aX += xInc; aY += yInc;
sl@0
   770
				*bufferPtr |= TUint8(ReadRgbNormal(aX,aY)._Gray4() << 2);
sl@0
   771
				aX += xInc; aY += yInc;
sl@0
   772
				*bufferPtr |= TUint8(ReadRgbNormal(aX,aY)._Gray4() << 4);
sl@0
   773
				aX += xInc; aY += yInc;
sl@0
   774
				*bufferPtr++ |= TUint8(ReadRgbNormal(aX,aY)._Gray4() << 6);
sl@0
   775
				aX += xInc; aY += yInc;
sl@0
   776
				aLength -= 4;
sl@0
   777
				}
sl@0
   778
			if (aLength > 0)
sl@0
   779
				{
sl@0
   780
				*bufferPtr = TUint8(ReadRgbNormal(aX,aY)._Gray4());
sl@0
   781
				aX += xInc; aY += yInc;
sl@0
   782
				aLength--;
sl@0
   783
				}
sl@0
   784
			if (aLength > 0)
sl@0
   785
				{
sl@0
   786
				*bufferPtr |= TUint8(ReadRgbNormal(aX,aY)._Gray4() << 2);
sl@0
   787
				aX += xInc; aY += yInc;
sl@0
   788
				aLength--;
sl@0
   789
				}
sl@0
   790
			if (aLength > 0)
sl@0
   791
				*bufferPtr |= TUint8(ReadRgbNormal(aX,aY)._Gray4() << 4);
sl@0
   792
			}
sl@0
   793
			break;
sl@0
   794
		case EGray16:
sl@0
   795
			{
sl@0
   796
			TUint8* bufferPtr = (TUint8*)aBuffer;
sl@0
   797
sl@0
   798
			while (aLength > 1)
sl@0
   799
				{
sl@0
   800
				*bufferPtr = TUint8(ReadRgbNormal(aX,aY)._Gray16());
sl@0
   801
				aX += xInc; aY += yInc;
sl@0
   802
				*bufferPtr++ |= TUint8(ReadRgbNormal(aX,aY)._Gray16() << 4);
sl@0
   803
				aX += xInc; aY += yInc;
sl@0
   804
				aLength -= 2;
sl@0
   805
				}
sl@0
   806
			if (aLength > 0)
sl@0
   807
				*bufferPtr = TUint8(ReadRgbNormal(aX,aY)._Gray16());
sl@0
   808
			}
sl@0
   809
			break;
sl@0
   810
		case EGray256:
sl@0
   811
			{
sl@0
   812
			TUint8* bufferPtr = (TUint8*)aBuffer;
sl@0
   813
			const TUint8* bufferPtrLimit = bufferPtr + aLength;
sl@0
   814
sl@0
   815
			while (bufferPtr < bufferPtrLimit)
sl@0
   816
				{
sl@0
   817
				*bufferPtr++ = TUint8(ReadRgbNormal(aX,aY)._Gray256());
sl@0
   818
				aX += xInc; aY += yInc;
sl@0
   819
				}
sl@0
   820
			}
sl@0
   821
			break;
sl@0
   822
		case EColor16:
sl@0
   823
			{
sl@0
   824
			TUint8* bufferPtr = (TUint8*)aBuffer;
sl@0
   825
sl@0
   826
			while (aLength > 1)
sl@0
   827
				{
sl@0
   828
				*bufferPtr = TUint8(ReadRgbNormal(aX,aY).Color16());
sl@0
   829
				aX += xInc; aY += yInc;
sl@0
   830
				*bufferPtr++ |= TUint8(ReadRgbNormal(aX,aY).Color16() << 4);
sl@0
   831
				aX += xInc; aY += yInc;
sl@0
   832
				aLength -= 2;
sl@0
   833
				}
sl@0
   834
			if (aLength > 0)
sl@0
   835
				*bufferPtr = TUint8(ReadRgbNormal(aX,aY).Color16());
sl@0
   836
			}
sl@0
   837
			break;
sl@0
   838
		case EColor256:
sl@0
   839
			{
sl@0
   840
			TUint8* bufferPtr = (TUint8*)aBuffer;
sl@0
   841
			const TUint8* bufferPtrLimit = bufferPtr + aLength;
sl@0
   842
sl@0
   843
			while (bufferPtr < bufferPtrLimit)
sl@0
   844
				{
sl@0
   845
				*bufferPtr++ = TUint8(ReadRgbNormal(aX,aY).Color256());
sl@0
   846
				aX += xInc; aY += yInc;
sl@0
   847
				}
sl@0
   848
			}
sl@0
   849
			break;
sl@0
   850
		case EColor4K:
sl@0
   851
			{
sl@0
   852
			TUint16* bufferPtr = (TUint16*)aBuffer;
sl@0
   853
			const TUint16* bufferPtrLimit = bufferPtr + aLength;
sl@0
   854
sl@0
   855
			while (bufferPtr < bufferPtrLimit)
sl@0
   856
				{
sl@0
   857
				*bufferPtr++ = TUint16(ReadRgbNormal(aX,aY)._Color4K());
sl@0
   858
				aX += xInc; aY += yInc;
sl@0
   859
				}
sl@0
   860
			}
sl@0
   861
			break;
sl@0
   862
		case EColor64K:
sl@0
   863
			{
sl@0
   864
			TUint16* bufferPtr = (TUint16*)aBuffer;
sl@0
   865
			const TUint16* bufferPtrLimit = bufferPtr + aLength;
sl@0
   866
sl@0
   867
			while (bufferPtr < bufferPtrLimit)
sl@0
   868
				{
sl@0
   869
				*bufferPtr++ = TUint16(ReadRgbNormal(aX,aY)._Color64K());
sl@0
   870
				aX += xInc; aY += yInc;
sl@0
   871
				}
sl@0
   872
			}
sl@0
   873
			break;
sl@0
   874
		case EColor16M:
sl@0
   875
			{
sl@0
   876
			TUint8* bufferPtr = (TUint8*)aBuffer;
sl@0
   877
			const TUint8* bufferPtrLimit = bufferPtr + (aLength * 3);
sl@0
   878
sl@0
   879
			while (bufferPtr < bufferPtrLimit)
sl@0
   880
				{
sl@0
   881
				TUint32 pixelColorValue = ReadRgbNormal(aX,aY).Internal();
sl@0
   882
				aX += xInc; aY += yInc;
sl@0
   883
				bufferPtr[0] = TUint8(pixelColorValue);
sl@0
   884
				bufferPtr[1] = TUint8(pixelColorValue >> 8);
sl@0
   885
				bufferPtr[2] = TUint8(pixelColorValue >> 16);
sl@0
   886
				bufferPtr += 3;
sl@0
   887
				}
sl@0
   888
			}
sl@0
   889
			break;
sl@0
   890
		case ERgb:
sl@0
   891
			{
sl@0
   892
			TRgb* bufferPtr = (TRgb*)aBuffer;
sl@0
   893
			const TRgb* bufferPtrLimit = bufferPtr + aLength;
sl@0
   894
sl@0
   895
			while (bufferPtr < bufferPtrLimit)
sl@0
   896
				{
sl@0
   897
				*bufferPtr++ = ReadRgbNormal(aX,aY);
sl@0
   898
				aX += xInc; aY += yInc;
sl@0
   899
				}
sl@0
   900
			}
sl@0
   901
			break;
sl@0
   902
		case EColor16MU:
sl@0
   903
			{
sl@0
   904
			TUint32* bufferPtr = (TUint32*)aBuffer;
sl@0
   905
			const TUint32* bufferPtrLimit = bufferPtr + aLength;
sl@0
   906
sl@0
   907
			while (bufferPtr < bufferPtrLimit)
sl@0
   908
				{
sl@0
   909
				*bufferPtr++ = ReadRgbNormal(aX,aY)._Color16MU();//BGRA (Blue/Green/Red/Alpha) as little endian bite order
sl@0
   910
				aX += xInc; aY += yInc;
sl@0
   911
				}
sl@0
   912
			}
sl@0
   913
			break;
sl@0
   914
		case EColor16MA:
sl@0
   915
			{
sl@0
   916
			TUint32* bufferPtr = (TUint32*)aBuffer;
sl@0
   917
			const TUint32* bufferPtrLimit = bufferPtr + aLength;
sl@0
   918
sl@0
   919
			while (bufferPtr < bufferPtrLimit)
sl@0
   920
				{
sl@0
   921
				*bufferPtr++ = ReadRgbNormal(aX,aY)._Color16MA();//BGRA (Blue/Green/Red/Alpha) as little endian bite order
sl@0
   922
				aX += xInc; aY += yInc;
sl@0
   923
				}
sl@0
   924
			}
sl@0
   925
			break;
sl@0
   926
		case EColor16MAP:
sl@0
   927
			{
sl@0
   928
			TUint32* bufferPtr = (TUint32*)aBuffer;
sl@0
   929
			const TUint32* bufferPtrLimit = bufferPtr + aLength;
sl@0
   930
sl@0
   931
			while (bufferPtr < bufferPtrLimit)
sl@0
   932
				{
sl@0
   933
				*bufferPtr++ = ReadRgbNormal(aX,aY)._Color16MAP();;
sl@0
   934
				aX += xInc; aY += yInc;
sl@0
   935
				}
sl@0
   936
			}
sl@0
   937
			break;
sl@0
   938
		default:
sl@0
   939
			Panic(EScreenDriverPanicInvalidDisplayMode);
sl@0
   940
		}
sl@0
   941
	}
sl@0
   942
sl@0
   943
//aX, aY - logical coordinates
sl@0
   944
void CDrawBitmap::WriteRgb(TInt aX,TInt aY,TRgb aColor,CGraphicsContext::TDrawMode aDrawMode)
sl@0
   945
	{
sl@0
   946
	register TInt width = -1;
sl@0
   947
	register TInt height = -1;
sl@0
   948
	PreWriteRgb(width, height, aX, aY, aDrawMode);
sl@0
   949
	WriteRgb(width, height, aX, aY, aColor, aDrawMode);
sl@0
   950
	}
sl@0
   951
sl@0
   952
//aX, aY - logical coordinates
sl@0
   953
void CDrawBitmap::WriteRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aHeight,
sl@0
   954
								TRgb aColor,CGraphicsContext::TDrawMode aDrawMode)
sl@0
   955
	{
sl@0
   956
	const TRect rect = DeOrientate(TRect(aX,aY,aX + aLength,aY + aHeight));//rect - physical coordinates
sl@0
   957
	aX = rect.iTl.iX;
sl@0
   958
	aY = rect.iTl.iY;
sl@0
   959
	aLength = rect.Width();
sl@0
   960
	aHeight = rect.Height();
sl@0
   961
sl@0
   962
	__ASSERT_DEBUG(aX>=0 && aX+aLength<=iSize.iWidth,Panic(EScreenDriverPanicOutOfBounds));
sl@0
   963
	__ASSERT_DEBUG(aY>=0 && aY+aHeight<=iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds));
sl@0
   964
sl@0
   965
	MapColorToUserDisplayMode(aColor);
sl@0
   966
	if(iShadowMode)
sl@0
   967
		{
sl@0
   968
		Shadow(aColor);
sl@0
   969
		}
sl@0
   970
	if(aDrawMode&CGraphicsContext::EInvertPen)
sl@0
   971
		{
sl@0
   972
		aColor=~aColor;
sl@0
   973
		}
sl@0
   974
	if(aDrawMode&CGraphicsContext::EPenmode)
sl@0
   975
		{
sl@0
   976
		BlendRgbMulti(aX,aY,aLength,aHeight,aColor);
sl@0
   977
		return;
sl@0
   978
		}
sl@0
   979
	if(aDrawMode&CGraphicsContext::EWriteAlpha)
sl@0
   980
		{
sl@0
   981
		WriteRgbMulti(aX,aY,aLength,aHeight,aColor);
sl@0
   982
		return;
sl@0
   983
		}
sl@0
   984
	if(aDrawMode&CGraphicsContext::EInvertScreen)
sl@0
   985
		{
sl@0
   986
		WriteRgbMultiXOR(aX,aY,aLength,aHeight,KRgbWhite);
sl@0
   987
		}
sl@0
   988
	if(aDrawMode&CGraphicsContext::EXor)
sl@0
   989
		{
sl@0
   990
		WriteRgbMultiXOR(aX,aY,aLength,aHeight,aColor);
sl@0
   991
		}
sl@0
   992
	else if(aDrawMode&CGraphicsContext::EAnd)
sl@0
   993
		{
sl@0
   994
		WriteRgbMultiAND(aX,aY,aLength,aHeight,aColor);
sl@0
   995
		}
sl@0
   996
	else if(aDrawMode&CGraphicsContext::EOr)
sl@0
   997
		{
sl@0
   998
		WriteRgbMultiOR(aX,aY,aLength,aHeight,aColor);
sl@0
   999
		}
sl@0
  1000
	}
sl@0
  1001
sl@0
  1002
//aX, aY - logical coordinates
sl@0
  1003
void CDrawBitmap::WriteBinary(TInt aX,TInt aY,TUint32* aBuffer,TInt aLength,
sl@0
  1004
							  TInt aHeight,TRgb aColor,CGraphicsContext::TDrawMode aDrawMode)
sl@0
  1005
	{
sl@0
  1006
	TRect drawRect;
sl@0
  1007
	GetDrawRect(drawRect);
sl@0
  1008
	__ASSERT_DEBUG(aX >= drawRect.iTl.iX && (aX + aLength) <= drawRect.iBr.iX, Panic(EScreenDriverPanicOutOfBounds));
sl@0
  1009
	__ASSERT_DEBUG(aY >= drawRect.iTl.iY && (aY + aHeight) <= drawRect.iBr.iY, Panic(EScreenDriverPanicOutOfBounds));
sl@0
  1010
	__ASSERT_DEBUG(aBuffer, Panic(EScreenDriverPanicNullPointer));
sl@0
  1011
	__ASSERT_DEBUG(aLength > 0, Panic(EScreenDriverPanicZeroLength));
sl@0
  1012
	__ASSERT_DEBUG(aLength <= 32, Panic(EScreenDriverPanicOutOfBounds));
sl@0
  1013
sl@0
  1014
	MapColorToUserDisplayMode(aColor);
sl@0
  1015
	if(iShadowMode)
sl@0
  1016
		Shadow(aColor);
sl@0
  1017
	if(aDrawMode&CGraphicsContext::EInvertPen)
sl@0
  1018
		aColor=~aColor;
sl@0
  1019
	if(aDrawMode&CGraphicsContext::EPenmode)
sl@0
  1020
		{
sl@0
  1021
		WriteBinary(aX,aY,aBuffer,aLength,aHeight,aColor);
sl@0
  1022
		return;
sl@0
  1023
		}
sl@0
  1024
	if(aDrawMode&CGraphicsContext::EInvertScreen)
sl@0
  1025
		WriteBinaryOp(aX,aY,aBuffer,aLength,aHeight,KRgbWhite,CGraphicsContext::EDrawModeXOR);
sl@0
  1026
	if(aDrawMode&CGraphicsContext::ELogicalOp)
sl@0
  1027
		WriteBinaryOp(aX,aY,aBuffer,aLength,aHeight,aColor,(CGraphicsContext::TDrawMode)(aDrawMode&CGraphicsContext::ELogicalOp));
sl@0
  1028
	}
sl@0
  1029
sl@0
  1030
//aX, aY - logical coordinates
sl@0
  1031
void CDrawBitmap::WriteBinaryLine(TInt aX,TInt aY,TUint32* aBuffer,
sl@0
  1032
								  TInt aLength,TRgb aColor,
sl@0
  1033
								  CGraphicsContext::TDrawMode aDrawMode)
sl@0
  1034
	{
sl@0
  1035
	MapColorToUserDisplayMode(aColor);
sl@0
  1036
	while(aLength>32)
sl@0
  1037
		{
sl@0
  1038
		WriteBinary(aX,aY,aBuffer,32,1,aColor,aDrawMode);
sl@0
  1039
		aX+=32;
sl@0
  1040
		aBuffer++;
sl@0
  1041
		aLength-=32;
sl@0
  1042
		}
sl@0
  1043
	WriteBinary(aX,aY,aBuffer,aLength,1,aColor,aDrawMode);
sl@0
  1044
	}
sl@0
  1045
sl@0
  1046
//aX, aY - logical coordinates
sl@0
  1047
void CDrawBitmap::WriteBinaryLineVertical(TInt aX,TInt aY,TUint32* aBuffer,
sl@0
  1048
										  TInt aHeight,TRgb aColor,
sl@0
  1049
										  CGraphicsContext::TDrawMode aDrawMode,TBool aUp)
sl@0
  1050
	{
sl@0
  1051
	TRect drawRect;
sl@0
  1052
	GetDrawRect(drawRect);
sl@0
  1053
	__ASSERT_DEBUG(aX >= drawRect.iTl.iX && aX < drawRect.iBr.iX, Panic(EScreenDriverPanicOutOfBounds));
sl@0
  1054
	__ASSERT_DEBUG(aY >= drawRect.iTl.iY, Panic(EScreenDriverPanicOutOfBounds));
sl@0
  1055
	__ASSERT_DEBUG(aUp || (aY + aHeight) <= drawRect.iBr.iY, Panic(EScreenDriverPanicOutOfBounds));
sl@0
  1056
	__ASSERT_DEBUG(!aUp || (aY - aHeight + 1) >= drawRect.iTl.iY, Panic(EScreenDriverPanicOutOfBounds));
sl@0
  1057
	__ASSERT_DEBUG(aBuffer, Panic(EScreenDriverPanicNullPointer));
sl@0
  1058
	__ASSERT_DEBUG(aHeight > 0, Panic(EScreenDriverPanicZeroLength));
sl@0
  1059
sl@0
  1060
	MapColorToUserDisplayMode(aColor);
sl@0
  1061
	if((aDrawMode & CGraphicsContext::EPenmode) && iScalingOff)
sl@0
  1062
		{
sl@0
  1063
		if(iShadowMode)
sl@0
  1064
			Shadow(aColor);
sl@0
  1065
		if(aDrawMode&CGraphicsContext::EInvertPen)
sl@0
  1066
			aColor=~aColor;
sl@0
  1067
		WriteBinaryLineVertical(aX,aY,aBuffer,aHeight,aColor,aUp);
sl@0
  1068
		return;
sl@0
  1069
		}
sl@0
  1070
sl@0
  1071
	TUint32 mask = 1;
sl@0
  1072
	TUint32 data = *aBuffer++;
sl@0
  1073
	TInt endrow = aY + (aUp ? -aHeight : aHeight);
sl@0
  1074
	TInt rowInc = aUp ? -1 : 1;
sl@0
  1075
sl@0
  1076
	while (aY != endrow)
sl@0
  1077
		{
sl@0
  1078
		if (!mask)
sl@0
  1079
			{
sl@0
  1080
			data = *aBuffer++;
sl@0
  1081
			mask = 1;
sl@0
  1082
			}
sl@0
  1083
sl@0
  1084
		if (data & mask)
sl@0
  1085
			{
sl@0
  1086
			WriteRgb(aX, aY, aColor, aDrawMode);
sl@0
  1087
			}
sl@0
  1088
sl@0
  1089
		aY += rowInc;
sl@0
  1090
		mask <<= 1;
sl@0
  1091
		}
sl@0
  1092
	}
sl@0
  1093
sl@0
  1094
//aX, aY - logical coordinates
sl@0
  1095
void CDrawBitmap::WriteLine(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer,
sl@0
  1096
							CGraphicsContext::TDrawMode aDrawMode)
sl@0
  1097
	{
sl@0
  1098
	const TPoint originalPoint(aX,aY);
sl@0
  1099
	DeOrientate(aX,aY);//aX and aY - physical coordinates
sl@0
  1100
sl@0
  1101
	__ASSERT_DEBUG(aX >= 0,Panic(EScreenDriverPanicOutOfBounds));
sl@0
  1102
	__ASSERT_DEBUG(aY >= 0,Panic(EScreenDriverPanicOutOfBounds));
sl@0
  1103
#if defined(_DEBUG)
sl@0
  1104
	switch (iOrientation)
sl@0
  1105
		{
sl@0
  1106
	case EOrientationNormal:
sl@0
  1107
		__ASSERT_DEBUG(aX + aLength <= iSize.iWidth,Panic(EScreenDriverPanicOutOfBounds));
sl@0
  1108
		break;
sl@0
  1109
	case EOrientationRotated90:
sl@0
  1110
		__ASSERT_DEBUG(aY + aLength <= iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds));
sl@0
  1111
		break;
sl@0
  1112
	case EOrientationRotated180:
sl@0
  1113
		__ASSERT_DEBUG(aX - aLength >= -1,Panic(EScreenDriverPanicOutOfBounds));
sl@0
  1114
		break;
sl@0
  1115
	default: // EOrientationRotated270
sl@0
  1116
		__ASSERT_DEBUG(aY - aLength >= -1,Panic(EScreenDriverPanicOutOfBounds));
sl@0
  1117
		break;
sl@0
  1118
		}
sl@0
  1119
#endif
sl@0
  1120
	__ASSERT_DEBUG(aLength > 0,Panic(EScreenDriverPanicZeroLength));
sl@0
  1121
	__ASSERT_DEBUG(aBuffer,Panic(EScreenDriverPanicNullPointer));
sl@0
  1122
sl@0
  1123
	MapBufferToUserDisplayMode(aLength,aBuffer);
sl@0
  1124
	if(iShadowMode)
sl@0
  1125
		{
sl@0
  1126
		ShadowBuffer(aLength,aBuffer);
sl@0
  1127
		}
sl@0
  1128
	if(aDrawMode&CGraphicsContext::EInvertPen)
sl@0
  1129
		{
sl@0
  1130
		InvertBuffer(aLength,aBuffer);
sl@0
  1131
		}
sl@0
  1132
	if(aDrawMode&CGraphicsContext::EPenmode)
sl@0
  1133
		{
sl@0
  1134
		BlendLine(aX,aY,aLength,aBuffer);
sl@0
  1135
		return;
sl@0
  1136
		}
sl@0
  1137
	if(aDrawMode&CGraphicsContext::EWriteAlpha)
sl@0
  1138
		{
sl@0
  1139
		WriteLine(aX,aY,aLength,aBuffer);
sl@0
  1140
		return;
sl@0
  1141
		}
sl@0
  1142
	if(aDrawMode&CGraphicsContext::EInvertScreen)
sl@0
  1143
		{
sl@0
  1144
		const TRect rect = DeOrientate(TRect(originalPoint,TSize(aLength,1)));//"rect" - deorientated and scaled
sl@0
  1145
		WriteRgbMultiXOR(rect.iTl.iX,rect.iTl.iY,rect.Width(),rect.Height(),KRgbWhite);
sl@0
  1146
		}
sl@0
  1147
	if(aDrawMode&CGraphicsContext::EXor)
sl@0
  1148
		{
sl@0
  1149
		WriteLineXOR(aX,aY,aLength,aBuffer);
sl@0
  1150
		}
sl@0
  1151
	else if(aDrawMode&CGraphicsContext::EAnd)
sl@0
  1152
		{
sl@0
  1153
		WriteLineAND(aX,aY,aLength,aBuffer);
sl@0
  1154
		}
sl@0
  1155
	else if(aDrawMode&CGraphicsContext::EOr)
sl@0
  1156
		{
sl@0
  1157
		WriteLineOR(aX,aY,aLength,aBuffer);
sl@0
  1158
		}
sl@0
  1159
	}
sl@0
  1160
sl@0
  1161
TAny* CDrawBitmap::CopyOffset(TAny* aDestination,const TAny* aSource,TInt aWordsToCopy,TInt aSourceBitOffset)
sl@0
  1162
	{
sl@0
  1163
	ASSERT(aSourceBitOffset > 0 && aSourceBitOffset < 32);
sl@0
  1164
sl@0
  1165
	const TUint32* srcPtr = REINTERPRET_CAST(const TUint32*,aSource);
sl@0
  1166
	TUint32* destPtr = REINTERPRET_CAST(TUint32*,aDestination);
sl@0
  1167
	const TUint32* destPtrLimit = destPtr + aWordsToCopy;
sl@0
  1168
	const TInt sourceBitOffsetComplement = 32 - aSourceBitOffset;
sl@0
  1169
sl@0
  1170
	TUint32 sourceValue = *srcPtr++;
sl@0
  1171
sl@0
  1172
	while (destPtr < destPtrLimit)
sl@0
  1173
		{
sl@0
  1174
		TUint32 destValue = sourceValue >> aSourceBitOffset;
sl@0
  1175
		sourceValue = *srcPtr++;
sl@0
  1176
		destValue |= sourceValue << sourceBitOffsetComplement;
sl@0
  1177
		*destPtr++ = destValue;
sl@0
  1178
		}
sl@0
  1179
	return destPtr;
sl@0
  1180
	}
sl@0
  1181
/**	Common code to read a line of pixels where there are >1 pixels per byte.
sl@0
  1182
  	The source words must be shifted to fit the target buffer.
sl@0
  1183
@param 	aPixelPtr 	Source location to start copying from (word aligned, last word is safe)
sl@0
  1184
@param	aBufferPtr	Target location to write to (word aligned - may or may not own all last word)
sl@0
  1185
@param	aWordsCnt	Number of source words that can be safely copied
sl@0
  1186
@param	aRestPixels	Number of pixels that must be read from the next word for the final byte copy
sl@0
  1187
@param	aBytesCount	Number of bytes to write from final input word
sl@0
  1188
@param	aShiftBits	Number of bits shifted between input and output words.
sl@0
  1189
 **/
sl@0
  1190
void CDrawBitmap::ReadLineCommon(TUint32* aPixelPtr,TUint32* aBufferPtr,TInt aWordsCount,TInt aRestPixels,TInt aBytesCount,TInt aShiftBits)
sl@0
  1191
	{
sl@0
  1192
// 	As many pixels as possible are copied by shifting whole words.
sl@0
  1193
// 	This involves reading two source words, shifting them, 
sl@0
  1194
// 	and merging the result to one target word.
sl@0
  1195
//  	However, two cases mean the last few pixels need to be treated carefully:
sl@0
  1196
//  	1) The target buffer may be a number of bytes, not whole words.
sl@0
  1197
//			The number of pixels to copy defines the number of bytes to copy.
sl@0
  1198
//  	2) The number of pixels to read may mean the last read does not need 
sl@0
  1199
//  	   	to read a second word in order to satisfy the number of pixels requested.
sl@0
  1200
//  	   	This next word may not be mapped, so must not be read!
sl@0
  1201
sl@0
  1202
	//Are we willing to pay for these asserts for every scanline copy, even in debug?
sl@0
  1203
	__ASSERT_DEBUG(aPixelPtr, User::Invariant());
sl@0
  1204
	__ASSERT_DEBUG(aBufferPtr, User::Invariant());
sl@0
  1205
	__ASSERT_DEBUG(aWordsCount>=0, User::Invariant());
sl@0
  1206
	__ASSERT_DEBUG(aBytesCount<5, User::Invariant());
sl@0
  1207
	__ASSERT_DEBUG(aShiftBits>=0 && aShiftBits<33, User::Invariant());
sl@0
  1208
	
sl@0
  1209
	TUint32 nextpixel;
sl@0
  1210
	if(aWordsCount>0)	
sl@0
  1211
		{
sl@0
  1212
		if (aShiftBits==0)
sl@0
  1213
			{
sl@0
  1214
			while (aWordsCount--)
sl@0
  1215
				{
sl@0
  1216
				*aBufferPtr++ = *aPixelPtr++;
sl@0
  1217
				}
sl@0
  1218
			if (aBytesCount>0)	//I hope the optimiser can concatenate these two tests?
sl@0
  1219
				{
sl@0
  1220
				nextpixel=aPixelPtr[0];
sl@0
  1221
				}
sl@0
  1222
			}
sl@0
  1223
		else
sl@0
  1224
			{
sl@0
  1225
			const TInt shiftBitsExtra = 32 - aShiftBits;
sl@0
  1226
			nextpixel=aPixelPtr[0]; 
sl@0
  1227
			while (aWordsCount--)
sl@0
  1228
				{
sl@0
  1229
				TUint32 prevpixel=nextpixel;
sl@0
  1230
				nextpixel=aPixelPtr[1];	//this must not read forward when it doesn't need to
sl@0
  1231
				aBufferPtr[0] = (prevpixel >> aShiftBits) | (nextpixel << shiftBitsExtra);
sl@0
  1232
sl@0
  1233
				aPixelPtr++;
sl@0
  1234
				aBufferPtr++;
sl@0
  1235
				}
sl@0
  1236
			}
sl@0
  1237
		}
sl@0
  1238
	else
sl@0
  1239
		{
sl@0
  1240
		nextpixel=aPixelPtr[0];
sl@0
  1241
		}
sl@0
  1242
	
sl@0
  1243
	//deal with the trailing bytes
sl@0
  1244
	if (aBytesCount>0)
sl@0
  1245
		{
sl@0
  1246
		if (aBytesCount==4)
sl@0
  1247
			{
sl@0
  1248
			//The client only requests 4 bytes rather than 1 more word when the requested pixels
sl@0
  1249
			//mean the second word should not be read from.
sl@0
  1250
			//Can also write the result in a single operation!
sl@0
  1251
			aBufferPtr[0]=nextpixel>> aShiftBits;
sl@0
  1252
			}
sl@0
  1253
		else
sl@0
  1254
			{
sl@0
  1255
			if (aRestPixels>0)
sl@0
  1256
				{	
sl@0
  1257
				//do need to read from next word to fill all the requested pixels.
sl@0
  1258
				aWordsCount=(nextpixel >> aShiftBits) | (aPixelPtr[1] << (32 - aShiftBits));
sl@0
  1259
				}
sl@0
  1260
			else
sl@0
  1261
				{	
sl@0
  1262
				//Don't read second word, otherwise might read past end of picture data!
sl@0
  1263
				aWordsCount=(nextpixel >> aShiftBits);	
sl@0
  1264
				}
sl@0
  1265
			TUint8*	bufferPtrChar=reinterpret_cast <TUint8*> (aBufferPtr);
sl@0
  1266
sl@0
  1267
			//max 3 bytes to store
sl@0
  1268
			if (aBytesCount&2)
sl@0
  1269
				{
sl@0
  1270
				bufferPtrChar[0]=aWordsCount;
sl@0
  1271
				bufferPtrChar[1]=aWordsCount>>8;
sl@0
  1272
				bufferPtrChar+=2;
sl@0
  1273
				aWordsCount>>=16;
sl@0
  1274
				}
sl@0
  1275
			if (aBytesCount&1)
sl@0
  1276
				{
sl@0
  1277
				bufferPtrChar[0]=aWordsCount;
sl@0
  1278
				}
sl@0
  1279
			}
sl@0
  1280
		}
sl@0
  1281
	}
sl@0
  1282
sl@0
  1283
/**
sl@0
  1284
The method performs an alpha blending of the source data - aRgbBuffer and screen pixels, using
sl@0
  1285
the data from aMaskBuffer buffer as an alpha blending factor.
sl@0
  1286
If the shadowing/fading flag is set, a shadow/fade copy of the source bitmap will be used.
sl@0
  1287
The formula used for that, is:
sl@0
  1288
(C1 * A + C2 * (255 - A)) / 255, where:
sl@0
  1289
- C1 - a pixel from aRgbBuffer;
sl@0
  1290
- C2 - a pixel from the sceen;
sl@0
  1291
- A  - a pixel from aMaskBuffer;
sl@0
  1292
The content of source and mask buffers is preserved.
sl@0
  1293
The calculated alpha blended pixel is written to the destination - the screen or a bitmap.
sl@0
  1294
@param aX Logical X coordinate of the position in the target the result should be drawn to.
sl@0
  1295
@param aY Logical Y coordinate of the position in the target the result should be drawn to.
sl@0
  1296
@param aLength Source data - length in pixels.
sl@0
  1297
@param aRgbBuffer A pointer to a line of the source bitmap data.
sl@0
  1298
@param aMaskBuffer Buffer containing the data which should be used as an
sl@0
  1299
                   alpha blending factor.
sl@0
  1300
*/
sl@0
  1301
void CDrawBitmap::WriteRgbAlphaLine(TInt aX, TInt aY, TInt aLength,
sl@0
  1302
                                    TUint8* aRgbBuffer, TUint8* aMaskBuffer,
sl@0
  1303
                                    CGraphicsContext::TDrawMode aDrawMode)
sl@0
  1304
	{
sl@0
  1305
	iAlphaBlend->WriteRgbAlphaLine(aX, aY, aLength, aRgbBuffer, aMaskBuffer,
sl@0
  1306
                                   MAlphaBlend::EShdwBefore,
sl@0
  1307
                                   aDrawMode);
sl@0
  1308
	}
sl@0
  1309
sl@0
  1310
/**
sl@0
  1311
The method performs an alpha blending of the source data - aRgbBuffer1 and aBuffer2, using
sl@0
  1312
the data from aMaskBuffer buffer as an alpha blending factor.
sl@0
  1313
If the shadowing/fading flag is set, the resulting pixels will be shadowed/faded.
sl@0
  1314
The formula used for that, is:
sl@0
  1315
(C1 * A + C2 * (255 - A)) / 255, where:
sl@0
  1316
- C1 - a pixel from aRgbBuffer1;
sl@0
  1317
- C2 - a pixel from aBuffer2;
sl@0
  1318
- A  - a pixel from aMaskBuffer;
sl@0
  1319
The content of source and mask buffers is preserved.
sl@0
  1320
The calculated alpha blended pixel is written to the destination - the screen or a bitmap.
sl@0
  1321
@param aX Logical X coordinate of the position in the target the result should be drawn to.
sl@0
  1322
@param aY Logical Y coordinate of the position in the target the result should be drawn to.
sl@0
  1323
@param aLength Source data - length in pixels.
sl@0
  1324
@param aRgbBuffer1 A pointer to a line of the source bitmap data 1.
sl@0
  1325
@param aBuffer2 A pointer to a line of the source bitmap data 2.
sl@0
  1326
                Source bitmap data 2 should be mapped to current display mode
sl@0
  1327
				before the method call.
sl@0
  1328
@param aMaskBuffer Buffer containing the data which should be used as an
sl@0
  1329
                   alpha blending factor.
sl@0
  1330
@param aDrawMode Drawing mode
sl@0
  1331
*/
sl@0
  1332
void CDrawBitmap::WriteRgbAlphaLine(TInt aX,TInt aY,TInt aLength,
sl@0
  1333
									const TUint8* aRgbBuffer1,
sl@0
  1334
									const TUint8* aBuffer2,
sl@0
  1335
									const TUint8* aMaskBuffer,
sl@0
  1336
									CGraphicsContext::TDrawMode aDrawMode)
sl@0
  1337
	{
sl@0
  1338
	// Save current shadow mode
sl@0
  1339
	TShadowMode temp_mode = iShadowMode;
sl@0
  1340
	iShadowMode = ENoShadow;
sl@0
  1341
	// copy the source data 2 to the screen/bitmap target buffer
sl@0
  1342
	WriteLine(aX, aY, aLength, (TUint32*)aBuffer2, aDrawMode);
sl@0
  1343
	// restore current shadow mode
sl@0
  1344
	iShadowMode = temp_mode;
sl@0
  1345
	// DrawModePen is the only supported operation for blending masks. 
sl@0
  1346
	iAlphaBlend->WriteRgbAlphaLine(aX, aY, aLength, aRgbBuffer1, aMaskBuffer,
sl@0
  1347
                                   MAlphaBlend::EShdwAfter, CGraphicsContext::EDrawModePEN);
sl@0
  1348
	}
sl@0
  1349
sl@0
  1350
//Initializes iSize and iDrawRect data members.
sl@0
  1351
//It should be called every time when iSize is going to be changed - Construct() implementations
sl@0
  1352
//in derived classes.
sl@0
  1353
//The method does not use iOrientation data member.
sl@0
  1354
//@param aSize Physical screen size in pixels.
sl@0
  1355
//@panic EScreenDriverPanicInvalidSize - Invalid aSize parameter. This might happen if the
sl@0
  1356
//device is scaled and the scaling origin goes outside physical drawing rectangle.
sl@0
  1357
void CDrawBitmap::SetSize(const TSize& aSize)
sl@0
  1358
	{
sl@0
  1359
	iSize = aSize;
sl@0
  1360
	InitLogicalCoordinates();
sl@0
  1361
	}
sl@0
  1362
sl@0
  1363
/**
sl@0
  1364
The method swaps bitmap device's width and height.
sl@0
  1365
For example: if the size is (40, 20), the swapped size will be (20, 40).
sl@0
  1366
The device's content is not preserved.
sl@0
  1367
The method leaves CDrawBitmap object in a consistent state -
sl@0
  1368
scaling settings will be set with their default values (the scaling is switched off),
sl@0
  1369
iDitherOrigin will be set to (0,0), iOrigin to (0,0).
sl@0
  1370
sl@0
  1371
Note: This method is used internally by BITGDI component. Do not call it!
sl@0
  1372
*/
sl@0
  1373
void CDrawBitmap::SwapWidthAndHeight()
sl@0
  1374
	{
sl@0
  1375
	SetDefaults();
sl@0
  1376
	//Swap width and height
sl@0
  1377
	TSize swappedSize(iSize.iHeight, iSize.iWidth);
sl@0
  1378
	//Initialize iSize, iScanLineWords, iLongWidth data members.
sl@0
  1379
	SetSize(swappedSize);
sl@0
  1380
	}
sl@0
  1381
sl@0
  1382
//This method initializes some of the data members.
sl@0
  1383
//Espetially it switches scaling off, sets iDitherOrigin to (0,0),
sl@0
  1384
//iOrigin to (0,0), iDrawRect to (0,0,0,0). iSize value is preserved.
sl@0
  1385
//Do not forget to update it if adding new data members!
sl@0
  1386
void CDrawBitmap::SetDefaults()
sl@0
  1387
	{
sl@0
  1388
	iLongWidth = 0;
sl@0
  1389
	iDitherOrigin.SetXY(0, 0);
sl@0
  1390
	iFadeMapFactor = 128;
sl@0
  1391
	iFadeMapOffset = 128;
sl@0
  1392
	iScalingSettings = TScalingSettings();
sl@0
  1393
	iOrigin.SetXY(0, 0);
sl@0
  1394
	iScalingOff = ETrue;
sl@0
  1395
	iOriginIsZero = ETrue;
sl@0
  1396
	iDrawRect.SetRect(0, 0, 0, 0);
sl@0
  1397
	}
sl@0
  1398
sl@0
  1399
/**
sl@0
  1400
Implementation for CFbsDrawDevice::GetInterface().
sl@0
  1401
Retrieves a pointer to a specified interface of CFbsDrawDevice implementation.
sl@0
  1402
@param aInterfaceId Interface identifier of the interface to be retrieved.
sl@0
  1403
@param aInterface Address of variable that retrieves the specified interface.
sl@0
  1404
@return KErrNone If the interface is supported, KErrNotSupported otherwise.
sl@0
  1405
*/
sl@0
  1406
TInt CDrawBitmap::GetInterface(TInt aInterfaceId, TAny*& aInterface)
sl@0
  1407
	{
sl@0
  1408
	aInterface = NULL;
sl@0
  1409
	TInt err = KErrNotSupported;
sl@0
  1410
sl@0
  1411
	switch (aInterfaceId)
sl@0
  1412
		{
sl@0
  1413
		case KScalingSettingsInterfaceID:
sl@0
  1414
			{
sl@0
  1415
			if(CanBeScaled())
sl@0
  1416
				{
sl@0
  1417
				aInterface = static_cast <MScalingSettings*> (this);
sl@0
  1418
				err = KErrNone;
sl@0
  1419
				}
sl@0
  1420
			break;
sl@0
  1421
			}
sl@0
  1422
		case KDrawDeviceOriginInterfaceID:
sl@0
  1423
			{
sl@0
  1424
			if(CanOriginBeMoved())
sl@0
  1425
				{
sl@0
  1426
				aInterface = static_cast <MDrawDeviceOrigin*> (this);
sl@0
  1427
				err = KErrNone;
sl@0
  1428
				}
sl@0
  1429
			break;
sl@0
  1430
			}
sl@0
  1431
		case KAlphaBlendInterfaceID:
sl@0
  1432
			{
sl@0
  1433
			aInterface = static_cast <MAlphaBlend*> (this);
sl@0
  1434
			err = KErrNone;
sl@0
  1435
			break;
sl@0
  1436
			}
sl@0
  1437
		case KOrientationInterfaceID:
sl@0
  1438
			{
sl@0
  1439
			aInterface = static_cast <MDrawDeviceOrientation*> (this);
sl@0
  1440
			err = KErrNone;    		
sl@0
  1441
			break;
sl@0
  1442
			}
sl@0
  1443
		case KOutlineAndShadowInterfaceID:
sl@0
  1444
			{
sl@0
  1445
			aInterface = static_cast <MOutlineAndShadowBlend*> (this);
sl@0
  1446
			err = KErrNone;    		
sl@0
  1447
			break;
sl@0
  1448
			}
sl@0
  1449
		case KFastBlendInterfaceID:
sl@0
  1450
			{
sl@0
  1451
			aInterface = static_cast <MFastBlend*> (this);
sl@0
  1452
			err = KErrNone;
sl@0
  1453
			break;
sl@0
  1454
			}
sl@0
  1455
		}
sl@0
  1456
	
sl@0
  1457
	return err;
sl@0
  1458
	}
sl@0
  1459
sl@0
  1460
void CDrawBitmap::BlendRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
sl@0
  1461
	{
sl@0
  1462
	WriteRgbMulti(aX,aY,aLength,aHeight,aColor);
sl@0
  1463
	}
sl@0
  1464
sl@0
  1465
void CDrawBitmap::BlendLine(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
sl@0
  1466
	{
sl@0
  1467
	WriteLine(aX, aY,aLength, aBuffer);
sl@0
  1468
	}
sl@0
  1469
sl@0
  1470
/**
sl@0
  1471
Convert a RGB pixel into the color associated to the user display mode.
sl@0
  1472
@param aRed red color
sl@0
  1473
@param aGreen green color
sl@0
  1474
@param aBlue blue color
sl@0
  1475
@internalComponent
sl@0
  1476
*/
sl@0
  1477
void CDrawBitmap::MapColorToUserDisplayMode(TInt& aRed,TInt& aGreen,TInt& aBlue)
sl@0
  1478
	{
sl@0
  1479
	TUint32 tmpValue;
sl@0
  1480
		
sl@0
  1481
	switch (iUserDispMode)
sl@0
  1482
		{
sl@0
  1483
		case EGray2:
sl@0
  1484
			tmpValue = ((aRed<<1) + aGreen + (aGreen<<2) + aBlue) >> 10;
sl@0
  1485
			if (tmpValue) 	{ aRed = 0xff; aBlue = 0xff; aGreen = 0xff; }
sl@0
  1486
			else			{ aRed = 0x00; aBlue = 0x00; aGreen = 0x00; }
sl@0
  1487
			break;
sl@0
  1488
		case EGray4:
sl@0
  1489
			tmpValue = ((aRed<<1) + aGreen + (aGreen<<2) + aBlue) >> 9;
sl@0
  1490
			tmpValue = tmpValue | (tmpValue << 2) | (tmpValue << 4) | (tmpValue << 6);
sl@0
  1491
			aRed = tmpValue; aGreen = tmpValue; aBlue = tmpValue;
sl@0
  1492
			break;
sl@0
  1493
		case EGray16:
sl@0
  1494
			tmpValue = ((aRed<<1) + aGreen + (aGreen<<2) + aBlue) >> 7;
sl@0
  1495
			tmpValue = tmpValue | (tmpValue << 4);
sl@0
  1496
			aRed = tmpValue; aGreen = tmpValue; aBlue = tmpValue;
sl@0
  1497
			break;
sl@0
  1498
	  	case EGray256:
sl@0
  1499
			tmpValue = ((aRed<<1) + aGreen + (aGreen<<2) + aBlue) >> 3;
sl@0
  1500
	  		aRed = tmpValue; aGreen = tmpValue; aBlue = tmpValue;
sl@0
  1501
	  		break;
sl@0
  1502
	  	case EColor16:
sl@0
  1503
	  		{
sl@0
  1504
	  		TRgb aColor(aRed,aGreen,aBlue);
sl@0
  1505
	  		aColor = TRgb::Color16(aColor.Color16());
sl@0
  1506
	  		aRed = aColor.Red(); aGreen = aColor.Green(); aBlue = aColor.Blue();
sl@0
  1507
	  		break;  		
sl@0
  1508
	  		}
sl@0
  1509
	  	case EColor256:
sl@0
  1510
	  		{
sl@0
  1511
	  		TRgb aColor2(aRed,aGreen,aBlue);
sl@0
  1512
	  		aColor2 = TRgb::Color256(aColor2.Color256());
sl@0
  1513
	  		aRed = aColor2.Red(); aGreen = aColor2.Green(); aBlue = aColor2.Blue();
sl@0
  1514
	  		break;
sl@0
  1515
	  		}
sl@0
  1516
	  	case EColor4K:
sl@0
  1517
	  		aBlue = aBlue  & 0xf0; 	aBlue |= (aBlue >> 4);
sl@0
  1518
	  		aGreen = aGreen  & 0xf0;	aGreen |= (aGreen >> 4);
sl@0
  1519
	  		aRed = aRed  & 0xf0; 		aRed |= (aRed >> 4);
sl@0
  1520
	  		break;
sl@0
  1521
	  	case EColor64K:
sl@0
  1522
	  		aBlue = aBlue  & 0xf8;	aBlue += (aBlue >> 5);
sl@0
  1523
	  		aGreen = aGreen  & 0xfc;	aGreen += (aGreen >> 6);
sl@0
  1524
	  		aRed = aRed  & 0xf8;		aRed += (aRed >> 5);
sl@0
  1525
	  		break;
sl@0
  1526
	  	default:
sl@0
  1527
	  		break;
sl@0
  1528
  		}
sl@0
  1529
	}
sl@0
  1530
sl@0
  1531
/**
sl@0
  1532
CDrawBitmap::Orientation() implementation.
sl@0
  1533
@internalTechnology
sl@0
  1534
@see MDrawDeviceOrientation::Orientation()
sl@0
  1535
*/
sl@0
  1536
CFbsDrawDevice::TOrientation CDrawBitmap::Orientation()
sl@0
  1537
	{
sl@0
  1538
	return iOrientation;
sl@0
  1539
	}
sl@0
  1540
sl@0
  1541
#ifdef __ARMCC__
sl@0
  1542
#ifndef __MARM_THUMB__
sl@0
  1543
#define USE_SCREENDRIVER_ARM_ASM
sl@0
  1544
#endif //__MARM_THUMB__
sl@0
  1545
#endif //__ARMCC__
sl@0
  1546
sl@0
  1547
#ifdef USE_SCREENDRIVER_ARM_ASM
sl@0
  1548
/**
sl@0
  1549
MemFill - using an unrolled loop to perform the following:
sl@0
  1550
	for (TUint32* tempWordPtr = wordPtr; tempWordPtr < wordPtrLimit; tempWordPtr++)
sl@0
  1551
		{
sl@0
  1552
		*tempWordPtr = colorWord;
sl@0
  1553
		}
sl@0
  1554
*/
sl@0
  1555
__asm void MemFillTUint32(TUint32* /*aTrg*/, TInt /*aLength*/, const TUint32 /*aValue*/)
sl@0
  1556
	{
sl@0
  1557
	//r0 - aTrg, r1 - aLength, r2 - aValue
sl@0
  1558
	push     {r1,r3,lr}
sl@0
  1559
	and      r3,r1,#7
sl@0
  1560
	cmp      r3,#7
sl@0
  1561
	addls    pc,pc,r3,LSL #2
sl@0
  1562
	b        mf_switch0
sl@0
  1563
	b        mf_switch0
sl@0
  1564
	b        mf_switch1
sl@0
  1565
	b        mf_switch2
sl@0
  1566
	b        mf_switch3
sl@0
  1567
	b        mf_switch4
sl@0
  1568
	b        mf_switch5
sl@0
  1569
	b        mf_switch6
sl@0
  1570
	b        mf_switch7
sl@0
  1571
mf_switch7
sl@0
  1572
	str      r2,[r0],#4
sl@0
  1573
mf_switch6
sl@0
  1574
	str      r2,[r0],#4
sl@0
  1575
mf_switch5
sl@0
  1576
	str      r2,[r0],#4
sl@0
  1577
mf_switch4
sl@0
  1578
	str      r2,[r0],#4
sl@0
  1579
mf_switch3
sl@0
  1580
	str      r2,[r0],#4
sl@0
  1581
mf_switch2
sl@0
  1582
	str      r2,[r0],#4
sl@0
  1583
mf_switch1
sl@0
  1584
	str      r2,[r0],#4
sl@0
  1585
mf_switch0
sl@0
  1586
sl@0
  1587
	asr      r1,r1,#3
sl@0
  1588
	cmp      r1,#0
sl@0
  1589
	beq      mf_complete
sl@0
  1590
sl@0
  1591
	push     {r0,r2,r4-r8}
sl@0
  1592
	mov      r3,r2
sl@0
  1593
	mov      r4,r2
sl@0
  1594
    mov      r5,r2
sl@0
  1595
    mov      r6,r2
sl@0
  1596
	mov      r7,r2
sl@0
  1597
	mov      r8,r2
sl@0
  1598
	mov      lr,r2
sl@0
  1599
sl@0
  1600
mf_more
sl@0
  1601
	stmia    r0!,{r2-r8,lr}
sl@0
  1602
	subs     r1,r1,#1
sl@0
  1603
	bgt      mf_more
sl@0
  1604
	pop     {r0,r2,r4-r8}
sl@0
  1605
sl@0
  1606
mf_complete
sl@0
  1607
	pop     {r1,r3,pc}
sl@0
  1608
	}
sl@0
  1609
sl@0
  1610
#else //USE_SCREENDRIVER_ARM_ASM
sl@0
  1611
sl@0
  1612
const TInt KDevideByEightShift = 3;
sl@0
  1613
const TInt KModulusByEightFlag = 7;
sl@0
  1614
sl@0
  1615
void MemFillTUint32(TUint32* tempWordPtr, TInt aCount,  const TUint32 aValue)
sl@0
  1616
	{
sl@0
  1617
	TInt remainder = aCount & KModulusByEightFlag;
sl@0
  1618
	switch (remainder)
sl@0
  1619
		{
sl@0
  1620
	case 7:
sl@0
  1621
		*tempWordPtr++ = aValue;
sl@0
  1622
	case 6:
sl@0
  1623
		*tempWordPtr++ = aValue;
sl@0
  1624
	case 5:
sl@0
  1625
		*tempWordPtr++ = aValue;
sl@0
  1626
	case 4:
sl@0
  1627
		*tempWordPtr++ = aValue;
sl@0
  1628
	case 3:
sl@0
  1629
		*tempWordPtr++ = aValue;
sl@0
  1630
	case 2:
sl@0
  1631
		*tempWordPtr++ = aValue;
sl@0
  1632
	case 1:
sl@0
  1633
		*tempWordPtr++ = aValue;
sl@0
  1634
		}
sl@0
  1635
	register TUint32 value0 = aValue;
sl@0
  1636
	register TUint32 value1 = aValue;
sl@0
  1637
	register TUint32 value2 = aValue;
sl@0
  1638
	for(TInt times = (aCount >> KDevideByEightShift); times > 0; --times)
sl@0
  1639
		{
sl@0
  1640
		*tempWordPtr++ = value0;
sl@0
  1641
		*tempWordPtr++ = value1;
sl@0
  1642
		*tempWordPtr++ = value2;
sl@0
  1643
		*tempWordPtr++ = aValue;
sl@0
  1644
		*tempWordPtr++ = value0;
sl@0
  1645
		*tempWordPtr++ = value1;
sl@0
  1646
		*tempWordPtr++ = value2;
sl@0
  1647
		*tempWordPtr++ = aValue;
sl@0
  1648
		}
sl@0
  1649
	}
sl@0
  1650
sl@0
  1651
#endif //USE_SCREENDRIVER_ARM_ASM
sl@0
  1652