os/graphics/graphicsdeviceinterface/bitgdi/sbit/BITBLT.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 "BITPANIC.H"
sl@0
    17
#include <fntstore.h>
sl@0
    18
#include <bitmap.h>
sl@0
    19
#include <bitstd.h>
sl@0
    20
#include <bitdev.h>
sl@0
    21
#include <bitdraw.h>
sl@0
    22
#include <bitdrawscaling.h>
sl@0
    23
#include <bitdrawinterfaceid.h>
sl@0
    24
#include <bmalphablend.h>
sl@0
    25
#include <graphics/fbsrasterizer.h>
sl@0
    26
#include <graphics/bitmap.inl>
sl@0
    27
#include <graphics/gdi/gdiinline.inl>
sl@0
    28
sl@0
    29
GLREF_C void XorBuffers(TUint32* aDestBuffer,const TUint32* aSrceBuffer,TInt aNumBytes);
sl@0
    30
GLREF_C void AndBuffers(TUint32* aDestBuffer,const TUint32* aSrceBuffer,TInt aNumBytes);
sl@0
    31
GLREF_C void InvertBuffer(TUint32* aDestBuffer,TInt aNumBytes);
sl@0
    32
GLREF_C void InvertBuffer(TUint8* aDestBuffer,TInt aNumBytes);
sl@0
    33
LOCAL_C void TileScanLine(TPtr8& aScanLine,
sl@0
    34
						  TInt aLengthInPixels,
sl@0
    35
						  const TPoint& aSrcPt,
sl@0
    36
						  const CBitwiseBitmap* aMaskBitmap,
sl@0
    37
						  TLineScanningPosition& aScanLinePos,
sl@0
    38
						  TUint32* aMaskBase,
sl@0
    39
						  TDisplayMode aDisplayMode
sl@0
    40
						  );
sl@0
    41
sl@0
    42
/** Draws from another CFbsBitGc.
sl@0
    43
sl@0
    44
@param aPoint The position to draw the top left corner of the piece of bitmap
sl@0
    45
@param aGc The source bitmap graphics context */
sl@0
    46
EXPORT_C void CFbsBitGc::BitBlt(const TPoint& aDest,const CFbsBitGc& aGc)
sl@0
    47
	{
sl@0
    48
	TRect deviceRect;
sl@0
    49
	aGc.iDevice->iDrawDevice->GetDrawRect(deviceRect);
sl@0
    50
	BitBlt(aDest,aGc,deviceRect);
sl@0
    51
	}
sl@0
    52
sl@0
    53
/** Draws a particular rectangle from another CFbsBitGc.
sl@0
    54
sl@0
    55
@param aPoint The position to draw the top left corner of the piece of bitmap.
sl@0
    56
@param aGc The source bitmap graphics context.
sl@0
    57
@param aSrceRect A rectangle defining the piece of the source to be drawn. */
sl@0
    58
EXPORT_C void CFbsBitGc::BitBlt(const TPoint& aDest,
sl@0
    59
								const CFbsBitGc& aGc,
sl@0
    60
								const TRect& aSrceRect)
sl@0
    61
	{
sl@0
    62
	if (CheckDevice(aSrceRect))
sl@0
    63
		return;
sl@0
    64
	aGc.CheckDevice();
sl@0
    65
	CFbsDevice* srceDevice = aGc.iDevice;
sl@0
    66
	if (!srceDevice)
sl@0
    67
		return;
sl@0
    68
sl@0
    69
	TRect srceRect(aSrceRect);
sl@0
    70
	TRect deviceRect;
sl@0
    71
	srceDevice->GetDrawRect(deviceRect);
sl@0
    72
	if (!srceRect.Intersects(deviceRect))
sl@0
    73
		return;
sl@0
    74
	srceRect.Intersection(deviceRect);
sl@0
    75
sl@0
    76
	const TPoint destPoint(aDest + iOrigin + srceRect.iTl - aSrceRect.iTl);
sl@0
    77
	const TRect destRect(destPoint,srceRect.Size());
sl@0
    78
	const TPoint offset(srceRect.iTl - destPoint);
sl@0
    79
sl@0
    80
	TRect clippedDestRect(destRect);
sl@0
    81
	AddRect(clippedDestRect);
sl@0
    82
	if (UserClipRect(clippedDestRect))
sl@0
    83
		return;
sl@0
    84
sl@0
    85
	SetupDevice();
sl@0
    86
	aGc.iDevice->DrawingBegin();
sl@0
    87
	iDevice->DrawingBegin();
sl@0
    88
sl@0
    89
	const TInt limit = iDefaultRegionPtr->Count();
sl@0
    90
	TBool opaqueSource = (!IsAlphaChannel(srceDevice->DisplayMode())) && (iDrawMode == EDrawModePEN);
sl@0
    91
	for(TInt count=0;count<limit;count++)
sl@0
    92
		{
sl@0
    93
		iClipRect=(*iDefaultRegionPtr)[count];
sl@0
    94
		if(!iClipRect.Intersects(clippedDestRect))
sl@0
    95
			continue;
sl@0
    96
		iClipRect.Intersection(clippedDestRect);
sl@0
    97
sl@0
    98
		TRect clippedSrceRect(iClipRect);
sl@0
    99
		clippedSrceRect.Move(offset);
sl@0
   100
sl@0
   101
		if (opaqueSource)
sl@0
   102
			iDrawMode = EDrawModeWriteAlpha;// ie write rather then blend
sl@0
   103
		DoBitBlt(iClipRect.iTl,srceDevice,clippedSrceRect);
sl@0
   104
		if (opaqueSource)
sl@0
   105
			iDrawMode = EDrawModePEN;// set it back how it was
sl@0
   106
		iDevice->iDrawDevice->UpdateRegion(iClipRect);
sl@0
   107
		}
sl@0
   108
sl@0
   109
	aGc.iDevice->DrawingEnd();
sl@0
   110
	iDevice->DrawingEnd();
sl@0
   111
	}
sl@0
   112
sl@0
   113
sl@0
   114
/** Draws the whole of a CFbsBitmap.
sl@0
   115
sl@0
   116
@param aDest   The position to draw the top left corner of the bitmap.
sl@0
   117
@param aBitmap The source bitmap. */
sl@0
   118
EXPORT_C void CFbsBitGc::BitBlt(const TPoint& aDest,const CFbsBitmap* aBitmap)
sl@0
   119
    {
sl@0
   120
    if (aBitmap == NULL || !aBitmap->Handle())
sl@0
   121
    	return;
sl@0
   122
    
sl@0
   123
	aBitmap->BeginDataAccess();
sl@0
   124
    BitBlt(aDest,aBitmap,TRect(aBitmap->SizeInPixels()));
sl@0
   125
	aBitmap->EndDataAccess(ETrue);
sl@0
   126
	}
sl@0
   127
sl@0
   128
sl@0
   129
/** Draws a particular rectangle from a CFbsBitmap.
sl@0
   130
sl@0
   131
@param aDest The position to draw the top left corner of the bitmap.
sl@0
   132
@param aBitmap The source bitmap.
sl@0
   133
@param aSrceRect A rectangle defining the piece of the source to be drawn. */
sl@0
   134
EXPORT_C void CFbsBitGc::BitBlt(const TPoint& aDest,
sl@0
   135
								const CFbsBitmap* aBitmap,
sl@0
   136
								const TRect& aSrceRect)
sl@0
   137
    {
sl@0
   138
	if (aBitmap == NULL || !aBitmap->Handle()|| CheckDevice(aSrceRect))
sl@0
   139
		return;
sl@0
   140
sl@0
   141
	aBitmap->BeginDataAccess();
sl@0
   142
		
sl@0
   143
	TRect srceRect(aSrceRect);
sl@0
   144
	const TRect area(aBitmap->SizeInPixels());
sl@0
   145
	if (!srceRect.Intersects(area))
sl@0
   146
		{
sl@0
   147
		aBitmap->EndDataAccess(ETrue);
sl@0
   148
		return;
sl@0
   149
		}
sl@0
   150
	srceRect.Intersection(area);
sl@0
   151
sl@0
   152
	const TPoint destPoint(aDest + iOrigin + srceRect.iTl - aSrceRect.iTl);
sl@0
   153
	const TPoint offset(srceRect.iTl - destPoint);
sl@0
   154
sl@0
   155
	TRect targetRect(destPoint,srceRect.Size());
sl@0
   156
	AddRect(targetRect);
sl@0
   157
	if (UserClipRect(targetRect))
sl@0
   158
		{
sl@0
   159
		aBitmap->EndDataAccess(ETrue);
sl@0
   160
		return;
sl@0
   161
		}
sl@0
   162
sl@0
   163
	SetupDevice();
sl@0
   164
	iDevice->DrawingBegin();
sl@0
   165
sl@0
   166
	CBitwiseBitmap* srce = ((CFbsBitGcBitmap*)aBitmap)->Address();
sl@0
   167
	BG_ASSERT_DEBUG(srce,EBitgdiPanicInvalidBitmap);
sl@0
   168
sl@0
   169
	CFbsRasterizer* rasterizer = PrepareRasterizerForExtendedBitmap(*aBitmap, targetRect, offset);
sl@0
   170
sl@0
   171
	TInt count;
sl@0
   172
	const TInt limit = iDefaultRegionPtr->Count();
sl@0
   173
	CGraphicsAccelerator* ga = GraphicsAccelerator();
sl@0
   174
	TBool opaqueSource = (!IsAlphaChannel(aBitmap->DisplayMode())) && (iDrawMode == EDrawModePEN);
sl@0
   175
sl@0
   176
	if(ga && (iShadowMode == CFbsDrawDevice::ENoShadow))
sl@0
   177
		{
sl@0
   178
	    TInt gaOperationResult = KErrUnknown;
sl@0
   179
		TAcceleratedBitmapSpec bitmapSpec(const_cast<CFbsBitmap*>(aBitmap));
sl@0
   180
        iDevice->DrawingEnd();
sl@0
   181
sl@0
   182
		for(count=0;count<limit;count++)
sl@0
   183
			{
sl@0
   184
sl@0
   185
			iClipRect=(*iDefaultRegionPtr)[count];
sl@0
   186
			if(!iClipRect.Intersects(targetRect))
sl@0
   187
				continue;
sl@0
   188
			iClipRect.Intersection(targetRect);
sl@0
   189
sl@0
   190
			TRect clippedSrceRect(iClipRect);
sl@0
   191
			clippedSrceRect.Move(offset);
sl@0
   192
sl@0
   193
			gaOperationResult = ga->Operation(TGopBitBlt(iClipRect.iTl,bitmapSpec,clippedSrceRect));
sl@0
   194
			if(gaOperationResult != KErrNone)
sl@0
   195
				break;
sl@0
   196
			iDevice->iDrawDevice->UpdateRegion(iClipRect);
sl@0
   197
			}
sl@0
   198
		if(gaOperationResult == KErrNone)
sl@0
   199
			goto finish;
sl@0
   200
		iDevice->DrawingBegin();
sl@0
   201
		}
sl@0
   202
sl@0
   203
	for(count=0;count<limit;count++)
sl@0
   204
		{
sl@0
   205
		iClipRect=(*iDefaultRegionPtr)[count];
sl@0
   206
		if(!iClipRect.Intersects(targetRect))
sl@0
   207
			continue;
sl@0
   208
		iClipRect.Intersection(targetRect);
sl@0
   209
sl@0
   210
		TRect clippedSrceRect(iClipRect);
sl@0
   211
		clippedSrceRect.Move(offset);
sl@0
   212
sl@0
   213
		if (opaqueSource)
sl@0
   214
			iDrawMode = EDrawModeWriteAlpha;// ie write rather then blend
sl@0
   215
		DoBitBlt(iClipRect.iTl,srce,aBitmap->DataAddress(),aBitmap->DataStride(),clippedSrceRect);
sl@0
   216
		if (opaqueSource)
sl@0
   217
			iDrawMode = EDrawModePEN;// set it back how it was
sl@0
   218
		iDevice->iDrawDevice->UpdateRegion(iClipRect);
sl@0
   219
		}
sl@0
   220
sl@0
   221
	iDevice->DrawingEnd();
sl@0
   222
finish:
sl@0
   223
	if (rasterizer)
sl@0
   224
		{
sl@0
   225
		rasterizer->EndBitmap(aBitmap->SerialNumber());
sl@0
   226
		}
sl@0
   227
	aBitmap->EndDataAccess(ETrue);
sl@0
   228
	}
sl@0
   229
sl@0
   230
sl@0
   231
/** Performs a masked bitmap block transfer.
sl@0
   232
sl@0
   233
The function provides a concrete implementation of the pure virtual
sl@0
   234
function CBitmapContext::BitBltMasked(). The function
sl@0
   235
behaviour is the same as documented in that class.
sl@0
   236
sl@0
   237
There are several points to note about this implementation of
sl@0
   238
BitBltMasked():
sl@0
   239
sl@0
   240
1.For best performance the aMaskBitmap and source aBitmap should
sl@0
   241
have the same display mode as the destination device/bitmap.
sl@0
   242
sl@0
   243
2.For performance reasons this implementation does not validate
sl@0
   244
the contents of the aMaskBitmap. The caller must ensure the mask
sl@0
   245
pixels are either black or white otherwise undefined blitting causing
sl@0
   246
unpredictable discoloration will result. This is especially true
sl@0
   247
for index (where pixel is palette entry) display modes (e.g. EColor16).
sl@0
   248
It is up to the caller to decide if they wish to utilise
sl@0
   249
CFbsBitmap::IsMonochrome().
sl@0
   250
sl@0
   251
3.Alpha blending is used when the display mode of the mask bitmap aMaskBitmap
sl@0
   252
is EGray256.
sl@0
   253
sl@0
   254
@see CBitmapContext::BitBltMasked() */
sl@0
   255
EXPORT_C void CFbsBitGc::BitBltMasked(const TPoint& aDest,
sl@0
   256
									  const CFbsBitmap* aBitmap,
sl@0
   257
									  const TRect& aSourceRect,
sl@0
   258
									  const CFbsBitmap* aMaskBitmap,
sl@0
   259
									  TBool aInvertMask)
sl@0
   260
    {
sl@0
   261
	if (aBitmap == NULL || !aBitmap->Handle() ||
sl@0
   262
		aMaskBitmap == NULL || !aMaskBitmap->Handle() ||
sl@0
   263
		CheckDevice(aSourceRect))
sl@0
   264
		return;
sl@0
   265
sl@0
   266
	aBitmap->BeginDataAccess();
sl@0
   267
	aMaskBitmap->BeginDataAccess();
sl@0
   268
		
sl@0
   269
	TRect srceRect(aSourceRect);
sl@0
   270
	const TRect area(aBitmap->SizeInPixels());
sl@0
   271
	if (!srceRect.Intersects(area))
sl@0
   272
		{
sl@0
   273
		aBitmap->EndDataAccess(ETrue);
sl@0
   274
		aMaskBitmap->EndDataAccess(ETrue);
sl@0
   275
		return;
sl@0
   276
		}
sl@0
   277
	srceRect.Intersection(area);
sl@0
   278
sl@0
   279
	const TPoint destPoint(aDest + iOrigin + srceRect.iTl - aSourceRect.iTl);
sl@0
   280
	const TRect destRect(destPoint,srceRect.Size());
sl@0
   281
	const TPoint offset(srceRect.iTl - destPoint);
sl@0
   282
	const TPoint ditherorigin(iDitherOrigin + aDest);
sl@0
   283
sl@0
   284
	TRect clippedDestRect(destRect);
sl@0
   285
	AddRect(clippedDestRect);
sl@0
   286
	if (UserClipRect(clippedDestRect))
sl@0
   287
		{
sl@0
   288
		aBitmap->EndDataAccess(ETrue);
sl@0
   289
		aMaskBitmap->EndDataAccess(ETrue);
sl@0
   290
		return;
sl@0
   291
		}
sl@0
   292
sl@0
   293
	SetupDevice();
sl@0
   294
	iDevice->DrawingBegin();
sl@0
   295
sl@0
   296
sl@0
   297
	CBitwiseBitmap* srcebmp = ((CFbsBitGcBitmap*)aBitmap)->Address();
sl@0
   298
	CBitwiseBitmap* maskbmp = ((CFbsBitGcBitmap*)aMaskBitmap)->Address();
sl@0
   299
	BG_ASSERT_DEBUG(srcebmp,EBitgdiPanicInvalidBitmap);
sl@0
   300
	BG_ASSERT_DEBUG(maskbmp,EBitgdiPanicInvalidBitmap);
sl@0
   301
sl@0
   302
	const TDisplayMode maskMode = maskbmp->DisplayMode();
sl@0
   303
sl@0
   304
	// Do the background fill the lazy way with flicker if any of the following are true:
sl@0
   305
	// 1. There is no anti-flicker buffer
sl@0
   306
	// 2. The source and mask bitmaps are the same
sl@0
   307
	// 3. The brush style is patterned and the mask is an alpha mask
sl@0
   308
	// 4. The brush style is not null or solid or patterned
sl@0
   309
sl@0
   310
	if (!iDevice->iBitBltMaskedBuffer ||
sl@0
   311
		srcebmp == maskbmp ||
sl@0
   312
		(maskMode == EGray256 && iBrushStyle == EPatternedBrush) ||
sl@0
   313
		iBrushStyle > EPatternedBrush)
sl@0
   314
		{
sl@0
   315
		iBrushBitmap.BeginDataAccess();
sl@0
   316
		CFbsRasterizer* brushRasterizer = PrepareRasterizerForExtendedBitmap(iBrushBitmap);
sl@0
   317
		RectFill(destRect);
sl@0
   318
		if (brushRasterizer)
sl@0
   319
			{
sl@0
   320
			brushRasterizer->EndBitmap(iBrushBitmap.SerialNumber());
sl@0
   321
			}
sl@0
   322
		iBrushBitmap.EndDataAccess(ETrue);
sl@0
   323
		}
sl@0
   324
sl@0
   325
	const TInt8 shadowMode = iShadowMode;
sl@0
   326
	iShadowMode = CFbsDrawDevice::ENoShadow;
sl@0
   327
	SetupDevice();
sl@0
   328
sl@0
   329
	CFbsRasterizer* rasterizer = PrepareRasterizerForExtendedBitmap(*aBitmap, clippedDestRect, offset);
sl@0
   330
	CFbsRasterizer* maskRasterizer = NULL;
sl@0
   331
	if (srcebmp != maskbmp)
sl@0
   332
		{
sl@0
   333
		if (aMaskBitmap->SizeInPixels().iWidth >= aBitmap->SizeInPixels().iWidth
sl@0
   334
			&& aMaskBitmap->SizeInPixels().iHeight >= aBitmap->SizeInPixels().iHeight)
sl@0
   335
			{
sl@0
   336
			// Mask is not tiled. Pass same region of interest as source bitmap to rasterizer.
sl@0
   337
			maskRasterizer = PrepareRasterizerForExtendedBitmap(*aMaskBitmap, clippedDestRect, offset);
sl@0
   338
			}
sl@0
   339
		else
sl@0
   340
			{
sl@0
   341
			// Mask is tiled. Do not pass any region of interest to rasterizer.
sl@0
   342
			maskRasterizer = PrepareRasterizerForExtendedBitmap(*aMaskBitmap);
sl@0
   343
			}
sl@0
   344
		}
sl@0
   345
sl@0
   346
    TInt count;
sl@0
   347
	const TInt limit = iDefaultRegionPtr->Count();
sl@0
   348
	CGraphicsAccelerator* ga = GraphicsAccelerator();
sl@0
   349
	TBool opaqueSource = (!IsAlphaChannel(aBitmap->DisplayMode())) && (iDrawMode == EDrawModePEN);
sl@0
   350
sl@0
   351
	if(ga)
sl@0
   352
		{
sl@0
   353
		if((iBrushStyle == ENullBrush) && aInvertMask &&
sl@0
   354
		   (shadowMode == CFbsDrawDevice::ENoShadow))
sl@0
   355
			{
sl@0
   356
			TInt gaOperationResult = KErrUnknown;
sl@0
   357
			TAcceleratedBitmapSpec bitmapSpec(const_cast<CFbsBitmap*>(aBitmap));
sl@0
   358
			TAcceleratedBitmapSpec bitmapMaskSpec(const_cast<CFbsBitmap*>(aMaskBitmap));
sl@0
   359
			iDevice->DrawingEnd();
sl@0
   360
sl@0
   361
			for(count=0;count<limit;count++)
sl@0
   362
				{
sl@0
   363
				iClipRect=(*iDefaultRegionPtr)[count];
sl@0
   364
				if(!iClipRect.Intersects(clippedDestRect))
sl@0
   365
					continue;
sl@0
   366
				iClipRect.Intersection(clippedDestRect);
sl@0
   367
				TRect clippedSrceRect(iClipRect);
sl@0
   368
				clippedSrceRect.Move(offset);
sl@0
   369
sl@0
   370
				if(maskbmp->DisplayMode() == EGray256)
sl@0
   371
					gaOperationResult = ga->Operation(TGopBitBltAlphaBitmap(iClipRect.iTl,
sl@0
   372
																			bitmapSpec,
sl@0
   373
																			clippedSrceRect,
sl@0
   374
																			bitmapMaskSpec));
sl@0
   375
				else
sl@0
   376
					gaOperationResult = ga->Operation(TGopBitBltMasked(iClipRect.iTl,
sl@0
   377
																	   bitmapSpec,
sl@0
   378
																	   clippedSrceRect,
sl@0
   379
																	   bitmapMaskSpec));
sl@0
   380
sl@0
   381
				if(gaOperationResult != KErrNone)
sl@0
   382
					break;
sl@0
   383
				iDevice->iDrawDevice->UpdateRegion(iClipRect);
sl@0
   384
				}
sl@0
   385
			if(gaOperationResult == KErrNone)
sl@0
   386
				goto finish;
sl@0
   387
			iDevice->DrawingBegin();
sl@0
   388
			}
sl@0
   389
		}
sl@0
   390
sl@0
   391
	for(count=0;count<limit;count++)
sl@0
   392
		{
sl@0
   393
		iClipRect=(*iDefaultRegionPtr)[count];
sl@0
   394
		if (!iClipRect.Intersects(clippedDestRect))
sl@0
   395
			continue;
sl@0
   396
		iClipRect.Intersection(clippedDestRect);
sl@0
   397
sl@0
   398
		TRect clippedSrceRect(iClipRect);
sl@0
   399
		clippedSrceRect.Move(offset);
sl@0
   400
sl@0
   401
		if (opaqueSource)
sl@0
   402
			iDrawMode = EDrawModeWriteAlpha;// ie write rather then blend
sl@0
   403
		DoBitBltMasked(iClipRect.iTl,
sl@0
   404
					   srcebmp,
sl@0
   405
					   aBitmap->DataAddress(),
sl@0
   406
					   clippedSrceRect,
sl@0
   407
					   maskbmp,
sl@0
   408
					   aMaskBitmap->DataAddress(),
sl@0
   409
					   aInvertMask,
sl@0
   410
					   ditherorigin,
sl@0
   411
					   shadowMode);
sl@0
   412
		if (opaqueSource)
sl@0
   413
			iDrawMode = EDrawModePEN;// set it back how it was
sl@0
   414
		iDevice->iDrawDevice->UpdateRegion(iClipRect);
sl@0
   415
		}
sl@0
   416
sl@0
   417
	iDevice->DrawingEnd();
sl@0
   418
finish:
sl@0
   419
	if (rasterizer)
sl@0
   420
		{
sl@0
   421
		rasterizer->EndBitmap(aBitmap->SerialNumber());
sl@0
   422
		}
sl@0
   423
	if (maskRasterizer)
sl@0
   424
		{
sl@0
   425
		maskRasterizer->EndBitmap(aMaskBitmap->SerialNumber());
sl@0
   426
		}
sl@0
   427
	aBitmap->EndDataAccess(ETrue);
sl@0
   428
	aMaskBitmap->EndDataAccess(ETrue);
sl@0
   429
	iShadowMode = shadowMode;
sl@0
   430
	}
sl@0
   431
/**
sl@0
   432
Does BitBlt operation of source and bitmap per scanline.
sl@0
   433
sl@0
   434
*/
sl@0
   435
void CFbsBitGc::DoBitBlt(const TPoint& aDest,CFbsDevice* aSrce,const TRect& aSrceRect)
sl@0
   436
	{
sl@0
   437
	const TInt width = aSrceRect.Width();
sl@0
   438
	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
sl@0
   439
#ifdef _DEBUG
sl@0
   440
	TRect deviceSrcRect;
sl@0
   441
	aSrce->iDrawDevice->GetDrawRect(deviceSrcRect);
sl@0
   442
	TRect deviceDestRect;
sl@0
   443
	drawDevice->GetDrawRect(deviceDestRect);
sl@0
   444
#endif
sl@0
   445
	BG_ASSERT_DEBUG(aSrceRect.iTl.iX >= deviceSrcRect.iTl.iX, EBitgdiPanicOutOfBounds);
sl@0
   446
	BG_ASSERT_DEBUG(aSrceRect.iTl.iY >= deviceSrcRect.iTl.iY, EBitgdiPanicOutOfBounds);
sl@0
   447
	BG_ASSERT_DEBUG(aSrceRect.iBr.iX <= deviceSrcRect.iBr.iX, EBitgdiPanicOutOfBounds);
sl@0
   448
	BG_ASSERT_DEBUG(aSrceRect.iBr.iY <= deviceSrcRect.iBr.iY, EBitgdiPanicOutOfBounds);
sl@0
   449
	BG_ASSERT_DEBUG(aDest.iX >= deviceDestRect.iTl.iX, EBitgdiPanicOutOfBounds);
sl@0
   450
	BG_ASSERT_DEBUG(aDest.iY >= deviceDestRect.iTl.iY, EBitgdiPanicOutOfBounds);
sl@0
   451
	BG_ASSERT_DEBUG((aDest.iX + aSrceRect.Width())  <= deviceDestRect.iBr.iX, EBitgdiPanicOutOfBounds);
sl@0
   452
	BG_ASSERT_DEBUG((aDest.iY + aSrceRect.Height()) <= deviceDestRect.iBr.iY, EBitgdiPanicOutOfBounds);
sl@0
   453
sl@0
   454
	CFbsDrawDevice* srcDrawDevice = aSrce->iDrawDevice;
sl@0
   455
	TAny* interface=NULL;
sl@0
   456
	if (iDrawMode==EDrawModeWriteAlpha &&
sl@0
   457
		iShadowMode == CFbsDrawDevice::ENoShadow &&
sl@0
   458
		(aSrceRect.iTl.iX >= 0) &&  (aSrceRect.iTl.iY >= 0) &&
sl@0
   459
		(aDest.iX >= 0) && (aDest.iY >= 0) &&
sl@0
   460
	    srcDrawDevice->DisplayMode() == drawDevice->DisplayMode() &&
sl@0
   461
		drawDevice->GetInterface(KFastBlit2InterfaceID, interface) == KErrNone)
sl@0
   462
		{
sl@0
   463
		// Conditions in CFbsBitGc allow for optimised blitting.
sl@0
   464
		// The draw device supports the optimised blitting function.
sl@0
   465
		// Operation may fail regardless due to unacceptable conditions in the draw device.
sl@0
   466
		BG_ASSERT_DEBUG(interface!=NULL, EBitgdiPanicNullPointer);
sl@0
   467
		MFastBlit2* fastBlit = reinterpret_cast<MFastBlit2*>(interface);
sl@0
   468
		if (fastBlit->WriteBitmapBlock(aDest, srcDrawDevice, aSrceRect) == KErrNone)
sl@0
   469
			{
sl@0
   470
			return;
sl@0
   471
			}
sl@0
   472
		}
sl@0
   473
	MFastBlend* fastBlend=NULL;
sl@0
   474
	if (FastBlendInterface(NULL,NULL,fastBlend)==KErrNone)
sl@0
   475
		{
sl@0
   476
		if (fastBlend->FastBlendBitmap(aDest, srcDrawDevice, aSrceRect, iDrawMode, iShadowMode)==KErrNone)
sl@0
   477
			{
sl@0
   478
			return;
sl@0
   479
			}
sl@0
   480
		}
sl@0
   481
	//scanLineBuffer is destination scanline buffer.
sl@0
   482
	TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
sl@0
   483
	const TInt scanLineBytes = drawDevice->ScanLineBytes();
sl@0
   484
	TPtr8 scanLineDes((TUint8*)scanLineBuffer,scanLineBytes,scanLineBytes);
sl@0
   485
	//dispMode is destination display mode.
sl@0
   486
	const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
sl@0
   487
	TInt destY = aDest.iY;
sl@0
   488
	//Gets the scanline from the source, into the buffer scanLineDes.
sl@0
   489
	//The DoGetScanLine operation is also responsible for converting
sl@0
   490
	// the buffer pixel format to destination display format.
sl@0
   491
sl@0
   492
	for (TInt row = aSrceRect.iTl.iY; row < aSrceRect.iBr.iY; row++,destY++)
sl@0
   493
		{
sl@0
   494
		aSrce->DoGetScanLine(scanLineDes,TPoint(aSrceRect.iTl.iX,row),width,dispMode);
sl@0
   495
		drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,iDrawMode);
sl@0
   496
		}
sl@0
   497
	}
sl@0
   498
sl@0
   499
/**
sl@0
   500
Calculates the position into the scanline for the given x coordinate
sl@0
   501
*/
sl@0
   502
TUint CFbsBitGc::MemoryOffsetForPixelPitch(TUint aX, TDisplayMode aDisplayMode)
sl@0
   503
	{
sl@0
   504
	switch (aDisplayMode)
sl@0
   505
		{
sl@0
   506
		case EColor16MU:
sl@0
   507
		case EColor16MA:
sl@0
   508
		case EColor16MAP:
sl@0
   509
			return aX << 2;
sl@0
   510
sl@0
   511
		case EColor16M:
sl@0
   512
			return aX * 3;
sl@0
   513
sl@0
   514
		case EColor4K:
sl@0
   515
		case EColor64K:
sl@0
   516
			return aX << 1;
sl@0
   517
sl@0
   518
		case EGray256:
sl@0
   519
		case EColor256:
sl@0
   520
			return aX;
sl@0
   521
sl@0
   522
		default:
sl@0
   523
			BG_PANIC_DEBUG(EBitgdiPanicInvalidDisplayMode);
sl@0
   524
		break;
sl@0
   525
		}
sl@0
   526
	return 0;
sl@0
   527
	}
sl@0
   528
sl@0
   529
/**
sl@0
   530
Gets the scanline pointer with the offset
sl@0
   531
*/
sl@0
   532
TUint32* CFbsBitGc::GetScanLineOffsetPtr(CBitwiseBitmap* aSrce, TUint32*& aSlptr, TInt aLength, TPoint aPixel,TUint32* aBase, TLineScanningPosition& aLineScanningPosition, TUint aXOffset)
sl@0
   533
	{
sl@0
   534
	aSrce->GetScanLinePtr(aSlptr, aLength, aPixel, aBase, aLineScanningPosition);
sl@0
   535
	return (TUint32*)((TUint8*)aSlptr + aXOffset);
sl@0
   536
	}
sl@0
   537
sl@0
   538
void CFbsBitGc::DoBitBlt(const TPoint& aDest,
sl@0
   539
						 CBitwiseBitmap* aSrce,
sl@0
   540
						 TUint32* aBase,
sl@0
   541
						 TInt aStride,
sl@0
   542
						 const TRect& aSrceRect)
sl@0
   543
	{
sl@0
   544
	// Does multiple bitmap widths for painting rects only
sl@0
   545
	const TInt width = aSrceRect.Width();
sl@0
   546
	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
sl@0
   547
#ifdef _DEBUG
sl@0
   548
	TRect deviceDestRect;
sl@0
   549
	drawDevice->GetDrawRect(deviceDestRect);
sl@0
   550
#endif
sl@0
   551
	BG_ASSERT_DEBUG(aDest.iX >= deviceDestRect.iTl.iX, EBitgdiPanicOutOfBounds);
sl@0
   552
	BG_ASSERT_DEBUG(aDest.iY >= deviceDestRect.iTl.iY, EBitgdiPanicOutOfBounds);
sl@0
   553
	BG_ASSERT_DEBUG((aDest.iX + aSrceRect.Width())  <= deviceDestRect.iBr.iX, EBitgdiPanicOutOfBounds);
sl@0
   554
	BG_ASSERT_DEBUG((aDest.iY + aSrceRect.Height()) <= deviceDestRect.iBr.iY, EBitgdiPanicOutOfBounds);
sl@0
   555
sl@0
   556
	TSize srcSize = aSrce->SizeInPixels();
sl@0
   557
	if (srcSize.iWidth == 0 || srcSize.iHeight == 0)
sl@0
   558
		return; //no point doing anything if asked to draw zero size bitmap
sl@0
   559
sl@0
   560
	TAny* interface=NULL;
sl@0
   561
	if (iDrawMode==EDrawModeWriteAlpha &&
sl@0
   562
		iShadowMode == CFbsDrawDevice::ENoShadow &&
sl@0
   563
		aSrceRect.iTl.iX >= 0 &&
sl@0
   564
		aSrceRect.iTl.iY >= 0 &&
sl@0
   565
		aSrceRect.iBr.iX <= srcSize.iWidth &&
sl@0
   566
		aSrceRect.iBr.iY <= srcSize.iHeight &&
sl@0
   567
		(aDest.iX >= 0) && (aDest.iY >= 0) &&
sl@0
   568
		!aSrce->IsCompressed() &&
sl@0
   569
		aSrce->DisplayMode() == drawDevice->DisplayMode() &&
sl@0
   570
		drawDevice->GetInterface(KFastBlit2InterfaceID, interface) == KErrNone)
sl@0
   571
		{
sl@0
   572
		// Conditions in CFbsBitGc allow for optimised blitting.
sl@0
   573
		// The draw device supports the optimised blitting function.
sl@0
   574
		// Operation may fail regardless due to unacceptable conditions in the draw device.
sl@0
   575
		BG_ASSERT_DEBUG(interface!=NULL, EBitgdiPanicNullPointer);
sl@0
   576
		MFastBlit2* fastBlit = reinterpret_cast<MFastBlit2*>(interface);
sl@0
   577
		if (fastBlit && (fastBlit->WriteBitmapBlock(aDest, aBase, aStride, srcSize, aSrceRect) == KErrNone))
sl@0
   578
			{
sl@0
   579
			return;
sl@0
   580
			}
sl@0
   581
		}
sl@0
   582
	MFastBlend* fastBlend=NULL;
sl@0
   583
	if (FastBlendInterface(aSrce,NULL,fastBlend)==KErrNone)
sl@0
   584
		{
sl@0
   585
		if (fastBlend->FastBlendBitmap(aDest, aBase, aStride, srcSize, aSrceRect, aSrce->DisplayMode(), iDrawMode, iShadowMode)== KErrNone)
sl@0
   586
			{
sl@0
   587
			return;
sl@0
   588
			}
sl@0
   589
		}
sl@0
   590
sl@0
   591
	const TInt scanLineBytes = drawDevice->ScanLineBytes();
sl@0
   592
	TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
sl@0
   593
	TPtr8 scanLineDes((TUint8*)scanLineBuffer,scanLineBytes,scanLineBytes);
sl@0
   594
sl@0
   595
	const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
sl@0
   596
sl@0
   597
	const TBool useScanLinePtr = (!iShadowMode) && (dispMode == aSrce->DisplayMode()) && (TDisplayModeUtils::NumDisplayModeBitsPerPixel(dispMode)>=8);
sl@0
   598
	TUint32* slptr=NULL;
sl@0
   599
	TUint offset = 0;
sl@0
   600
	TUint32* lastScanLine = NULL;
sl@0
   601
	if (useScanLinePtr)
sl@0
   602
		lastScanLine = aSrce->ScanLineAddress(aBase,aSrceRect.iBr.iY-1);
sl@0
   603
sl@0
   604
	TInt srceWidth = srcSize.iWidth;
sl@0
   605
	TInt partlinestart = 0;
sl@0
   606
	partlinestart = aSrceRect.iTl.iX % srceWidth;
sl@0
   607
	if (partlinestart < 0)
sl@0
   608
		partlinestart += srceWidth;
sl@0
   609
	const TInt partlinelength = Min(srceWidth - partlinestart,width);
sl@0
   610
	TInt destX = aDest.iX;
sl@0
   611
	const TInt destXlimit=destX+width;
sl@0
   612
sl@0
   613
	// first part line
sl@0
   614
	if (partlinestart > 0 && partlinelength > 0)
sl@0
   615
		{
sl@0
   616
		TPoint srcecoord1(partlinestart,aSrceRect.iTl.iY);
sl@0
   617
		TInt desty = aDest.iY;
sl@0
   618
		TPoint ditherorigin(iDitherOrigin);
sl@0
   619
		ditherorigin.iX += aDest.iX;
sl@0
   620
		ditherorigin.iY += desty;
sl@0
   621
sl@0
   622
		TLineScanningPosition lineScanPos(aBase);
sl@0
   623
sl@0
   624
		if (useScanLinePtr)
sl@0
   625
			{
sl@0
   626
			offset = MemoryOffsetForPixelPitch(partlinestart, dispMode);
sl@0
   627
			if (aSrce->IsCompressed())
sl@0
   628
				{
sl@0
   629
				while (srcecoord1.iY < aSrceRect.iBr.iY)
sl@0
   630
					{
sl@0
   631
					scanLineBuffer = GetScanLineOffsetPtr(aSrce, slptr, partlinelength, srcecoord1, aBase, lineScanPos, offset);
sl@0
   632
					if (srcecoord1.iY==aSrceRect.iTl.iY)
sl@0
   633
						{
sl@0
   634
						aSrce->SetCompressionBookmark(lineScanPos,aBase,NULL);
sl@0
   635
						}
sl@0
   636
					drawDevice->WriteLine(aDest.iX,desty,partlinelength, scanLineBuffer,iDrawMode);
sl@0
   637
					srcecoord1.iY++,desty++,ditherorigin.iY++;
sl@0
   638
					}
sl@0
   639
				}
sl@0
   640
			else
sl@0
   641
				{
sl@0
   642
				while (srcecoord1.iY < aSrceRect.iBr.iY)
sl@0
   643
					{
sl@0
   644
					scanLineBuffer = GetScanLineOffsetPtr(aSrce, slptr, partlinelength, srcecoord1, aBase, lineScanPos, offset);
sl@0
   645
					do
sl@0
   646
						{
sl@0
   647
						drawDevice->WriteLine(aDest.iX,desty,partlinelength, scanLineBuffer,iDrawMode);
sl@0
   648
						scanLineBuffer = (TUint32*)((TUint8*)scanLineBuffer + aStride);
sl@0
   649
						srcecoord1.iY++,desty++,ditherorigin.iY++;
sl@0
   650
						}
sl@0
   651
					while ((srcecoord1.iY < aSrceRect.iBr.iY) && (scanLineBuffer < lastScanLine));
sl@0
   652
					}
sl@0
   653
				}
sl@0
   654
			}
sl@0
   655
		else
sl@0
   656
			{
sl@0
   657
			for (; srcecoord1.iY < aSrceRect.iBr.iY; srcecoord1.iY++,desty++,ditherorigin.iY++)
sl@0
   658
				{
sl@0
   659
				aSrce->GetScanLine(scanLineDes,srcecoord1,partlinelength,ETrue,
sl@0
   660
						   ditherorigin,dispMode,aBase, lineScanPos);
sl@0
   661
				if (srcecoord1.iY==aSrceRect.iTl.iY)
sl@0
   662
					{
sl@0
   663
					aSrce->SetCompressionBookmark(lineScanPos,aBase,NULL);
sl@0
   664
					}
sl@0
   665
				drawDevice->WriteLine(aDest.iX,desty,partlinelength, scanLineBuffer,iDrawMode);
sl@0
   666
				}
sl@0
   667
			}
sl@0
   668
sl@0
   669
		destX+=partlinelength;
sl@0
   670
		}
sl@0
   671
sl@0
   672
	// multiple complete lines - columns
sl@0
   673
	TInt numcolumns = 0;
sl@0
   674
	numcolumns = (destXlimit - destX) / srceWidth;
sl@0
   675
	if (numcolumns > 0)
sl@0
   676
		{
sl@0
   677
		TPoint srcecoord2(0,aSrceRect.iTl.iY);
sl@0
   678
		TInt desty = aDest.iY;
sl@0
   679
		TPoint ditherorigin(iDitherOrigin);
sl@0
   680
		ditherorigin.iX += destX;
sl@0
   681
		ditherorigin.iY += desty;
sl@0
   682
sl@0
   683
		TLineScanningPosition lineScanPos(aBase);
sl@0
   684
sl@0
   685
		if (useScanLinePtr)
sl@0
   686
			{
sl@0
   687
			if (aSrce->IsCompressed())
sl@0
   688
				{
sl@0
   689
				while (srcecoord2.iY < aSrceRect.iBr.iY)
sl@0
   690
					{
sl@0
   691
					TPoint coord(srcecoord2);
sl@0
   692
					aSrce->GetScanLinePtr(slptr, srceWidth, coord,aBase, lineScanPos);
sl@0
   693
					if (srcecoord2.iY==aSrceRect.iTl.iY)
sl@0
   694
						{
sl@0
   695
						aSrce->SetCompressionBookmark(lineScanPos, aBase,NULL);
sl@0
   696
						}
sl@0
   697
					TInt tempdestX = destX;
sl@0
   698
					for (TInt count = 0; count < numcolumns; count++,tempdestX+=srceWidth)
sl@0
   699
						{
sl@0
   700
						drawDevice->WriteLine(tempdestX,desty,srceWidth, slptr,iDrawMode);
sl@0
   701
						ditherorigin.iX += srceWidth;
sl@0
   702
						}
sl@0
   703
					srcecoord2.iY++,desty++,ditherorigin.iY++;
sl@0
   704
					}
sl@0
   705
				}
sl@0
   706
			else
sl@0
   707
				{
sl@0
   708
				while (srcecoord2.iY < aSrceRect.iBr.iY)
sl@0
   709
					{
sl@0
   710
					TPoint coord(srcecoord2);
sl@0
   711
					aSrce->GetScanLinePtr(slptr, srceWidth, coord,aBase, lineScanPos);
sl@0
   712
					do
sl@0
   713
						{
sl@0
   714
						TInt tempdestX = destX;
sl@0
   715
						for (TInt count = 0; count < numcolumns; count++,tempdestX+=srceWidth)
sl@0
   716
							{
sl@0
   717
							drawDevice->WriteLine(tempdestX,desty,srceWidth, slptr,iDrawMode);
sl@0
   718
							ditherorigin.iX += srceWidth;
sl@0
   719
							}
sl@0
   720
						slptr = (TUint32*)((TUint8*)slptr + aStride);
sl@0
   721
						srcecoord2.iY++,desty++,ditherorigin.iY++;
sl@0
   722
						}
sl@0
   723
					while ((srcecoord2.iY < aSrceRect.iBr.iY) && (slptr < lastScanLine));
sl@0
   724
					}
sl@0
   725
				}
sl@0
   726
			}
sl@0
   727
		else
sl@0
   728
			{
sl@0
   729
			for (; srcecoord2.iY < aSrceRect.iBr.iY; srcecoord2.iY++,desty++,ditherorigin.iY++)
sl@0
   730
				{
sl@0
   731
				TInt tempdestX = destX;
sl@0
   732
				TPoint coord(srcecoord2);
sl@0
   733
				aSrce->GetScanLinePtr(slptr, srceWidth, coord,aBase, lineScanPos);
sl@0
   734
				if (srcecoord2.iY==aSrceRect.iTl.iY)
sl@0
   735
					{
sl@0
   736
					aSrce->SetCompressionBookmark(lineScanPos, aBase,NULL);
sl@0
   737
					}
sl@0
   738
				for (TInt count = 0; count < numcolumns; count++,tempdestX+=srceWidth)
sl@0
   739
					{
sl@0
   740
					aSrce->GetScanLine(slptr, scanLineDes,coord,srceWidth,ETrue,
sl@0
   741
						   ditherorigin,dispMode);
sl@0
   742
					drawDevice->WriteLine(tempdestX,desty,srceWidth, scanLineBuffer,iDrawMode);
sl@0
   743
					ditherorigin.iX += srceWidth;
sl@0
   744
					}
sl@0
   745
				}
sl@0
   746
			}
sl@0
   747
sl@0
   748
		destX += numcolumns * srceWidth;
sl@0
   749
		}
sl@0
   750
sl@0
   751
	// final part line
sl@0
   752
	if (destX < destXlimit)
sl@0
   753
		{
sl@0
   754
		const TInt restofline = destXlimit - destX;
sl@0
   755
		TPoint srcecoord3(0,aSrceRect.iTl.iY);
sl@0
   756
		TInt desty = aDest.iY;
sl@0
   757
		TPoint ditherorigin(iDitherOrigin);
sl@0
   758
		ditherorigin.iX += destX;
sl@0
   759
		ditherorigin.iY += desty;
sl@0
   760
sl@0
   761
		TLineScanningPosition lineScanPos(aBase);
sl@0
   762
sl@0
   763
		if (useScanLinePtr)
sl@0
   764
			{
sl@0
   765
			offset = 0;
sl@0
   766
			if (aSrce->IsCompressed())
sl@0
   767
				{
sl@0
   768
				while (srcecoord3.iY < aSrceRect.iBr.iY)
sl@0
   769
					{
sl@0
   770
					scanLineBuffer = GetScanLineOffsetPtr(aSrce, slptr, srceWidth, srcecoord3, aBase, lineScanPos, offset);
sl@0
   771
					if (srcecoord3.iY==aSrceRect.iTl.iY)
sl@0
   772
						{
sl@0
   773
						aSrce->SetCompressionBookmark(lineScanPos,aBase,NULL);
sl@0
   774
						}
sl@0
   775
					drawDevice->WriteLine(destX,desty,restofline,scanLineBuffer,iDrawMode);
sl@0
   776
					srcecoord3.iY++,desty++,ditherorigin.iY++;
sl@0
   777
					}
sl@0
   778
				}
sl@0
   779
			else
sl@0
   780
				{
sl@0
   781
				while (srcecoord3.iY < aSrceRect.iBr.iY)
sl@0
   782
					{
sl@0
   783
					scanLineBuffer = GetScanLineOffsetPtr(aSrce, slptr, srceWidth, srcecoord3, aBase, lineScanPos, offset);
sl@0
   784
					do
sl@0
   785
						{
sl@0
   786
						drawDevice->WriteLine(destX,desty,restofline,scanLineBuffer,iDrawMode);
sl@0
   787
						scanLineBuffer = (TUint32*)((TUint8*)scanLineBuffer + aStride);
sl@0
   788
						srcecoord3.iY++,desty++,ditherorigin.iY++;
sl@0
   789
						}
sl@0
   790
					while ((srcecoord3.iY < aSrceRect.iBr.iY) && (scanLineBuffer < lastScanLine));
sl@0
   791
					}
sl@0
   792
				}
sl@0
   793
			}
sl@0
   794
		else
sl@0
   795
			{
sl@0
   796
			for (; srcecoord3.iY < aSrceRect.iBr.iY; srcecoord3.iY++,desty++,ditherorigin.iY++)
sl@0
   797
				{
sl@0
   798
				aSrce->GetScanLine(scanLineDes,srcecoord3,srceWidth,ETrue,
sl@0
   799
								   ditherorigin,dispMode,aBase,lineScanPos);
sl@0
   800
				if (srcecoord3.iY==aSrceRect.iTl.iY)
sl@0
   801
					{
sl@0
   802
					aSrce->SetCompressionBookmark(lineScanPos, aBase,NULL);
sl@0
   803
					}
sl@0
   804
				drawDevice->WriteLine(destX,desty,restofline,scanLineBuffer,iDrawMode);
sl@0
   805
				}
sl@0
   806
			}
sl@0
   807
		}
sl@0
   808
	}
sl@0
   809
sl@0
   810
void CFbsBitGc::DoBitBltMasked(const TPoint& aDest,
sl@0
   811
							   CBitwiseBitmap* aSourceBitmap,
sl@0
   812
							   TUint32* aSourceBase,
sl@0
   813
							   const TRect& aSourceRect,
sl@0
   814
							   CBitwiseBitmap* aMaskBitmap,
sl@0
   815
							   TUint32* aMaskBase,
sl@0
   816
							   TBool aInvertMask,
sl@0
   817
							   const TPoint& aDitherOrigin,
sl@0
   818
							   TInt aShadowMode)
sl@0
   819
	{
sl@0
   820
	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
sl@0
   821
#ifdef _DEBUG
sl@0
   822
	TRect deviceDestRect;
sl@0
   823
	drawDevice->GetDrawRect(deviceDestRect);
sl@0
   824
#endif
sl@0
   825
	BG_ASSERT_DEBUG(aDest.iX >= deviceDestRect.iTl.iX, EBitgdiPanicOutOfBounds);
sl@0
   826
	BG_ASSERT_DEBUG(aDest.iY >= deviceDestRect.iTl.iY, EBitgdiPanicOutOfBounds);
sl@0
   827
	BG_ASSERT_DEBUG((aDest.iX + aSourceRect.Width()) <= deviceDestRect.iBr.iX, EBitgdiPanicOutOfBounds);
sl@0
   828
	BG_ASSERT_DEBUG((aDest.iY + aSourceRect.Height()) <= deviceDestRect.iBr.iY, EBitgdiPanicOutOfBounds);
sl@0
   829
sl@0
   830
	MFastBlend* fastBlend=NULL;
sl@0
   831
	if (FastBlendInterface(aSourceBitmap,aMaskBitmap,fastBlend)==KErrNone)
sl@0
   832
		{
sl@0
   833
		if (fastBlend->FastBlendBitmapMasked(aDest, aSourceBase, aSourceBitmap->DataStride(), aSourceBitmap->SizeInPixels(), aSourceRect, aSourceBitmap->DisplayMode(),
sl@0
   834
							aMaskBase, aMaskBitmap->DataStride(), aMaskBitmap->DisplayMode(), aMaskBitmap->SizeInPixels(), aSourceRect.iTl, aInvertMask,
sl@0
   835
							iDrawMode, aShadowMode)==KErrNone)
sl@0
   836
			{
sl@0
   837
			return;
sl@0
   838
			}
sl@0
   839
		}
sl@0
   840
sl@0
   841
	const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
sl@0
   842
	if (aMaskBitmap->DisplayMode() == EGray256)
sl@0
   843
		{
sl@0
   844
		DoBitBltAlpha(aDest,aSourceBitmap,aSourceBase,aSourceRect,
sl@0
   845
					  aMaskBitmap,aMaskBase,aSourceRect.iTl,aShadowMode, EFalse);
sl@0
   846
		}
sl@0
   847
	// if screen driver is 16MAP we avoid logical operator pen modes by using DoBitBltAlpha() for blitting
sl@0
   848
	else if (dispMode == EColor16MAP)
sl@0
   849
		{
sl@0
   850
		DoBitBltAlpha(aDest,aSourceBitmap,aSourceBase,aSourceRect,
sl@0
   851
					  aMaskBitmap,aMaskBase,aSourceRect.iTl,aShadowMode, aInvertMask);
sl@0
   852
		}
sl@0
   853
sl@0
   854
	else if (aSourceBitmap == aMaskBitmap)
sl@0
   855
		{
sl@0
   856
		const TInt width = aSourceRect.Width();
sl@0
   857
		TPoint ditherOrigin(aDitherOrigin + aDest);
sl@0
   858
		const TDrawMode drawMode = aInvertMask ? EDrawModeAND : EDrawModeOR;
sl@0
   859
		TPoint srcePoint(aSourceRect.iTl);
sl@0
   860
		TInt destY = aDest.iY;
sl@0
   861
sl@0
   862
		TLineScanningPosition lineScanPos(aSourceBase);
sl@0
   863
sl@0
   864
		const TBool useScanLinePtr = (!aShadowMode) && (dispMode == aSourceBitmap->DisplayMode() && (TDisplayModeUtils::NumDisplayModeBitsPerPixel(dispMode)>=8));
sl@0
   865
		if (useScanLinePtr)
sl@0
   866
			{
sl@0
   867
			TUint32* scanLineBuffer = NULL;
sl@0
   868
			TUint32* slptr=NULL;
sl@0
   869
			TUint offset = MemoryOffsetForPixelPitch(srcePoint.iX, dispMode);
sl@0
   870
sl@0
   871
			if (aSourceBitmap->IsCompressed())
sl@0
   872
				{
sl@0
   873
				for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++,ditherOrigin.iY++)
sl@0
   874
					{
sl@0
   875
					scanLineBuffer = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPos, offset);
sl@0
   876
					drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,drawMode);
sl@0
   877
					}
sl@0
   878
				}
sl@0
   879
			else
sl@0
   880
				{
sl@0
   881
				TUint stride = aSourceBitmap->DataStride();
sl@0
   882
				TUint32* lastScanLine = aSourceBitmap->ScanLineAddress(aSourceBase,aSourceRect.iBr.iY-1);
sl@0
   883
sl@0
   884
				while (srcePoint.iY < aSourceRect.iBr.iY)
sl@0
   885
					{
sl@0
   886
					scanLineBuffer = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPos, offset);
sl@0
   887
					do
sl@0
   888
						{
sl@0
   889
						drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,drawMode);
sl@0
   890
						scanLineBuffer = (TUint32*)((TUint8*)scanLineBuffer + stride);
sl@0
   891
						destY++,srcePoint.iY++,ditherOrigin.iY++;
sl@0
   892
						}
sl@0
   893
					while ((srcePoint.iY < aSourceRect.iBr.iY) && (scanLineBuffer < lastScanLine));
sl@0
   894
					}
sl@0
   895
				}
sl@0
   896
			}
sl@0
   897
		else
sl@0
   898
			{
sl@0
   899
			const TInt scanLineBytes = drawDevice->ScanLineBytes();
sl@0
   900
			TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
sl@0
   901
			TPtr8 scanLineDes((TUint8*)scanLineBuffer,scanLineBytes,scanLineBytes);
sl@0
   902
			for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++,ditherOrigin.iY++)
sl@0
   903
				{
sl@0
   904
				aSourceBitmap->GetScanLine(scanLineDes,srcePoint,width,
sl@0
   905
								   ETrue,ditherOrigin,dispMode,aSourceBase,lineScanPos);
sl@0
   906
sl@0
   907
				if (aShadowMode)
sl@0
   908
					{
sl@0
   909
					drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
sl@0
   910
					drawDevice->ShadowBuffer(width,scanLineBuffer);
sl@0
   911
					drawDevice->SetShadowMode(CFbsDrawDevice::ENoShadow);
sl@0
   912
					}
sl@0
   913
sl@0
   914
				drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,drawMode);
sl@0
   915
				}
sl@0
   916
			}
sl@0
   917
		}
sl@0
   918
	else
sl@0
   919
		{
sl@0
   920
		if (iDevice->iBitBltMaskedBuffer)
sl@0
   921
			{
sl@0
   922
			if (iBrushStyle == ESolidBrush)
sl@0
   923
				DoBitBltMaskedNonFlickerSolid(aDest,aSourceBitmap,aSourceBase,aSourceRect,
sl@0
   924
											  aMaskBitmap,aMaskBase,aInvertMask,aDitherOrigin,
sl@0
   925
											  aShadowMode);
sl@0
   926
			else if (iBrushStyle == EPatternedBrush)
sl@0
   927
				DoBitBltMaskedNonFlickerPatterned(aDest,aSourceBitmap,aSourceBase,aSourceRect,
sl@0
   928
												  aMaskBitmap,aMaskBase,aInvertMask,
sl@0
   929
												  aDitherOrigin,aShadowMode);
sl@0
   930
			else
sl@0
   931
				DoBitBltMaskedNonFlicker(aDest,aSourceBitmap,aSourceBase,aSourceRect,
sl@0
   932
										 aMaskBitmap,aMaskBase,aInvertMask,aDitherOrigin,
sl@0
   933
										 aShadowMode);
sl@0
   934
			}
sl@0
   935
		else
sl@0
   936
			DoBitBltMaskedFlicker(aDest,aSourceBitmap,aSourceBase,aSourceRect,aMaskBitmap,
sl@0
   937
								  aMaskBase,aInvertMask,aDitherOrigin,aShadowMode);
sl@0
   938
		}
sl@0
   939
	}
sl@0
   940
sl@0
   941
void CFbsBitGc::DoBitBltMaskedFlicker(const TPoint& aDest,
sl@0
   942
									  CBitwiseBitmap* aSourceBitmap,
sl@0
   943
									  TUint32* aSourceBase,
sl@0
   944
									  const TRect& aSourceRect,
sl@0
   945
									  CBitwiseBitmap* aMaskBitmap,
sl@0
   946
									  TUint32* aMaskBase,
sl@0
   947
									  TBool aInvertMask,
sl@0
   948
									  const TPoint& aDitherOrigin,
sl@0
   949
									  TInt aShadowMode)
sl@0
   950
	{
sl@0
   951
	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
sl@0
   952
sl@0
   953
	const TInt width = aSourceRect.Width();
sl@0
   954
	TInt destY = aDest.iY;
sl@0
   955
	TPoint srcePoint(aSourceRect.iTl);
sl@0
   956
sl@0
   957
	TLineScanningPosition lineScanPos(aSourceBase);
sl@0
   958
	TLineScanningPosition lineScanPosMask(aMaskBase);
sl@0
   959
sl@0
   960
	const TDisplayMode srcFormat = aSourceBitmap->DisplayMode();
sl@0
   961
	const TDisplayMode maskFormat = aMaskBitmap->DisplayMode();
sl@0
   962
	
sl@0
   963
	if (aMaskBitmap->IsCompressed()) 
sl@0
   964
       { 
sl@0
   965
       HBufC8* hBuf= CFbsBitmap::GetDecompressionBuffer(aMaskBitmap->DataStride() + 4); 
sl@0
   966
       if (!hBuf) 
sl@0
   967
          return; // Out of memory so do not draw anything 
sl@0
   968
       lineScanPosMask.iScanLineBuffer = hBuf; 
sl@0
   969
       } 
sl@0
   970
sl@0
   971
	TAny* interface=NULL;
sl@0
   972
	if ( (srcFormat == EColor16MU || srcFormat == EColor64K ) &&
sl@0
   973
		maskFormat == EGray2 &&
sl@0
   974
		!aShadowMode &&
sl@0
   975
		aSourceBitmap->SizeInPixels().iWidth <= aMaskBitmap->SizeInPixels().iWidth &&
sl@0
   976
		aSourceBitmap->SizeInPixels().iHeight <= aMaskBitmap->SizeInPixels().iHeight &&
sl@0
   977
		drawDevice->GetInterface(KFastBlitInterfaceID, interface) == KErrNone )
sl@0
   978
		{
sl@0
   979
		// Parameters allow optimised code path
sl@0
   980
		TInt length = width;
sl@0
   981
		TUint32* srcPtr=NULL;
sl@0
   982
		TUint32* maskPtr=NULL;
sl@0
   983
		MFastBlit* fastBlit = reinterpret_cast<MFastBlit*>(interface);
sl@0
   984
sl@0
   985
		while (srcePoint.iY < aSourceRect.iBr.iY)
sl@0
   986
			{
sl@0
   987
			aSourceBitmap->GetScanLinePtr(srcPtr, length, srcePoint, aSourceBase, lineScanPos);
sl@0
   988
			aMaskBitmap->GetScanLinePtr(maskPtr, length, srcePoint, aMaskBase, lineScanPosMask);
sl@0
   989
sl@0
   990
			fastBlit->WriteMaskLineEx(aDest.iX,destY,length,srcePoint.iX,srcPtr,srcFormat,srcePoint.iX,maskPtr,aInvertMask);
sl@0
   991
sl@0
   992
			destY++;
sl@0
   993
			++srcePoint.iY;
sl@0
   994
			}
sl@0
   995
		return;
sl@0
   996
		}
sl@0
   997
sl@0
   998
	TPoint ditherOrigin(aDitherOrigin + aDest);
sl@0
   999
	const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
sl@0
  1000
	const TDrawMode drawMode = aInvertMask ? EDrawModeAND : EDrawModeANDNOT;
sl@0
  1001
sl@0
  1002
	TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
sl@0
  1003
	const TInt scanLineBytes = drawDevice->ScanLineBytes();
sl@0
  1004
	TPtr8 scanLineDes((TUint8*)scanLineBuffer,scanLineBytes,scanLineBytes);
sl@0
  1005
sl@0
  1006
	TLineScanningPosition lineScanPos2(aSourceBase);
sl@0
  1007
sl@0
  1008
	//scanline modifications required if using shadows, different modes, bits per pixel less than 8
sl@0
  1009
	if ((!aShadowMode) && (dispMode == aSourceBitmap->DisplayMode()) && (TDisplayModeUtils::NumDisplayModeBitsPerPixel(dispMode)>=8))
sl@0
  1010
		{
sl@0
  1011
		TUint offset = MemoryOffsetForPixelPitch(srcePoint.iX, dispMode);
sl@0
  1012
		TUint32* slptr=NULL;
sl@0
  1013
		//mask scanline modifications required for EInvertPen, different screen modes
sl@0
  1014
		if ((drawMode != EDrawModeANDNOT) && (dispMode == aMaskBitmap->DisplayMode()))
sl@0
  1015
			{
sl@0
  1016
			TUint32* scanLineBufferMask = NULL;
sl@0
  1017
			//stride jumping not possible with compressed bitmaps
sl@0
  1018
			if (aSourceBitmap->IsCompressed() || aMaskBitmap->IsCompressed())
sl@0
  1019
				{
sl@0
  1020
				for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++,ditherOrigin.iY++)
sl@0
  1021
					{
sl@0
  1022
		 			scanLineBuffer = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPos, offset);
sl@0
  1023
					drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,EDrawModeXOR);
sl@0
  1024
		 			scanLineBufferMask = GetScanLineOffsetPtr(aMaskBitmap, slptr, width, srcePoint, aMaskBase, lineScanPosMask, offset);
sl@0
  1025
					drawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferMask,drawMode);
sl@0
  1026
					drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,EDrawModeXOR);
sl@0
  1027
					}
sl@0
  1028
				}
sl@0
  1029
			else
sl@0
  1030
				{
sl@0
  1031
				TUint strideSrc = aSourceBitmap->DataStride();
sl@0
  1032
				TUint strideMask = aMaskBitmap->DataStride();
sl@0
  1033
				TUint32* lastScanLineSrc = aSourceBitmap->ScanLineAddress(aSourceBase,aSourceRect.iBr.iY-1);
sl@0
  1034
				TUint32* lastScanLineMask = aMaskBitmap->ScanLineAddress(aMaskBase,aSourceRect.iBr.iY-1);
sl@0
  1035
sl@0
  1036
				while (srcePoint.iY < aSourceRect.iBr.iY)
sl@0
  1037
					{
sl@0
  1038
		 			scanLineBuffer = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPos, offset);
sl@0
  1039
		 			scanLineBufferMask = GetScanLineOffsetPtr(aMaskBitmap, slptr, width, srcePoint, aMaskBase, lineScanPosMask, offset);
sl@0
  1040
sl@0
  1041
		 			do
sl@0
  1042
		 				{
sl@0
  1043
						drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,EDrawModeXOR);
sl@0
  1044
						drawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferMask,drawMode);
sl@0
  1045
						drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,EDrawModeXOR);
sl@0
  1046
						destY++,srcePoint.iY++,ditherOrigin.iY++;
sl@0
  1047
		 				}
sl@0
  1048
		 			while ((srcePoint.iY < aSourceRect.iBr.iY) && (scanLineBuffer < lastScanLineSrc) && (scanLineBufferMask < lastScanLineMask)
sl@0
  1049
		 				&& ((scanLineBuffer = (TUint32*)((TUint8*)scanLineBuffer + strideSrc))>(TUint32*)0)
sl@0
  1050
		 				&& ((scanLineBufferMask = (TUint32*)((TUint8*)scanLineBufferMask + strideMask))>(TUint32*)0)
sl@0
  1051
		 				);
sl@0
  1052
					}
sl@0
  1053
				}
sl@0
  1054
			}
sl@0
  1055
		else
sl@0
  1056
			{
sl@0
  1057
			TUint32* scanLineBufferPtr = NULL;
sl@0
  1058
			//stride jumping not possible with compressed bitmaps
sl@0
  1059
			if (aSourceBitmap->IsCompressed())
sl@0
  1060
				{
sl@0
  1061
				for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++,ditherOrigin.iY++)
sl@0
  1062
					{
sl@0
  1063
		 			scanLineBufferPtr = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPos, offset);
sl@0
  1064
					drawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferPtr,EDrawModeXOR);
sl@0
  1065
					aMaskBitmap->GetScanLine(scanLineDes,srcePoint,width,EFalse,ditherOrigin,dispMode, aMaskBase, lineScanPosMask);
sl@0
  1066
					::TileScanLine(scanLineDes, width, srcePoint, aMaskBitmap, lineScanPosMask, aMaskBase, dispMode);
sl@0
  1067
					drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,drawMode);
sl@0
  1068
					drawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferPtr,EDrawModeXOR);
sl@0
  1069
					}
sl@0
  1070
				}
sl@0
  1071
			else
sl@0
  1072
				{
sl@0
  1073
				TUint stride = aSourceBitmap->DataStride();
sl@0
  1074
				TUint32* lastScanLine = aSourceBitmap->ScanLineAddress(aSourceBase,aSourceRect.iBr.iY-1);
sl@0
  1075
				while (srcePoint.iY < aSourceRect.iBr.iY)
sl@0
  1076
					{
sl@0
  1077
		 			scanLineBufferPtr = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPos, offset);
sl@0
  1078
		 			do
sl@0
  1079
		 				{
sl@0
  1080
						drawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferPtr,EDrawModeXOR);
sl@0
  1081
						aMaskBitmap->GetScanLine(scanLineDes,srcePoint,width,EFalse,ditherOrigin,dispMode,aMaskBase, lineScanPosMask);
sl@0
  1082
						::TileScanLine(scanLineDes, width, srcePoint, aMaskBitmap, lineScanPosMask, aMaskBase, dispMode);
sl@0
  1083
						drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,drawMode);
sl@0
  1084
						drawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferPtr,EDrawModeXOR);
sl@0
  1085
						destY++,srcePoint.iY++,ditherOrigin.iY++;
sl@0
  1086
		 				}
sl@0
  1087
					while ((srcePoint.iY < aSourceRect.iBr.iY) && (scanLineBufferPtr < lastScanLine)
sl@0
  1088
						&& ((scanLineBufferPtr = (TUint32*)((TUint8*)scanLineBufferPtr + stride))>(TUint32*)0));
sl@0
  1089
					}
sl@0
  1090
				}
sl@0
  1091
			}
sl@0
  1092
		}
sl@0
  1093
	else
sl@0
  1094
		{
sl@0
  1095
		for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++,ditherOrigin.iY++)
sl@0
  1096
			{
sl@0
  1097
			aSourceBitmap->GetScanLine(scanLineDes,srcePoint,width,ETrue,ditherOrigin,
sl@0
  1098
								dispMode,aSourceBase,lineScanPos);
sl@0
  1099
sl@0
  1100
			if (aShadowMode)
sl@0
  1101
				{
sl@0
  1102
				drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
sl@0
  1103
				drawDevice->ShadowBuffer(width,scanLineBuffer);
sl@0
  1104
				drawDevice->SetShadowMode(CFbsDrawDevice::ENoShadow);
sl@0
  1105
				}
sl@0
  1106
sl@0
  1107
			drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,EDrawModeXOR);
sl@0
  1108
sl@0
  1109
			aMaskBitmap->GetScanLine(scanLineDes,srcePoint,width,EFalse,ditherOrigin,dispMode,
sl@0
  1110
									 aMaskBase, lineScanPosMask);
sl@0
  1111
			::TileScanLine(scanLineDes, width, srcePoint, aMaskBitmap, lineScanPosMask,
sl@0
  1112
						   aMaskBase, dispMode);
sl@0
  1113
			drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,drawMode);
sl@0
  1114
sl@0
  1115
			aSourceBitmap->GetScanLine(scanLineDes,srcePoint,width,ETrue,ditherOrigin,dispMode,
sl@0
  1116
							   aSourceBase,lineScanPos2);
sl@0
  1117
sl@0
  1118
			if(aShadowMode)
sl@0
  1119
				{
sl@0
  1120
				drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
sl@0
  1121
				drawDevice->ShadowBuffer(width,scanLineBuffer);
sl@0
  1122
				drawDevice->SetShadowMode(CFbsDrawDevice::ENoShadow);
sl@0
  1123
				}
sl@0
  1124
sl@0
  1125
			drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,EDrawModeXOR);
sl@0
  1126
			}
sl@0
  1127
		}
sl@0
  1128
	}
sl@0
  1129
sl@0
  1130
void CFbsBitGc::DoBitBltMaskedNonFlicker(const TPoint& aDest,
sl@0
  1131
										 CBitwiseBitmap* aSourceBitmap,
sl@0
  1132
										 TUint32* aSourceBase,
sl@0
  1133
										 const TRect& aSourceRect,
sl@0
  1134
										 CBitwiseBitmap* aMaskBitmap,
sl@0
  1135
										 TUint32* aMaskBase,
sl@0
  1136
										 TBool aInvertMask,
sl@0
  1137
										 const TPoint& aDitherOrigin,
sl@0
  1138
										 TInt aShadowMode)
sl@0
  1139
	{
sl@0
  1140
	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
sl@0
  1141
sl@0
  1142
	const TInt width = aSourceRect.Width();
sl@0
  1143
	TInt destY = aDest.iY;
sl@0
  1144
	TPoint srcePoint(aSourceRect.iTl);
sl@0
  1145
sl@0
  1146
	TLineScanningPosition lineScanPos(aSourceBase);
sl@0
  1147
	TLineScanningPosition lineScanPosMask(aMaskBase);
sl@0
  1148
sl@0
  1149
	const TDisplayMode srcFormat = aSourceBitmap->DisplayMode();
sl@0
  1150
	const TDisplayMode maskFormat = aMaskBitmap->DisplayMode();
sl@0
  1151
	
sl@0
  1152
	if (aMaskBitmap->IsCompressed()) 
sl@0
  1153
       { 
sl@0
  1154
       HBufC8* hBuf= CFbsBitmap::GetDecompressionBuffer(aMaskBitmap->DataStride() + 4); 
sl@0
  1155
       if (!hBuf) 
sl@0
  1156
          return; // Out of memory so do not draw anything 
sl@0
  1157
       lineScanPosMask.iScanLineBuffer = hBuf; 
sl@0
  1158
       } 
sl@0
  1159
sl@0
  1160
	TAny* interface=NULL;
sl@0
  1161
	if ( (srcFormat == EColor16MU || srcFormat == EColor64K ) &&
sl@0
  1162
		maskFormat == EGray2 &&
sl@0
  1163
		!aShadowMode &&
sl@0
  1164
		aSourceBitmap->SizeInPixels().iWidth <= aMaskBitmap->SizeInPixels().iWidth &&
sl@0
  1165
		aSourceBitmap->SizeInPixels().iHeight <= aMaskBitmap->SizeInPixels().iHeight &&
sl@0
  1166
		drawDevice->GetInterface(KFastBlitInterfaceID, interface) == KErrNone )
sl@0
  1167
		{
sl@0
  1168
		// Parameters allow optimised code path
sl@0
  1169
		TInt length = width;
sl@0
  1170
		TUint32* srcPtr=NULL;
sl@0
  1171
		TUint32* maskPtr=NULL;
sl@0
  1172
		MFastBlit* fastBlit = reinterpret_cast<MFastBlit*>(interface);
sl@0
  1173
sl@0
  1174
		while (srcePoint.iY < aSourceRect.iBr.iY)
sl@0
  1175
			{
sl@0
  1176
			aSourceBitmap->GetScanLinePtr(srcPtr, length, srcePoint, aSourceBase, lineScanPos);
sl@0
  1177
			aMaskBitmap->GetScanLinePtr(maskPtr, length, srcePoint, aMaskBase, lineScanPosMask);
sl@0
  1178
sl@0
  1179
			fastBlit->WriteMaskLineEx(aDest.iX,destY,length,srcePoint.iX,srcPtr,srcFormat,srcePoint.iX,maskPtr,aInvertMask);
sl@0
  1180
sl@0
  1181
			destY++;
sl@0
  1182
			++srcePoint.iY;
sl@0
  1183
			}
sl@0
  1184
sl@0
  1185
		return;
sl@0
  1186
		}
sl@0
  1187
sl@0
  1188
	TPoint ditherOrigin(aDitherOrigin + aDest);
sl@0
  1189
sl@0
  1190
	TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
sl@0
  1191
	const TInt scanLineBytes = drawDevice->ScanLineBytes();
sl@0
  1192
	TPtr8 scanLineDes((TUint8*)scanLineBuffer,scanLineBytes,scanLineBytes);
sl@0
  1193
sl@0
  1194
	TUint32* bitBltBuffer = (TUint32*)iDevice->iBitBltMaskedBuffer;
sl@0
  1195
	const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
sl@0
  1196
	const TInt bufferBytes = CFbsBitmap::ScanLineLength(width, dispMode);
sl@0
  1197
	TUint32* scanLineCopy = (TUint32*) new TUint8[bufferBytes];
sl@0
  1198
sl@0
  1199
	TLineScanningPosition lineScanPos2(aSourceBase);
sl@0
  1200
	for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++,ditherOrigin.iY++)
sl@0
  1201
		{
sl@0
  1202
		drawDevice->ReadLine(aDest.iX,destY,width,bitBltBuffer,dispMode);
sl@0
  1203
		aSourceBitmap->GetScanLine(scanLineDes,srcePoint,width,ETrue,ditherOrigin,dispMode,
sl@0
  1204
								   aSourceBase,lineScanPos);
sl@0
  1205
sl@0
  1206
		if (scanLineCopy)
sl@0
  1207
			{
sl@0
  1208
			Mem::Copy(scanLineCopy,scanLineBuffer,bufferBytes);
sl@0
  1209
			}
sl@0
  1210
sl@0
  1211
		if (aShadowMode)
sl@0
  1212
			{
sl@0
  1213
			drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
sl@0
  1214
			drawDevice->ShadowBuffer(width,scanLineBuffer);
sl@0
  1215
			drawDevice->SetShadowMode(CFbsDrawDevice::ENoShadow);
sl@0
  1216
			}
sl@0
  1217
sl@0
  1218
		XorBuffers(bitBltBuffer,scanLineBuffer,bufferBytes);
sl@0
  1219
sl@0
  1220
		aMaskBitmap->GetScanLine(scanLineDes,srcePoint,width,EFalse,ditherOrigin,dispMode,
sl@0
  1221
								 aMaskBase,lineScanPosMask);
sl@0
  1222
		::TileScanLine(scanLineDes, width, srcePoint, aMaskBitmap, lineScanPosMask,
sl@0
  1223
					   aMaskBase, dispMode);
sl@0
  1224
sl@0
  1225
		if (!aInvertMask)
sl@0
  1226
			InvertBuffer(scanLineBuffer,bufferBytes);
sl@0
  1227
		AndBuffers(bitBltBuffer,scanLineBuffer,bufferBytes);
sl@0
  1228
sl@0
  1229
		// Slow call when memory low?
sl@0
  1230
		TUint32* scanLine;
sl@0
  1231
		if (!scanLineCopy)
sl@0
  1232
			{
sl@0
  1233
			aSourceBitmap->GetScanLine(scanLineDes,srcePoint,width,ETrue,ditherOrigin,
sl@0
  1234
									   dispMode,aSourceBase,lineScanPos2);
sl@0
  1235
			scanLine = scanLineBuffer;
sl@0
  1236
			}
sl@0
  1237
		else
sl@0
  1238
			scanLine = scanLineCopy;
sl@0
  1239
sl@0
  1240
		if(aShadowMode)
sl@0
  1241
			{
sl@0
  1242
			drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
sl@0
  1243
			drawDevice->ShadowBuffer(width,scanLine);
sl@0
  1244
			drawDevice->SetShadowMode(CFbsDrawDevice::ENoShadow);
sl@0
  1245
			}
sl@0
  1246
sl@0
  1247
		XorBuffers(bitBltBuffer,scanLine,bufferBytes);
sl@0
  1248
sl@0
  1249
		drawDevice->WriteLine(aDest.iX,destY,width,bitBltBuffer,iDrawMode);
sl@0
  1250
		}
sl@0
  1251
	if (scanLineCopy)
sl@0
  1252
		{
sl@0
  1253
		delete[] scanLineCopy;
sl@0
  1254
		}
sl@0
  1255
	}
sl@0
  1256
sl@0
  1257
void CFbsBitGc::DoBitBltMaskedNonFlickerSolid(const TPoint& aDest,
sl@0
  1258
											  CBitwiseBitmap* aSourceBitmap,
sl@0
  1259
											  TUint32* aSourceBase,
sl@0
  1260
											  const TRect& aSourceRect,
sl@0
  1261
											  CBitwiseBitmap* aMaskBitmap,
sl@0
  1262
											  TUint32* aMaskBase,
sl@0
  1263
											  TBool aInvertMask,
sl@0
  1264
											  const TPoint& aDitherOrigin,
sl@0
  1265
											  TInt aShadowMode)
sl@0
  1266
	{
sl@0
  1267
	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
sl@0
  1268
	const TInt width = aSourceRect.Width();
sl@0
  1269
	TPoint ditherOrigin(aDitherOrigin + aDest);
sl@0
  1270
	const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
sl@0
  1271
	TInt destY = aDest.iY;
sl@0
  1272
	TPoint srcePoint(aSourceRect.iTl);
sl@0
  1273
sl@0
  1274
	TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
sl@0
  1275
	const TInt scanLineBytes = drawDevice->ScanLineBytes();
sl@0
  1276
	TPtr8 scanLineDes((TUint8*)scanLineBuffer,scanLineBytes,scanLineBytes);
sl@0
  1277
sl@0
  1278
	TUint32* bitBltBuffer = (TUint32*)iDevice->iBitBltMaskedBuffer;
sl@0
  1279
	TUint32* backgroundBuffer = (TUint32*)(iDevice->iBitBltMaskedBuffer + scanLineBytes);
sl@0
  1280
	const TInt bufferBytes = CFbsBitmap::ScanLineLength(width, dispMode);
sl@0
  1281
sl@0
  1282
	drawDevice->WriteRgbMulti(aDest.iX,aDest.iY,width,1,iBrushColor,iDrawMode);
sl@0
  1283
	drawDevice->ReadLine(aDest.iX,destY,width,backgroundBuffer,dispMode);
sl@0
  1284
sl@0
  1285
	TLineScanningPosition lineScanPos(aSourceBase);
sl@0
  1286
	TLineScanningPosition lineScanPos2(aSourceBase);
sl@0
  1287
	TLineScanningPosition lineScanPosMask(aMaskBase);
sl@0
  1288
sl@0
  1289
	for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++,ditherOrigin.iY++)
sl@0
  1290
		{
sl@0
  1291
		Mem::Copy(bitBltBuffer,backgroundBuffer,bufferBytes);
sl@0
  1292
sl@0
  1293
		aSourceBitmap->GetScanLine(scanLineDes,srcePoint,width,ETrue,ditherOrigin,dispMode,
sl@0
  1294
								   aSourceBase,lineScanPos);
sl@0
  1295
		XorBuffers(bitBltBuffer,scanLineBuffer,bufferBytes);
sl@0
  1296
sl@0
  1297
		aMaskBitmap->GetScanLine(scanLineDes,srcePoint,width,EFalse,ditherOrigin,dispMode,
sl@0
  1298
								 aMaskBase,lineScanPosMask);
sl@0
  1299
		::TileScanLine(scanLineDes, width, srcePoint, aMaskBitmap, lineScanPosMask,
sl@0
  1300
					   aMaskBase, dispMode);
sl@0
  1301
sl@0
  1302
		if (!aInvertMask)
sl@0
  1303
			InvertBuffer(scanLineBuffer,bufferBytes);
sl@0
  1304
		AndBuffers(bitBltBuffer,scanLineBuffer,bufferBytes);
sl@0
  1305
		aSourceBitmap->GetScanLine(scanLineDes,srcePoint,width,ETrue,ditherOrigin,
sl@0
  1306
								   dispMode,aSourceBase,lineScanPos2);
sl@0
  1307
sl@0
  1308
		XorBuffers(bitBltBuffer,scanLineBuffer,bufferBytes);
sl@0
  1309
sl@0
  1310
		if(aShadowMode)
sl@0
  1311
			drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
sl@0
  1312
sl@0
  1313
		drawDevice->WriteLine(aDest.iX,destY,width,bitBltBuffer,iDrawMode);
sl@0
  1314
sl@0
  1315
		if(aShadowMode)
sl@0
  1316
			drawDevice->SetShadowMode(CFbsDrawDevice::ENoShadow);
sl@0
  1317
		}
sl@0
  1318
	}
sl@0
  1319
sl@0
  1320
void CFbsBitGc::DoBitBltMaskedNonFlickerPatterned(const TPoint& aDest,
sl@0
  1321
												  CBitwiseBitmap* aSourceBitmap,
sl@0
  1322
												  TUint32* aSourceBase,
sl@0
  1323
												  const TRect& aSourceRect,
sl@0
  1324
												  CBitwiseBitmap* aMaskBitmap,
sl@0
  1325
												  TUint32* aMaskBase,
sl@0
  1326
												  TBool aInvertMask,
sl@0
  1327
												  const TPoint& aDitherOrigin,
sl@0
  1328
												  TInt aShadowMode)
sl@0
  1329
	{
sl@0
  1330
	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
sl@0
  1331
	const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
sl@0
  1332
sl@0
  1333
	drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
sl@0
  1334
sl@0
  1335
	iBrushBitmap.BeginDataAccess();
sl@0
  1336
	CBitwiseBitmap* brushBitmap = iBrushBitmap.Address();
sl@0
  1337
	BG_ASSERT_ALWAYS(iBrushUsed, EBitgdiPanicInvalidBitmap);
sl@0
  1338
	BG_ASSERT_ALWAYS(brushBitmap != NULL, EBitgdiPanicInvalidBitmap);
sl@0
  1339
sl@0
  1340
	CFbsRasterizer* brushRasterizer = PrepareRasterizerForExtendedBitmap(iBrushBitmap);
sl@0
  1341
	TUint32* brushData = iBrushBitmap.DataAddress();
sl@0
  1342
	TPoint brushSourcePoint(aDest - iBrushOrigin - iOrigin);
sl@0
  1343
	const TSize brushSize(iBrushBitmap.SizeInPixels());
sl@0
  1344
	if (brushSourcePoint.iX < 0 || brushSourcePoint.iX >= brushSize.iWidth)
sl@0
  1345
		brushSourcePoint.iX %= brushSize.iWidth;
sl@0
  1346
	if (brushSourcePoint.iX < 0)
sl@0
  1347
		brushSourcePoint.iX += brushSize.iWidth;
sl@0
  1348
sl@0
  1349
	TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
sl@0
  1350
	const TInt scanLineBytes = drawDevice->ScanLineBytes();
sl@0
  1351
	TPtr8 scanLineDes((TUint8*)scanLineBuffer,scanLineBytes,scanLineBytes);
sl@0
  1352
sl@0
  1353
	TUint32* bitBltBuffer = (TUint32*)iDevice->iBitBltMaskedBuffer;
sl@0
  1354
	TPtr8 bitBltDes(iDevice->iBitBltMaskedBuffer, scanLineBytes, scanLineBytes);
sl@0
  1355
sl@0
  1356
	TInt widthRemaining = aSourceRect.Width();
sl@0
  1357
	TPoint sourcePoint(aSourceRect.iTl);
sl@0
  1358
	TInt destX = aDest.iX;
sl@0
  1359
sl@0
  1360
	TInt width = Min(widthRemaining,brushSize.iWidth);
sl@0
  1361
sl@0
  1362
	if (brushSourcePoint.iX + widthRemaining > brushSize.iWidth)
sl@0
  1363
		width = brushSize.iWidth - brushSourcePoint.iX;
sl@0
  1364
sl@0
  1365
	while (widthRemaining > 0)
sl@0
  1366
		{
sl@0
  1367
		TInt destY = aDest.iY;
sl@0
  1368
		sourcePoint.iY = aSourceRect.iTl.iY;
sl@0
  1369
		brushSourcePoint.iY = aDest.iY - iBrushOrigin.iY - iOrigin.iY;
sl@0
  1370
		TPoint ditherOrigin(aDitherOrigin + TPoint(destX,aDest.iY));
sl@0
  1371
		const TInt bufferBytes = CFbsBitmap::ScanLineLength(width, dispMode);
sl@0
  1372
sl@0
  1373
		TLineScanningPosition lineScanPosBrush(brushData);
sl@0
  1374
		TLineScanningPosition lineScanPosMask(aMaskBase);
sl@0
  1375
		TLineScanningPosition lineScanPosSrc(aSourceBase);
sl@0
  1376
		TLineScanningPosition lineScanPosSrc2(aSourceBase);
sl@0
  1377
sl@0
  1378
		for ( ;sourcePoint.iY < aSourceRect.iBr.iY;
sl@0
  1379
			   destY++,sourcePoint.iY++,ditherOrigin.iY++,brushSourcePoint.iY++)
sl@0
  1380
			{
sl@0
  1381
			brushBitmap->GetScanLine(bitBltDes,brushSourcePoint,width,ETrue,ditherOrigin,
sl@0
  1382
									 dispMode,brushData,lineScanPosBrush);
sl@0
  1383
			aSourceBitmap->GetScanLine(scanLineDes,sourcePoint,width,ETrue,ditherOrigin,
sl@0
  1384
									   dispMode,aSourceBase,lineScanPosSrc);
sl@0
  1385
			XorBuffers(bitBltBuffer,scanLineBuffer,scanLineBytes);
sl@0
  1386
sl@0
  1387
			aMaskBitmap->GetScanLine(scanLineDes,sourcePoint,width,EFalse,ditherOrigin,
sl@0
  1388
									 dispMode,aMaskBase,lineScanPosMask);
sl@0
  1389
			::TileScanLine(scanLineDes, width, sourcePoint, aMaskBitmap, lineScanPosMask,
sl@0
  1390
						   aMaskBase, dispMode);
sl@0
  1391
sl@0
  1392
			if (!aInvertMask)
sl@0
  1393
				InvertBuffer(scanLineBuffer,bufferBytes);
sl@0
  1394
			AndBuffers(bitBltBuffer,scanLineBuffer,bufferBytes);
sl@0
  1395
sl@0
  1396
			aSourceBitmap->GetScanLine(scanLineDes,sourcePoint,width,ETrue,ditherOrigin,
sl@0
  1397
									   dispMode,aSourceBase,lineScanPosSrc2);
sl@0
  1398
			XorBuffers(bitBltBuffer,scanLineBuffer,bufferBytes);
sl@0
  1399
sl@0
  1400
			drawDevice->WriteLine(destX,destY,width,bitBltBuffer,iDrawMode);
sl@0
  1401
			}
sl@0
  1402
sl@0
  1403
		widthRemaining -= width;
sl@0
  1404
		sourcePoint.iX += width;
sl@0
  1405
		brushSourcePoint.iX += width;
sl@0
  1406
		destX += width;
sl@0
  1407
sl@0
  1408
		width = Min(widthRemaining,brushSize.iWidth);
sl@0
  1409
		}
sl@0
  1410
	if (brushRasterizer)
sl@0
  1411
		{
sl@0
  1412
		brushRasterizer->EndBitmap(iBrushBitmap.SerialNumber());
sl@0
  1413
		}
sl@0
  1414
	iBrushBitmap.EndDataAccess(ETrue);
sl@0
  1415
	}
sl@0
  1416
sl@0
  1417
void CFbsBitGc::DoBitBltAlpha(const TPoint& aDest,CBitwiseBitmap* aSourceBitmap,
sl@0
  1418
							  TUint32* aSourceBase,const TRect& aSourceRect,
sl@0
  1419
							  CBitwiseBitmap* aMaskBitmap,TUint32* aMaskBase,
sl@0
  1420
							  const TPoint& aAlphaPoint,TInt aShadowMode, TBool aInvertMask)
sl@0
  1421
	{
sl@0
  1422
	MFastBlend* fastBlend=NULL;
sl@0
  1423
	if (FastBlendInterface(aSourceBitmap,aMaskBitmap,fastBlend)==KErrNone)
sl@0
  1424
		{
sl@0
  1425
		if (fastBlend->FastBlendBitmapMasked(aDest, aSourceBase, aSourceBitmap->DataStride(), aSourceBitmap->SizeInPixels(), aSourceRect, aSourceBitmap->DisplayMode(),
sl@0
  1426
							aMaskBase, aMaskBitmap->DataStride(), aMaskBitmap->DisplayMode(), aMaskBitmap->SizeInPixels(), aAlphaPoint, aInvertMask,
sl@0
  1427
							iDrawMode, aShadowMode)==KErrNone)
sl@0
  1428
			{
sl@0
  1429
			return;
sl@0
  1430
			}
sl@0
  1431
		}
sl@0
  1432
	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
sl@0
  1433
sl@0
  1434
	const TPoint KZeroPoint(0,0);
sl@0
  1435
	const TInt KScanLineLength = 256;
sl@0
  1436
	const TInt KRgbSize = 4;
sl@0
  1437
sl@0
  1438
	TUint8 srceRgbBuffer[KScanLineLength * KRgbSize];
sl@0
  1439
	TUint8 maskBuffer[KScanLineLength];
sl@0
  1440
	TUint8* srceRgbBufferPtr(srceRgbBuffer);
sl@0
  1441
sl@0
  1442
	TPtr8 srceRgbDes(srceRgbBuffer,KScanLineLength * KRgbSize,KScanLineLength * KRgbSize);
sl@0
  1443
	TPtr8 maskDes(maskBuffer,KScanLineLength,KScanLineLength);
sl@0
  1444
sl@0
  1445
	drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
sl@0
  1446
sl@0
  1447
	const TSize sourceSize = aSourceBitmap->SizeInPixels();
sl@0
  1448
	// Convert negative or large offsets into sensible positive ones.
sl@0
  1449
	TPoint alphaOffset(aAlphaPoint.iX % sourceSize.iWidth, aAlphaPoint.iY % sourceSize.iHeight);
sl@0
  1450
	if ( alphaOffset.iX < 0 ) 
sl@0
  1451
		alphaOffset.iX += sourceSize.iWidth;
sl@0
  1452
	if ( alphaOffset.iY < 0 ) 
sl@0
  1453
		alphaOffset.iY += sourceSize.iHeight;
sl@0
  1454
	
sl@0
  1455
	TInt srceY = aSourceRect.iTl.iY;
sl@0
  1456
	TInt destY = aDest.iY;
sl@0
  1457
	TInt alphaY = alphaOffset.iY;
sl@0
  1458
	
sl@0
  1459
	TLineScanningPosition lineScanPosSrc(aSourceBase);
sl@0
  1460
	TLineScanningPosition lineScanPosMask(aMaskBase);
sl@0
  1461
sl@0
  1462
	TDisplayMode sourceMode = aSourceBitmap->DisplayMode();
sl@0
  1463
sl@0
  1464
	if (aMaskBitmap->IsCompressed())
sl@0
  1465
		{
sl@0
  1466
		HBufC8* hBuf= CFbsBitmap::GetDecompressionBuffer(aMaskBitmap->DataStride());
sl@0
  1467
		if (!hBuf)
sl@0
  1468
			{
sl@0
  1469
			return;  // Out of memory so do not draw anything
sl@0
  1470
			}
sl@0
  1471
		lineScanPosMask.iScanLineBuffer = hBuf;
sl@0
  1472
		}
sl@0
  1473
sl@0
  1474
	TAny* interface=NULL;
sl@0
  1475
	if ( (sourceMode == EColor16MU || sourceMode == EColor64K) &&
sl@0
  1476
			aMaskBitmap->DisplayMode() == EGray256 && // ensure a monochrome mask isn't passed in as an alpha channel
sl@0
  1477
			aSourceBitmap->SizeInPixels().iWidth  <= aMaskBitmap->SizeInPixels().iWidth &&
sl@0
  1478
			aSourceBitmap->SizeInPixels().iHeight <= aMaskBitmap->SizeInPixels().iHeight &&
sl@0
  1479
			drawDevice->GetInterface(KFastBlitInterfaceID, interface) == KErrNone )
sl@0
  1480
		{
sl@0
  1481
		TInt length = aSourceRect.Width();
sl@0
  1482
		const TInt srceX = aSourceRect.iTl.iX;				
sl@0
  1483
		const TInt alphaX = alphaOffset.iX;
sl@0
  1484
		const TInt destX = aDest.iX;
sl@0
  1485
		MFastBlit* fastBlit = reinterpret_cast<MFastBlit*>(interface);
sl@0
  1486
sl@0
  1487
		while (srceY < aSourceRect.iBr.iY)
sl@0
  1488
			{
sl@0
  1489
			TUint32* srcPtr;
sl@0
  1490
			TUint32* maskPtr;
sl@0
  1491
			TPoint srcPoint(srceX, srceY);
sl@0
  1492
			TPoint maskPoint(alphaX, alphaY);
sl@0
  1493
sl@0
  1494
			aSourceBitmap->GetScanLinePtr(srcPtr, length, srcPoint, aSourceBase, lineScanPosSrc);
sl@0
  1495
			aMaskBitmap->GetScanLinePtr(maskPtr, length, maskPoint, aMaskBase, lineScanPosMask);
sl@0
  1496
sl@0
  1497
			fastBlit->WriteAlphaLineEx(destX,destY,length,srceX,srcPtr,sourceMode,alphaX,maskPtr,MAlphaBlend::EShdwBefore);
sl@0
  1498
sl@0
  1499
			srceY++;
sl@0
  1500
			destY++;
sl@0
  1501
			alphaY++;
sl@0
  1502
			}
sl@0
  1503
		return;
sl@0
  1504
		}
sl@0
  1505
sl@0
  1506
	const TBool useScanLinePtr = ((!aShadowMode) && (EColor16MA == aSourceBitmap->DisplayMode()));
sl@0
  1507
	TUint32* slptr=NULL;
sl@0
  1508
	TUint offset = 0;
sl@0
  1509
	TDisplayMode srcMode = ERgb;
sl@0
  1510
	
sl@0
  1511
	while (srceY < aSourceRect.iBr.iY)
sl@0
  1512
		{
sl@0
  1513
		TInt srceX = aSourceRect.iTl.iX;
sl@0
  1514
		TInt destX = aDest.iX;
sl@0
  1515
		TInt alphaX = alphaOffset.iX;
sl@0
  1516
		
sl@0
  1517
		while (srceX < aSourceRect.iBr.iX)
sl@0
  1518
			{
sl@0
  1519
			TPoint srcePoint(srceX,srceY);
sl@0
  1520
			TPoint alphaPoint(alphaX,alphaY);
sl@0
  1521
			const TInt width = Min(KScanLineLength,aSourceRect.iBr.iX - srceX);
sl@0
  1522
sl@0
  1523
			if (useScanLinePtr)
sl@0
  1524
				{
sl@0
  1525
				offset = MemoryOffsetForPixelPitch(srceX, EColor16MU);
sl@0
  1526
				srceRgbBufferPtr = (TUint8*)GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPosSrc, offset);
sl@0
  1527
				}
sl@0
  1528
			else
sl@0
  1529
				{
sl@0
  1530
				aSourceBitmap->GetScanLine(srceRgbDes,srcePoint,width,EFalse,KZeroPoint,
sl@0
  1531
								   srcMode,aSourceBase,lineScanPosSrc);
sl@0
  1532
				}
sl@0
  1533
sl@0
  1534
			aMaskBitmap->GetScanLine(maskDes,alphaPoint,width,EFalse,KZeroPoint,
sl@0
  1535
									 EGray256,aMaskBase,lineScanPosMask);
sl@0
  1536
			::TileScanLine(maskDes, width, alphaPoint, aMaskBitmap, lineScanPosMask,
sl@0
  1537
						   aMaskBase, EGray256);
sl@0
  1538
			// aInvertMask is not used for alpha channels (EGray256 mask)
sl@0
  1539
			if (aInvertMask && aMaskBitmap->DisplayMode() != EGray256)
sl@0
  1540
				{
sl@0
  1541
				for (TInt i = 0; i < width; ++i)
sl@0
  1542
					maskBuffer[i] = ~maskBuffer[i];
sl@0
  1543
				}
sl@0
  1544
			drawDevice->WriteRgbAlphaLine(destX,destY,width,srceRgbBufferPtr,maskBuffer,iDrawMode);
sl@0
  1545
sl@0
  1546
			srceX += KScanLineLength;
sl@0
  1547
			destX += KScanLineLength;
sl@0
  1548
			alphaX += KScanLineLength;
sl@0
  1549
			}
sl@0
  1550
sl@0
  1551
		srceY++;
sl@0
  1552
		destY++;
sl@0
  1553
		alphaY++;
sl@0
  1554
		}
sl@0
  1555
	}
sl@0
  1556
sl@0
  1557
/**
sl@0
  1558
The method performs an alpha blending of the source data - aSrcBmp1 and aSrcBmp2, using
sl@0
  1559
the data from aAlphaBmp as an alpha blending factor.
sl@0
  1560
@internalComponent
sl@0
  1561
@see CFbsBitGc::AlphaBlendBitmaps.
sl@0
  1562
*/
sl@0
  1563
void CFbsBitGc::DoBitBltAlpha(const TPoint& aDestPt,
sl@0
  1564
							  const CBitwiseBitmap* aSrcBmp1,
sl@0
  1565
							  TUint32* aSrcBmpDataAddr1,
sl@0
  1566
							  const CBitwiseBitmap* aSrcBmp2,
sl@0
  1567
							  TUint32* aSrcBmpDataAddr2,
sl@0
  1568
							  const CBitwiseBitmap* aAlphaBmp,
sl@0
  1569
							  TUint32* aAlphaBmpDataAddr,
sl@0
  1570
							  const TRect& aSrcRect1,
sl@0
  1571
							  const TPoint& aSrcPt2,
sl@0
  1572
							  const TPoint& aAlphaPt,
sl@0
  1573
							  TInt aShadowMode)
sl@0
  1574
	{
sl@0
  1575
	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
sl@0
  1576
#ifdef _DEBUG
sl@0
  1577
	TRect deviceDestRect;
sl@0
  1578
	drawDevice->GetDrawRect(deviceDestRect);
sl@0
  1579
#endif
sl@0
  1580
	//Check the destination point.
sl@0
  1581
	BG_ASSERT_DEBUG(aDestPt.iX >= deviceDestRect.iTl.iX, EBitgdiPanicOutOfBounds);
sl@0
  1582
	BG_ASSERT_DEBUG(aDestPt.iY >= deviceDestRect.iTl.iY, EBitgdiPanicOutOfBounds);
sl@0
  1583
	BG_ASSERT_DEBUG((aDestPt.iX + aSrcRect1.Width()) <= deviceDestRect.iBr.iX, EBitgdiPanicOutOfBounds);
sl@0
  1584
	BG_ASSERT_DEBUG((aDestPt.iY + aSrcRect1.Height()) <= deviceDestRect.iBr.iY, EBitgdiPanicOutOfBounds);
sl@0
  1585
sl@0
  1586
	const TPoint KZeroPoint(0,0);
sl@0
  1587
	const TInt KScanLineLength = 256;//128 is not enough to fill buffer for 16MA and 16MU display modes
sl@0
  1588
	const TInt KRgbSize = 4;
sl@0
  1589
sl@0
  1590
	TUint8 srceRgbBuffer1[KScanLineLength * KRgbSize];
sl@0
  1591
	TUint8 srceBuffer2[KScanLineLength * KRgbSize];
sl@0
  1592
	TUint8 alphaBuffer[KScanLineLength];
sl@0
  1593
sl@0
  1594
	TPtr8 srceRgbDes1(srceRgbBuffer1,KScanLineLength * KRgbSize,KScanLineLength * KRgbSize);
sl@0
  1595
	TPtr8 srceDes2(srceBuffer2,KScanLineLength * KRgbSize,KScanLineLength * KRgbSize);
sl@0
  1596
	TPtr8 alphaDes(alphaBuffer,KScanLineLength,KScanLineLength);
sl@0
  1597
sl@0
  1598
	const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
sl@0
  1599
	drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
sl@0
  1600
sl@0
  1601
	TInt srceY1 = aSrcRect1.iTl.iY;
sl@0
  1602
	TInt srceY2 = aSrcPt2.iY;
sl@0
  1603
	TInt alphaY = aAlphaPt.iY;
sl@0
  1604
	TInt destY = aDestPt.iY;
sl@0
  1605
sl@0
  1606
	TLineScanningPosition lineScanPosSrc1(aSrcBmpDataAddr1);
sl@0
  1607
	TLineScanningPosition lineScanPosSrc2(aSrcBmpDataAddr2);
sl@0
  1608
	TLineScanningPosition lineScanPosAlpha(aAlphaBmpDataAddr);
sl@0
  1609
sl@0
  1610
	while (srceY1 < aSrcRect1.iBr.iY)
sl@0
  1611
		{
sl@0
  1612
		TInt srceX1 = aSrcRect1.iTl.iX;
sl@0
  1613
		TInt srceX2 = aSrcPt2.iX;
sl@0
  1614
		TInt alphaX = aAlphaPt.iX;
sl@0
  1615
		TInt destX = aDestPt.iX;
sl@0
  1616
sl@0
  1617
		while (srceX1 < aSrcRect1.iBr.iX)
sl@0
  1618
			{
sl@0
  1619
			TPoint srcePoint1(srceX1,srceY1);
sl@0
  1620
			TPoint srcePoint2(srceX2,srceY2);
sl@0
  1621
			TPoint alphaPoint(alphaX,alphaY);
sl@0
  1622
			const TInt width = Min(KScanLineLength,aSrcRect1.iBr.iX - srceX1);
sl@0
  1623
sl@0
  1624
			aSrcBmp1->GetScanLine(srceRgbDes1,srcePoint1,width,EFalse,KZeroPoint,EColor16MU,
sl@0
  1625
								  aSrcBmpDataAddr1,lineScanPosSrc1);
sl@0
  1626
			aSrcBmp2->GetScanLine(srceDes2,srcePoint2,width,EFalse,KZeroPoint,dispMode,
sl@0
  1627
								  aSrcBmpDataAddr2,lineScanPosSrc2);
sl@0
  1628
			aAlphaBmp->GetScanLine(alphaDes,alphaPoint,width,EFalse,KZeroPoint,EGray256,
sl@0
  1629
								   aAlphaBmpDataAddr,lineScanPosAlpha);
sl@0
  1630
			::TileScanLine(alphaDes, width, alphaPoint, aAlphaBmp, lineScanPosAlpha, aAlphaBmpDataAddr, EGray256);
sl@0
  1631
sl@0
  1632
			drawDevice->WriteRgbAlphaLine(destX,
sl@0
  1633
										  destY,
sl@0
  1634
										  width,
sl@0
  1635
										  srceRgbBuffer1,
sl@0
  1636
										  srceBuffer2,
sl@0
  1637
										  alphaBuffer,
sl@0
  1638
										  iDrawMode);
sl@0
  1639
sl@0
  1640
			srceX1 += KScanLineLength;
sl@0
  1641
			srceX2 += KScanLineLength;
sl@0
  1642
			alphaX += KScanLineLength;
sl@0
  1643
			destX += KScanLineLength;
sl@0
  1644
			}
sl@0
  1645
sl@0
  1646
		srceY1++;
sl@0
  1647
		srceY2++;
sl@0
  1648
		alphaY++;
sl@0
  1649
		destY++;
sl@0
  1650
		}
sl@0
  1651
	}
sl@0
  1652
sl@0
  1653
/**
sl@0
  1654
The method performs an alpha blending of the source data - aSrcBmp1 and aSrcBmp2, using
sl@0
  1655
the data from aAlphaBmp as an alpha blending factor.
sl@0
  1656
The formula used for that, is:
sl@0
  1657
(C1 * A + C2 * (255 - A)) / 255, where:
sl@0
  1658
- C1 - a pixel from aSrcBmp1;
sl@0
  1659
- C2 - a pixel from aSrcBmp2;
sl@0
  1660
- A  - a pixel from aAlphaBmp;
sl@0
  1661
The content of source and alpha bitmap is preserved.
sl@0
  1662
The calculated alpha blended pixels are written to the destination - the screen or a bitmap.
sl@0
  1663
@publishedAll
sl@0
  1664
@released
sl@0
  1665
@param aDestPt Position in the target the result should be drawn to.
sl@0
  1666
@param aSrcBmp1 A pointer to the source bitmap 1.
sl@0
  1667
@param aSrcBmp2 A pointer to the source bitmap 2.
sl@0
  1668
@param aAlphaBmp A pointer to the bitmap used as an alpha blending factor.
sl@0
  1669
@param aSrcRect1 A part of bitmap 1 that should be used as a source for the alpha blending.
sl@0
  1670
@param aSrcPt2 Position of the first pixel in bitmap 2 that should be used as a source
sl@0
  1671
               for the alpha blending. The size of the area is the same as the
sl@0
  1672
			   bitmap 1 area - aSrcRect1 parameter.
sl@0
  1673
@param aAlphaPt Position of the first pixel in the alpha bitmap that should be used as a source
sl@0
  1674
                for the alpha blending. The size of the area is the same as the
sl@0
  1675
                bitmap 1 area - aSrcRect1 parameter.
sl@0
  1676
@pre !aSrcRect1.IsEmpty()
sl@0
  1677
@pre aSrcBmp1 != NULL
sl@0
  1678
@pre aSrcBmp1->Handle() != NULL
sl@0
  1679
@pre aSrcBmp2 != NULL
sl@0
  1680
@pre aSrcBmp2->Handle() != NULL
sl@0
  1681
@pre aAlphaBmp != NULL
sl@0
  1682
@pre aAlphaBmp->Handle() != NULL
sl@0
  1683
@pre aAlphaBmp->DisplayMode() <= EGray256
sl@0
  1684
@return KErrNone If the call is successful, KErrArgument otherwise.
sl@0
  1685
*/
sl@0
  1686
EXPORT_C  TInt CFbsBitGc::AlphaBlendBitmaps(const TPoint& aDestPt,
sl@0
  1687
											const CFbsBitmap* aSrcBmp1,
sl@0
  1688
											const CFbsBitmap* aSrcBmp2,
sl@0
  1689
											const TRect& aSrcRect1,
sl@0
  1690
											const TPoint& aSrcPt2,
sl@0
  1691
											const CFbsBitmap* aAlphaBmp,
sl@0
  1692
											const TPoint& aAlphaPt)
sl@0
  1693
	{
sl@0
  1694
	//Check the bitmap pointers and handles. Check the CFbsDevice instance -
sl@0
  1695
	//it shouldn't be NULL - that means - CFbsBitGc instance (this pointer)
sl@0
  1696
	//should be created either using CFbsDevice::CreateContext() or CFbsBitGc::Activate() -
sl@0
  1697
	//before the method was called.
sl@0
  1698
	if(!aSrcBmp1 || !aSrcBmp1->Handle() || !aSrcBmp2 || !aSrcBmp2->Handle() ||
sl@0
  1699
	   !aAlphaBmp || !aAlphaBmp->Handle() || CheckDevice(aSrcRect1))
sl@0
  1700
		{
sl@0
  1701
		return KErrArgument;
sl@0
  1702
		}
sl@0
  1703
		
sl@0
  1704
	aSrcBmp1->BeginDataAccess();
sl@0
  1705
	aSrcBmp2->BeginDataAccess();
sl@0
  1706
	aAlphaBmp->BeginDataAccess();
sl@0
  1707
		
sl@0
  1708
	//Check display mode of the alpha bitmap. Bitmaps which display mode is greater than
sl@0
  1709
	//EGray256 can't be used as alpha bitmaps.
sl@0
  1710
	if(aAlphaBmp->DisplayMode() > EGray256)
sl@0
  1711
		{
sl@0
  1712
		aSrcBmp1->EndDataAccess(ETrue);
sl@0
  1713
		aSrcBmp2->EndDataAccess(ETrue);
sl@0
  1714
		aAlphaBmp->EndDataAccess(ETrue);
sl@0
  1715
		return KErrArgument;
sl@0
  1716
		}
sl@0
  1717
	//Check source rect 1. Bitmap 1 must contain the whole source rect 1.
sl@0
  1718
	TRect srcRect1(aSrcRect1);
sl@0
  1719
	TRect area1(aSrcBmp1->SizeInPixels());
sl@0
  1720
	srcRect1.Intersection(area1);
sl@0
  1721
	if(srcRect1 != aSrcRect1)
sl@0
  1722
		{
sl@0
  1723
		aSrcBmp1->EndDataAccess(ETrue);
sl@0
  1724
		aSrcBmp2->EndDataAccess(ETrue);
sl@0
  1725
		aAlphaBmp->EndDataAccess(ETrue);
sl@0
  1726
		return KErrArgument;
sl@0
  1727
		}
sl@0
  1728
	//Create and check source rect 2. Bitmap 2 must contain the whole source rect 2.
sl@0
  1729
	TRect srcRect2(TSize(aSrcRect1.Width(), aSrcRect1.Height()));
sl@0
  1730
	srcRect2.Move(aSrcPt2);
sl@0
  1731
	TRect srcRect2t(srcRect2);
sl@0
  1732
	TRect area2(aSrcBmp2->SizeInPixels());
sl@0
  1733
	srcRect2.Intersection(area2);
sl@0
  1734
	if(srcRect2 != srcRect2t)
sl@0
  1735
		{
sl@0
  1736
		aSrcBmp1->EndDataAccess(ETrue);
sl@0
  1737
		aSrcBmp2->EndDataAccess(ETrue);
sl@0
  1738
		aAlphaBmp->EndDataAccess(ETrue);
sl@0
  1739
		return KErrArgument;
sl@0
  1740
		}
sl@0
  1741
	//Calculate the destination rect
sl@0
  1742
	TPoint destPt(aDestPt + iOrigin);
sl@0
  1743
	TRect destRect(destPt, srcRect1.Size());
sl@0
  1744
	TPoint offset(srcRect1.iTl - destPt);
sl@0
  1745
	TPoint offset2(srcRect2.iTl - destPt);
sl@0
  1746
	TRect clippedDestRect(destRect);
sl@0
  1747
	AddRect(clippedDestRect);
sl@0
  1748
	if(UserClipRect(clippedDestRect))
sl@0
  1749
		{
sl@0
  1750
		aSrcBmp1->EndDataAccess(ETrue);
sl@0
  1751
		aSrcBmp2->EndDataAccess(ETrue);
sl@0
  1752
		aAlphaBmp->EndDataAccess(ETrue);
sl@0
  1753
		return KErrArgument;
sl@0
  1754
		}
sl@0
  1755
	//Save current shadow mode
sl@0
  1756
	TInt8 shadowMode = iShadowMode;
sl@0
  1757
	iShadowMode = CFbsDrawDevice::ENoShadow;
sl@0
  1758
	//Setup the device and prevent the bitmaps from being cleaned away by client code.
sl@0
  1759
	//Drawing begins.
sl@0
  1760
	SetupDevice();
sl@0
  1761
	iDevice->DrawingBegin();
sl@0
  1762
	CBitwiseBitmap* srcBmp1 = ((CFbsBitGcBitmap*)aSrcBmp1)->Address();
sl@0
  1763
	CBitwiseBitmap* srcBmp2 = ((CFbsBitGcBitmap*)aSrcBmp2)->Address();
sl@0
  1764
	CBitwiseBitmap* alphaBmp = ((CFbsBitGcBitmap*)aAlphaBmp)->Address();
sl@0
  1765
	BG_ASSERT_DEBUG(srcBmp1, EBitgdiPanicInvalidBitmap);
sl@0
  1766
	BG_ASSERT_DEBUG(srcBmp2, EBitgdiPanicInvalidBitmap);
sl@0
  1767
	BG_ASSERT_DEBUG(alphaBmp, EBitgdiPanicInvalidBitmap);
sl@0
  1768
sl@0
  1769
	TUint32* srcDataAddr1 = aSrcBmp1->DataAddress();
sl@0
  1770
	TUint32* srcDataAddr2 = aSrcBmp2->DataAddress();
sl@0
  1771
	TUint32* alphaDataAddr = aAlphaBmp->DataAddress();
sl@0
  1772
sl@0
  1773
	CFbsRasterizer* rasterizer1 = PrepareRasterizerForExtendedBitmap(*aSrcBmp1, clippedDestRect, offset);
sl@0
  1774
	CFbsRasterizer* rasterizer2 = PrepareRasterizerForExtendedBitmap(*aSrcBmp2, clippedDestRect, offset2);
sl@0
  1775
	CFbsRasterizer* alphaRasterizer;
sl@0
  1776
	if (aAlphaPt.iX >= 0 && aAlphaPt.iY >= 0
sl@0
  1777
		&& aAlphaPt.iX + aSrcRect1.Width() <= aAlphaBmp->SizeInPixels().iWidth
sl@0
  1778
		&& aAlphaPt.iY + aSrcRect1.Height() <= aAlphaBmp->SizeInPixels().iHeight)
sl@0
  1779
		{
sl@0
  1780
		// Alpha blending bitmap is not tiled. Pass same region of interest as source bitmaps to rasterizer.
sl@0
  1781
		alphaRasterizer = PrepareRasterizerForExtendedBitmap(*aAlphaBmp, clippedDestRect, aAlphaPt - destPt);
sl@0
  1782
		}
sl@0
  1783
	else
sl@0
  1784
		{
sl@0
  1785
		// Alpha blending bitmap is tiled. Do not pass any region of interest to rasterizer.
sl@0
  1786
		alphaRasterizer = PrepareRasterizerForExtendedBitmap(*aAlphaBmp);
sl@0
  1787
		}
sl@0
  1788
sl@0
  1789
	//For each region - find the clipping rect and draw
sl@0
  1790
	TInt limit = iDefaultRegionPtr->Count();
sl@0
  1791
	CGraphicsAccelerator* ga = GraphicsAccelerator();
sl@0
  1792
	// Code for Graphics Accelerated Drawing
sl@0
  1793
	if(ga && (shadowMode == CFbsDrawDevice::ENoShadow))
sl@0
  1794
		{
sl@0
  1795
		TInt gaOperationResult = KErrUnknown;
sl@0
  1796
		TAcceleratedBitmapSpec srcBmp1Spec(const_cast<CFbsBitmap*>(aSrcBmp1));
sl@0
  1797
		TAcceleratedBitmapSpec srcBmp2Spec(const_cast<CFbsBitmap*>(aSrcBmp2));
sl@0
  1798
		TAcceleratedBitmapSpec alphaBmpSpec(const_cast<CFbsBitmap*>(aAlphaBmp));
sl@0
  1799
		iDevice->DrawingEnd();
sl@0
  1800
sl@0
  1801
		for(TInt count=0;count<limit;count++)
sl@0
  1802
			{
sl@0
  1803
			iClipRect=(*iDefaultRegionPtr)[count];
sl@0
  1804
			if(!iClipRect.Intersects(clippedDestRect))
sl@0
  1805
				{
sl@0
  1806
				continue;
sl@0
  1807
				}
sl@0
  1808
			//clippedDestRect was constructed from destRect. destRect was constructed from srcRect1.
sl@0
  1809
			iClipRect.Intersection(clippedDestRect);
sl@0
  1810
			TRect clippedSrcRect(iClipRect);
sl@0
  1811
			clippedSrcRect.Move(offset);//clippedSrcRect - maps to a part of srcRect1 now.
sl@0
  1812
			TPoint shift(clippedSrcRect.iTl - srcRect1.iTl);
sl@0
  1813
			BG_ASSERT_DEBUG(shift.iX >= 0, EBitgdiPanicNegativeShift);
sl@0
  1814
			BG_ASSERT_DEBUG(shift.iY >= 0, EBitgdiPanicNegativeShift);
sl@0
  1815
sl@0
  1816
			gaOperationResult = ga->Operation(TGopAlphaBlendTwoBitmaps(iClipRect.iTl,srcBmp1Spec,srcBmp2Spec,clippedSrcRect,aSrcPt2 + shift,alphaBmpSpec,aAlphaPt + shift));
sl@0
  1817
			if(gaOperationResult != KErrNone)
sl@0
  1818
				break;
sl@0
  1819
			iDevice->iDrawDevice->UpdateRegion(iClipRect);
sl@0
  1820
			}
sl@0
  1821
		if(gaOperationResult == KErrNone)
sl@0
  1822
			goto finish;
sl@0
  1823
		iDevice->DrawingBegin();
sl@0
  1824
		}
sl@0
  1825
sl@0
  1826
	// Code for non- Graphics Accelerated Drawing
sl@0
  1827
	for(TInt count=0;count<limit;count++)
sl@0
  1828
		{
sl@0
  1829
		iClipRect=(*iDefaultRegionPtr)[count];
sl@0
  1830
		if(!iClipRect.Intersects(clippedDestRect))
sl@0
  1831
			{
sl@0
  1832
			continue;
sl@0
  1833
			}
sl@0
  1834
		//clippedDestRect was constructed from destRect. destRect was constructed from srcRect1.
sl@0
  1835
		iClipRect.Intersection(clippedDestRect);
sl@0
  1836
		TRect clippedSrcRect(iClipRect);
sl@0
  1837
		clippedSrcRect.Move(offset);//clippedSrcRect - maps to a part of srcRect1 now.
sl@0
  1838
		TPoint shift(clippedSrcRect.iTl - srcRect1.iTl);
sl@0
  1839
		BG_ASSERT_DEBUG(shift.iX >= 0, EBitgdiPanicNegativeShift);
sl@0
  1840
		BG_ASSERT_DEBUG(shift.iY >= 0, EBitgdiPanicNegativeShift);
sl@0
  1841
sl@0
  1842
		TDrawMode drawMode = iDrawMode;
sl@0
  1843
		iDrawMode = EDrawModeWriteAlpha; // this is the only mode currently supported
sl@0
  1844
		DoBitBltAlpha(iClipRect.iTl,
sl@0
  1845
					  srcBmp1,
sl@0
  1846
					  srcDataAddr1,
sl@0
  1847
					  srcBmp2,
sl@0
  1848
					  srcDataAddr2,
sl@0
  1849
					  alphaBmp,
sl@0
  1850
					  alphaDataAddr,
sl@0
  1851
					  clippedSrcRect,
sl@0
  1852
					  aSrcPt2 + shift,
sl@0
  1853
					  aAlphaPt + shift,
sl@0
  1854
					  shadowMode);
sl@0
  1855
		iDrawMode = drawMode; // restore the previous draw mode
sl@0
  1856
sl@0
  1857
		iDevice->iDrawDevice->UpdateRegion(iClipRect);
sl@0
  1858
		}
sl@0
  1859
sl@0
  1860
	//Drawig ends. Restore the previous shadow mode
sl@0
  1861
	iDevice->DrawingEnd();
sl@0
  1862
finish:
sl@0
  1863
	if (rasterizer1)
sl@0
  1864
		{
sl@0
  1865
		rasterizer1->EndBitmap(aSrcBmp1->SerialNumber());
sl@0
  1866
		}
sl@0
  1867
	if (rasterizer2)
sl@0
  1868
		{
sl@0
  1869
		rasterizer2->EndBitmap(aSrcBmp2->SerialNumber());
sl@0
  1870
		}
sl@0
  1871
	if (alphaRasterizer)
sl@0
  1872
		{
sl@0
  1873
		alphaRasterizer->EndBitmap(aAlphaBmp->SerialNumber());
sl@0
  1874
		}
sl@0
  1875
	aSrcBmp1->EndDataAccess(ETrue);
sl@0
  1876
	aSrcBmp2->EndDataAccess(ETrue);
sl@0
  1877
	aAlphaBmp->EndDataAccess(ETrue);
sl@0
  1878
	iShadowMode = shadowMode;
sl@0
  1879
sl@0
  1880
	return KErrNone;
sl@0
  1881
	}
sl@0
  1882
sl@0
  1883
/**
sl@0
  1884
The method performs an alpha blending of the source data - aSrcBmp - with the existing image, using
sl@0
  1885
the data from aAlphaBmp as an alpha blending factor.
sl@0
  1886
The formula used for that, is:
sl@0
  1887
(C * A + D * (255 - A)) / 255, where:
sl@0
  1888
- C - a pixel from aSrcBmp;
sl@0
  1889
- D - a pixel from the destination;
sl@0
  1890
- A  - a pixel from aAlphaBmp;
sl@0
  1891
The content of source and alpha bitmap is preserved.
sl@0
  1892
The calculated alpha blended pixels are written to the destination - the screen or a bitmap.
sl@0
  1893
@publishedAll
sl@0
  1894
@released
sl@0
  1895
@param aDestPt Position in the target the result should be drawn to.
sl@0
  1896
@param aSrcBmp A pointer to the source bitmap.
sl@0
  1897
@param aAlphaBmp A pointer to the bitmap used as an alpha blending factor.
sl@0
  1898
@param aSrcRect A part of aSrcBmp that should be used as a source for the alpha blending.
sl@0
  1899
				DISCLAIMER: if aSrcRect is bigger (width and/or height) the behaviour is undefined
sl@0
  1900
@param aAlphaPt Position of the first pixel in the alpha bitmap that should be used as a source
sl@0
  1901
                for the alpha blending. The size of the area is
sl@0
  1902
                the same as the aSrcRect parameter (read DISCLAIMER above).
sl@0
  1903
@pre !aSrcRect.IsEmpty()
sl@0
  1904
@pre aSrcBmp != NULL
sl@0
  1905
@pre aSrcBmp->Handle() != NULL
sl@0
  1906
@pre aAlphaBmp != NULL
sl@0
  1907
@pre aAlphaBmp->Handle() != NULL
sl@0
  1908
@pre aAlphaBmp->DisplayMode() <= EGray256
sl@0
  1909
@return KErrNone If the call is successfull, KErrArgument otherwise.
sl@0
  1910
*/
sl@0
  1911
EXPORT_C  TInt CFbsBitGc::AlphaBlendBitmaps(const TPoint& aDestPt,
sl@0
  1912
											const CFbsBitmap* aSrcBmp,
sl@0
  1913
											const TRect& aSrcRect,
sl@0
  1914
											const CFbsBitmap* aAlphaBmp,
sl@0
  1915
											const TPoint& aAlphaPt)
sl@0
  1916
	{
sl@0
  1917
	//Check the bitmap pointers and handles. Check the CFbsDevice instance -
sl@0
  1918
	//it shouldn't be NULL - that means - CFbsBitGc instance (this pointer)
sl@0
  1919
	//should be created either using CFbsDevice::CreateContext() or CFbsBitGc::Activate() -
sl@0
  1920
	//before the method was called.
sl@0
  1921
	if(!aSrcBmp || !aSrcBmp->Handle() ||
sl@0
  1922
	   !aAlphaBmp || !aAlphaBmp->Handle() || CheckDevice(aSrcRect))
sl@0
  1923
		{
sl@0
  1924
		return KErrArgument;
sl@0
  1925
		}
sl@0
  1926
		
sl@0
  1927
	aSrcBmp->BeginDataAccess();
sl@0
  1928
	aAlphaBmp->BeginDataAccess();
sl@0
  1929
		
sl@0
  1930
	//Check display mode of the alpha bitmap. Bitmaps which display mode is greater than
sl@0
  1931
	//EGray256 can't be used as alpha bitmaps.
sl@0
  1932
	if(aAlphaBmp->DisplayMode() > EGray256)
sl@0
  1933
		{
sl@0
  1934
		aSrcBmp->EndDataAccess(ETrue);
sl@0
  1935
		aAlphaBmp->EndDataAccess(ETrue);
sl@0
  1936
		return KErrArgument;
sl@0
  1937
		}
sl@0
  1938
	//Taking the actual part of the source rect contained in the Bitmap.
sl@0
  1939
	TRect srcRect(aSrcRect);
sl@0
  1940
	TRect area(aSrcBmp->SizeInPixels());
sl@0
  1941
	if(!srcRect.Intersects(area))
sl@0
  1942
		{
sl@0
  1943
		aSrcBmp->EndDataAccess(ETrue);
sl@0
  1944
		aAlphaBmp->EndDataAccess(ETrue);
sl@0
  1945
		return KErrArgument;
sl@0
  1946
		}
sl@0
  1947
	srcRect.Intersection(area);
sl@0
  1948
	//Calculate the destination rect
sl@0
  1949
	TPoint destPt(aDestPt + iOrigin);
sl@0
  1950
	TRect destRect(destPt, srcRect.Size());
sl@0
  1951
	TPoint offset(srcRect.iTl - destPt);
sl@0
  1952
	TRect clippedDestRect(destRect);
sl@0
  1953
	AddRect(clippedDestRect);
sl@0
  1954
	if(UserClipRect(clippedDestRect))
sl@0
  1955
		{
sl@0
  1956
		aSrcBmp->EndDataAccess(ETrue);
sl@0
  1957
		aAlphaBmp->EndDataAccess(ETrue);
sl@0
  1958
		return KErrArgument;
sl@0
  1959
		}
sl@0
  1960
	//Save current shadow mode
sl@0
  1961
	TInt8 shadowMode = iShadowMode;
sl@0
  1962
	iShadowMode = CFbsDrawDevice::ENoShadow;
sl@0
  1963
	//Setup the device and prevent the bitmaps from being cleaned away by client code.
sl@0
  1964
	//Drawing begins.
sl@0
  1965
	SetupDevice();
sl@0
  1966
	iDevice->DrawingBegin();
sl@0
  1967
	
sl@0
  1968
	CBitwiseBitmap* srcBmp = ((CFbsBitGcBitmap*)aSrcBmp)->Address();
sl@0
  1969
	CBitwiseBitmap* alphaBmp = ((CFbsBitGcBitmap*)aAlphaBmp)->Address();
sl@0
  1970
	BG_ASSERT_DEBUG(srcBmp, EBitgdiPanicInvalidBitmap);
sl@0
  1971
	BG_ASSERT_DEBUG(alphaBmp, EBitgdiPanicInvalidBitmap);
sl@0
  1972
	TUint32* srcDataAddr = aSrcBmp->DataAddress();
sl@0
  1973
	TUint32* alphaDataAddr = aAlphaBmp->DataAddress();
sl@0
  1974
sl@0
  1975
	CFbsRasterizer* rasterizer = PrepareRasterizerForExtendedBitmap(*aSrcBmp, clippedDestRect, offset);
sl@0
  1976
	CFbsRasterizer* alphaRasterizer;
sl@0
  1977
	if (aAlphaPt.iX >= 0 && aAlphaPt.iY >= 0
sl@0
  1978
		&& aAlphaPt.iX + srcRect.Width() <= aAlphaBmp->SizeInPixels().iWidth
sl@0
  1979
		&& aAlphaPt.iY + srcRect.Height() <= aAlphaBmp->SizeInPixels().iHeight)
sl@0
  1980
		{
sl@0
  1981
		// Alpha blending bitmap is not tiled. Pass same region of interest as source bitmap to rasterizer.
sl@0
  1982
		alphaRasterizer = PrepareRasterizerForExtendedBitmap(*aAlphaBmp, clippedDestRect, aAlphaPt - destPt);
sl@0
  1983
		}
sl@0
  1984
	else
sl@0
  1985
		{
sl@0
  1986
		// Alpha blending bitmap is tiled. Do not pass any region of interest to rasterizer.
sl@0
  1987
		alphaRasterizer = PrepareRasterizerForExtendedBitmap(*aAlphaBmp);
sl@0
  1988
		}
sl@0
  1989
sl@0
  1990
	//For each region - find the clipping rect and draw
sl@0
  1991
	TInt limit = iDefaultRegionPtr->Count();
sl@0
  1992
	CGraphicsAccelerator* ga = GraphicsAccelerator();
sl@0
  1993
	// Code for Graphics Accelerated Drawing
sl@0
  1994
	if(ga && (shadowMode == CFbsDrawDevice::ENoShadow))
sl@0
  1995
		{
sl@0
  1996
		TInt gaOperationResult = KErrUnknown;
sl@0
  1997
		TAcceleratedBitmapSpec srcBmpSpec(const_cast<CFbsBitmap*>(aSrcBmp));
sl@0
  1998
		TAcceleratedBitmapSpec alphaBmpSpec(const_cast<CFbsBitmap*>(aAlphaBmp));
sl@0
  1999
		iDevice->DrawingEnd();
sl@0
  2000
sl@0
  2001
		for(TInt count=0;count<limit;count++)
sl@0
  2002
			{
sl@0
  2003
			iClipRect=(*iDefaultRegionPtr)[count];
sl@0
  2004
			if(!iClipRect.Intersects(clippedDestRect))
sl@0
  2005
				{
sl@0
  2006
				continue;
sl@0
  2007
				}
sl@0
  2008
			//clippedDestRect was constructed from destRect. destRect was constructed from srcRect.
sl@0
  2009
			iClipRect.Intersection(clippedDestRect);
sl@0
  2010
			TRect clippedSrcRect(iClipRect);
sl@0
  2011
			clippedSrcRect.Move(offset);//clippedSrcRect - maps to a part of srcRect now.
sl@0
  2012
			TPoint shift(clippedSrcRect.iTl - srcRect.iTl);
sl@0
  2013
			BG_ASSERT_DEBUG(shift.iX >= 0, EBitgdiPanicNegativeShift);
sl@0
  2014
			BG_ASSERT_DEBUG(shift.iY >= 0, EBitgdiPanicNegativeShift);
sl@0
  2015
sl@0
  2016
			gaOperationResult = ga->Operation(TGopAlphaBlendOneBitmap(iClipRect.iTl,srcBmpSpec,clippedSrcRect,alphaBmpSpec,aAlphaPt + shift));
sl@0
  2017
			if(gaOperationResult != KErrNone)
sl@0
  2018
				break;
sl@0
  2019
			iDevice->iDrawDevice->UpdateRegion(iClipRect);
sl@0
  2020
			}
sl@0
  2021
		if(gaOperationResult == KErrNone)
sl@0
  2022
			goto finish;
sl@0
  2023
		iDevice->DrawingBegin();
sl@0
  2024
		}
sl@0
  2025
sl@0
  2026
	// Code for non- Graphics Accelerated Drawing
sl@0
  2027
	for(TInt count=0;count<limit;count++)
sl@0
  2028
		{
sl@0
  2029
		iClipRect=(*iDefaultRegionPtr)[count];
sl@0
  2030
		if(!iClipRect.Intersects(clippedDestRect))
sl@0
  2031
			{
sl@0
  2032
			continue;
sl@0
  2033
			}
sl@0
  2034
		//clippedDestRect was constructed from destRect. destRect was constructed from srcRect.
sl@0
  2035
		iClipRect.Intersection(clippedDestRect);
sl@0
  2036
		TRect clippedSrcRect(iClipRect);
sl@0
  2037
		clippedSrcRect.Move(offset);//clippedSrcRect - maps to a part of srcRect now.
sl@0
  2038
		TPoint shift(clippedSrcRect.iTl - srcRect.iTl);
sl@0
  2039
		BG_ASSERT_DEBUG(shift.iX >= 0, EBitgdiPanicNegativeShift);
sl@0
  2040
		BG_ASSERT_DEBUG(shift.iY >= 0, EBitgdiPanicNegativeShift);
sl@0
  2041
		DoBitBltAlpha(iClipRect.iTl,
sl@0
  2042
					  srcBmp,
sl@0
  2043
					  srcDataAddr,
sl@0
  2044
					  clippedSrcRect,
sl@0
  2045
					  alphaBmp,
sl@0
  2046
					  alphaDataAddr,
sl@0
  2047
					  aAlphaPt + shift,
sl@0
  2048
					  shadowMode,
sl@0
  2049
					  EFalse);
sl@0
  2050
		iDevice->iDrawDevice->UpdateRegion(iClipRect);
sl@0
  2051
		}
sl@0
  2052
sl@0
  2053
	// Drawing ends. Restore the previous shadow mode.
sl@0
  2054
	iDevice->DrawingEnd();
sl@0
  2055
finish:
sl@0
  2056
	if (rasterizer)
sl@0
  2057
		{
sl@0
  2058
		rasterizer->EndBitmap(aSrcBmp->SerialNumber());
sl@0
  2059
		}
sl@0
  2060
	if (alphaRasterizer)
sl@0
  2061
		{
sl@0
  2062
		alphaRasterizer->EndBitmap(aAlphaBmp->SerialNumber());
sl@0
  2063
		}
sl@0
  2064
	aSrcBmp->EndDataAccess(ETrue);
sl@0
  2065
	aAlphaBmp->EndDataAccess(ETrue);
sl@0
  2066
	iShadowMode = shadowMode;
sl@0
  2067
sl@0
  2068
	return KErrNone;
sl@0
  2069
	}
sl@0
  2070
sl@0
  2071
GLDEF_C void XorBuffers(TUint32* aDestBuffer,const TUint32* aSrceBuffer,TInt aNumBytes)
sl@0
  2072
	{
sl@0
  2073
	// Round up to nearest word boundary
sl@0
  2074
	const TUint32* const destBufferLimit = aDestBuffer + ((aNumBytes + sizeof(TUint32) - 1) / sizeof(TUint32));
sl@0
  2075
sl@0
  2076
	while (aDestBuffer < destBufferLimit)
sl@0
  2077
		*aDestBuffer++ ^= *aSrceBuffer++;
sl@0
  2078
	}
sl@0
  2079
sl@0
  2080
GLDEF_C void AndBuffers(TUint32* aDestBuffer,const TUint32* aSrceBuffer,TInt aNumBytes)
sl@0
  2081
	{
sl@0
  2082
	// Round up to nearest word boundary
sl@0
  2083
	const TUint32* const destBufferLimit = aDestBuffer + ((aNumBytes + sizeof(TUint32) - 1) / sizeof(TUint32));
sl@0
  2084
sl@0
  2085
	while (aDestBuffer < destBufferLimit)
sl@0
  2086
		*aDestBuffer++ &= *aSrceBuffer++;
sl@0
  2087
	}
sl@0
  2088
sl@0
  2089
GLDEF_C void InvertBuffer(TUint32* aDestBuffer,TInt aNumBytes)
sl@0
  2090
	{
sl@0
  2091
	// Round up to nearest word boundary
sl@0
  2092
	const TUint32* const destBufferLimit = aDestBuffer + ((aNumBytes + sizeof(TUint32) - 1) / sizeof(TUint32));
sl@0
  2093
sl@0
  2094
	while (aDestBuffer < destBufferLimit)
sl@0
  2095
		{
sl@0
  2096
		*aDestBuffer = *aDestBuffer ^ KMaxTUint32;
sl@0
  2097
		++aDestBuffer;
sl@0
  2098
		}
sl@0
  2099
	}
sl@0
  2100
sl@0
  2101
GLDEF_C void InvertBuffer(TUint8* aDestBuffer,TInt aNumBytes)
sl@0
  2102
	{
sl@0
  2103
	const TUint8* const destBufferLimit = aDestBuffer + aNumBytes;
sl@0
  2104
sl@0
  2105
	while (aDestBuffer < destBufferLimit)
sl@0
  2106
		{
sl@0
  2107
		*aDestBuffer = static_cast<TUint8>(*aDestBuffer ^ KMaxTUint8);
sl@0
  2108
		++aDestBuffer;
sl@0
  2109
		}
sl@0
  2110
	}
sl@0
  2111
sl@0
  2112
/**
sl@0
  2113
The method tiles the scan line if its length in pixels is less than
sl@0
  2114
aLengthInPixels argument.
sl@0
  2115
@internalComponent
sl@0
  2116
@param aScanLine A pointer to the scan line buffer.
sl@0
  2117
@param aLengthInPixels The scan line buffer should have that count of pixels after the method call.
sl@0
  2118
@param aSrcPt Position of the first pixel in aMaskBitmap that should be used as a source
sl@0
  2119
              for the pixels in scan line buffer.
sl@0
  2120
@param aMaskBitmap Any additional pixels for the scan line buffer will be taken from here.
sl@0
  2121
@param aScanLinePos This argument is used for some internal optimizations. It should not be
sl@0
  2122
                    modified by the caller.
sl@0
  2123
@param aMaskBase The base address of aMaskBitmap data.
sl@0
  2124
@param aDisplayMode Any additional pixels should be taken from aMaskBitmap using aDisplayMode
sl@0
  2125
                    as an argument for GetScanLine() call.
sl@0
  2126
*/
sl@0
  2127
LOCAL_C void TileScanLine(TPtr8& aScanLine,
sl@0
  2128
						  TInt aLengthInPixels,
sl@0
  2129
						  const TPoint& aSrcPt,
sl@0
  2130
						  const CBitwiseBitmap* aMaskBitmap,
sl@0
  2131
						  TLineScanningPosition& aScanLinePos,
sl@0
  2132
						  TUint32* aMaskBase,
sl@0
  2133
						  TDisplayMode aDisplayMode
sl@0
  2134
						  )
sl@0
  2135
	{
sl@0
  2136
	TInt lengthInBytes = CFbsBitmap::ScanLineLength(aLengthInPixels, aDisplayMode);
sl@0
  2137
	BG_ASSERT_DEBUG(lengthInBytes <= aScanLine.MaxLength(), EBitgdiPanicInvalidArg);
sl@0
  2138
	TInt scanLineLength = aScanLine.Length();
sl@0
  2139
	if(scanLineLength < lengthInBytes && aSrcPt.iX > 0)
sl@0
  2140
		{
sl@0
  2141
		//If, for example, src bmp is 100 pixels width, mask bmp is 20 pixels width and src
sl@0
  2142
		//rect is (10, 0, 100, 1) -> We will read only pixels 10..19 from the first scan line
sl@0
  2143
		//of the mask bmp. We have to have 90 mask bmp pixels.
sl@0
  2144
		//So we have to make a second mask bmp read startig from pixel 0 - 10 pixels length.
sl@0
  2145
		TInt maxLen = Min(aScanLine.MaxLength() - scanLineLength, aSrcPt.iX);
sl@0
  2146
		TPtr8 maskDes2(const_cast <TUint8*> (aScanLine.Ptr()) + scanLineLength, maxLen, maxLen);
sl@0
  2147
		TPoint srcPt(0, aSrcPt.iY);
sl@0
  2148
		TPoint zeroPt(0, 0);
sl@0
  2149
		aMaskBitmap->GetScanLine(maskDes2, srcPt, maxLen, EFalse, zeroPt, aDisplayMode, aMaskBase, aScanLinePos);
sl@0
  2150
		aScanLine.SetLength(scanLineLength + maskDes2.Length());
sl@0
  2151
		scanLineLength = aScanLine.Length();
sl@0
  2152
		}
sl@0
  2153
	if(scanLineLength >= lengthInBytes || scanLineLength == 0)
sl@0
  2154
		{
sl@0
  2155
		return;
sl@0
  2156
		}
sl@0
  2157
	//If we still don't have enough mask bmp pixels - we have to tile the scan line
sl@0
  2158
	TInt repeatCnt = lengthInBytes / scanLineLength - 1;
sl@0
  2159
	TInt bytesLeft = lengthInBytes % scanLineLength;
sl@0
  2160
	const TUint8* src = aScanLine.Ptr();
sl@0
  2161
	TUint8* dest = const_cast <TUint8*> (src) + scanLineLength;
sl@0
  2162
	for(;repeatCnt>0;dest+=scanLineLength,repeatCnt--)
sl@0
  2163
		{
sl@0
  2164
		Mem::Copy(dest, src, scanLineLength);
sl@0
  2165
		}
sl@0
  2166
	if(bytesLeft)
sl@0
  2167
		{
sl@0
  2168
		Mem::Copy(dest, src, bytesLeft);
sl@0
  2169
		}
sl@0
  2170
	aScanLine.SetLength(lengthInBytes);
sl@0
  2171
	}
sl@0
  2172
sl@0
  2173
/**
sl@0
  2174
The method draws a masked rectangular section of the source
sl@0
  2175
bitmap and does a compress/stretch to fit a given destination
sl@0
  2176
rectangle.
sl@0
  2177
@internalComponent
sl@0
  2178
*/
sl@0
  2179
void CFbsBitGc::DoDrawBitmapMasked(const TRect& aDestRect,
sl@0
  2180
							   CBitwiseBitmap* aSourceBitmap,
sl@0
  2181
							   TUint32* aSourceBase,
sl@0
  2182
							   const TRect& aSourceRect,
sl@0
  2183
							   CBitwiseBitmap* aMaskBitmap,
sl@0
  2184
							   TUint32* aMaskBase,
sl@0
  2185
							   TBool aInvertMask, const TPoint& aDitherOrigin)
sl@0
  2186
	{
sl@0
  2187
	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
sl@0
  2188
#ifdef _DEBUG
sl@0
  2189
	TRect deviceDestRect;
sl@0
  2190
	drawDevice->GetDrawRect(deviceDestRect);
sl@0
  2191
	BG_ASSERT_DEBUG(iClipRect.iTl.iX >= deviceDestRect.iTl.iX, EBitgdiPanicOutOfBounds);
sl@0
  2192
	BG_ASSERT_DEBUG(iClipRect.iTl.iY >= deviceDestRect.iTl.iY, EBitgdiPanicOutOfBounds);
sl@0
  2193
	BG_ASSERT_DEBUG(iClipRect.iBr.iX <= deviceDestRect.iBr.iX, EBitgdiPanicOutOfBounds);
sl@0
  2194
	BG_ASSERT_DEBUG(iClipRect.iBr.iY <= deviceDestRect.iBr.iY, EBitgdiPanicOutOfBounds);
sl@0
  2195
#endif
sl@0
  2196
sl@0
  2197
	// The clipped version of the destination rectangle
sl@0
  2198
	TRect clippedDestRect(aDestRect);
sl@0
  2199
	clippedDestRect.Intersection(iClipRect);
sl@0
  2200
sl@0
  2201
	// If the source rectangle and the destination rectangle are same,
sl@0
  2202
	// no stretch/compress operation required, just do BitBltMasked
sl@0
  2203
	if (aDestRect.Size() == aSourceRect.Size())
sl@0
  2204
		{
sl@0
  2205
		if (!clippedDestRect.IsEmpty())
sl@0
  2206
			{
sl@0
  2207
			const TPoint destPoint(clippedDestRect.iTl);
sl@0
  2208
			clippedDestRect.Move(aSourceRect.iTl - aDestRect.iTl);
sl@0
  2209
			DoBitBltMasked(destPoint,
sl@0
  2210
						   aSourceBitmap,
sl@0
  2211
						   aSourceBase,
sl@0
  2212
						   clippedDestRect,
sl@0
  2213
						   aMaskBitmap,
sl@0
  2214
						   aMaskBase,
sl@0
  2215
						   aInvertMask,
sl@0
  2216
						   aDitherOrigin,
sl@0
  2217
						   CFbsDrawDevice::ENoShadow);
sl@0
  2218
			}
sl@0
  2219
		return;
sl@0
  2220
		}
sl@0
  2221
	MFastBlend* fastBlend=NULL;
sl@0
  2222
	if (FastBlendInterface(aSourceBitmap,aMaskBitmap,fastBlend)==KErrNone)
sl@0
  2223
		{
sl@0
  2224
		if (fastBlend->FastBlendBitmapMaskedScaled(iClipRect, aDestRect, aSourceRect, aSourceBase, aSourceBitmap->DataStride(),
sl@0
  2225
				aSourceBitmap->DisplayMode(),aSourceBitmap->SizeInPixels(), 
sl@0
  2226
				aMaskBase, aMaskBitmap->DataStride(), aMaskBitmap->DisplayMode(), aMaskBitmap->SizeInPixels(), aInvertMask, 
sl@0
  2227
				iDrawMode, iShadowMode)==KErrNone)
sl@0
  2228
			{
sl@0
  2229
			return;
sl@0
  2230
			}
sl@0
  2231
		}
sl@0
  2232
sl@0
  2233
	TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
sl@0
  2234
	const TInt scanLineBytes = drawDevice->ScanLineBytes();
sl@0
  2235
	TPtr8 scanLineDes(REINTERPRET_CAST(TUint8*,scanLineBuffer),scanLineBytes,scanLineBytes);
sl@0
  2236
sl@0
  2237
	// This constant is associated to the value used in TestGdi::DoDrawBitmapMaskedL, case #24.
sl@0
  2238
	// If this value is changed, then that one must be updated as well otherwise the test will no longer be valid.	
sl@0
  2239
	const TInt KScanLineLength = 256;
sl@0
  2240
	const TInt KRgbSize = 4;
sl@0
  2241
	TUint8 maskBuffer[KScanLineLength];
sl@0
  2242
sl@0
  2243
	TUint8 sourceBuffer[KScanLineLength*KRgbSize];
sl@0
  2244
	TPtr8 sourceDes(sourceBuffer,KScanLineLength*KRgbSize,KScanLineLength*KRgbSize);
sl@0
  2245
sl@0
  2246
	const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
sl@0
  2247
	TDrawMode drawMode = aInvertMask ? EDrawModeAND : EDrawModeANDNOT;
sl@0
  2248
	// If the source bitmap and the mask bitmap are same, draw the source bitmap either
sl@0
  2249
	// with EDrawModeAND or EDrawModeOR based on aInvertMask parameter.
sl@0
  2250
	if (aSourceBitmap == aMaskBitmap)
sl@0
  2251
		{
sl@0
  2252
		drawMode = aInvertMask ? EDrawModeAND : EDrawModeOR;
sl@0
  2253
		}
sl@0
  2254
sl@0
  2255
	TLinearDDA xLine;
sl@0
  2256
	TInt bitmapXStart = 0;
sl@0
  2257
	xLine.Construct(TPoint(aSourceRect.iTl.iX,aDestRect.iTl.iX),
sl@0
  2258
					TPoint(aSourceRect.iBr.iX,aDestRect.iBr.iX),TLinearDDA::ELeft);
sl@0
  2259
	xLine.JumpToYCoord2(bitmapXStart,clippedDestRect.iTl.iX);
sl@0
  2260
sl@0
  2261
	TLinearDDA yLine;
sl@0
  2262
	TPoint yCoord(aSourceRect.iTl.iY,aDestRect.iTl.iY);
sl@0
  2263
	yLine.Construct(yCoord,TPoint(aSourceRect.iBr.iY,aDestRect.iBr.iY),TLinearDDA::ELeft);
sl@0
  2264
	TInt dummy;
sl@0
  2265
	yLine.JumpToYCoord2(dummy,clippedDestRect.iTl.iY);
sl@0
  2266
	yCoord.SetXY(dummy,clippedDestRect.iTl.iY);
sl@0
  2267
sl@0
  2268
	TPoint ditherOrigin(aDitherOrigin + clippedDestRect.iTl);
sl@0
  2269
	const TInt srceWidth = aSourceRect.Width();
sl@0
  2270
	const TInt destWidth = aDestRect.Width();
sl@0
  2271
	const TInt clipWidth = clippedDestRect.Width();
sl@0
  2272
	const TInt clipStrch = clippedDestRect.iTl.iX - aDestRect.iTl.iX;
sl@0
  2273
	const TInt sourceBmpWidth = aSourceBitmap->SizeInPixels().iWidth;
sl@0
  2274
	const TInt maskWidth = aMaskBitmap->SizeInPixels().iWidth;
sl@0
  2275
	const TInt maskHeight = aMaskBitmap->SizeInPixels().iHeight;
sl@0
  2276
sl@0
  2277
	TLineScanningPosition lineScanPos(aSourceBase);
sl@0
  2278
	TLineScanningPosition lineScanPos2(aSourceBase);
sl@0
  2279
	TLineScanningPosition lineScanPosMask(aMaskBase);
sl@0
  2280
sl@0
  2281
	HBufC8* alphaBuffer = NULL;
sl@0
  2282
	TPtr8 alphaBufferDes(NULL, 0);
sl@0
  2283
	const TDisplayMode maskDisplayMode = aMaskBitmap->DisplayMode();
sl@0
  2284
sl@0
  2285
	// Mask inversion is not supported if the original source mask format is EGray256.
sl@0
  2286
	// Note that this is only used for pre-multiplied alpha targets.
sl@0
  2287
	TUint8 maskInverter = (aInvertMask && maskDisplayMode != EGray256) ? 0xFF : 0x00;
sl@0
  2288
sl@0
  2289
	if (aSourceBitmap != aMaskBitmap)
sl@0
  2290
		{
sl@0
  2291
		// Get buffer to be used to convert non-EGray256 masks to EGray256 when display mode is EColor16MAP
sl@0
  2292
		// or to tile the mask when the mask width is smaller than the source bitmap width.
sl@0
  2293
		if (maskDisplayMode != EGray256 && (dispMode == EColor16MAP || maskWidth < sourceBmpWidth))
sl@0
  2294
			{
sl@0
  2295
			alphaBuffer = CFbsBitmap::GetExtraBuffer(CFbsBitmap::ScanLineLength(maskWidth, EGray256));
sl@0
  2296
			if (!alphaBuffer)
sl@0
  2297
				{
sl@0
  2298
				return;  // Out of memory so do not draw anything 
sl@0
  2299
				}
sl@0
  2300
			alphaBufferDes.Set(alphaBuffer->Des());
sl@0
  2301
			}
sl@0
  2302
sl@0
  2303
		// Get buffer to be used for decompressing compressed masks when mask is EGray256
sl@0
  2304
		if (maskDisplayMode == EGray256 && aMaskBitmap->IsCompressed())
sl@0
  2305
			{
sl@0
  2306
			HBufC8* hBuf= CFbsBitmap::GetDecompressionBuffer(aMaskBitmap->DataStride());
sl@0
  2307
			if (!hBuf)
sl@0
  2308
				{
sl@0
  2309
				return;  // Out of memory so do not draw anything
sl@0
  2310
				}
sl@0
  2311
			lineScanPosMask.iScanLineBuffer = hBuf;
sl@0
  2312
			}
sl@0
  2313
		}
sl@0
  2314
sl@0
  2315
	while (yCoord.iY < clippedDestRect.iBr.iY)
sl@0
  2316
		{
sl@0
  2317
		// Draw only the source bitmap, if the source bitmap and the mask bitmap are same.
sl@0
  2318
		// else draw both the bitmaps
sl@0
  2319
		if (aSourceBitmap == aMaskBitmap)
sl@0
  2320
			{
sl@0
  2321
			aSourceBitmap->StretchScanLine(scanLineDes,TPoint(bitmapXStart,yCoord.iX),
sl@0
  2322
								 clipStrch,clipWidth,destWidth,aSourceRect.iTl.iX,
sl@0
  2323
								 srceWidth,ditherOrigin,dispMode,aSourceBase,lineScanPos);
sl@0
  2324
			if (yCoord.iY==clippedDestRect.iTl.iY)
sl@0
  2325
				aSourceBitmap->SetCompressionBookmark(lineScanPos,aSourceBase,NULL);
sl@0
  2326
			drawDevice->WriteLine(clippedDestRect.iTl.iX,yCoord.iY,clipWidth,scanLineBuffer,drawMode);
sl@0
  2327
			}
sl@0
  2328
		else if ((maskDisplayMode == EGray256) || (dispMode == EColor16MAP))
sl@0
  2329
			{
sl@0
  2330
			// Stretch the source bitmap and the mask bitmap for KScanLineLength as stretch length
sl@0
  2331
			// then do alpha blending for this length. If the length is more then KScanLineLength
sl@0
  2332
			// repeat it till you stretch complete destination length.
sl@0
  2333
			const TPoint startPt(bitmapXStart,yCoord.iX);
sl@0
  2334
			TInt clipWidthPart = clippedDestRect.Width();
sl@0
  2335
			TBool loopLast = ETrue;
sl@0
  2336
			if(clipWidthPart > KScanLineLength)
sl@0
  2337
				{
sl@0
  2338
				clipWidthPart = KScanLineLength;
sl@0
  2339
				loopLast = EFalse;
sl@0
  2340
				}
sl@0
  2341
			TInt clipIncStrch = clippedDestRect.iTl.iX - aDestRect.iTl.iX;
sl@0
  2342
			TInt startClip=clippedDestRect.iTl.iX;
sl@0
  2343
			TPoint sourceDestXCoords(bitmapXStart,clippedDestRect.iTl.iX);
sl@0
  2344
			xLine.Construct(TPoint(aSourceRect.iTl.iX,aDestRect.iTl.iX),
sl@0
  2345
							TPoint(aSourceRect.iBr.iX,aDestRect.iBr.iX),TLinearDDA::ELeft);
sl@0
  2346
			xLine.JumpToYCoord2(sourceDestXCoords.iX,sourceDestXCoords.iY);
sl@0
  2347
			TPoint srcPixel(bitmapXStart % maskWidth,yCoord.iX % maskHeight);
sl@0
  2348
			TInt spaceLeft = 0;
sl@0
  2349
			TRgb maskRgbValue;
sl@0
  2350
			TUint32* maskScanLinePtr32 = NULL;
sl@0
  2351
			TPoint currentYValue(0,srcPixel.iY);
sl@0
  2352
			aMaskBitmap->GetScanLinePtr(maskScanLinePtr32, currentYValue, maskWidth, aMaskBase, lineScanPosMask);
sl@0
  2353
			// To implement non EGray256 mask support with EColor16MAP display mode, we convert
sl@0
  2354
			// the mask to EGray256.
sl@0
  2355
			if (maskDisplayMode != EGray256) // Convert scan-line to EGray256 and set maskScanLinePtr32 to the conversion.
sl@0
  2356
				{
sl@0
  2357
				aMaskBitmap->GetScanLine(maskScanLinePtr32, alphaBufferDes, currentYValue, maskWidth, EFalse, TPoint(0, 0), EGray256);
sl@0
  2358
				maskScanLinePtr32 = (TUint32*)alphaBuffer->Ptr();
sl@0
  2359
				}
sl@0
  2360
			TUint8* maskScanLinePtr = reinterpret_cast<TUint8*>(maskScanLinePtr32);
sl@0
  2361
sl@0
  2362
			// Outer loop over all KScanLineLengths
sl@0
  2363
			FOREVER
sl@0
  2364
				{
sl@0
  2365
				aSourceBitmap->StretchScanLine(sourceDes,startPt,clipIncStrch,clipWidthPart,destWidth,
sl@0
  2366
								aSourceRect.iTl.iX,srceWidth,ditherOrigin,EColor16MU,aSourceBase,lineScanPos);
sl@0
  2367
				// Inner loop to tile the mask if necessary
sl@0
  2368
				spaceLeft = clipWidthPart;
sl@0
  2369
	
sl@0
  2370
				do	{
sl@0
  2371
					srcPixel.iX = sourceDestXCoords.iX % maskWidth;
sl@0
  2372
			
sl@0
  2373
					// Invert the mask using the inversion mask.
sl@0
  2374
					maskBuffer[(sourceDestXCoords.iY-clippedDestRect.iTl.iX)%KScanLineLength]=
sl@0
  2375
						maskInverter^maskScanLinePtr[srcPixel.iX];
sl@0
  2376
					xLine.NextStep(sourceDestXCoords);
sl@0
  2377
					} while (--spaceLeft>0);
sl@0
  2378
				
sl@0
  2379
				if (yCoord.iY == clippedDestRect.iTl.iY && startClip == clippedDestRect.iTl.iX)
sl@0
  2380
					{
sl@0
  2381
					aSourceBitmap->SetCompressionBookmark(lineScanPos,aSourceBase,NULL);
sl@0
  2382
					aMaskBitmap->SetCompressionBookmark(lineScanPosMask,aMaskBase,NULL);
sl@0
  2383
					}
sl@0
  2384
				drawDevice->WriteRgbAlphaLine(startClip,yCoord.iY,clipWidthPart,sourceBuffer,maskBuffer,iDrawMode);
sl@0
  2385
				if (loopLast)
sl@0
  2386
					{
sl@0
  2387
					break;
sl@0
  2388
					}
sl@0
  2389
				startClip+=KScanLineLength;
sl@0
  2390
				if (clippedDestRect.iBr.iX - startClip <= KScanLineLength)
sl@0
  2391
 					{
sl@0
  2392
					loopLast = ETrue;
sl@0
  2393
					clipWidthPart = clippedDestRect.iBr.iX - startClip;
sl@0
  2394
					}
sl@0
  2395
				clipIncStrch += KScanLineLength;
sl@0
  2396
				}
sl@0
  2397
			}
sl@0
  2398
		else
sl@0
  2399
			{
sl@0
  2400
			aSourceBitmap->StretchScanLine(scanLineDes,TPoint(bitmapXStart,yCoord.iX),
sl@0
  2401
									 clipStrch,clipWidth,destWidth,aSourceRect.iTl.iX,
sl@0
  2402
									 srceWidth,ditherOrigin,dispMode,aSourceBase,lineScanPos2);
sl@0
  2403
			drawDevice->WriteLine(clippedDestRect.iTl.iX,yCoord.iY,clipWidth,scanLineBuffer,EDrawModeXOR);
sl@0
  2404
sl@0
  2405
			TInt maskXStart = bitmapXStart % maskWidth;
sl@0
  2406
			if(maskWidth < sourceBmpWidth)
sl@0
  2407
				{
sl@0
  2408
				TPoint sourceDestXCoords(bitmapXStart,clippedDestRect.iTl.iX);
sl@0
  2409
				xLine.Construct(TPoint(aSourceRect.iTl.iX,aDestRect.iTl.iX),
sl@0
  2410
								TPoint(aSourceRect.iBr.iX,aDestRect.iBr.iX),TLinearDDA::ELeft);
sl@0
  2411
				xLine.JumpToYCoord2(sourceDestXCoords.iX,sourceDestXCoords.iY);
sl@0
  2412
				TPoint srcPixel(maskXStart,yCoord.iX % maskHeight);
sl@0
  2413
				TInt spaceLeft = clipWidth;
sl@0
  2414
				TPoint prevSourceDestXCoords(-1,-1);
sl@0
  2415
				TRgb maskRgbValue;
sl@0
  2416
				aMaskBitmap->GetScanLine(alphaBufferDes, TPoint(0,srcPixel.iY), maskWidth, EFalse, TPoint(0, 0), EGray256, aMaskBase, lineScanPosMask);
sl@0
  2417
sl@0
  2418
				// Loop to tile the mask
sl@0
  2419
				do	{
sl@0
  2420
					if (sourceDestXCoords.iY != prevSourceDestXCoords.iY)
sl@0
  2421
						{
sl@0
  2422
						if (sourceDestXCoords.iX != prevSourceDestXCoords.iX)
sl@0
  2423
							{
sl@0
  2424
							srcPixel.iX = sourceDestXCoords.iX % maskWidth;
sl@0
  2425
							if (srcPixel.iX < 0)
sl@0
  2426
								srcPixel.iX += maskWidth;
sl@0
  2427
							maskRgbValue = TRgb::Gray256((*alphaBuffer)[srcPixel.iX]);
sl@0
  2428
							}
sl@0
  2429
						drawDevice->WriteRgb(sourceDestXCoords.iY,yCoord.iY,maskRgbValue,drawMode);
sl@0
  2430
						spaceLeft--;
sl@0
  2431
						}
sl@0
  2432
					prevSourceDestXCoords = sourceDestXCoords;
sl@0
  2433
					xLine.SingleStep(sourceDestXCoords);
sl@0
  2434
					} while (spaceLeft > 0);
sl@0
  2435
				}
sl@0
  2436
			else
sl@0
  2437
				{
sl@0
  2438
				// No need to tile the mask
sl@0
  2439
				aMaskBitmap->StretchScanLine(scanLineDes,TPoint(maskXStart,yCoord.iX % maskHeight),
sl@0
  2440
										clipStrch,clipWidth,destWidth,aSourceRect.iTl.iX,
sl@0
  2441
										srceWidth,ditherOrigin,dispMode,aMaskBase,lineScanPosMask);
sl@0
  2442
				drawDevice->WriteLine(clippedDestRect.iTl.iX,yCoord.iY,clipWidth,scanLineBuffer,drawMode);
sl@0
  2443
				// Redo stretching of the aSourceBitmap scanline
sl@0
  2444
				aSourceBitmap->StretchScanLine(scanLineDes,TPoint(bitmapXStart,yCoord.iX),
sl@0
  2445
									 	clipStrch,clipWidth,destWidth,aSourceRect.iTl.iX,
sl@0
  2446
									 	srceWidth,ditherOrigin,dispMode,aSourceBase,lineScanPos2);
sl@0
  2447
				}
sl@0
  2448
sl@0
  2449
			if (yCoord.iY==clippedDestRect.iTl.iY)
sl@0
  2450
				{
sl@0
  2451
				aSourceBitmap->SetCompressionBookmark(lineScanPos2,aSourceBase,NULL);
sl@0
  2452
				aMaskBitmap->SetCompressionBookmark(lineScanPosMask,aMaskBase,NULL);
sl@0
  2453
				}
sl@0
  2454
sl@0
  2455
			drawDevice->WriteLine(clippedDestRect.iTl.iX,yCoord.iY,clipWidth,scanLineBuffer,EDrawModeXOR);
sl@0
  2456
			}
sl@0
  2457
		yLine.NextStep(yCoord);
sl@0
  2458
		ditherOrigin.iY++;
sl@0
  2459
		}
sl@0
  2460
	}
sl@0
  2461
sl@0
  2462
EXPORT_C TInt CFbsBitGc::AlphaBlendBitmaps(const TPoint& aDestPt,
sl@0
  2463
											const CWsBitmap* aSrcBmp,
sl@0
  2464
											const TRect& aSrcRect,
sl@0
  2465
											const CWsBitmap* aAlphaBmp,
sl@0
  2466
											const TPoint& aAlphaPt)
sl@0
  2467
	{
sl@0
  2468
	return AlphaBlendBitmaps(aDestPt, REINTERPRET_CAST(const CFbsBitmap*, aSrcBmp), aSrcRect, REINTERPRET_CAST(const CFbsBitmap*, aAlphaBmp), aAlphaPt);
sl@0
  2469
	}
sl@0
  2470
sl@0
  2471
TInt CFbsBitGc::FastBlendInterface(const CBitwiseBitmap* aSource, const CBitwiseBitmap* aMask, MFastBlend*& aFastBlend) const
sl@0
  2472
	{
sl@0
  2473
#if defined(__ALLOW_FAST_BLEND_DISABLE__)
sl@0
  2474
	if (iFastBlendDisabled)
sl@0
  2475
		return(KErrNotSupported);
sl@0
  2476
#endif
sl@0
  2477
	if ((aSource && aSource->IsCompressed()) || (aMask && aMask->IsCompressed()))
sl@0
  2478
		return(KErrNotSupported);
sl@0
  2479
	TAny* interface=NULL;
sl@0
  2480
	TInt ret=iDevice->iDrawDevice->GetInterface(KFastBlendInterfaceID, interface);
sl@0
  2481
	aFastBlend=(MFastBlend*)interface;
sl@0
  2482
	return(ret);
sl@0
  2483
	}
sl@0
  2484
sl@0
  2485
/*
sl@0
  2486
Returns the pixel-format to be used when extracting a scan-line through CBitwiseBitmap::GetScanLine(), CBitwiseBitmap::GetVerticalScanLine(), and CBitwiseBitmap::StretchScanLine() for consumption by CFbsDrawDevice::WriteLine() and associated methods.
sl@0
  2487
sl@0
  2488
@see CBitwiseBitmap::GetScanLine()
sl@0
  2489
@see CBitwiseBitmap::GetVerticalScanLine()
sl@0
  2490
@see CBitwiseBitmap::StretchScanLine()
sl@0
  2491
@see CFbsDrawDevice::WriteLine()
sl@0
  2492
@internalComponent
sl@0
  2493
*/
sl@0
  2494
TDisplayMode CFbsBitGc::ScanLineBufferDisplayMode(CFbsDrawDevice* aDrawDevice)
sl@0
  2495
	{
sl@0
  2496
	return iDrawMode == EDrawModeWriteAlpha ? aDrawDevice->DisplayMode() : aDrawDevice->ScanLineDisplayMode();
sl@0
  2497
	}
sl@0
  2498
sl@0
  2499
/** Prepares the rasterizer to retrieve scan lines from a bitmap if it is an
sl@0
  2500
extended bitmap. No region of interest is passed to the rasterizer.
sl@0
  2501
This function calls CFbsRasterizer::BeginBitmap() with the appropriate
sl@0
  2502
parameters. When finished retrieving scan lines from the extended bitmap,
sl@0
  2503
CFbsRasterizer::EndBitmap() must be called.
sl@0
  2504
@param aBitmap The bitmap to retrieve scan lines from.
sl@0
  2505
@return A pointer to the rasterizer owned by this thread's FBServ session.
sl@0
  2506
@return NULL if the rasterizer is not present or aBitmap is not an extended bitmap.
sl@0
  2507
@see CFbsRasterizer
sl@0
  2508
@internalComponent
sl@0
  2509
*/
sl@0
  2510
CFbsRasterizer* CFbsBitGc::PrepareRasterizerForExtendedBitmap(const CFbsBitmap& aBitmap)
sl@0
  2511
	{
sl@0
  2512
	CFbsRasterizer* rasterizer = NULL;
sl@0
  2513
	CFbsRasterizer::TBitmapDesc desc;
sl@0
  2514
	desc.iDataType = aBitmap.ExtendedBitmapType();
sl@0
  2515
	if (desc.iDataType != KNullUid)
sl@0
  2516
		{
sl@0
  2517
		rasterizer = CFbsBitmap::Rasterizer();
sl@0
  2518
		if (rasterizer)
sl@0
  2519
			{
sl@0
  2520
			desc.iSizeInPixels = aBitmap.SizeInPixels();
sl@0
  2521
			desc.iDispMode = aBitmap.DisplayMode();
sl@0
  2522
			desc.iData = aBitmap.DataAddress();
sl@0
  2523
			desc.iDataSize = aBitmap.DataSize();
sl@0
  2524
			rasterizer->BeginBitmap(aBitmap.SerialNumber(), desc, NULL);
sl@0
  2525
			}
sl@0
  2526
		}
sl@0
  2527
	return rasterizer;
sl@0
  2528
	}
sl@0
  2529
sl@0
  2530
/** Prepares the rasterizer to retrieve scan lines from a bitmap if it is an
sl@0
  2531
extended bitmap. The region of interest passed to the rasterizer is the
sl@0
  2532
intersection of the clipping region and the specified rectangle.
sl@0
  2533
This function calls CFbsRasterizer::BeginBitmap() with the appropriate
sl@0
  2534
parameters. When finished retrieving scan lines from the extended bitmap,
sl@0
  2535
CFbsRasterizer::EndBitmap() must be called.
sl@0
  2536
@param aBitmap The bitmap to retrieve scan lines from.
sl@0
  2537
@param aDestRect A rectangle in coordinates relative to the graphics context that
sl@0
  2538
                 bounds the area that aBitmap is to be blitted onto.
sl@0
  2539
@param aOffset An offset that converts aDestRect into coordinates relative to
sl@0
  2540
               the source bitmap.
sl@0
  2541
@return A pointer to the rasterizer owned by this thread's FBServ session.
sl@0
  2542
@return NULL if the rasterizer is not present or aBitmap is not an extended bitmap.
sl@0
  2543
@see CFbsRasterizer
sl@0
  2544
@internalComponent
sl@0
  2545
*/
sl@0
  2546
CFbsRasterizer* CFbsBitGc::PrepareRasterizerForExtendedBitmap(const CFbsBitmap& aBitmap, const TRect& aDestRect, const TPoint& aOffset)
sl@0
  2547
	{
sl@0
  2548
	CFbsRasterizer* rasterizer = NULL;
sl@0
  2549
	CFbsRasterizer::TBitmapDesc desc;
sl@0
  2550
	desc.iDataType = aBitmap.ExtendedBitmapType();
sl@0
  2551
	if (desc.iDataType != KNullUid)
sl@0
  2552
		{
sl@0
  2553
		rasterizer = CFbsBitmap::Rasterizer();
sl@0
  2554
		if (rasterizer)
sl@0
  2555
			{
sl@0
  2556
			desc.iSizeInPixels = aBitmap.SizeInPixels();
sl@0
  2557
			desc.iDispMode = aBitmap.DisplayMode();
sl@0
  2558
			desc.iData = aBitmap.DataAddress();
sl@0
  2559
			desc.iDataSize = aBitmap.DataSize();
sl@0
  2560
			RRegion rgn;
sl@0
  2561
			rgn.Copy(*iDefaultRegionPtr);
sl@0
  2562
			rgn.ClipRect(aDestRect);
sl@0
  2563
			rgn.Offset(aOffset);
sl@0
  2564
			BG_ASSERT_DEBUG(rgn.IsContainedBy(desc.iSizeInPixels), EBitgdiPanicOutOfBounds);
sl@0
  2565
			rasterizer->BeginBitmap(aBitmap.SerialNumber(), desc, &rgn);
sl@0
  2566
			rgn.Close();
sl@0
  2567
			}
sl@0
  2568
		}
sl@0
  2569
	return rasterizer;
sl@0
  2570
	}
sl@0
  2571
sl@0
  2572
/** Prepares the rasterizer to retrieve scan lines from a bitmap if it is an
sl@0
  2573
extended bitmap. The region of interest passed to the rasterizer is the intersection
sl@0
  2574
of the clipping region, the clipping rectangle and the specified rectangle.
sl@0
  2575
This function calls CFbsRasterizer::BeginBitmap() with the appropriate
sl@0
  2576
parameters. When finished retrieving scan lines from the extended bitmap,
sl@0
  2577
CFbsRasterizer::EndBitmap() must be called.
sl@0
  2578
@param aBitmap The bitmap to retrieve scan lines from.
sl@0
  2579
@param aDestRect A rectangle in coordinates relative to the graphics context that
sl@0
  2580
                 bounds the area that aBitmap is to be drawn onto.
sl@0
  2581
@param aSourceRect A rectangle in coordinates relative to the source bitmap that maps
sl@0
  2582
                   to aDestRect after scaling and translation.
sl@0
  2583
@return A pointer to the rasterizer owned by this thread's FBServ session.
sl@0
  2584
@return NULL if the rasterizer is not present or aBitmap is not an extended bitmap.
sl@0
  2585
@see CFbsRasterizer
sl@0
  2586
@internalComponent
sl@0
  2587
*/
sl@0
  2588
CFbsRasterizer* CFbsBitGc::PrepareRasterizerForExtendedBitmap(const CFbsBitmap& aBitmap, const TRect& aDestRect, const TRect& aSourceRect)
sl@0
  2589
	{
sl@0
  2590
	CFbsRasterizer* rasterizer = NULL;
sl@0
  2591
	CFbsRasterizer::TBitmapDesc desc;
sl@0
  2592
	desc.iDataType = aBitmap.ExtendedBitmapType();
sl@0
  2593
	if (desc.iDataType != KNullUid)
sl@0
  2594
		{
sl@0
  2595
		rasterizer = CFbsBitmap::Rasterizer();
sl@0
  2596
		if (rasterizer)
sl@0
  2597
			{
sl@0
  2598
			desc.iSizeInPixels = aBitmap.SizeInPixels();
sl@0
  2599
			desc.iDispMode = aBitmap.DisplayMode();
sl@0
  2600
			desc.iData = aBitmap.DataAddress();
sl@0
  2601
			desc.iDataSize = aBitmap.DataSize();
sl@0
  2602
			RRegion rgn;
sl@0
  2603
			// Calculate the parameters for the linear DDA algorithm used to scale the region
sl@0
  2604
			// of interest before entering the rectangle loop, since they are invariant.
sl@0
  2605
			TLinearDDA xLine0, yLine0;
sl@0
  2606
			xLine0.Construct(TPoint(aSourceRect.iTl.iX, aDestRect.iTl.iX),
sl@0
  2607
			                 TPoint(aSourceRect.iBr.iX, aDestRect.iBr.iX),
sl@0
  2608
			                 TLinearDDA::ELeft);
sl@0
  2609
			yLine0.Construct(TPoint(aSourceRect.iTl.iY, aDestRect.iTl.iY),
sl@0
  2610
			                 TPoint(aSourceRect.iBr.iY, aDestRect.iBr.iY),
sl@0
  2611
			                 TLinearDDA::ELeft);
sl@0
  2612
			TInt n = iDefaultRegionPtr->Count();
sl@0
  2613
			for (TInt i = 0; i < n; ++i)
sl@0
  2614
				{
sl@0
  2615
				TRect rect = (*iDefaultRegionPtr)[i];
sl@0
  2616
				if (!rect.Intersects(iUserClipRect))
sl@0
  2617
					{
sl@0
  2618
					continue;
sl@0
  2619
					}
sl@0
  2620
				rect.Intersection(iUserClipRect);
sl@0
  2621
				if (!rect.Intersects(aDestRect))
sl@0
  2622
					{
sl@0
  2623
					continue;
sl@0
  2624
					}
sl@0
  2625
				rect.Intersection(aDestRect);
sl@0
  2626
				// Scale the region of interest from coordinates relative to the graphics
sl@0
  2627
				// context to coordinates relative to the bitmap, one rectangle at a time.
sl@0
  2628
				TLinearDDA xLine(xLine0), yLine(yLine0);
sl@0
  2629
				TInt ax, ay, bx, by;
sl@0
  2630
				xLine.JumpToYCoord(ax, rect.iTl.iX);
sl@0
  2631
				yLine.JumpToYCoord(ay, rect.iTl.iY);
sl@0
  2632
				xLine.JumpToYCoord(bx, rect.iBr.iX);
sl@0
  2633
				yLine.JumpToYCoord(by, rect.iBr.iY);
sl@0
  2634
				if (ax < bx && ay < by)
sl@0
  2635
					{
sl@0
  2636
					rgn.AddRect(TRect(ax, ay, bx, by));
sl@0
  2637
					}
sl@0
  2638
				}
sl@0
  2639
			BG_ASSERT_DEBUG(rgn.IsContainedBy(desc.iSizeInPixels), EBitgdiPanicOutOfBounds);
sl@0
  2640
			rasterizer->BeginBitmap(aBitmap.SerialNumber(), desc, &rgn);
sl@0
  2641
			rgn.Close();
sl@0
  2642
			}
sl@0
  2643
		}
sl@0
  2644
	return rasterizer;
sl@0
  2645
	}