os/graphics/graphicsdeviceinterface/bitgdi/sbit/BITBLT.CPP
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/graphics/graphicsdeviceinterface/bitgdi/sbit/BITBLT.CPP	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,2645 @@
     1.4 +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +//
    1.18 +
    1.19 +#include "BITPANIC.H"
    1.20 +#include <fntstore.h>
    1.21 +#include <bitmap.h>
    1.22 +#include <bitstd.h>
    1.23 +#include <bitdev.h>
    1.24 +#include <bitdraw.h>
    1.25 +#include <bitdrawscaling.h>
    1.26 +#include <bitdrawinterfaceid.h>
    1.27 +#include <bmalphablend.h>
    1.28 +#include <graphics/fbsrasterizer.h>
    1.29 +#include <graphics/bitmap.inl>
    1.30 +#include <graphics/gdi/gdiinline.inl>
    1.31 +
    1.32 +GLREF_C void XorBuffers(TUint32* aDestBuffer,const TUint32* aSrceBuffer,TInt aNumBytes);
    1.33 +GLREF_C void AndBuffers(TUint32* aDestBuffer,const TUint32* aSrceBuffer,TInt aNumBytes);
    1.34 +GLREF_C void InvertBuffer(TUint32* aDestBuffer,TInt aNumBytes);
    1.35 +GLREF_C void InvertBuffer(TUint8* aDestBuffer,TInt aNumBytes);
    1.36 +LOCAL_C void TileScanLine(TPtr8& aScanLine,
    1.37 +						  TInt aLengthInPixels,
    1.38 +						  const TPoint& aSrcPt,
    1.39 +						  const CBitwiseBitmap* aMaskBitmap,
    1.40 +						  TLineScanningPosition& aScanLinePos,
    1.41 +						  TUint32* aMaskBase,
    1.42 +						  TDisplayMode aDisplayMode
    1.43 +						  );
    1.44 +
    1.45 +/** Draws from another CFbsBitGc.
    1.46 +
    1.47 +@param aPoint The position to draw the top left corner of the piece of bitmap
    1.48 +@param aGc The source bitmap graphics context */
    1.49 +EXPORT_C void CFbsBitGc::BitBlt(const TPoint& aDest,const CFbsBitGc& aGc)
    1.50 +	{
    1.51 +	TRect deviceRect;
    1.52 +	aGc.iDevice->iDrawDevice->GetDrawRect(deviceRect);
    1.53 +	BitBlt(aDest,aGc,deviceRect);
    1.54 +	}
    1.55 +
    1.56 +/** Draws a particular rectangle from another CFbsBitGc.
    1.57 +
    1.58 +@param aPoint The position to draw the top left corner of the piece of bitmap.
    1.59 +@param aGc The source bitmap graphics context.
    1.60 +@param aSrceRect A rectangle defining the piece of the source to be drawn. */
    1.61 +EXPORT_C void CFbsBitGc::BitBlt(const TPoint& aDest,
    1.62 +								const CFbsBitGc& aGc,
    1.63 +								const TRect& aSrceRect)
    1.64 +	{
    1.65 +	if (CheckDevice(aSrceRect))
    1.66 +		return;
    1.67 +	aGc.CheckDevice();
    1.68 +	CFbsDevice* srceDevice = aGc.iDevice;
    1.69 +	if (!srceDevice)
    1.70 +		return;
    1.71 +
    1.72 +	TRect srceRect(aSrceRect);
    1.73 +	TRect deviceRect;
    1.74 +	srceDevice->GetDrawRect(deviceRect);
    1.75 +	if (!srceRect.Intersects(deviceRect))
    1.76 +		return;
    1.77 +	srceRect.Intersection(deviceRect);
    1.78 +
    1.79 +	const TPoint destPoint(aDest + iOrigin + srceRect.iTl - aSrceRect.iTl);
    1.80 +	const TRect destRect(destPoint,srceRect.Size());
    1.81 +	const TPoint offset(srceRect.iTl - destPoint);
    1.82 +
    1.83 +	TRect clippedDestRect(destRect);
    1.84 +	AddRect(clippedDestRect);
    1.85 +	if (UserClipRect(clippedDestRect))
    1.86 +		return;
    1.87 +
    1.88 +	SetupDevice();
    1.89 +	aGc.iDevice->DrawingBegin();
    1.90 +	iDevice->DrawingBegin();
    1.91 +
    1.92 +	const TInt limit = iDefaultRegionPtr->Count();
    1.93 +	TBool opaqueSource = (!IsAlphaChannel(srceDevice->DisplayMode())) && (iDrawMode == EDrawModePEN);
    1.94 +	for(TInt count=0;count<limit;count++)
    1.95 +		{
    1.96 +		iClipRect=(*iDefaultRegionPtr)[count];
    1.97 +		if(!iClipRect.Intersects(clippedDestRect))
    1.98 +			continue;
    1.99 +		iClipRect.Intersection(clippedDestRect);
   1.100 +
   1.101 +		TRect clippedSrceRect(iClipRect);
   1.102 +		clippedSrceRect.Move(offset);
   1.103 +
   1.104 +		if (opaqueSource)
   1.105 +			iDrawMode = EDrawModeWriteAlpha;// ie write rather then blend
   1.106 +		DoBitBlt(iClipRect.iTl,srceDevice,clippedSrceRect);
   1.107 +		if (opaqueSource)
   1.108 +			iDrawMode = EDrawModePEN;// set it back how it was
   1.109 +		iDevice->iDrawDevice->UpdateRegion(iClipRect);
   1.110 +		}
   1.111 +
   1.112 +	aGc.iDevice->DrawingEnd();
   1.113 +	iDevice->DrawingEnd();
   1.114 +	}
   1.115 +
   1.116 +
   1.117 +/** Draws the whole of a CFbsBitmap.
   1.118 +
   1.119 +@param aDest   The position to draw the top left corner of the bitmap.
   1.120 +@param aBitmap The source bitmap. */
   1.121 +EXPORT_C void CFbsBitGc::BitBlt(const TPoint& aDest,const CFbsBitmap* aBitmap)
   1.122 +    {
   1.123 +    if (aBitmap == NULL || !aBitmap->Handle())
   1.124 +    	return;
   1.125 +    
   1.126 +	aBitmap->BeginDataAccess();
   1.127 +    BitBlt(aDest,aBitmap,TRect(aBitmap->SizeInPixels()));
   1.128 +	aBitmap->EndDataAccess(ETrue);
   1.129 +	}
   1.130 +
   1.131 +
   1.132 +/** Draws a particular rectangle from a CFbsBitmap.
   1.133 +
   1.134 +@param aDest The position to draw the top left corner of the bitmap.
   1.135 +@param aBitmap The source bitmap.
   1.136 +@param aSrceRect A rectangle defining the piece of the source to be drawn. */
   1.137 +EXPORT_C void CFbsBitGc::BitBlt(const TPoint& aDest,
   1.138 +								const CFbsBitmap* aBitmap,
   1.139 +								const TRect& aSrceRect)
   1.140 +    {
   1.141 +	if (aBitmap == NULL || !aBitmap->Handle()|| CheckDevice(aSrceRect))
   1.142 +		return;
   1.143 +
   1.144 +	aBitmap->BeginDataAccess();
   1.145 +		
   1.146 +	TRect srceRect(aSrceRect);
   1.147 +	const TRect area(aBitmap->SizeInPixels());
   1.148 +	if (!srceRect.Intersects(area))
   1.149 +		{
   1.150 +		aBitmap->EndDataAccess(ETrue);
   1.151 +		return;
   1.152 +		}
   1.153 +	srceRect.Intersection(area);
   1.154 +
   1.155 +	const TPoint destPoint(aDest + iOrigin + srceRect.iTl - aSrceRect.iTl);
   1.156 +	const TPoint offset(srceRect.iTl - destPoint);
   1.157 +
   1.158 +	TRect targetRect(destPoint,srceRect.Size());
   1.159 +	AddRect(targetRect);
   1.160 +	if (UserClipRect(targetRect))
   1.161 +		{
   1.162 +		aBitmap->EndDataAccess(ETrue);
   1.163 +		return;
   1.164 +		}
   1.165 +
   1.166 +	SetupDevice();
   1.167 +	iDevice->DrawingBegin();
   1.168 +
   1.169 +	CBitwiseBitmap* srce = ((CFbsBitGcBitmap*)aBitmap)->Address();
   1.170 +	BG_ASSERT_DEBUG(srce,EBitgdiPanicInvalidBitmap);
   1.171 +
   1.172 +	CFbsRasterizer* rasterizer = PrepareRasterizerForExtendedBitmap(*aBitmap, targetRect, offset);
   1.173 +
   1.174 +	TInt count;
   1.175 +	const TInt limit = iDefaultRegionPtr->Count();
   1.176 +	CGraphicsAccelerator* ga = GraphicsAccelerator();
   1.177 +	TBool opaqueSource = (!IsAlphaChannel(aBitmap->DisplayMode())) && (iDrawMode == EDrawModePEN);
   1.178 +
   1.179 +	if(ga && (iShadowMode == CFbsDrawDevice::ENoShadow))
   1.180 +		{
   1.181 +	    TInt gaOperationResult = KErrUnknown;
   1.182 +		TAcceleratedBitmapSpec bitmapSpec(const_cast<CFbsBitmap*>(aBitmap));
   1.183 +        iDevice->DrawingEnd();
   1.184 +
   1.185 +		for(count=0;count<limit;count++)
   1.186 +			{
   1.187 +
   1.188 +			iClipRect=(*iDefaultRegionPtr)[count];
   1.189 +			if(!iClipRect.Intersects(targetRect))
   1.190 +				continue;
   1.191 +			iClipRect.Intersection(targetRect);
   1.192 +
   1.193 +			TRect clippedSrceRect(iClipRect);
   1.194 +			clippedSrceRect.Move(offset);
   1.195 +
   1.196 +			gaOperationResult = ga->Operation(TGopBitBlt(iClipRect.iTl,bitmapSpec,clippedSrceRect));
   1.197 +			if(gaOperationResult != KErrNone)
   1.198 +				break;
   1.199 +			iDevice->iDrawDevice->UpdateRegion(iClipRect);
   1.200 +			}
   1.201 +		if(gaOperationResult == KErrNone)
   1.202 +			goto finish;
   1.203 +		iDevice->DrawingBegin();
   1.204 +		}
   1.205 +
   1.206 +	for(count=0;count<limit;count++)
   1.207 +		{
   1.208 +		iClipRect=(*iDefaultRegionPtr)[count];
   1.209 +		if(!iClipRect.Intersects(targetRect))
   1.210 +			continue;
   1.211 +		iClipRect.Intersection(targetRect);
   1.212 +
   1.213 +		TRect clippedSrceRect(iClipRect);
   1.214 +		clippedSrceRect.Move(offset);
   1.215 +
   1.216 +		if (opaqueSource)
   1.217 +			iDrawMode = EDrawModeWriteAlpha;// ie write rather then blend
   1.218 +		DoBitBlt(iClipRect.iTl,srce,aBitmap->DataAddress(),aBitmap->DataStride(),clippedSrceRect);
   1.219 +		if (opaqueSource)
   1.220 +			iDrawMode = EDrawModePEN;// set it back how it was
   1.221 +		iDevice->iDrawDevice->UpdateRegion(iClipRect);
   1.222 +		}
   1.223 +
   1.224 +	iDevice->DrawingEnd();
   1.225 +finish:
   1.226 +	if (rasterizer)
   1.227 +		{
   1.228 +		rasterizer->EndBitmap(aBitmap->SerialNumber());
   1.229 +		}
   1.230 +	aBitmap->EndDataAccess(ETrue);
   1.231 +	}
   1.232 +
   1.233 +
   1.234 +/** Performs a masked bitmap block transfer.
   1.235 +
   1.236 +The function provides a concrete implementation of the pure virtual
   1.237 +function CBitmapContext::BitBltMasked(). The function
   1.238 +behaviour is the same as documented in that class.
   1.239 +
   1.240 +There are several points to note about this implementation of
   1.241 +BitBltMasked():
   1.242 +
   1.243 +1.For best performance the aMaskBitmap and source aBitmap should
   1.244 +have the same display mode as the destination device/bitmap.
   1.245 +
   1.246 +2.For performance reasons this implementation does not validate
   1.247 +the contents of the aMaskBitmap. The caller must ensure the mask
   1.248 +pixels are either black or white otherwise undefined blitting causing
   1.249 +unpredictable discoloration will result. This is especially true
   1.250 +for index (where pixel is palette entry) display modes (e.g. EColor16).
   1.251 +It is up to the caller to decide if they wish to utilise
   1.252 +CFbsBitmap::IsMonochrome().
   1.253 +
   1.254 +3.Alpha blending is used when the display mode of the mask bitmap aMaskBitmap
   1.255 +is EGray256.
   1.256 +
   1.257 +@see CBitmapContext::BitBltMasked() */
   1.258 +EXPORT_C void CFbsBitGc::BitBltMasked(const TPoint& aDest,
   1.259 +									  const CFbsBitmap* aBitmap,
   1.260 +									  const TRect& aSourceRect,
   1.261 +									  const CFbsBitmap* aMaskBitmap,
   1.262 +									  TBool aInvertMask)
   1.263 +    {
   1.264 +	if (aBitmap == NULL || !aBitmap->Handle() ||
   1.265 +		aMaskBitmap == NULL || !aMaskBitmap->Handle() ||
   1.266 +		CheckDevice(aSourceRect))
   1.267 +		return;
   1.268 +
   1.269 +	aBitmap->BeginDataAccess();
   1.270 +	aMaskBitmap->BeginDataAccess();
   1.271 +		
   1.272 +	TRect srceRect(aSourceRect);
   1.273 +	const TRect area(aBitmap->SizeInPixels());
   1.274 +	if (!srceRect.Intersects(area))
   1.275 +		{
   1.276 +		aBitmap->EndDataAccess(ETrue);
   1.277 +		aMaskBitmap->EndDataAccess(ETrue);
   1.278 +		return;
   1.279 +		}
   1.280 +	srceRect.Intersection(area);
   1.281 +
   1.282 +	const TPoint destPoint(aDest + iOrigin + srceRect.iTl - aSourceRect.iTl);
   1.283 +	const TRect destRect(destPoint,srceRect.Size());
   1.284 +	const TPoint offset(srceRect.iTl - destPoint);
   1.285 +	const TPoint ditherorigin(iDitherOrigin + aDest);
   1.286 +
   1.287 +	TRect clippedDestRect(destRect);
   1.288 +	AddRect(clippedDestRect);
   1.289 +	if (UserClipRect(clippedDestRect))
   1.290 +		{
   1.291 +		aBitmap->EndDataAccess(ETrue);
   1.292 +		aMaskBitmap->EndDataAccess(ETrue);
   1.293 +		return;
   1.294 +		}
   1.295 +
   1.296 +	SetupDevice();
   1.297 +	iDevice->DrawingBegin();
   1.298 +
   1.299 +
   1.300 +	CBitwiseBitmap* srcebmp = ((CFbsBitGcBitmap*)aBitmap)->Address();
   1.301 +	CBitwiseBitmap* maskbmp = ((CFbsBitGcBitmap*)aMaskBitmap)->Address();
   1.302 +	BG_ASSERT_DEBUG(srcebmp,EBitgdiPanicInvalidBitmap);
   1.303 +	BG_ASSERT_DEBUG(maskbmp,EBitgdiPanicInvalidBitmap);
   1.304 +
   1.305 +	const TDisplayMode maskMode = maskbmp->DisplayMode();
   1.306 +
   1.307 +	// Do the background fill the lazy way with flicker if any of the following are true:
   1.308 +	// 1. There is no anti-flicker buffer
   1.309 +	// 2. The source and mask bitmaps are the same
   1.310 +	// 3. The brush style is patterned and the mask is an alpha mask
   1.311 +	// 4. The brush style is not null or solid or patterned
   1.312 +
   1.313 +	if (!iDevice->iBitBltMaskedBuffer ||
   1.314 +		srcebmp == maskbmp ||
   1.315 +		(maskMode == EGray256 && iBrushStyle == EPatternedBrush) ||
   1.316 +		iBrushStyle > EPatternedBrush)
   1.317 +		{
   1.318 +		iBrushBitmap.BeginDataAccess();
   1.319 +		CFbsRasterizer* brushRasterizer = PrepareRasterizerForExtendedBitmap(iBrushBitmap);
   1.320 +		RectFill(destRect);
   1.321 +		if (brushRasterizer)
   1.322 +			{
   1.323 +			brushRasterizer->EndBitmap(iBrushBitmap.SerialNumber());
   1.324 +			}
   1.325 +		iBrushBitmap.EndDataAccess(ETrue);
   1.326 +		}
   1.327 +
   1.328 +	const TInt8 shadowMode = iShadowMode;
   1.329 +	iShadowMode = CFbsDrawDevice::ENoShadow;
   1.330 +	SetupDevice();
   1.331 +
   1.332 +	CFbsRasterizer* rasterizer = PrepareRasterizerForExtendedBitmap(*aBitmap, clippedDestRect, offset);
   1.333 +	CFbsRasterizer* maskRasterizer = NULL;
   1.334 +	if (srcebmp != maskbmp)
   1.335 +		{
   1.336 +		if (aMaskBitmap->SizeInPixels().iWidth >= aBitmap->SizeInPixels().iWidth
   1.337 +			&& aMaskBitmap->SizeInPixels().iHeight >= aBitmap->SizeInPixels().iHeight)
   1.338 +			{
   1.339 +			// Mask is not tiled. Pass same region of interest as source bitmap to rasterizer.
   1.340 +			maskRasterizer = PrepareRasterizerForExtendedBitmap(*aMaskBitmap, clippedDestRect, offset);
   1.341 +			}
   1.342 +		else
   1.343 +			{
   1.344 +			// Mask is tiled. Do not pass any region of interest to rasterizer.
   1.345 +			maskRasterizer = PrepareRasterizerForExtendedBitmap(*aMaskBitmap);
   1.346 +			}
   1.347 +		}
   1.348 +
   1.349 +    TInt count;
   1.350 +	const TInt limit = iDefaultRegionPtr->Count();
   1.351 +	CGraphicsAccelerator* ga = GraphicsAccelerator();
   1.352 +	TBool opaqueSource = (!IsAlphaChannel(aBitmap->DisplayMode())) && (iDrawMode == EDrawModePEN);
   1.353 +
   1.354 +	if(ga)
   1.355 +		{
   1.356 +		if((iBrushStyle == ENullBrush) && aInvertMask &&
   1.357 +		   (shadowMode == CFbsDrawDevice::ENoShadow))
   1.358 +			{
   1.359 +			TInt gaOperationResult = KErrUnknown;
   1.360 +			TAcceleratedBitmapSpec bitmapSpec(const_cast<CFbsBitmap*>(aBitmap));
   1.361 +			TAcceleratedBitmapSpec bitmapMaskSpec(const_cast<CFbsBitmap*>(aMaskBitmap));
   1.362 +			iDevice->DrawingEnd();
   1.363 +
   1.364 +			for(count=0;count<limit;count++)
   1.365 +				{
   1.366 +				iClipRect=(*iDefaultRegionPtr)[count];
   1.367 +				if(!iClipRect.Intersects(clippedDestRect))
   1.368 +					continue;
   1.369 +				iClipRect.Intersection(clippedDestRect);
   1.370 +				TRect clippedSrceRect(iClipRect);
   1.371 +				clippedSrceRect.Move(offset);
   1.372 +
   1.373 +				if(maskbmp->DisplayMode() == EGray256)
   1.374 +					gaOperationResult = ga->Operation(TGopBitBltAlphaBitmap(iClipRect.iTl,
   1.375 +																			bitmapSpec,
   1.376 +																			clippedSrceRect,
   1.377 +																			bitmapMaskSpec));
   1.378 +				else
   1.379 +					gaOperationResult = ga->Operation(TGopBitBltMasked(iClipRect.iTl,
   1.380 +																	   bitmapSpec,
   1.381 +																	   clippedSrceRect,
   1.382 +																	   bitmapMaskSpec));
   1.383 +
   1.384 +				if(gaOperationResult != KErrNone)
   1.385 +					break;
   1.386 +				iDevice->iDrawDevice->UpdateRegion(iClipRect);
   1.387 +				}
   1.388 +			if(gaOperationResult == KErrNone)
   1.389 +				goto finish;
   1.390 +			iDevice->DrawingBegin();
   1.391 +			}
   1.392 +		}
   1.393 +
   1.394 +	for(count=0;count<limit;count++)
   1.395 +		{
   1.396 +		iClipRect=(*iDefaultRegionPtr)[count];
   1.397 +		if (!iClipRect.Intersects(clippedDestRect))
   1.398 +			continue;
   1.399 +		iClipRect.Intersection(clippedDestRect);
   1.400 +
   1.401 +		TRect clippedSrceRect(iClipRect);
   1.402 +		clippedSrceRect.Move(offset);
   1.403 +
   1.404 +		if (opaqueSource)
   1.405 +			iDrawMode = EDrawModeWriteAlpha;// ie write rather then blend
   1.406 +		DoBitBltMasked(iClipRect.iTl,
   1.407 +					   srcebmp,
   1.408 +					   aBitmap->DataAddress(),
   1.409 +					   clippedSrceRect,
   1.410 +					   maskbmp,
   1.411 +					   aMaskBitmap->DataAddress(),
   1.412 +					   aInvertMask,
   1.413 +					   ditherorigin,
   1.414 +					   shadowMode);
   1.415 +		if (opaqueSource)
   1.416 +			iDrawMode = EDrawModePEN;// set it back how it was
   1.417 +		iDevice->iDrawDevice->UpdateRegion(iClipRect);
   1.418 +		}
   1.419 +
   1.420 +	iDevice->DrawingEnd();
   1.421 +finish:
   1.422 +	if (rasterizer)
   1.423 +		{
   1.424 +		rasterizer->EndBitmap(aBitmap->SerialNumber());
   1.425 +		}
   1.426 +	if (maskRasterizer)
   1.427 +		{
   1.428 +		maskRasterizer->EndBitmap(aMaskBitmap->SerialNumber());
   1.429 +		}
   1.430 +	aBitmap->EndDataAccess(ETrue);
   1.431 +	aMaskBitmap->EndDataAccess(ETrue);
   1.432 +	iShadowMode = shadowMode;
   1.433 +	}
   1.434 +/**
   1.435 +Does BitBlt operation of source and bitmap per scanline.
   1.436 +
   1.437 +*/
   1.438 +void CFbsBitGc::DoBitBlt(const TPoint& aDest,CFbsDevice* aSrce,const TRect& aSrceRect)
   1.439 +	{
   1.440 +	const TInt width = aSrceRect.Width();
   1.441 +	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
   1.442 +#ifdef _DEBUG
   1.443 +	TRect deviceSrcRect;
   1.444 +	aSrce->iDrawDevice->GetDrawRect(deviceSrcRect);
   1.445 +	TRect deviceDestRect;
   1.446 +	drawDevice->GetDrawRect(deviceDestRect);
   1.447 +#endif
   1.448 +	BG_ASSERT_DEBUG(aSrceRect.iTl.iX >= deviceSrcRect.iTl.iX, EBitgdiPanicOutOfBounds);
   1.449 +	BG_ASSERT_DEBUG(aSrceRect.iTl.iY >= deviceSrcRect.iTl.iY, EBitgdiPanicOutOfBounds);
   1.450 +	BG_ASSERT_DEBUG(aSrceRect.iBr.iX <= deviceSrcRect.iBr.iX, EBitgdiPanicOutOfBounds);
   1.451 +	BG_ASSERT_DEBUG(aSrceRect.iBr.iY <= deviceSrcRect.iBr.iY, EBitgdiPanicOutOfBounds);
   1.452 +	BG_ASSERT_DEBUG(aDest.iX >= deviceDestRect.iTl.iX, EBitgdiPanicOutOfBounds);
   1.453 +	BG_ASSERT_DEBUG(aDest.iY >= deviceDestRect.iTl.iY, EBitgdiPanicOutOfBounds);
   1.454 +	BG_ASSERT_DEBUG((aDest.iX + aSrceRect.Width())  <= deviceDestRect.iBr.iX, EBitgdiPanicOutOfBounds);
   1.455 +	BG_ASSERT_DEBUG((aDest.iY + aSrceRect.Height()) <= deviceDestRect.iBr.iY, EBitgdiPanicOutOfBounds);
   1.456 +
   1.457 +	CFbsDrawDevice* srcDrawDevice = aSrce->iDrawDevice;
   1.458 +	TAny* interface=NULL;
   1.459 +	if (iDrawMode==EDrawModeWriteAlpha &&
   1.460 +		iShadowMode == CFbsDrawDevice::ENoShadow &&
   1.461 +		(aSrceRect.iTl.iX >= 0) &&  (aSrceRect.iTl.iY >= 0) &&
   1.462 +		(aDest.iX >= 0) && (aDest.iY >= 0) &&
   1.463 +	    srcDrawDevice->DisplayMode() == drawDevice->DisplayMode() &&
   1.464 +		drawDevice->GetInterface(KFastBlit2InterfaceID, interface) == KErrNone)
   1.465 +		{
   1.466 +		// Conditions in CFbsBitGc allow for optimised blitting.
   1.467 +		// The draw device supports the optimised blitting function.
   1.468 +		// Operation may fail regardless due to unacceptable conditions in the draw device.
   1.469 +		BG_ASSERT_DEBUG(interface!=NULL, EBitgdiPanicNullPointer);
   1.470 +		MFastBlit2* fastBlit = reinterpret_cast<MFastBlit2*>(interface);
   1.471 +		if (fastBlit->WriteBitmapBlock(aDest, srcDrawDevice, aSrceRect) == KErrNone)
   1.472 +			{
   1.473 +			return;
   1.474 +			}
   1.475 +		}
   1.476 +	MFastBlend* fastBlend=NULL;
   1.477 +	if (FastBlendInterface(NULL,NULL,fastBlend)==KErrNone)
   1.478 +		{
   1.479 +		if (fastBlend->FastBlendBitmap(aDest, srcDrawDevice, aSrceRect, iDrawMode, iShadowMode)==KErrNone)
   1.480 +			{
   1.481 +			return;
   1.482 +			}
   1.483 +		}
   1.484 +	//scanLineBuffer is destination scanline buffer.
   1.485 +	TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
   1.486 +	const TInt scanLineBytes = drawDevice->ScanLineBytes();
   1.487 +	TPtr8 scanLineDes((TUint8*)scanLineBuffer,scanLineBytes,scanLineBytes);
   1.488 +	//dispMode is destination display mode.
   1.489 +	const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
   1.490 +	TInt destY = aDest.iY;
   1.491 +	//Gets the scanline from the source, into the buffer scanLineDes.
   1.492 +	//The DoGetScanLine operation is also responsible for converting
   1.493 +	// the buffer pixel format to destination display format.
   1.494 +
   1.495 +	for (TInt row = aSrceRect.iTl.iY; row < aSrceRect.iBr.iY; row++,destY++)
   1.496 +		{
   1.497 +		aSrce->DoGetScanLine(scanLineDes,TPoint(aSrceRect.iTl.iX,row),width,dispMode);
   1.498 +		drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,iDrawMode);
   1.499 +		}
   1.500 +	}
   1.501 +
   1.502 +/**
   1.503 +Calculates the position into the scanline for the given x coordinate
   1.504 +*/
   1.505 +TUint CFbsBitGc::MemoryOffsetForPixelPitch(TUint aX, TDisplayMode aDisplayMode)
   1.506 +	{
   1.507 +	switch (aDisplayMode)
   1.508 +		{
   1.509 +		case EColor16MU:
   1.510 +		case EColor16MA:
   1.511 +		case EColor16MAP:
   1.512 +			return aX << 2;
   1.513 +
   1.514 +		case EColor16M:
   1.515 +			return aX * 3;
   1.516 +
   1.517 +		case EColor4K:
   1.518 +		case EColor64K:
   1.519 +			return aX << 1;
   1.520 +
   1.521 +		case EGray256:
   1.522 +		case EColor256:
   1.523 +			return aX;
   1.524 +
   1.525 +		default:
   1.526 +			BG_PANIC_DEBUG(EBitgdiPanicInvalidDisplayMode);
   1.527 +		break;
   1.528 +		}
   1.529 +	return 0;
   1.530 +	}
   1.531 +
   1.532 +/**
   1.533 +Gets the scanline pointer with the offset
   1.534 +*/
   1.535 +TUint32* CFbsBitGc::GetScanLineOffsetPtr(CBitwiseBitmap* aSrce, TUint32*& aSlptr, TInt aLength, TPoint aPixel,TUint32* aBase, TLineScanningPosition& aLineScanningPosition, TUint aXOffset)
   1.536 +	{
   1.537 +	aSrce->GetScanLinePtr(aSlptr, aLength, aPixel, aBase, aLineScanningPosition);
   1.538 +	return (TUint32*)((TUint8*)aSlptr + aXOffset);
   1.539 +	}
   1.540 +
   1.541 +void CFbsBitGc::DoBitBlt(const TPoint& aDest,
   1.542 +						 CBitwiseBitmap* aSrce,
   1.543 +						 TUint32* aBase,
   1.544 +						 TInt aStride,
   1.545 +						 const TRect& aSrceRect)
   1.546 +	{
   1.547 +	// Does multiple bitmap widths for painting rects only
   1.548 +	const TInt width = aSrceRect.Width();
   1.549 +	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
   1.550 +#ifdef _DEBUG
   1.551 +	TRect deviceDestRect;
   1.552 +	drawDevice->GetDrawRect(deviceDestRect);
   1.553 +#endif
   1.554 +	BG_ASSERT_DEBUG(aDest.iX >= deviceDestRect.iTl.iX, EBitgdiPanicOutOfBounds);
   1.555 +	BG_ASSERT_DEBUG(aDest.iY >= deviceDestRect.iTl.iY, EBitgdiPanicOutOfBounds);
   1.556 +	BG_ASSERT_DEBUG((aDest.iX + aSrceRect.Width())  <= deviceDestRect.iBr.iX, EBitgdiPanicOutOfBounds);
   1.557 +	BG_ASSERT_DEBUG((aDest.iY + aSrceRect.Height()) <= deviceDestRect.iBr.iY, EBitgdiPanicOutOfBounds);
   1.558 +
   1.559 +	TSize srcSize = aSrce->SizeInPixels();
   1.560 +	if (srcSize.iWidth == 0 || srcSize.iHeight == 0)
   1.561 +		return; //no point doing anything if asked to draw zero size bitmap
   1.562 +
   1.563 +	TAny* interface=NULL;
   1.564 +	if (iDrawMode==EDrawModeWriteAlpha &&
   1.565 +		iShadowMode == CFbsDrawDevice::ENoShadow &&
   1.566 +		aSrceRect.iTl.iX >= 0 &&
   1.567 +		aSrceRect.iTl.iY >= 0 &&
   1.568 +		aSrceRect.iBr.iX <= srcSize.iWidth &&
   1.569 +		aSrceRect.iBr.iY <= srcSize.iHeight &&
   1.570 +		(aDest.iX >= 0) && (aDest.iY >= 0) &&
   1.571 +		!aSrce->IsCompressed() &&
   1.572 +		aSrce->DisplayMode() == drawDevice->DisplayMode() &&
   1.573 +		drawDevice->GetInterface(KFastBlit2InterfaceID, interface) == KErrNone)
   1.574 +		{
   1.575 +		// Conditions in CFbsBitGc allow for optimised blitting.
   1.576 +		// The draw device supports the optimised blitting function.
   1.577 +		// Operation may fail regardless due to unacceptable conditions in the draw device.
   1.578 +		BG_ASSERT_DEBUG(interface!=NULL, EBitgdiPanicNullPointer);
   1.579 +		MFastBlit2* fastBlit = reinterpret_cast<MFastBlit2*>(interface);
   1.580 +		if (fastBlit && (fastBlit->WriteBitmapBlock(aDest, aBase, aStride, srcSize, aSrceRect) == KErrNone))
   1.581 +			{
   1.582 +			return;
   1.583 +			}
   1.584 +		}
   1.585 +	MFastBlend* fastBlend=NULL;
   1.586 +	if (FastBlendInterface(aSrce,NULL,fastBlend)==KErrNone)
   1.587 +		{
   1.588 +		if (fastBlend->FastBlendBitmap(aDest, aBase, aStride, srcSize, aSrceRect, aSrce->DisplayMode(), iDrawMode, iShadowMode)== KErrNone)
   1.589 +			{
   1.590 +			return;
   1.591 +			}
   1.592 +		}
   1.593 +
   1.594 +	const TInt scanLineBytes = drawDevice->ScanLineBytes();
   1.595 +	TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
   1.596 +	TPtr8 scanLineDes((TUint8*)scanLineBuffer,scanLineBytes,scanLineBytes);
   1.597 +
   1.598 +	const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
   1.599 +
   1.600 +	const TBool useScanLinePtr = (!iShadowMode) && (dispMode == aSrce->DisplayMode()) && (TDisplayModeUtils::NumDisplayModeBitsPerPixel(dispMode)>=8);
   1.601 +	TUint32* slptr=NULL;
   1.602 +	TUint offset = 0;
   1.603 +	TUint32* lastScanLine = NULL;
   1.604 +	if (useScanLinePtr)
   1.605 +		lastScanLine = aSrce->ScanLineAddress(aBase,aSrceRect.iBr.iY-1);
   1.606 +
   1.607 +	TInt srceWidth = srcSize.iWidth;
   1.608 +	TInt partlinestart = 0;
   1.609 +	partlinestart = aSrceRect.iTl.iX % srceWidth;
   1.610 +	if (partlinestart < 0)
   1.611 +		partlinestart += srceWidth;
   1.612 +	const TInt partlinelength = Min(srceWidth - partlinestart,width);
   1.613 +	TInt destX = aDest.iX;
   1.614 +	const TInt destXlimit=destX+width;
   1.615 +
   1.616 +	// first part line
   1.617 +	if (partlinestart > 0 && partlinelength > 0)
   1.618 +		{
   1.619 +		TPoint srcecoord1(partlinestart,aSrceRect.iTl.iY);
   1.620 +		TInt desty = aDest.iY;
   1.621 +		TPoint ditherorigin(iDitherOrigin);
   1.622 +		ditherorigin.iX += aDest.iX;
   1.623 +		ditherorigin.iY += desty;
   1.624 +
   1.625 +		TLineScanningPosition lineScanPos(aBase);
   1.626 +
   1.627 +		if (useScanLinePtr)
   1.628 +			{
   1.629 +			offset = MemoryOffsetForPixelPitch(partlinestart, dispMode);
   1.630 +			if (aSrce->IsCompressed())
   1.631 +				{
   1.632 +				while (srcecoord1.iY < aSrceRect.iBr.iY)
   1.633 +					{
   1.634 +					scanLineBuffer = GetScanLineOffsetPtr(aSrce, slptr, partlinelength, srcecoord1, aBase, lineScanPos, offset);
   1.635 +					if (srcecoord1.iY==aSrceRect.iTl.iY)
   1.636 +						{
   1.637 +						aSrce->SetCompressionBookmark(lineScanPos,aBase,NULL);
   1.638 +						}
   1.639 +					drawDevice->WriteLine(aDest.iX,desty,partlinelength, scanLineBuffer,iDrawMode);
   1.640 +					srcecoord1.iY++,desty++,ditherorigin.iY++;
   1.641 +					}
   1.642 +				}
   1.643 +			else
   1.644 +				{
   1.645 +				while (srcecoord1.iY < aSrceRect.iBr.iY)
   1.646 +					{
   1.647 +					scanLineBuffer = GetScanLineOffsetPtr(aSrce, slptr, partlinelength, srcecoord1, aBase, lineScanPos, offset);
   1.648 +					do
   1.649 +						{
   1.650 +						drawDevice->WriteLine(aDest.iX,desty,partlinelength, scanLineBuffer,iDrawMode);
   1.651 +						scanLineBuffer = (TUint32*)((TUint8*)scanLineBuffer + aStride);
   1.652 +						srcecoord1.iY++,desty++,ditherorigin.iY++;
   1.653 +						}
   1.654 +					while ((srcecoord1.iY < aSrceRect.iBr.iY) && (scanLineBuffer < lastScanLine));
   1.655 +					}
   1.656 +				}
   1.657 +			}
   1.658 +		else
   1.659 +			{
   1.660 +			for (; srcecoord1.iY < aSrceRect.iBr.iY; srcecoord1.iY++,desty++,ditherorigin.iY++)
   1.661 +				{
   1.662 +				aSrce->GetScanLine(scanLineDes,srcecoord1,partlinelength,ETrue,
   1.663 +						   ditherorigin,dispMode,aBase, lineScanPos);
   1.664 +				if (srcecoord1.iY==aSrceRect.iTl.iY)
   1.665 +					{
   1.666 +					aSrce->SetCompressionBookmark(lineScanPos,aBase,NULL);
   1.667 +					}
   1.668 +				drawDevice->WriteLine(aDest.iX,desty,partlinelength, scanLineBuffer,iDrawMode);
   1.669 +				}
   1.670 +			}
   1.671 +
   1.672 +		destX+=partlinelength;
   1.673 +		}
   1.674 +
   1.675 +	// multiple complete lines - columns
   1.676 +	TInt numcolumns = 0;
   1.677 +	numcolumns = (destXlimit - destX) / srceWidth;
   1.678 +	if (numcolumns > 0)
   1.679 +		{
   1.680 +		TPoint srcecoord2(0,aSrceRect.iTl.iY);
   1.681 +		TInt desty = aDest.iY;
   1.682 +		TPoint ditherorigin(iDitherOrigin);
   1.683 +		ditherorigin.iX += destX;
   1.684 +		ditherorigin.iY += desty;
   1.685 +
   1.686 +		TLineScanningPosition lineScanPos(aBase);
   1.687 +
   1.688 +		if (useScanLinePtr)
   1.689 +			{
   1.690 +			if (aSrce->IsCompressed())
   1.691 +				{
   1.692 +				while (srcecoord2.iY < aSrceRect.iBr.iY)
   1.693 +					{
   1.694 +					TPoint coord(srcecoord2);
   1.695 +					aSrce->GetScanLinePtr(slptr, srceWidth, coord,aBase, lineScanPos);
   1.696 +					if (srcecoord2.iY==aSrceRect.iTl.iY)
   1.697 +						{
   1.698 +						aSrce->SetCompressionBookmark(lineScanPos, aBase,NULL);
   1.699 +						}
   1.700 +					TInt tempdestX = destX;
   1.701 +					for (TInt count = 0; count < numcolumns; count++,tempdestX+=srceWidth)
   1.702 +						{
   1.703 +						drawDevice->WriteLine(tempdestX,desty,srceWidth, slptr,iDrawMode);
   1.704 +						ditherorigin.iX += srceWidth;
   1.705 +						}
   1.706 +					srcecoord2.iY++,desty++,ditherorigin.iY++;
   1.707 +					}
   1.708 +				}
   1.709 +			else
   1.710 +				{
   1.711 +				while (srcecoord2.iY < aSrceRect.iBr.iY)
   1.712 +					{
   1.713 +					TPoint coord(srcecoord2);
   1.714 +					aSrce->GetScanLinePtr(slptr, srceWidth, coord,aBase, lineScanPos);
   1.715 +					do
   1.716 +						{
   1.717 +						TInt tempdestX = destX;
   1.718 +						for (TInt count = 0; count < numcolumns; count++,tempdestX+=srceWidth)
   1.719 +							{
   1.720 +							drawDevice->WriteLine(tempdestX,desty,srceWidth, slptr,iDrawMode);
   1.721 +							ditherorigin.iX += srceWidth;
   1.722 +							}
   1.723 +						slptr = (TUint32*)((TUint8*)slptr + aStride);
   1.724 +						srcecoord2.iY++,desty++,ditherorigin.iY++;
   1.725 +						}
   1.726 +					while ((srcecoord2.iY < aSrceRect.iBr.iY) && (slptr < lastScanLine));
   1.727 +					}
   1.728 +				}
   1.729 +			}
   1.730 +		else
   1.731 +			{
   1.732 +			for (; srcecoord2.iY < aSrceRect.iBr.iY; srcecoord2.iY++,desty++,ditherorigin.iY++)
   1.733 +				{
   1.734 +				TInt tempdestX = destX;
   1.735 +				TPoint coord(srcecoord2);
   1.736 +				aSrce->GetScanLinePtr(slptr, srceWidth, coord,aBase, lineScanPos);
   1.737 +				if (srcecoord2.iY==aSrceRect.iTl.iY)
   1.738 +					{
   1.739 +					aSrce->SetCompressionBookmark(lineScanPos, aBase,NULL);
   1.740 +					}
   1.741 +				for (TInt count = 0; count < numcolumns; count++,tempdestX+=srceWidth)
   1.742 +					{
   1.743 +					aSrce->GetScanLine(slptr, scanLineDes,coord,srceWidth,ETrue,
   1.744 +						   ditherorigin,dispMode);
   1.745 +					drawDevice->WriteLine(tempdestX,desty,srceWidth, scanLineBuffer,iDrawMode);
   1.746 +					ditherorigin.iX += srceWidth;
   1.747 +					}
   1.748 +				}
   1.749 +			}
   1.750 +
   1.751 +		destX += numcolumns * srceWidth;
   1.752 +		}
   1.753 +
   1.754 +	// final part line
   1.755 +	if (destX < destXlimit)
   1.756 +		{
   1.757 +		const TInt restofline = destXlimit - destX;
   1.758 +		TPoint srcecoord3(0,aSrceRect.iTl.iY);
   1.759 +		TInt desty = aDest.iY;
   1.760 +		TPoint ditherorigin(iDitherOrigin);
   1.761 +		ditherorigin.iX += destX;
   1.762 +		ditherorigin.iY += desty;
   1.763 +
   1.764 +		TLineScanningPosition lineScanPos(aBase);
   1.765 +
   1.766 +		if (useScanLinePtr)
   1.767 +			{
   1.768 +			offset = 0;
   1.769 +			if (aSrce->IsCompressed())
   1.770 +				{
   1.771 +				while (srcecoord3.iY < aSrceRect.iBr.iY)
   1.772 +					{
   1.773 +					scanLineBuffer = GetScanLineOffsetPtr(aSrce, slptr, srceWidth, srcecoord3, aBase, lineScanPos, offset);
   1.774 +					if (srcecoord3.iY==aSrceRect.iTl.iY)
   1.775 +						{
   1.776 +						aSrce->SetCompressionBookmark(lineScanPos,aBase,NULL);
   1.777 +						}
   1.778 +					drawDevice->WriteLine(destX,desty,restofline,scanLineBuffer,iDrawMode);
   1.779 +					srcecoord3.iY++,desty++,ditherorigin.iY++;
   1.780 +					}
   1.781 +				}
   1.782 +			else
   1.783 +				{
   1.784 +				while (srcecoord3.iY < aSrceRect.iBr.iY)
   1.785 +					{
   1.786 +					scanLineBuffer = GetScanLineOffsetPtr(aSrce, slptr, srceWidth, srcecoord3, aBase, lineScanPos, offset);
   1.787 +					do
   1.788 +						{
   1.789 +						drawDevice->WriteLine(destX,desty,restofline,scanLineBuffer,iDrawMode);
   1.790 +						scanLineBuffer = (TUint32*)((TUint8*)scanLineBuffer + aStride);
   1.791 +						srcecoord3.iY++,desty++,ditherorigin.iY++;
   1.792 +						}
   1.793 +					while ((srcecoord3.iY < aSrceRect.iBr.iY) && (scanLineBuffer < lastScanLine));
   1.794 +					}
   1.795 +				}
   1.796 +			}
   1.797 +		else
   1.798 +			{
   1.799 +			for (; srcecoord3.iY < aSrceRect.iBr.iY; srcecoord3.iY++,desty++,ditherorigin.iY++)
   1.800 +				{
   1.801 +				aSrce->GetScanLine(scanLineDes,srcecoord3,srceWidth,ETrue,
   1.802 +								   ditherorigin,dispMode,aBase,lineScanPos);
   1.803 +				if (srcecoord3.iY==aSrceRect.iTl.iY)
   1.804 +					{
   1.805 +					aSrce->SetCompressionBookmark(lineScanPos, aBase,NULL);
   1.806 +					}
   1.807 +				drawDevice->WriteLine(destX,desty,restofline,scanLineBuffer,iDrawMode);
   1.808 +				}
   1.809 +			}
   1.810 +		}
   1.811 +	}
   1.812 +
   1.813 +void CFbsBitGc::DoBitBltMasked(const TPoint& aDest,
   1.814 +							   CBitwiseBitmap* aSourceBitmap,
   1.815 +							   TUint32* aSourceBase,
   1.816 +							   const TRect& aSourceRect,
   1.817 +							   CBitwiseBitmap* aMaskBitmap,
   1.818 +							   TUint32* aMaskBase,
   1.819 +							   TBool aInvertMask,
   1.820 +							   const TPoint& aDitherOrigin,
   1.821 +							   TInt aShadowMode)
   1.822 +	{
   1.823 +	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
   1.824 +#ifdef _DEBUG
   1.825 +	TRect deviceDestRect;
   1.826 +	drawDevice->GetDrawRect(deviceDestRect);
   1.827 +#endif
   1.828 +	BG_ASSERT_DEBUG(aDest.iX >= deviceDestRect.iTl.iX, EBitgdiPanicOutOfBounds);
   1.829 +	BG_ASSERT_DEBUG(aDest.iY >= deviceDestRect.iTl.iY, EBitgdiPanicOutOfBounds);
   1.830 +	BG_ASSERT_DEBUG((aDest.iX + aSourceRect.Width()) <= deviceDestRect.iBr.iX, EBitgdiPanicOutOfBounds);
   1.831 +	BG_ASSERT_DEBUG((aDest.iY + aSourceRect.Height()) <= deviceDestRect.iBr.iY, EBitgdiPanicOutOfBounds);
   1.832 +
   1.833 +	MFastBlend* fastBlend=NULL;
   1.834 +	if (FastBlendInterface(aSourceBitmap,aMaskBitmap,fastBlend)==KErrNone)
   1.835 +		{
   1.836 +		if (fastBlend->FastBlendBitmapMasked(aDest, aSourceBase, aSourceBitmap->DataStride(), aSourceBitmap->SizeInPixels(), aSourceRect, aSourceBitmap->DisplayMode(),
   1.837 +							aMaskBase, aMaskBitmap->DataStride(), aMaskBitmap->DisplayMode(), aMaskBitmap->SizeInPixels(), aSourceRect.iTl, aInvertMask,
   1.838 +							iDrawMode, aShadowMode)==KErrNone)
   1.839 +			{
   1.840 +			return;
   1.841 +			}
   1.842 +		}
   1.843 +
   1.844 +	const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
   1.845 +	if (aMaskBitmap->DisplayMode() == EGray256)
   1.846 +		{
   1.847 +		DoBitBltAlpha(aDest,aSourceBitmap,aSourceBase,aSourceRect,
   1.848 +					  aMaskBitmap,aMaskBase,aSourceRect.iTl,aShadowMode, EFalse);
   1.849 +		}
   1.850 +	// if screen driver is 16MAP we avoid logical operator pen modes by using DoBitBltAlpha() for blitting
   1.851 +	else if (dispMode == EColor16MAP)
   1.852 +		{
   1.853 +		DoBitBltAlpha(aDest,aSourceBitmap,aSourceBase,aSourceRect,
   1.854 +					  aMaskBitmap,aMaskBase,aSourceRect.iTl,aShadowMode, aInvertMask);
   1.855 +		}
   1.856 +
   1.857 +	else if (aSourceBitmap == aMaskBitmap)
   1.858 +		{
   1.859 +		const TInt width = aSourceRect.Width();
   1.860 +		TPoint ditherOrigin(aDitherOrigin + aDest);
   1.861 +		const TDrawMode drawMode = aInvertMask ? EDrawModeAND : EDrawModeOR;
   1.862 +		TPoint srcePoint(aSourceRect.iTl);
   1.863 +		TInt destY = aDest.iY;
   1.864 +
   1.865 +		TLineScanningPosition lineScanPos(aSourceBase);
   1.866 +
   1.867 +		const TBool useScanLinePtr = (!aShadowMode) && (dispMode == aSourceBitmap->DisplayMode() && (TDisplayModeUtils::NumDisplayModeBitsPerPixel(dispMode)>=8));
   1.868 +		if (useScanLinePtr)
   1.869 +			{
   1.870 +			TUint32* scanLineBuffer = NULL;
   1.871 +			TUint32* slptr=NULL;
   1.872 +			TUint offset = MemoryOffsetForPixelPitch(srcePoint.iX, dispMode);
   1.873 +
   1.874 +			if (aSourceBitmap->IsCompressed())
   1.875 +				{
   1.876 +				for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++,ditherOrigin.iY++)
   1.877 +					{
   1.878 +					scanLineBuffer = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPos, offset);
   1.879 +					drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,drawMode);
   1.880 +					}
   1.881 +				}
   1.882 +			else
   1.883 +				{
   1.884 +				TUint stride = aSourceBitmap->DataStride();
   1.885 +				TUint32* lastScanLine = aSourceBitmap->ScanLineAddress(aSourceBase,aSourceRect.iBr.iY-1);
   1.886 +
   1.887 +				while (srcePoint.iY < aSourceRect.iBr.iY)
   1.888 +					{
   1.889 +					scanLineBuffer = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPos, offset);
   1.890 +					do
   1.891 +						{
   1.892 +						drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,drawMode);
   1.893 +						scanLineBuffer = (TUint32*)((TUint8*)scanLineBuffer + stride);
   1.894 +						destY++,srcePoint.iY++,ditherOrigin.iY++;
   1.895 +						}
   1.896 +					while ((srcePoint.iY < aSourceRect.iBr.iY) && (scanLineBuffer < lastScanLine));
   1.897 +					}
   1.898 +				}
   1.899 +			}
   1.900 +		else
   1.901 +			{
   1.902 +			const TInt scanLineBytes = drawDevice->ScanLineBytes();
   1.903 +			TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
   1.904 +			TPtr8 scanLineDes((TUint8*)scanLineBuffer,scanLineBytes,scanLineBytes);
   1.905 +			for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++,ditherOrigin.iY++)
   1.906 +				{
   1.907 +				aSourceBitmap->GetScanLine(scanLineDes,srcePoint,width,
   1.908 +								   ETrue,ditherOrigin,dispMode,aSourceBase,lineScanPos);
   1.909 +
   1.910 +				if (aShadowMode)
   1.911 +					{
   1.912 +					drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
   1.913 +					drawDevice->ShadowBuffer(width,scanLineBuffer);
   1.914 +					drawDevice->SetShadowMode(CFbsDrawDevice::ENoShadow);
   1.915 +					}
   1.916 +
   1.917 +				drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,drawMode);
   1.918 +				}
   1.919 +			}
   1.920 +		}
   1.921 +	else
   1.922 +		{
   1.923 +		if (iDevice->iBitBltMaskedBuffer)
   1.924 +			{
   1.925 +			if (iBrushStyle == ESolidBrush)
   1.926 +				DoBitBltMaskedNonFlickerSolid(aDest,aSourceBitmap,aSourceBase,aSourceRect,
   1.927 +											  aMaskBitmap,aMaskBase,aInvertMask,aDitherOrigin,
   1.928 +											  aShadowMode);
   1.929 +			else if (iBrushStyle == EPatternedBrush)
   1.930 +				DoBitBltMaskedNonFlickerPatterned(aDest,aSourceBitmap,aSourceBase,aSourceRect,
   1.931 +												  aMaskBitmap,aMaskBase,aInvertMask,
   1.932 +												  aDitherOrigin,aShadowMode);
   1.933 +			else
   1.934 +				DoBitBltMaskedNonFlicker(aDest,aSourceBitmap,aSourceBase,aSourceRect,
   1.935 +										 aMaskBitmap,aMaskBase,aInvertMask,aDitherOrigin,
   1.936 +										 aShadowMode);
   1.937 +			}
   1.938 +		else
   1.939 +			DoBitBltMaskedFlicker(aDest,aSourceBitmap,aSourceBase,aSourceRect,aMaskBitmap,
   1.940 +								  aMaskBase,aInvertMask,aDitherOrigin,aShadowMode);
   1.941 +		}
   1.942 +	}
   1.943 +
   1.944 +void CFbsBitGc::DoBitBltMaskedFlicker(const TPoint& aDest,
   1.945 +									  CBitwiseBitmap* aSourceBitmap,
   1.946 +									  TUint32* aSourceBase,
   1.947 +									  const TRect& aSourceRect,
   1.948 +									  CBitwiseBitmap* aMaskBitmap,
   1.949 +									  TUint32* aMaskBase,
   1.950 +									  TBool aInvertMask,
   1.951 +									  const TPoint& aDitherOrigin,
   1.952 +									  TInt aShadowMode)
   1.953 +	{
   1.954 +	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
   1.955 +
   1.956 +	const TInt width = aSourceRect.Width();
   1.957 +	TInt destY = aDest.iY;
   1.958 +	TPoint srcePoint(aSourceRect.iTl);
   1.959 +
   1.960 +	TLineScanningPosition lineScanPos(aSourceBase);
   1.961 +	TLineScanningPosition lineScanPosMask(aMaskBase);
   1.962 +
   1.963 +	const TDisplayMode srcFormat = aSourceBitmap->DisplayMode();
   1.964 +	const TDisplayMode maskFormat = aMaskBitmap->DisplayMode();
   1.965 +	
   1.966 +	if (aMaskBitmap->IsCompressed()) 
   1.967 +       { 
   1.968 +       HBufC8* hBuf= CFbsBitmap::GetDecompressionBuffer(aMaskBitmap->DataStride() + 4); 
   1.969 +       if (!hBuf) 
   1.970 +          return; // Out of memory so do not draw anything 
   1.971 +       lineScanPosMask.iScanLineBuffer = hBuf; 
   1.972 +       } 
   1.973 +
   1.974 +	TAny* interface=NULL;
   1.975 +	if ( (srcFormat == EColor16MU || srcFormat == EColor64K ) &&
   1.976 +		maskFormat == EGray2 &&
   1.977 +		!aShadowMode &&
   1.978 +		aSourceBitmap->SizeInPixels().iWidth <= aMaskBitmap->SizeInPixels().iWidth &&
   1.979 +		aSourceBitmap->SizeInPixels().iHeight <= aMaskBitmap->SizeInPixels().iHeight &&
   1.980 +		drawDevice->GetInterface(KFastBlitInterfaceID, interface) == KErrNone )
   1.981 +		{
   1.982 +		// Parameters allow optimised code path
   1.983 +		TInt length = width;
   1.984 +		TUint32* srcPtr=NULL;
   1.985 +		TUint32* maskPtr=NULL;
   1.986 +		MFastBlit* fastBlit = reinterpret_cast<MFastBlit*>(interface);
   1.987 +
   1.988 +		while (srcePoint.iY < aSourceRect.iBr.iY)
   1.989 +			{
   1.990 +			aSourceBitmap->GetScanLinePtr(srcPtr, length, srcePoint, aSourceBase, lineScanPos);
   1.991 +			aMaskBitmap->GetScanLinePtr(maskPtr, length, srcePoint, aMaskBase, lineScanPosMask);
   1.992 +
   1.993 +			fastBlit->WriteMaskLineEx(aDest.iX,destY,length,srcePoint.iX,srcPtr,srcFormat,srcePoint.iX,maskPtr,aInvertMask);
   1.994 +
   1.995 +			destY++;
   1.996 +			++srcePoint.iY;
   1.997 +			}
   1.998 +		return;
   1.999 +		}
  1.1000 +
  1.1001 +	TPoint ditherOrigin(aDitherOrigin + aDest);
  1.1002 +	const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
  1.1003 +	const TDrawMode drawMode = aInvertMask ? EDrawModeAND : EDrawModeANDNOT;
  1.1004 +
  1.1005 +	TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
  1.1006 +	const TInt scanLineBytes = drawDevice->ScanLineBytes();
  1.1007 +	TPtr8 scanLineDes((TUint8*)scanLineBuffer,scanLineBytes,scanLineBytes);
  1.1008 +
  1.1009 +	TLineScanningPosition lineScanPos2(aSourceBase);
  1.1010 +
  1.1011 +	//scanline modifications required if using shadows, different modes, bits per pixel less than 8
  1.1012 +	if ((!aShadowMode) && (dispMode == aSourceBitmap->DisplayMode()) && (TDisplayModeUtils::NumDisplayModeBitsPerPixel(dispMode)>=8))
  1.1013 +		{
  1.1014 +		TUint offset = MemoryOffsetForPixelPitch(srcePoint.iX, dispMode);
  1.1015 +		TUint32* slptr=NULL;
  1.1016 +		//mask scanline modifications required for EInvertPen, different screen modes
  1.1017 +		if ((drawMode != EDrawModeANDNOT) && (dispMode == aMaskBitmap->DisplayMode()))
  1.1018 +			{
  1.1019 +			TUint32* scanLineBufferMask = NULL;
  1.1020 +			//stride jumping not possible with compressed bitmaps
  1.1021 +			if (aSourceBitmap->IsCompressed() || aMaskBitmap->IsCompressed())
  1.1022 +				{
  1.1023 +				for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++,ditherOrigin.iY++)
  1.1024 +					{
  1.1025 +		 			scanLineBuffer = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPos, offset);
  1.1026 +					drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,EDrawModeXOR);
  1.1027 +		 			scanLineBufferMask = GetScanLineOffsetPtr(aMaskBitmap, slptr, width, srcePoint, aMaskBase, lineScanPosMask, offset);
  1.1028 +					drawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferMask,drawMode);
  1.1029 +					drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,EDrawModeXOR);
  1.1030 +					}
  1.1031 +				}
  1.1032 +			else
  1.1033 +				{
  1.1034 +				TUint strideSrc = aSourceBitmap->DataStride();
  1.1035 +				TUint strideMask = aMaskBitmap->DataStride();
  1.1036 +				TUint32* lastScanLineSrc = aSourceBitmap->ScanLineAddress(aSourceBase,aSourceRect.iBr.iY-1);
  1.1037 +				TUint32* lastScanLineMask = aMaskBitmap->ScanLineAddress(aMaskBase,aSourceRect.iBr.iY-1);
  1.1038 +
  1.1039 +				while (srcePoint.iY < aSourceRect.iBr.iY)
  1.1040 +					{
  1.1041 +		 			scanLineBuffer = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPos, offset);
  1.1042 +		 			scanLineBufferMask = GetScanLineOffsetPtr(aMaskBitmap, slptr, width, srcePoint, aMaskBase, lineScanPosMask, offset);
  1.1043 +
  1.1044 +		 			do
  1.1045 +		 				{
  1.1046 +						drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,EDrawModeXOR);
  1.1047 +						drawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferMask,drawMode);
  1.1048 +						drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,EDrawModeXOR);
  1.1049 +						destY++,srcePoint.iY++,ditherOrigin.iY++;
  1.1050 +		 				}
  1.1051 +		 			while ((srcePoint.iY < aSourceRect.iBr.iY) && (scanLineBuffer < lastScanLineSrc) && (scanLineBufferMask < lastScanLineMask)
  1.1052 +		 				&& ((scanLineBuffer = (TUint32*)((TUint8*)scanLineBuffer + strideSrc))>(TUint32*)0)
  1.1053 +		 				&& ((scanLineBufferMask = (TUint32*)((TUint8*)scanLineBufferMask + strideMask))>(TUint32*)0)
  1.1054 +		 				);
  1.1055 +					}
  1.1056 +				}
  1.1057 +			}
  1.1058 +		else
  1.1059 +			{
  1.1060 +			TUint32* scanLineBufferPtr = NULL;
  1.1061 +			//stride jumping not possible with compressed bitmaps
  1.1062 +			if (aSourceBitmap->IsCompressed())
  1.1063 +				{
  1.1064 +				for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++,ditherOrigin.iY++)
  1.1065 +					{
  1.1066 +		 			scanLineBufferPtr = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPos, offset);
  1.1067 +					drawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferPtr,EDrawModeXOR);
  1.1068 +					aMaskBitmap->GetScanLine(scanLineDes,srcePoint,width,EFalse,ditherOrigin,dispMode, aMaskBase, lineScanPosMask);
  1.1069 +					::TileScanLine(scanLineDes, width, srcePoint, aMaskBitmap, lineScanPosMask, aMaskBase, dispMode);
  1.1070 +					drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,drawMode);
  1.1071 +					drawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferPtr,EDrawModeXOR);
  1.1072 +					}
  1.1073 +				}
  1.1074 +			else
  1.1075 +				{
  1.1076 +				TUint stride = aSourceBitmap->DataStride();
  1.1077 +				TUint32* lastScanLine = aSourceBitmap->ScanLineAddress(aSourceBase,aSourceRect.iBr.iY-1);
  1.1078 +				while (srcePoint.iY < aSourceRect.iBr.iY)
  1.1079 +					{
  1.1080 +		 			scanLineBufferPtr = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPos, offset);
  1.1081 +		 			do
  1.1082 +		 				{
  1.1083 +						drawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferPtr,EDrawModeXOR);
  1.1084 +						aMaskBitmap->GetScanLine(scanLineDes,srcePoint,width,EFalse,ditherOrigin,dispMode,aMaskBase, lineScanPosMask);
  1.1085 +						::TileScanLine(scanLineDes, width, srcePoint, aMaskBitmap, lineScanPosMask, aMaskBase, dispMode);
  1.1086 +						drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,drawMode);
  1.1087 +						drawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferPtr,EDrawModeXOR);
  1.1088 +						destY++,srcePoint.iY++,ditherOrigin.iY++;
  1.1089 +		 				}
  1.1090 +					while ((srcePoint.iY < aSourceRect.iBr.iY) && (scanLineBufferPtr < lastScanLine)
  1.1091 +						&& ((scanLineBufferPtr = (TUint32*)((TUint8*)scanLineBufferPtr + stride))>(TUint32*)0));
  1.1092 +					}
  1.1093 +				}
  1.1094 +			}
  1.1095 +		}
  1.1096 +	else
  1.1097 +		{
  1.1098 +		for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++,ditherOrigin.iY++)
  1.1099 +			{
  1.1100 +			aSourceBitmap->GetScanLine(scanLineDes,srcePoint,width,ETrue,ditherOrigin,
  1.1101 +								dispMode,aSourceBase,lineScanPos);
  1.1102 +
  1.1103 +			if (aShadowMode)
  1.1104 +				{
  1.1105 +				drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
  1.1106 +				drawDevice->ShadowBuffer(width,scanLineBuffer);
  1.1107 +				drawDevice->SetShadowMode(CFbsDrawDevice::ENoShadow);
  1.1108 +				}
  1.1109 +
  1.1110 +			drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,EDrawModeXOR);
  1.1111 +
  1.1112 +			aMaskBitmap->GetScanLine(scanLineDes,srcePoint,width,EFalse,ditherOrigin,dispMode,
  1.1113 +									 aMaskBase, lineScanPosMask);
  1.1114 +			::TileScanLine(scanLineDes, width, srcePoint, aMaskBitmap, lineScanPosMask,
  1.1115 +						   aMaskBase, dispMode);
  1.1116 +			drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,drawMode);
  1.1117 +
  1.1118 +			aSourceBitmap->GetScanLine(scanLineDes,srcePoint,width,ETrue,ditherOrigin,dispMode,
  1.1119 +							   aSourceBase,lineScanPos2);
  1.1120 +
  1.1121 +			if(aShadowMode)
  1.1122 +				{
  1.1123 +				drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
  1.1124 +				drawDevice->ShadowBuffer(width,scanLineBuffer);
  1.1125 +				drawDevice->SetShadowMode(CFbsDrawDevice::ENoShadow);
  1.1126 +				}
  1.1127 +
  1.1128 +			drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,EDrawModeXOR);
  1.1129 +			}
  1.1130 +		}
  1.1131 +	}
  1.1132 +
  1.1133 +void CFbsBitGc::DoBitBltMaskedNonFlicker(const TPoint& aDest,
  1.1134 +										 CBitwiseBitmap* aSourceBitmap,
  1.1135 +										 TUint32* aSourceBase,
  1.1136 +										 const TRect& aSourceRect,
  1.1137 +										 CBitwiseBitmap* aMaskBitmap,
  1.1138 +										 TUint32* aMaskBase,
  1.1139 +										 TBool aInvertMask,
  1.1140 +										 const TPoint& aDitherOrigin,
  1.1141 +										 TInt aShadowMode)
  1.1142 +	{
  1.1143 +	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
  1.1144 +
  1.1145 +	const TInt width = aSourceRect.Width();
  1.1146 +	TInt destY = aDest.iY;
  1.1147 +	TPoint srcePoint(aSourceRect.iTl);
  1.1148 +
  1.1149 +	TLineScanningPosition lineScanPos(aSourceBase);
  1.1150 +	TLineScanningPosition lineScanPosMask(aMaskBase);
  1.1151 +
  1.1152 +	const TDisplayMode srcFormat = aSourceBitmap->DisplayMode();
  1.1153 +	const TDisplayMode maskFormat = aMaskBitmap->DisplayMode();
  1.1154 +	
  1.1155 +	if (aMaskBitmap->IsCompressed()) 
  1.1156 +       { 
  1.1157 +       HBufC8* hBuf= CFbsBitmap::GetDecompressionBuffer(aMaskBitmap->DataStride() + 4); 
  1.1158 +       if (!hBuf) 
  1.1159 +          return; // Out of memory so do not draw anything 
  1.1160 +       lineScanPosMask.iScanLineBuffer = hBuf; 
  1.1161 +       } 
  1.1162 +
  1.1163 +	TAny* interface=NULL;
  1.1164 +	if ( (srcFormat == EColor16MU || srcFormat == EColor64K ) &&
  1.1165 +		maskFormat == EGray2 &&
  1.1166 +		!aShadowMode &&
  1.1167 +		aSourceBitmap->SizeInPixels().iWidth <= aMaskBitmap->SizeInPixels().iWidth &&
  1.1168 +		aSourceBitmap->SizeInPixels().iHeight <= aMaskBitmap->SizeInPixels().iHeight &&
  1.1169 +		drawDevice->GetInterface(KFastBlitInterfaceID, interface) == KErrNone )
  1.1170 +		{
  1.1171 +		// Parameters allow optimised code path
  1.1172 +		TInt length = width;
  1.1173 +		TUint32* srcPtr=NULL;
  1.1174 +		TUint32* maskPtr=NULL;
  1.1175 +		MFastBlit* fastBlit = reinterpret_cast<MFastBlit*>(interface);
  1.1176 +
  1.1177 +		while (srcePoint.iY < aSourceRect.iBr.iY)
  1.1178 +			{
  1.1179 +			aSourceBitmap->GetScanLinePtr(srcPtr, length, srcePoint, aSourceBase, lineScanPos);
  1.1180 +			aMaskBitmap->GetScanLinePtr(maskPtr, length, srcePoint, aMaskBase, lineScanPosMask);
  1.1181 +
  1.1182 +			fastBlit->WriteMaskLineEx(aDest.iX,destY,length,srcePoint.iX,srcPtr,srcFormat,srcePoint.iX,maskPtr,aInvertMask);
  1.1183 +
  1.1184 +			destY++;
  1.1185 +			++srcePoint.iY;
  1.1186 +			}
  1.1187 +
  1.1188 +		return;
  1.1189 +		}
  1.1190 +
  1.1191 +	TPoint ditherOrigin(aDitherOrigin + aDest);
  1.1192 +
  1.1193 +	TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
  1.1194 +	const TInt scanLineBytes = drawDevice->ScanLineBytes();
  1.1195 +	TPtr8 scanLineDes((TUint8*)scanLineBuffer,scanLineBytes,scanLineBytes);
  1.1196 +
  1.1197 +	TUint32* bitBltBuffer = (TUint32*)iDevice->iBitBltMaskedBuffer;
  1.1198 +	const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
  1.1199 +	const TInt bufferBytes = CFbsBitmap::ScanLineLength(width, dispMode);
  1.1200 +	TUint32* scanLineCopy = (TUint32*) new TUint8[bufferBytes];
  1.1201 +
  1.1202 +	TLineScanningPosition lineScanPos2(aSourceBase);
  1.1203 +	for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++,ditherOrigin.iY++)
  1.1204 +		{
  1.1205 +		drawDevice->ReadLine(aDest.iX,destY,width,bitBltBuffer,dispMode);
  1.1206 +		aSourceBitmap->GetScanLine(scanLineDes,srcePoint,width,ETrue,ditherOrigin,dispMode,
  1.1207 +								   aSourceBase,lineScanPos);
  1.1208 +
  1.1209 +		if (scanLineCopy)
  1.1210 +			{
  1.1211 +			Mem::Copy(scanLineCopy,scanLineBuffer,bufferBytes);
  1.1212 +			}
  1.1213 +
  1.1214 +		if (aShadowMode)
  1.1215 +			{
  1.1216 +			drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
  1.1217 +			drawDevice->ShadowBuffer(width,scanLineBuffer);
  1.1218 +			drawDevice->SetShadowMode(CFbsDrawDevice::ENoShadow);
  1.1219 +			}
  1.1220 +
  1.1221 +		XorBuffers(bitBltBuffer,scanLineBuffer,bufferBytes);
  1.1222 +
  1.1223 +		aMaskBitmap->GetScanLine(scanLineDes,srcePoint,width,EFalse,ditherOrigin,dispMode,
  1.1224 +								 aMaskBase,lineScanPosMask);
  1.1225 +		::TileScanLine(scanLineDes, width, srcePoint, aMaskBitmap, lineScanPosMask,
  1.1226 +					   aMaskBase, dispMode);
  1.1227 +
  1.1228 +		if (!aInvertMask)
  1.1229 +			InvertBuffer(scanLineBuffer,bufferBytes);
  1.1230 +		AndBuffers(bitBltBuffer,scanLineBuffer,bufferBytes);
  1.1231 +
  1.1232 +		// Slow call when memory low?
  1.1233 +		TUint32* scanLine;
  1.1234 +		if (!scanLineCopy)
  1.1235 +			{
  1.1236 +			aSourceBitmap->GetScanLine(scanLineDes,srcePoint,width,ETrue,ditherOrigin,
  1.1237 +									   dispMode,aSourceBase,lineScanPos2);
  1.1238 +			scanLine = scanLineBuffer;
  1.1239 +			}
  1.1240 +		else
  1.1241 +			scanLine = scanLineCopy;
  1.1242 +
  1.1243 +		if(aShadowMode)
  1.1244 +			{
  1.1245 +			drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
  1.1246 +			drawDevice->ShadowBuffer(width,scanLine);
  1.1247 +			drawDevice->SetShadowMode(CFbsDrawDevice::ENoShadow);
  1.1248 +			}
  1.1249 +
  1.1250 +		XorBuffers(bitBltBuffer,scanLine,bufferBytes);
  1.1251 +
  1.1252 +		drawDevice->WriteLine(aDest.iX,destY,width,bitBltBuffer,iDrawMode);
  1.1253 +		}
  1.1254 +	if (scanLineCopy)
  1.1255 +		{
  1.1256 +		delete[] scanLineCopy;
  1.1257 +		}
  1.1258 +	}
  1.1259 +
  1.1260 +void CFbsBitGc::DoBitBltMaskedNonFlickerSolid(const TPoint& aDest,
  1.1261 +											  CBitwiseBitmap* aSourceBitmap,
  1.1262 +											  TUint32* aSourceBase,
  1.1263 +											  const TRect& aSourceRect,
  1.1264 +											  CBitwiseBitmap* aMaskBitmap,
  1.1265 +											  TUint32* aMaskBase,
  1.1266 +											  TBool aInvertMask,
  1.1267 +											  const TPoint& aDitherOrigin,
  1.1268 +											  TInt aShadowMode)
  1.1269 +	{
  1.1270 +	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
  1.1271 +	const TInt width = aSourceRect.Width();
  1.1272 +	TPoint ditherOrigin(aDitherOrigin + aDest);
  1.1273 +	const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
  1.1274 +	TInt destY = aDest.iY;
  1.1275 +	TPoint srcePoint(aSourceRect.iTl);
  1.1276 +
  1.1277 +	TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
  1.1278 +	const TInt scanLineBytes = drawDevice->ScanLineBytes();
  1.1279 +	TPtr8 scanLineDes((TUint8*)scanLineBuffer,scanLineBytes,scanLineBytes);
  1.1280 +
  1.1281 +	TUint32* bitBltBuffer = (TUint32*)iDevice->iBitBltMaskedBuffer;
  1.1282 +	TUint32* backgroundBuffer = (TUint32*)(iDevice->iBitBltMaskedBuffer + scanLineBytes);
  1.1283 +	const TInt bufferBytes = CFbsBitmap::ScanLineLength(width, dispMode);
  1.1284 +
  1.1285 +	drawDevice->WriteRgbMulti(aDest.iX,aDest.iY,width,1,iBrushColor,iDrawMode);
  1.1286 +	drawDevice->ReadLine(aDest.iX,destY,width,backgroundBuffer,dispMode);
  1.1287 +
  1.1288 +	TLineScanningPosition lineScanPos(aSourceBase);
  1.1289 +	TLineScanningPosition lineScanPos2(aSourceBase);
  1.1290 +	TLineScanningPosition lineScanPosMask(aMaskBase);
  1.1291 +
  1.1292 +	for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++,ditherOrigin.iY++)
  1.1293 +		{
  1.1294 +		Mem::Copy(bitBltBuffer,backgroundBuffer,bufferBytes);
  1.1295 +
  1.1296 +		aSourceBitmap->GetScanLine(scanLineDes,srcePoint,width,ETrue,ditherOrigin,dispMode,
  1.1297 +								   aSourceBase,lineScanPos);
  1.1298 +		XorBuffers(bitBltBuffer,scanLineBuffer,bufferBytes);
  1.1299 +
  1.1300 +		aMaskBitmap->GetScanLine(scanLineDes,srcePoint,width,EFalse,ditherOrigin,dispMode,
  1.1301 +								 aMaskBase,lineScanPosMask);
  1.1302 +		::TileScanLine(scanLineDes, width, srcePoint, aMaskBitmap, lineScanPosMask,
  1.1303 +					   aMaskBase, dispMode);
  1.1304 +
  1.1305 +		if (!aInvertMask)
  1.1306 +			InvertBuffer(scanLineBuffer,bufferBytes);
  1.1307 +		AndBuffers(bitBltBuffer,scanLineBuffer,bufferBytes);
  1.1308 +		aSourceBitmap->GetScanLine(scanLineDes,srcePoint,width,ETrue,ditherOrigin,
  1.1309 +								   dispMode,aSourceBase,lineScanPos2);
  1.1310 +
  1.1311 +		XorBuffers(bitBltBuffer,scanLineBuffer,bufferBytes);
  1.1312 +
  1.1313 +		if(aShadowMode)
  1.1314 +			drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
  1.1315 +
  1.1316 +		drawDevice->WriteLine(aDest.iX,destY,width,bitBltBuffer,iDrawMode);
  1.1317 +
  1.1318 +		if(aShadowMode)
  1.1319 +			drawDevice->SetShadowMode(CFbsDrawDevice::ENoShadow);
  1.1320 +		}
  1.1321 +	}
  1.1322 +
  1.1323 +void CFbsBitGc::DoBitBltMaskedNonFlickerPatterned(const TPoint& aDest,
  1.1324 +												  CBitwiseBitmap* aSourceBitmap,
  1.1325 +												  TUint32* aSourceBase,
  1.1326 +												  const TRect& aSourceRect,
  1.1327 +												  CBitwiseBitmap* aMaskBitmap,
  1.1328 +												  TUint32* aMaskBase,
  1.1329 +												  TBool aInvertMask,
  1.1330 +												  const TPoint& aDitherOrigin,
  1.1331 +												  TInt aShadowMode)
  1.1332 +	{
  1.1333 +	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
  1.1334 +	const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
  1.1335 +
  1.1336 +	drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
  1.1337 +
  1.1338 +	iBrushBitmap.BeginDataAccess();
  1.1339 +	CBitwiseBitmap* brushBitmap = iBrushBitmap.Address();
  1.1340 +	BG_ASSERT_ALWAYS(iBrushUsed, EBitgdiPanicInvalidBitmap);
  1.1341 +	BG_ASSERT_ALWAYS(brushBitmap != NULL, EBitgdiPanicInvalidBitmap);
  1.1342 +
  1.1343 +	CFbsRasterizer* brushRasterizer = PrepareRasterizerForExtendedBitmap(iBrushBitmap);
  1.1344 +	TUint32* brushData = iBrushBitmap.DataAddress();
  1.1345 +	TPoint brushSourcePoint(aDest - iBrushOrigin - iOrigin);
  1.1346 +	const TSize brushSize(iBrushBitmap.SizeInPixels());
  1.1347 +	if (brushSourcePoint.iX < 0 || brushSourcePoint.iX >= brushSize.iWidth)
  1.1348 +		brushSourcePoint.iX %= brushSize.iWidth;
  1.1349 +	if (brushSourcePoint.iX < 0)
  1.1350 +		brushSourcePoint.iX += brushSize.iWidth;
  1.1351 +
  1.1352 +	TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
  1.1353 +	const TInt scanLineBytes = drawDevice->ScanLineBytes();
  1.1354 +	TPtr8 scanLineDes((TUint8*)scanLineBuffer,scanLineBytes,scanLineBytes);
  1.1355 +
  1.1356 +	TUint32* bitBltBuffer = (TUint32*)iDevice->iBitBltMaskedBuffer;
  1.1357 +	TPtr8 bitBltDes(iDevice->iBitBltMaskedBuffer, scanLineBytes, scanLineBytes);
  1.1358 +
  1.1359 +	TInt widthRemaining = aSourceRect.Width();
  1.1360 +	TPoint sourcePoint(aSourceRect.iTl);
  1.1361 +	TInt destX = aDest.iX;
  1.1362 +
  1.1363 +	TInt width = Min(widthRemaining,brushSize.iWidth);
  1.1364 +
  1.1365 +	if (brushSourcePoint.iX + widthRemaining > brushSize.iWidth)
  1.1366 +		width = brushSize.iWidth - brushSourcePoint.iX;
  1.1367 +
  1.1368 +	while (widthRemaining > 0)
  1.1369 +		{
  1.1370 +		TInt destY = aDest.iY;
  1.1371 +		sourcePoint.iY = aSourceRect.iTl.iY;
  1.1372 +		brushSourcePoint.iY = aDest.iY - iBrushOrigin.iY - iOrigin.iY;
  1.1373 +		TPoint ditherOrigin(aDitherOrigin + TPoint(destX,aDest.iY));
  1.1374 +		const TInt bufferBytes = CFbsBitmap::ScanLineLength(width, dispMode);
  1.1375 +
  1.1376 +		TLineScanningPosition lineScanPosBrush(brushData);
  1.1377 +		TLineScanningPosition lineScanPosMask(aMaskBase);
  1.1378 +		TLineScanningPosition lineScanPosSrc(aSourceBase);
  1.1379 +		TLineScanningPosition lineScanPosSrc2(aSourceBase);
  1.1380 +
  1.1381 +		for ( ;sourcePoint.iY < aSourceRect.iBr.iY;
  1.1382 +			   destY++,sourcePoint.iY++,ditherOrigin.iY++,brushSourcePoint.iY++)
  1.1383 +			{
  1.1384 +			brushBitmap->GetScanLine(bitBltDes,brushSourcePoint,width,ETrue,ditherOrigin,
  1.1385 +									 dispMode,brushData,lineScanPosBrush);
  1.1386 +			aSourceBitmap->GetScanLine(scanLineDes,sourcePoint,width,ETrue,ditherOrigin,
  1.1387 +									   dispMode,aSourceBase,lineScanPosSrc);
  1.1388 +			XorBuffers(bitBltBuffer,scanLineBuffer,scanLineBytes);
  1.1389 +
  1.1390 +			aMaskBitmap->GetScanLine(scanLineDes,sourcePoint,width,EFalse,ditherOrigin,
  1.1391 +									 dispMode,aMaskBase,lineScanPosMask);
  1.1392 +			::TileScanLine(scanLineDes, width, sourcePoint, aMaskBitmap, lineScanPosMask,
  1.1393 +						   aMaskBase, dispMode);
  1.1394 +
  1.1395 +			if (!aInvertMask)
  1.1396 +				InvertBuffer(scanLineBuffer,bufferBytes);
  1.1397 +			AndBuffers(bitBltBuffer,scanLineBuffer,bufferBytes);
  1.1398 +
  1.1399 +			aSourceBitmap->GetScanLine(scanLineDes,sourcePoint,width,ETrue,ditherOrigin,
  1.1400 +									   dispMode,aSourceBase,lineScanPosSrc2);
  1.1401 +			XorBuffers(bitBltBuffer,scanLineBuffer,bufferBytes);
  1.1402 +
  1.1403 +			drawDevice->WriteLine(destX,destY,width,bitBltBuffer,iDrawMode);
  1.1404 +			}
  1.1405 +
  1.1406 +		widthRemaining -= width;
  1.1407 +		sourcePoint.iX += width;
  1.1408 +		brushSourcePoint.iX += width;
  1.1409 +		destX += width;
  1.1410 +
  1.1411 +		width = Min(widthRemaining,brushSize.iWidth);
  1.1412 +		}
  1.1413 +	if (brushRasterizer)
  1.1414 +		{
  1.1415 +		brushRasterizer->EndBitmap(iBrushBitmap.SerialNumber());
  1.1416 +		}
  1.1417 +	iBrushBitmap.EndDataAccess(ETrue);
  1.1418 +	}
  1.1419 +
  1.1420 +void CFbsBitGc::DoBitBltAlpha(const TPoint& aDest,CBitwiseBitmap* aSourceBitmap,
  1.1421 +							  TUint32* aSourceBase,const TRect& aSourceRect,
  1.1422 +							  CBitwiseBitmap* aMaskBitmap,TUint32* aMaskBase,
  1.1423 +							  const TPoint& aAlphaPoint,TInt aShadowMode, TBool aInvertMask)
  1.1424 +	{
  1.1425 +	MFastBlend* fastBlend=NULL;
  1.1426 +	if (FastBlendInterface(aSourceBitmap,aMaskBitmap,fastBlend)==KErrNone)
  1.1427 +		{
  1.1428 +		if (fastBlend->FastBlendBitmapMasked(aDest, aSourceBase, aSourceBitmap->DataStride(), aSourceBitmap->SizeInPixels(), aSourceRect, aSourceBitmap->DisplayMode(),
  1.1429 +							aMaskBase, aMaskBitmap->DataStride(), aMaskBitmap->DisplayMode(), aMaskBitmap->SizeInPixels(), aAlphaPoint, aInvertMask,
  1.1430 +							iDrawMode, aShadowMode)==KErrNone)
  1.1431 +			{
  1.1432 +			return;
  1.1433 +			}
  1.1434 +		}
  1.1435 +	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
  1.1436 +
  1.1437 +	const TPoint KZeroPoint(0,0);
  1.1438 +	const TInt KScanLineLength = 256;
  1.1439 +	const TInt KRgbSize = 4;
  1.1440 +
  1.1441 +	TUint8 srceRgbBuffer[KScanLineLength * KRgbSize];
  1.1442 +	TUint8 maskBuffer[KScanLineLength];
  1.1443 +	TUint8* srceRgbBufferPtr(srceRgbBuffer);
  1.1444 +
  1.1445 +	TPtr8 srceRgbDes(srceRgbBuffer,KScanLineLength * KRgbSize,KScanLineLength * KRgbSize);
  1.1446 +	TPtr8 maskDes(maskBuffer,KScanLineLength,KScanLineLength);
  1.1447 +
  1.1448 +	drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
  1.1449 +
  1.1450 +	const TSize sourceSize = aSourceBitmap->SizeInPixels();
  1.1451 +	// Convert negative or large offsets into sensible positive ones.
  1.1452 +	TPoint alphaOffset(aAlphaPoint.iX % sourceSize.iWidth, aAlphaPoint.iY % sourceSize.iHeight);
  1.1453 +	if ( alphaOffset.iX < 0 ) 
  1.1454 +		alphaOffset.iX += sourceSize.iWidth;
  1.1455 +	if ( alphaOffset.iY < 0 ) 
  1.1456 +		alphaOffset.iY += sourceSize.iHeight;
  1.1457 +	
  1.1458 +	TInt srceY = aSourceRect.iTl.iY;
  1.1459 +	TInt destY = aDest.iY;
  1.1460 +	TInt alphaY = alphaOffset.iY;
  1.1461 +	
  1.1462 +	TLineScanningPosition lineScanPosSrc(aSourceBase);
  1.1463 +	TLineScanningPosition lineScanPosMask(aMaskBase);
  1.1464 +
  1.1465 +	TDisplayMode sourceMode = aSourceBitmap->DisplayMode();
  1.1466 +
  1.1467 +	if (aMaskBitmap->IsCompressed())
  1.1468 +		{
  1.1469 +		HBufC8* hBuf= CFbsBitmap::GetDecompressionBuffer(aMaskBitmap->DataStride());
  1.1470 +		if (!hBuf)
  1.1471 +			{
  1.1472 +			return;  // Out of memory so do not draw anything
  1.1473 +			}
  1.1474 +		lineScanPosMask.iScanLineBuffer = hBuf;
  1.1475 +		}
  1.1476 +
  1.1477 +	TAny* interface=NULL;
  1.1478 +	if ( (sourceMode == EColor16MU || sourceMode == EColor64K) &&
  1.1479 +			aMaskBitmap->DisplayMode() == EGray256 && // ensure a monochrome mask isn't passed in as an alpha channel
  1.1480 +			aSourceBitmap->SizeInPixels().iWidth  <= aMaskBitmap->SizeInPixels().iWidth &&
  1.1481 +			aSourceBitmap->SizeInPixels().iHeight <= aMaskBitmap->SizeInPixels().iHeight &&
  1.1482 +			drawDevice->GetInterface(KFastBlitInterfaceID, interface) == KErrNone )
  1.1483 +		{
  1.1484 +		TInt length = aSourceRect.Width();
  1.1485 +		const TInt srceX = aSourceRect.iTl.iX;				
  1.1486 +		const TInt alphaX = alphaOffset.iX;
  1.1487 +		const TInt destX = aDest.iX;
  1.1488 +		MFastBlit* fastBlit = reinterpret_cast<MFastBlit*>(interface);
  1.1489 +
  1.1490 +		while (srceY < aSourceRect.iBr.iY)
  1.1491 +			{
  1.1492 +			TUint32* srcPtr;
  1.1493 +			TUint32* maskPtr;
  1.1494 +			TPoint srcPoint(srceX, srceY);
  1.1495 +			TPoint maskPoint(alphaX, alphaY);
  1.1496 +
  1.1497 +			aSourceBitmap->GetScanLinePtr(srcPtr, length, srcPoint, aSourceBase, lineScanPosSrc);
  1.1498 +			aMaskBitmap->GetScanLinePtr(maskPtr, length, maskPoint, aMaskBase, lineScanPosMask);
  1.1499 +
  1.1500 +			fastBlit->WriteAlphaLineEx(destX,destY,length,srceX,srcPtr,sourceMode,alphaX,maskPtr,MAlphaBlend::EShdwBefore);
  1.1501 +
  1.1502 +			srceY++;
  1.1503 +			destY++;
  1.1504 +			alphaY++;
  1.1505 +			}
  1.1506 +		return;
  1.1507 +		}
  1.1508 +
  1.1509 +	const TBool useScanLinePtr = ((!aShadowMode) && (EColor16MA == aSourceBitmap->DisplayMode()));
  1.1510 +	TUint32* slptr=NULL;
  1.1511 +	TUint offset = 0;
  1.1512 +	TDisplayMode srcMode = ERgb;
  1.1513 +	
  1.1514 +	while (srceY < aSourceRect.iBr.iY)
  1.1515 +		{
  1.1516 +		TInt srceX = aSourceRect.iTl.iX;
  1.1517 +		TInt destX = aDest.iX;
  1.1518 +		TInt alphaX = alphaOffset.iX;
  1.1519 +		
  1.1520 +		while (srceX < aSourceRect.iBr.iX)
  1.1521 +			{
  1.1522 +			TPoint srcePoint(srceX,srceY);
  1.1523 +			TPoint alphaPoint(alphaX,alphaY);
  1.1524 +			const TInt width = Min(KScanLineLength,aSourceRect.iBr.iX - srceX);
  1.1525 +
  1.1526 +			if (useScanLinePtr)
  1.1527 +				{
  1.1528 +				offset = MemoryOffsetForPixelPitch(srceX, EColor16MU);
  1.1529 +				srceRgbBufferPtr = (TUint8*)GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPosSrc, offset);
  1.1530 +				}
  1.1531 +			else
  1.1532 +				{
  1.1533 +				aSourceBitmap->GetScanLine(srceRgbDes,srcePoint,width,EFalse,KZeroPoint,
  1.1534 +								   srcMode,aSourceBase,lineScanPosSrc);
  1.1535 +				}
  1.1536 +
  1.1537 +			aMaskBitmap->GetScanLine(maskDes,alphaPoint,width,EFalse,KZeroPoint,
  1.1538 +									 EGray256,aMaskBase,lineScanPosMask);
  1.1539 +			::TileScanLine(maskDes, width, alphaPoint, aMaskBitmap, lineScanPosMask,
  1.1540 +						   aMaskBase, EGray256);
  1.1541 +			// aInvertMask is not used for alpha channels (EGray256 mask)
  1.1542 +			if (aInvertMask && aMaskBitmap->DisplayMode() != EGray256)
  1.1543 +				{
  1.1544 +				for (TInt i = 0; i < width; ++i)
  1.1545 +					maskBuffer[i] = ~maskBuffer[i];
  1.1546 +				}
  1.1547 +			drawDevice->WriteRgbAlphaLine(destX,destY,width,srceRgbBufferPtr,maskBuffer,iDrawMode);
  1.1548 +
  1.1549 +			srceX += KScanLineLength;
  1.1550 +			destX += KScanLineLength;
  1.1551 +			alphaX += KScanLineLength;
  1.1552 +			}
  1.1553 +
  1.1554 +		srceY++;
  1.1555 +		destY++;
  1.1556 +		alphaY++;
  1.1557 +		}
  1.1558 +	}
  1.1559 +
  1.1560 +/**
  1.1561 +The method performs an alpha blending of the source data - aSrcBmp1 and aSrcBmp2, using
  1.1562 +the data from aAlphaBmp as an alpha blending factor.
  1.1563 +@internalComponent
  1.1564 +@see CFbsBitGc::AlphaBlendBitmaps.
  1.1565 +*/
  1.1566 +void CFbsBitGc::DoBitBltAlpha(const TPoint& aDestPt,
  1.1567 +							  const CBitwiseBitmap* aSrcBmp1,
  1.1568 +							  TUint32* aSrcBmpDataAddr1,
  1.1569 +							  const CBitwiseBitmap* aSrcBmp2,
  1.1570 +							  TUint32* aSrcBmpDataAddr2,
  1.1571 +							  const CBitwiseBitmap* aAlphaBmp,
  1.1572 +							  TUint32* aAlphaBmpDataAddr,
  1.1573 +							  const TRect& aSrcRect1,
  1.1574 +							  const TPoint& aSrcPt2,
  1.1575 +							  const TPoint& aAlphaPt,
  1.1576 +							  TInt aShadowMode)
  1.1577 +	{
  1.1578 +	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
  1.1579 +#ifdef _DEBUG
  1.1580 +	TRect deviceDestRect;
  1.1581 +	drawDevice->GetDrawRect(deviceDestRect);
  1.1582 +#endif
  1.1583 +	//Check the destination point.
  1.1584 +	BG_ASSERT_DEBUG(aDestPt.iX >= deviceDestRect.iTl.iX, EBitgdiPanicOutOfBounds);
  1.1585 +	BG_ASSERT_DEBUG(aDestPt.iY >= deviceDestRect.iTl.iY, EBitgdiPanicOutOfBounds);
  1.1586 +	BG_ASSERT_DEBUG((aDestPt.iX + aSrcRect1.Width()) <= deviceDestRect.iBr.iX, EBitgdiPanicOutOfBounds);
  1.1587 +	BG_ASSERT_DEBUG((aDestPt.iY + aSrcRect1.Height()) <= deviceDestRect.iBr.iY, EBitgdiPanicOutOfBounds);
  1.1588 +
  1.1589 +	const TPoint KZeroPoint(0,0);
  1.1590 +	const TInt KScanLineLength = 256;//128 is not enough to fill buffer for 16MA and 16MU display modes
  1.1591 +	const TInt KRgbSize = 4;
  1.1592 +
  1.1593 +	TUint8 srceRgbBuffer1[KScanLineLength * KRgbSize];
  1.1594 +	TUint8 srceBuffer2[KScanLineLength * KRgbSize];
  1.1595 +	TUint8 alphaBuffer[KScanLineLength];
  1.1596 +
  1.1597 +	TPtr8 srceRgbDes1(srceRgbBuffer1,KScanLineLength * KRgbSize,KScanLineLength * KRgbSize);
  1.1598 +	TPtr8 srceDes2(srceBuffer2,KScanLineLength * KRgbSize,KScanLineLength * KRgbSize);
  1.1599 +	TPtr8 alphaDes(alphaBuffer,KScanLineLength,KScanLineLength);
  1.1600 +
  1.1601 +	const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
  1.1602 +	drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
  1.1603 +
  1.1604 +	TInt srceY1 = aSrcRect1.iTl.iY;
  1.1605 +	TInt srceY2 = aSrcPt2.iY;
  1.1606 +	TInt alphaY = aAlphaPt.iY;
  1.1607 +	TInt destY = aDestPt.iY;
  1.1608 +
  1.1609 +	TLineScanningPosition lineScanPosSrc1(aSrcBmpDataAddr1);
  1.1610 +	TLineScanningPosition lineScanPosSrc2(aSrcBmpDataAddr2);
  1.1611 +	TLineScanningPosition lineScanPosAlpha(aAlphaBmpDataAddr);
  1.1612 +
  1.1613 +	while (srceY1 < aSrcRect1.iBr.iY)
  1.1614 +		{
  1.1615 +		TInt srceX1 = aSrcRect1.iTl.iX;
  1.1616 +		TInt srceX2 = aSrcPt2.iX;
  1.1617 +		TInt alphaX = aAlphaPt.iX;
  1.1618 +		TInt destX = aDestPt.iX;
  1.1619 +
  1.1620 +		while (srceX1 < aSrcRect1.iBr.iX)
  1.1621 +			{
  1.1622 +			TPoint srcePoint1(srceX1,srceY1);
  1.1623 +			TPoint srcePoint2(srceX2,srceY2);
  1.1624 +			TPoint alphaPoint(alphaX,alphaY);
  1.1625 +			const TInt width = Min(KScanLineLength,aSrcRect1.iBr.iX - srceX1);
  1.1626 +
  1.1627 +			aSrcBmp1->GetScanLine(srceRgbDes1,srcePoint1,width,EFalse,KZeroPoint,EColor16MU,
  1.1628 +								  aSrcBmpDataAddr1,lineScanPosSrc1);
  1.1629 +			aSrcBmp2->GetScanLine(srceDes2,srcePoint2,width,EFalse,KZeroPoint,dispMode,
  1.1630 +								  aSrcBmpDataAddr2,lineScanPosSrc2);
  1.1631 +			aAlphaBmp->GetScanLine(alphaDes,alphaPoint,width,EFalse,KZeroPoint,EGray256,
  1.1632 +								   aAlphaBmpDataAddr,lineScanPosAlpha);
  1.1633 +			::TileScanLine(alphaDes, width, alphaPoint, aAlphaBmp, lineScanPosAlpha, aAlphaBmpDataAddr, EGray256);
  1.1634 +
  1.1635 +			drawDevice->WriteRgbAlphaLine(destX,
  1.1636 +										  destY,
  1.1637 +										  width,
  1.1638 +										  srceRgbBuffer1,
  1.1639 +										  srceBuffer2,
  1.1640 +										  alphaBuffer,
  1.1641 +										  iDrawMode);
  1.1642 +
  1.1643 +			srceX1 += KScanLineLength;
  1.1644 +			srceX2 += KScanLineLength;
  1.1645 +			alphaX += KScanLineLength;
  1.1646 +			destX += KScanLineLength;
  1.1647 +			}
  1.1648 +
  1.1649 +		srceY1++;
  1.1650 +		srceY2++;
  1.1651 +		alphaY++;
  1.1652 +		destY++;
  1.1653 +		}
  1.1654 +	}
  1.1655 +
  1.1656 +/**
  1.1657 +The method performs an alpha blending of the source data - aSrcBmp1 and aSrcBmp2, using
  1.1658 +the data from aAlphaBmp as an alpha blending factor.
  1.1659 +The formula used for that, is:
  1.1660 +(C1 * A + C2 * (255 - A)) / 255, where:
  1.1661 +- C1 - a pixel from aSrcBmp1;
  1.1662 +- C2 - a pixel from aSrcBmp2;
  1.1663 +- A  - a pixel from aAlphaBmp;
  1.1664 +The content of source and alpha bitmap is preserved.
  1.1665 +The calculated alpha blended pixels are written to the destination - the screen or a bitmap.
  1.1666 +@publishedAll
  1.1667 +@released
  1.1668 +@param aDestPt Position in the target the result should be drawn to.
  1.1669 +@param aSrcBmp1 A pointer to the source bitmap 1.
  1.1670 +@param aSrcBmp2 A pointer to the source bitmap 2.
  1.1671 +@param aAlphaBmp A pointer to the bitmap used as an alpha blending factor.
  1.1672 +@param aSrcRect1 A part of bitmap 1 that should be used as a source for the alpha blending.
  1.1673 +@param aSrcPt2 Position of the first pixel in bitmap 2 that should be used as a source
  1.1674 +               for the alpha blending. The size of the area is the same as the
  1.1675 +			   bitmap 1 area - aSrcRect1 parameter.
  1.1676 +@param aAlphaPt Position of the first pixel in the alpha bitmap that should be used as a source
  1.1677 +                for the alpha blending. The size of the area is the same as the
  1.1678 +                bitmap 1 area - aSrcRect1 parameter.
  1.1679 +@pre !aSrcRect1.IsEmpty()
  1.1680 +@pre aSrcBmp1 != NULL
  1.1681 +@pre aSrcBmp1->Handle() != NULL
  1.1682 +@pre aSrcBmp2 != NULL
  1.1683 +@pre aSrcBmp2->Handle() != NULL
  1.1684 +@pre aAlphaBmp != NULL
  1.1685 +@pre aAlphaBmp->Handle() != NULL
  1.1686 +@pre aAlphaBmp->DisplayMode() <= EGray256
  1.1687 +@return KErrNone If the call is successful, KErrArgument otherwise.
  1.1688 +*/
  1.1689 +EXPORT_C  TInt CFbsBitGc::AlphaBlendBitmaps(const TPoint& aDestPt,
  1.1690 +											const CFbsBitmap* aSrcBmp1,
  1.1691 +											const CFbsBitmap* aSrcBmp2,
  1.1692 +											const TRect& aSrcRect1,
  1.1693 +											const TPoint& aSrcPt2,
  1.1694 +											const CFbsBitmap* aAlphaBmp,
  1.1695 +											const TPoint& aAlphaPt)
  1.1696 +	{
  1.1697 +	//Check the bitmap pointers and handles. Check the CFbsDevice instance -
  1.1698 +	//it shouldn't be NULL - that means - CFbsBitGc instance (this pointer)
  1.1699 +	//should be created either using CFbsDevice::CreateContext() or CFbsBitGc::Activate() -
  1.1700 +	//before the method was called.
  1.1701 +	if(!aSrcBmp1 || !aSrcBmp1->Handle() || !aSrcBmp2 || !aSrcBmp2->Handle() ||
  1.1702 +	   !aAlphaBmp || !aAlphaBmp->Handle() || CheckDevice(aSrcRect1))
  1.1703 +		{
  1.1704 +		return KErrArgument;
  1.1705 +		}
  1.1706 +		
  1.1707 +	aSrcBmp1->BeginDataAccess();
  1.1708 +	aSrcBmp2->BeginDataAccess();
  1.1709 +	aAlphaBmp->BeginDataAccess();
  1.1710 +		
  1.1711 +	//Check display mode of the alpha bitmap. Bitmaps which display mode is greater than
  1.1712 +	//EGray256 can't be used as alpha bitmaps.
  1.1713 +	if(aAlphaBmp->DisplayMode() > EGray256)
  1.1714 +		{
  1.1715 +		aSrcBmp1->EndDataAccess(ETrue);
  1.1716 +		aSrcBmp2->EndDataAccess(ETrue);
  1.1717 +		aAlphaBmp->EndDataAccess(ETrue);
  1.1718 +		return KErrArgument;
  1.1719 +		}
  1.1720 +	//Check source rect 1. Bitmap 1 must contain the whole source rect 1.
  1.1721 +	TRect srcRect1(aSrcRect1);
  1.1722 +	TRect area1(aSrcBmp1->SizeInPixels());
  1.1723 +	srcRect1.Intersection(area1);
  1.1724 +	if(srcRect1 != aSrcRect1)
  1.1725 +		{
  1.1726 +		aSrcBmp1->EndDataAccess(ETrue);
  1.1727 +		aSrcBmp2->EndDataAccess(ETrue);
  1.1728 +		aAlphaBmp->EndDataAccess(ETrue);
  1.1729 +		return KErrArgument;
  1.1730 +		}
  1.1731 +	//Create and check source rect 2. Bitmap 2 must contain the whole source rect 2.
  1.1732 +	TRect srcRect2(TSize(aSrcRect1.Width(), aSrcRect1.Height()));
  1.1733 +	srcRect2.Move(aSrcPt2);
  1.1734 +	TRect srcRect2t(srcRect2);
  1.1735 +	TRect area2(aSrcBmp2->SizeInPixels());
  1.1736 +	srcRect2.Intersection(area2);
  1.1737 +	if(srcRect2 != srcRect2t)
  1.1738 +		{
  1.1739 +		aSrcBmp1->EndDataAccess(ETrue);
  1.1740 +		aSrcBmp2->EndDataAccess(ETrue);
  1.1741 +		aAlphaBmp->EndDataAccess(ETrue);
  1.1742 +		return KErrArgument;
  1.1743 +		}
  1.1744 +	//Calculate the destination rect
  1.1745 +	TPoint destPt(aDestPt + iOrigin);
  1.1746 +	TRect destRect(destPt, srcRect1.Size());
  1.1747 +	TPoint offset(srcRect1.iTl - destPt);
  1.1748 +	TPoint offset2(srcRect2.iTl - destPt);
  1.1749 +	TRect clippedDestRect(destRect);
  1.1750 +	AddRect(clippedDestRect);
  1.1751 +	if(UserClipRect(clippedDestRect))
  1.1752 +		{
  1.1753 +		aSrcBmp1->EndDataAccess(ETrue);
  1.1754 +		aSrcBmp2->EndDataAccess(ETrue);
  1.1755 +		aAlphaBmp->EndDataAccess(ETrue);
  1.1756 +		return KErrArgument;
  1.1757 +		}
  1.1758 +	//Save current shadow mode
  1.1759 +	TInt8 shadowMode = iShadowMode;
  1.1760 +	iShadowMode = CFbsDrawDevice::ENoShadow;
  1.1761 +	//Setup the device and prevent the bitmaps from being cleaned away by client code.
  1.1762 +	//Drawing begins.
  1.1763 +	SetupDevice();
  1.1764 +	iDevice->DrawingBegin();
  1.1765 +	CBitwiseBitmap* srcBmp1 = ((CFbsBitGcBitmap*)aSrcBmp1)->Address();
  1.1766 +	CBitwiseBitmap* srcBmp2 = ((CFbsBitGcBitmap*)aSrcBmp2)->Address();
  1.1767 +	CBitwiseBitmap* alphaBmp = ((CFbsBitGcBitmap*)aAlphaBmp)->Address();
  1.1768 +	BG_ASSERT_DEBUG(srcBmp1, EBitgdiPanicInvalidBitmap);
  1.1769 +	BG_ASSERT_DEBUG(srcBmp2, EBitgdiPanicInvalidBitmap);
  1.1770 +	BG_ASSERT_DEBUG(alphaBmp, EBitgdiPanicInvalidBitmap);
  1.1771 +
  1.1772 +	TUint32* srcDataAddr1 = aSrcBmp1->DataAddress();
  1.1773 +	TUint32* srcDataAddr2 = aSrcBmp2->DataAddress();
  1.1774 +	TUint32* alphaDataAddr = aAlphaBmp->DataAddress();
  1.1775 +
  1.1776 +	CFbsRasterizer* rasterizer1 = PrepareRasterizerForExtendedBitmap(*aSrcBmp1, clippedDestRect, offset);
  1.1777 +	CFbsRasterizer* rasterizer2 = PrepareRasterizerForExtendedBitmap(*aSrcBmp2, clippedDestRect, offset2);
  1.1778 +	CFbsRasterizer* alphaRasterizer;
  1.1779 +	if (aAlphaPt.iX >= 0 && aAlphaPt.iY >= 0
  1.1780 +		&& aAlphaPt.iX + aSrcRect1.Width() <= aAlphaBmp->SizeInPixels().iWidth
  1.1781 +		&& aAlphaPt.iY + aSrcRect1.Height() <= aAlphaBmp->SizeInPixels().iHeight)
  1.1782 +		{
  1.1783 +		// Alpha blending bitmap is not tiled. Pass same region of interest as source bitmaps to rasterizer.
  1.1784 +		alphaRasterizer = PrepareRasterizerForExtendedBitmap(*aAlphaBmp, clippedDestRect, aAlphaPt - destPt);
  1.1785 +		}
  1.1786 +	else
  1.1787 +		{
  1.1788 +		// Alpha blending bitmap is tiled. Do not pass any region of interest to rasterizer.
  1.1789 +		alphaRasterizer = PrepareRasterizerForExtendedBitmap(*aAlphaBmp);
  1.1790 +		}
  1.1791 +
  1.1792 +	//For each region - find the clipping rect and draw
  1.1793 +	TInt limit = iDefaultRegionPtr->Count();
  1.1794 +	CGraphicsAccelerator* ga = GraphicsAccelerator();
  1.1795 +	// Code for Graphics Accelerated Drawing
  1.1796 +	if(ga && (shadowMode == CFbsDrawDevice::ENoShadow))
  1.1797 +		{
  1.1798 +		TInt gaOperationResult = KErrUnknown;
  1.1799 +		TAcceleratedBitmapSpec srcBmp1Spec(const_cast<CFbsBitmap*>(aSrcBmp1));
  1.1800 +		TAcceleratedBitmapSpec srcBmp2Spec(const_cast<CFbsBitmap*>(aSrcBmp2));
  1.1801 +		TAcceleratedBitmapSpec alphaBmpSpec(const_cast<CFbsBitmap*>(aAlphaBmp));
  1.1802 +		iDevice->DrawingEnd();
  1.1803 +
  1.1804 +		for(TInt count=0;count<limit;count++)
  1.1805 +			{
  1.1806 +			iClipRect=(*iDefaultRegionPtr)[count];
  1.1807 +			if(!iClipRect.Intersects(clippedDestRect))
  1.1808 +				{
  1.1809 +				continue;
  1.1810 +				}
  1.1811 +			//clippedDestRect was constructed from destRect. destRect was constructed from srcRect1.
  1.1812 +			iClipRect.Intersection(clippedDestRect);
  1.1813 +			TRect clippedSrcRect(iClipRect);
  1.1814 +			clippedSrcRect.Move(offset);//clippedSrcRect - maps to a part of srcRect1 now.
  1.1815 +			TPoint shift(clippedSrcRect.iTl - srcRect1.iTl);
  1.1816 +			BG_ASSERT_DEBUG(shift.iX >= 0, EBitgdiPanicNegativeShift);
  1.1817 +			BG_ASSERT_DEBUG(shift.iY >= 0, EBitgdiPanicNegativeShift);
  1.1818 +
  1.1819 +			gaOperationResult = ga->Operation(TGopAlphaBlendTwoBitmaps(iClipRect.iTl,srcBmp1Spec,srcBmp2Spec,clippedSrcRect,aSrcPt2 + shift,alphaBmpSpec,aAlphaPt + shift));
  1.1820 +			if(gaOperationResult != KErrNone)
  1.1821 +				break;
  1.1822 +			iDevice->iDrawDevice->UpdateRegion(iClipRect);
  1.1823 +			}
  1.1824 +		if(gaOperationResult == KErrNone)
  1.1825 +			goto finish;
  1.1826 +		iDevice->DrawingBegin();
  1.1827 +		}
  1.1828 +
  1.1829 +	// Code for non- Graphics Accelerated Drawing
  1.1830 +	for(TInt count=0;count<limit;count++)
  1.1831 +		{
  1.1832 +		iClipRect=(*iDefaultRegionPtr)[count];
  1.1833 +		if(!iClipRect.Intersects(clippedDestRect))
  1.1834 +			{
  1.1835 +			continue;
  1.1836 +			}
  1.1837 +		//clippedDestRect was constructed from destRect. destRect was constructed from srcRect1.
  1.1838 +		iClipRect.Intersection(clippedDestRect);
  1.1839 +		TRect clippedSrcRect(iClipRect);
  1.1840 +		clippedSrcRect.Move(offset);//clippedSrcRect - maps to a part of srcRect1 now.
  1.1841 +		TPoint shift(clippedSrcRect.iTl - srcRect1.iTl);
  1.1842 +		BG_ASSERT_DEBUG(shift.iX >= 0, EBitgdiPanicNegativeShift);
  1.1843 +		BG_ASSERT_DEBUG(shift.iY >= 0, EBitgdiPanicNegativeShift);
  1.1844 +
  1.1845 +		TDrawMode drawMode = iDrawMode;
  1.1846 +		iDrawMode = EDrawModeWriteAlpha; // this is the only mode currently supported
  1.1847 +		DoBitBltAlpha(iClipRect.iTl,
  1.1848 +					  srcBmp1,
  1.1849 +					  srcDataAddr1,
  1.1850 +					  srcBmp2,
  1.1851 +					  srcDataAddr2,
  1.1852 +					  alphaBmp,
  1.1853 +					  alphaDataAddr,
  1.1854 +					  clippedSrcRect,
  1.1855 +					  aSrcPt2 + shift,
  1.1856 +					  aAlphaPt + shift,
  1.1857 +					  shadowMode);
  1.1858 +		iDrawMode = drawMode; // restore the previous draw mode
  1.1859 +
  1.1860 +		iDevice->iDrawDevice->UpdateRegion(iClipRect);
  1.1861 +		}
  1.1862 +
  1.1863 +	//Drawig ends. Restore the previous shadow mode
  1.1864 +	iDevice->DrawingEnd();
  1.1865 +finish:
  1.1866 +	if (rasterizer1)
  1.1867 +		{
  1.1868 +		rasterizer1->EndBitmap(aSrcBmp1->SerialNumber());
  1.1869 +		}
  1.1870 +	if (rasterizer2)
  1.1871 +		{
  1.1872 +		rasterizer2->EndBitmap(aSrcBmp2->SerialNumber());
  1.1873 +		}
  1.1874 +	if (alphaRasterizer)
  1.1875 +		{
  1.1876 +		alphaRasterizer->EndBitmap(aAlphaBmp->SerialNumber());
  1.1877 +		}
  1.1878 +	aSrcBmp1->EndDataAccess(ETrue);
  1.1879 +	aSrcBmp2->EndDataAccess(ETrue);
  1.1880 +	aAlphaBmp->EndDataAccess(ETrue);
  1.1881 +	iShadowMode = shadowMode;
  1.1882 +
  1.1883 +	return KErrNone;
  1.1884 +	}
  1.1885 +
  1.1886 +/**
  1.1887 +The method performs an alpha blending of the source data - aSrcBmp - with the existing image, using
  1.1888 +the data from aAlphaBmp as an alpha blending factor.
  1.1889 +The formula used for that, is:
  1.1890 +(C * A + D * (255 - A)) / 255, where:
  1.1891 +- C - a pixel from aSrcBmp;
  1.1892 +- D - a pixel from the destination;
  1.1893 +- A  - a pixel from aAlphaBmp;
  1.1894 +The content of source and alpha bitmap is preserved.
  1.1895 +The calculated alpha blended pixels are written to the destination - the screen or a bitmap.
  1.1896 +@publishedAll
  1.1897 +@released
  1.1898 +@param aDestPt Position in the target the result should be drawn to.
  1.1899 +@param aSrcBmp A pointer to the source bitmap.
  1.1900 +@param aAlphaBmp A pointer to the bitmap used as an alpha blending factor.
  1.1901 +@param aSrcRect A part of aSrcBmp that should be used as a source for the alpha blending.
  1.1902 +				DISCLAIMER: if aSrcRect is bigger (width and/or height) the behaviour is undefined
  1.1903 +@param aAlphaPt Position of the first pixel in the alpha bitmap that should be used as a source
  1.1904 +                for the alpha blending. The size of the area is
  1.1905 +                the same as the aSrcRect parameter (read DISCLAIMER above).
  1.1906 +@pre !aSrcRect.IsEmpty()
  1.1907 +@pre aSrcBmp != NULL
  1.1908 +@pre aSrcBmp->Handle() != NULL
  1.1909 +@pre aAlphaBmp != NULL
  1.1910 +@pre aAlphaBmp->Handle() != NULL
  1.1911 +@pre aAlphaBmp->DisplayMode() <= EGray256
  1.1912 +@return KErrNone If the call is successfull, KErrArgument otherwise.
  1.1913 +*/
  1.1914 +EXPORT_C  TInt CFbsBitGc::AlphaBlendBitmaps(const TPoint& aDestPt,
  1.1915 +											const CFbsBitmap* aSrcBmp,
  1.1916 +											const TRect& aSrcRect,
  1.1917 +											const CFbsBitmap* aAlphaBmp,
  1.1918 +											const TPoint& aAlphaPt)
  1.1919 +	{
  1.1920 +	//Check the bitmap pointers and handles. Check the CFbsDevice instance -
  1.1921 +	//it shouldn't be NULL - that means - CFbsBitGc instance (this pointer)
  1.1922 +	//should be created either using CFbsDevice::CreateContext() or CFbsBitGc::Activate() -
  1.1923 +	//before the method was called.
  1.1924 +	if(!aSrcBmp || !aSrcBmp->Handle() ||
  1.1925 +	   !aAlphaBmp || !aAlphaBmp->Handle() || CheckDevice(aSrcRect))
  1.1926 +		{
  1.1927 +		return KErrArgument;
  1.1928 +		}
  1.1929 +		
  1.1930 +	aSrcBmp->BeginDataAccess();
  1.1931 +	aAlphaBmp->BeginDataAccess();
  1.1932 +		
  1.1933 +	//Check display mode of the alpha bitmap. Bitmaps which display mode is greater than
  1.1934 +	//EGray256 can't be used as alpha bitmaps.
  1.1935 +	if(aAlphaBmp->DisplayMode() > EGray256)
  1.1936 +		{
  1.1937 +		aSrcBmp->EndDataAccess(ETrue);
  1.1938 +		aAlphaBmp->EndDataAccess(ETrue);
  1.1939 +		return KErrArgument;
  1.1940 +		}
  1.1941 +	//Taking the actual part of the source rect contained in the Bitmap.
  1.1942 +	TRect srcRect(aSrcRect);
  1.1943 +	TRect area(aSrcBmp->SizeInPixels());
  1.1944 +	if(!srcRect.Intersects(area))
  1.1945 +		{
  1.1946 +		aSrcBmp->EndDataAccess(ETrue);
  1.1947 +		aAlphaBmp->EndDataAccess(ETrue);
  1.1948 +		return KErrArgument;
  1.1949 +		}
  1.1950 +	srcRect.Intersection(area);
  1.1951 +	//Calculate the destination rect
  1.1952 +	TPoint destPt(aDestPt + iOrigin);
  1.1953 +	TRect destRect(destPt, srcRect.Size());
  1.1954 +	TPoint offset(srcRect.iTl - destPt);
  1.1955 +	TRect clippedDestRect(destRect);
  1.1956 +	AddRect(clippedDestRect);
  1.1957 +	if(UserClipRect(clippedDestRect))
  1.1958 +		{
  1.1959 +		aSrcBmp->EndDataAccess(ETrue);
  1.1960 +		aAlphaBmp->EndDataAccess(ETrue);
  1.1961 +		return KErrArgument;
  1.1962 +		}
  1.1963 +	//Save current shadow mode
  1.1964 +	TInt8 shadowMode = iShadowMode;
  1.1965 +	iShadowMode = CFbsDrawDevice::ENoShadow;
  1.1966 +	//Setup the device and prevent the bitmaps from being cleaned away by client code.
  1.1967 +	//Drawing begins.
  1.1968 +	SetupDevice();
  1.1969 +	iDevice->DrawingBegin();
  1.1970 +	
  1.1971 +	CBitwiseBitmap* srcBmp = ((CFbsBitGcBitmap*)aSrcBmp)->Address();
  1.1972 +	CBitwiseBitmap* alphaBmp = ((CFbsBitGcBitmap*)aAlphaBmp)->Address();
  1.1973 +	BG_ASSERT_DEBUG(srcBmp, EBitgdiPanicInvalidBitmap);
  1.1974 +	BG_ASSERT_DEBUG(alphaBmp, EBitgdiPanicInvalidBitmap);
  1.1975 +	TUint32* srcDataAddr = aSrcBmp->DataAddress();
  1.1976 +	TUint32* alphaDataAddr = aAlphaBmp->DataAddress();
  1.1977 +
  1.1978 +	CFbsRasterizer* rasterizer = PrepareRasterizerForExtendedBitmap(*aSrcBmp, clippedDestRect, offset);
  1.1979 +	CFbsRasterizer* alphaRasterizer;
  1.1980 +	if (aAlphaPt.iX >= 0 && aAlphaPt.iY >= 0
  1.1981 +		&& aAlphaPt.iX + srcRect.Width() <= aAlphaBmp->SizeInPixels().iWidth
  1.1982 +		&& aAlphaPt.iY + srcRect.Height() <= aAlphaBmp->SizeInPixels().iHeight)
  1.1983 +		{
  1.1984 +		// Alpha blending bitmap is not tiled. Pass same region of interest as source bitmap to rasterizer.
  1.1985 +		alphaRasterizer = PrepareRasterizerForExtendedBitmap(*aAlphaBmp, clippedDestRect, aAlphaPt - destPt);
  1.1986 +		}
  1.1987 +	else
  1.1988 +		{
  1.1989 +		// Alpha blending bitmap is tiled. Do not pass any region of interest to rasterizer.
  1.1990 +		alphaRasterizer = PrepareRasterizerForExtendedBitmap(*aAlphaBmp);
  1.1991 +		}
  1.1992 +
  1.1993 +	//For each region - find the clipping rect and draw
  1.1994 +	TInt limit = iDefaultRegionPtr->Count();
  1.1995 +	CGraphicsAccelerator* ga = GraphicsAccelerator();
  1.1996 +	// Code for Graphics Accelerated Drawing
  1.1997 +	if(ga && (shadowMode == CFbsDrawDevice::ENoShadow))
  1.1998 +		{
  1.1999 +		TInt gaOperationResult = KErrUnknown;
  1.2000 +		TAcceleratedBitmapSpec srcBmpSpec(const_cast<CFbsBitmap*>(aSrcBmp));
  1.2001 +		TAcceleratedBitmapSpec alphaBmpSpec(const_cast<CFbsBitmap*>(aAlphaBmp));
  1.2002 +		iDevice->DrawingEnd();
  1.2003 +
  1.2004 +		for(TInt count=0;count<limit;count++)
  1.2005 +			{
  1.2006 +			iClipRect=(*iDefaultRegionPtr)[count];
  1.2007 +			if(!iClipRect.Intersects(clippedDestRect))
  1.2008 +				{
  1.2009 +				continue;
  1.2010 +				}
  1.2011 +			//clippedDestRect was constructed from destRect. destRect was constructed from srcRect.
  1.2012 +			iClipRect.Intersection(clippedDestRect);
  1.2013 +			TRect clippedSrcRect(iClipRect);
  1.2014 +			clippedSrcRect.Move(offset);//clippedSrcRect - maps to a part of srcRect now.
  1.2015 +			TPoint shift(clippedSrcRect.iTl - srcRect.iTl);
  1.2016 +			BG_ASSERT_DEBUG(shift.iX >= 0, EBitgdiPanicNegativeShift);
  1.2017 +			BG_ASSERT_DEBUG(shift.iY >= 0, EBitgdiPanicNegativeShift);
  1.2018 +
  1.2019 +			gaOperationResult = ga->Operation(TGopAlphaBlendOneBitmap(iClipRect.iTl,srcBmpSpec,clippedSrcRect,alphaBmpSpec,aAlphaPt + shift));
  1.2020 +			if(gaOperationResult != KErrNone)
  1.2021 +				break;
  1.2022 +			iDevice->iDrawDevice->UpdateRegion(iClipRect);
  1.2023 +			}
  1.2024 +		if(gaOperationResult == KErrNone)
  1.2025 +			goto finish;
  1.2026 +		iDevice->DrawingBegin();
  1.2027 +		}
  1.2028 +
  1.2029 +	// Code for non- Graphics Accelerated Drawing
  1.2030 +	for(TInt count=0;count<limit;count++)
  1.2031 +		{
  1.2032 +		iClipRect=(*iDefaultRegionPtr)[count];
  1.2033 +		if(!iClipRect.Intersects(clippedDestRect))
  1.2034 +			{
  1.2035 +			continue;
  1.2036 +			}
  1.2037 +		//clippedDestRect was constructed from destRect. destRect was constructed from srcRect.
  1.2038 +		iClipRect.Intersection(clippedDestRect);
  1.2039 +		TRect clippedSrcRect(iClipRect);
  1.2040 +		clippedSrcRect.Move(offset);//clippedSrcRect - maps to a part of srcRect now.
  1.2041 +		TPoint shift(clippedSrcRect.iTl - srcRect.iTl);
  1.2042 +		BG_ASSERT_DEBUG(shift.iX >= 0, EBitgdiPanicNegativeShift);
  1.2043 +		BG_ASSERT_DEBUG(shift.iY >= 0, EBitgdiPanicNegativeShift);
  1.2044 +		DoBitBltAlpha(iClipRect.iTl,
  1.2045 +					  srcBmp,
  1.2046 +					  srcDataAddr,
  1.2047 +					  clippedSrcRect,
  1.2048 +					  alphaBmp,
  1.2049 +					  alphaDataAddr,
  1.2050 +					  aAlphaPt + shift,
  1.2051 +					  shadowMode,
  1.2052 +					  EFalse);
  1.2053 +		iDevice->iDrawDevice->UpdateRegion(iClipRect);
  1.2054 +		}
  1.2055 +
  1.2056 +	// Drawing ends. Restore the previous shadow mode.
  1.2057 +	iDevice->DrawingEnd();
  1.2058 +finish:
  1.2059 +	if (rasterizer)
  1.2060 +		{
  1.2061 +		rasterizer->EndBitmap(aSrcBmp->SerialNumber());
  1.2062 +		}
  1.2063 +	if (alphaRasterizer)
  1.2064 +		{
  1.2065 +		alphaRasterizer->EndBitmap(aAlphaBmp->SerialNumber());
  1.2066 +		}
  1.2067 +	aSrcBmp->EndDataAccess(ETrue);
  1.2068 +	aAlphaBmp->EndDataAccess(ETrue);
  1.2069 +	iShadowMode = shadowMode;
  1.2070 +
  1.2071 +	return KErrNone;
  1.2072 +	}
  1.2073 +
  1.2074 +GLDEF_C void XorBuffers(TUint32* aDestBuffer,const TUint32* aSrceBuffer,TInt aNumBytes)
  1.2075 +	{
  1.2076 +	// Round up to nearest word boundary
  1.2077 +	const TUint32* const destBufferLimit = aDestBuffer + ((aNumBytes + sizeof(TUint32) - 1) / sizeof(TUint32));
  1.2078 +
  1.2079 +	while (aDestBuffer < destBufferLimit)
  1.2080 +		*aDestBuffer++ ^= *aSrceBuffer++;
  1.2081 +	}
  1.2082 +
  1.2083 +GLDEF_C void AndBuffers(TUint32* aDestBuffer,const TUint32* aSrceBuffer,TInt aNumBytes)
  1.2084 +	{
  1.2085 +	// Round up to nearest word boundary
  1.2086 +	const TUint32* const destBufferLimit = aDestBuffer + ((aNumBytes + sizeof(TUint32) - 1) / sizeof(TUint32));
  1.2087 +
  1.2088 +	while (aDestBuffer < destBufferLimit)
  1.2089 +		*aDestBuffer++ &= *aSrceBuffer++;
  1.2090 +	}
  1.2091 +
  1.2092 +GLDEF_C void InvertBuffer(TUint32* aDestBuffer,TInt aNumBytes)
  1.2093 +	{
  1.2094 +	// Round up to nearest word boundary
  1.2095 +	const TUint32* const destBufferLimit = aDestBuffer + ((aNumBytes + sizeof(TUint32) - 1) / sizeof(TUint32));
  1.2096 +
  1.2097 +	while (aDestBuffer < destBufferLimit)
  1.2098 +		{
  1.2099 +		*aDestBuffer = *aDestBuffer ^ KMaxTUint32;
  1.2100 +		++aDestBuffer;
  1.2101 +		}
  1.2102 +	}
  1.2103 +
  1.2104 +GLDEF_C void InvertBuffer(TUint8* aDestBuffer,TInt aNumBytes)
  1.2105 +	{
  1.2106 +	const TUint8* const destBufferLimit = aDestBuffer + aNumBytes;
  1.2107 +
  1.2108 +	while (aDestBuffer < destBufferLimit)
  1.2109 +		{
  1.2110 +		*aDestBuffer = static_cast<TUint8>(*aDestBuffer ^ KMaxTUint8);
  1.2111 +		++aDestBuffer;
  1.2112 +		}
  1.2113 +	}
  1.2114 +
  1.2115 +/**
  1.2116 +The method tiles the scan line if its length in pixels is less than
  1.2117 +aLengthInPixels argument.
  1.2118 +@internalComponent
  1.2119 +@param aScanLine A pointer to the scan line buffer.
  1.2120 +@param aLengthInPixels The scan line buffer should have that count of pixels after the method call.
  1.2121 +@param aSrcPt Position of the first pixel in aMaskBitmap that should be used as a source
  1.2122 +              for the pixels in scan line buffer.
  1.2123 +@param aMaskBitmap Any additional pixels for the scan line buffer will be taken from here.
  1.2124 +@param aScanLinePos This argument is used for some internal optimizations. It should not be
  1.2125 +                    modified by the caller.
  1.2126 +@param aMaskBase The base address of aMaskBitmap data.
  1.2127 +@param aDisplayMode Any additional pixels should be taken from aMaskBitmap using aDisplayMode
  1.2128 +                    as an argument for GetScanLine() call.
  1.2129 +*/
  1.2130 +LOCAL_C void TileScanLine(TPtr8& aScanLine,
  1.2131 +						  TInt aLengthInPixels,
  1.2132 +						  const TPoint& aSrcPt,
  1.2133 +						  const CBitwiseBitmap* aMaskBitmap,
  1.2134 +						  TLineScanningPosition& aScanLinePos,
  1.2135 +						  TUint32* aMaskBase,
  1.2136 +						  TDisplayMode aDisplayMode
  1.2137 +						  )
  1.2138 +	{
  1.2139 +	TInt lengthInBytes = CFbsBitmap::ScanLineLength(aLengthInPixels, aDisplayMode);
  1.2140 +	BG_ASSERT_DEBUG(lengthInBytes <= aScanLine.MaxLength(), EBitgdiPanicInvalidArg);
  1.2141 +	TInt scanLineLength = aScanLine.Length();
  1.2142 +	if(scanLineLength < lengthInBytes && aSrcPt.iX > 0)
  1.2143 +		{
  1.2144 +		//If, for example, src bmp is 100 pixels width, mask bmp is 20 pixels width and src
  1.2145 +		//rect is (10, 0, 100, 1) -> We will read only pixels 10..19 from the first scan line
  1.2146 +		//of the mask bmp. We have to have 90 mask bmp pixels.
  1.2147 +		//So we have to make a second mask bmp read startig from pixel 0 - 10 pixels length.
  1.2148 +		TInt maxLen = Min(aScanLine.MaxLength() - scanLineLength, aSrcPt.iX);
  1.2149 +		TPtr8 maskDes2(const_cast <TUint8*> (aScanLine.Ptr()) + scanLineLength, maxLen, maxLen);
  1.2150 +		TPoint srcPt(0, aSrcPt.iY);
  1.2151 +		TPoint zeroPt(0, 0);
  1.2152 +		aMaskBitmap->GetScanLine(maskDes2, srcPt, maxLen, EFalse, zeroPt, aDisplayMode, aMaskBase, aScanLinePos);
  1.2153 +		aScanLine.SetLength(scanLineLength + maskDes2.Length());
  1.2154 +		scanLineLength = aScanLine.Length();
  1.2155 +		}
  1.2156 +	if(scanLineLength >= lengthInBytes || scanLineLength == 0)
  1.2157 +		{
  1.2158 +		return;
  1.2159 +		}
  1.2160 +	//If we still don't have enough mask bmp pixels - we have to tile the scan line
  1.2161 +	TInt repeatCnt = lengthInBytes / scanLineLength - 1;
  1.2162 +	TInt bytesLeft = lengthInBytes % scanLineLength;
  1.2163 +	const TUint8* src = aScanLine.Ptr();
  1.2164 +	TUint8* dest = const_cast <TUint8*> (src) + scanLineLength;
  1.2165 +	for(;repeatCnt>0;dest+=scanLineLength,repeatCnt--)
  1.2166 +		{
  1.2167 +		Mem::Copy(dest, src, scanLineLength);
  1.2168 +		}
  1.2169 +	if(bytesLeft)
  1.2170 +		{
  1.2171 +		Mem::Copy(dest, src, bytesLeft);
  1.2172 +		}
  1.2173 +	aScanLine.SetLength(lengthInBytes);
  1.2174 +	}
  1.2175 +
  1.2176 +/**
  1.2177 +The method draws a masked rectangular section of the source
  1.2178 +bitmap and does a compress/stretch to fit a given destination
  1.2179 +rectangle.
  1.2180 +@internalComponent
  1.2181 +*/
  1.2182 +void CFbsBitGc::DoDrawBitmapMasked(const TRect& aDestRect,
  1.2183 +							   CBitwiseBitmap* aSourceBitmap,
  1.2184 +							   TUint32* aSourceBase,
  1.2185 +							   const TRect& aSourceRect,
  1.2186 +							   CBitwiseBitmap* aMaskBitmap,
  1.2187 +							   TUint32* aMaskBase,
  1.2188 +							   TBool aInvertMask, const TPoint& aDitherOrigin)
  1.2189 +	{
  1.2190 +	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
  1.2191 +#ifdef _DEBUG
  1.2192 +	TRect deviceDestRect;
  1.2193 +	drawDevice->GetDrawRect(deviceDestRect);
  1.2194 +	BG_ASSERT_DEBUG(iClipRect.iTl.iX >= deviceDestRect.iTl.iX, EBitgdiPanicOutOfBounds);
  1.2195 +	BG_ASSERT_DEBUG(iClipRect.iTl.iY >= deviceDestRect.iTl.iY, EBitgdiPanicOutOfBounds);
  1.2196 +	BG_ASSERT_DEBUG(iClipRect.iBr.iX <= deviceDestRect.iBr.iX, EBitgdiPanicOutOfBounds);
  1.2197 +	BG_ASSERT_DEBUG(iClipRect.iBr.iY <= deviceDestRect.iBr.iY, EBitgdiPanicOutOfBounds);
  1.2198 +#endif
  1.2199 +
  1.2200 +	// The clipped version of the destination rectangle
  1.2201 +	TRect clippedDestRect(aDestRect);
  1.2202 +	clippedDestRect.Intersection(iClipRect);
  1.2203 +
  1.2204 +	// If the source rectangle and the destination rectangle are same,
  1.2205 +	// no stretch/compress operation required, just do BitBltMasked
  1.2206 +	if (aDestRect.Size() == aSourceRect.Size())
  1.2207 +		{
  1.2208 +		if (!clippedDestRect.IsEmpty())
  1.2209 +			{
  1.2210 +			const TPoint destPoint(clippedDestRect.iTl);
  1.2211 +			clippedDestRect.Move(aSourceRect.iTl - aDestRect.iTl);
  1.2212 +			DoBitBltMasked(destPoint,
  1.2213 +						   aSourceBitmap,
  1.2214 +						   aSourceBase,
  1.2215 +						   clippedDestRect,
  1.2216 +						   aMaskBitmap,
  1.2217 +						   aMaskBase,
  1.2218 +						   aInvertMask,
  1.2219 +						   aDitherOrigin,
  1.2220 +						   CFbsDrawDevice::ENoShadow);
  1.2221 +			}
  1.2222 +		return;
  1.2223 +		}
  1.2224 +	MFastBlend* fastBlend=NULL;
  1.2225 +	if (FastBlendInterface(aSourceBitmap,aMaskBitmap,fastBlend)==KErrNone)
  1.2226 +		{
  1.2227 +		if (fastBlend->FastBlendBitmapMaskedScaled(iClipRect, aDestRect, aSourceRect, aSourceBase, aSourceBitmap->DataStride(),
  1.2228 +				aSourceBitmap->DisplayMode(),aSourceBitmap->SizeInPixels(), 
  1.2229 +				aMaskBase, aMaskBitmap->DataStride(), aMaskBitmap->DisplayMode(), aMaskBitmap->SizeInPixels(), aInvertMask, 
  1.2230 +				iDrawMode, iShadowMode)==KErrNone)
  1.2231 +			{
  1.2232 +			return;
  1.2233 +			}
  1.2234 +		}
  1.2235 +
  1.2236 +	TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
  1.2237 +	const TInt scanLineBytes = drawDevice->ScanLineBytes();
  1.2238 +	TPtr8 scanLineDes(REINTERPRET_CAST(TUint8*,scanLineBuffer),scanLineBytes,scanLineBytes);
  1.2239 +
  1.2240 +	// This constant is associated to the value used in TestGdi::DoDrawBitmapMaskedL, case #24.
  1.2241 +	// If this value is changed, then that one must be updated as well otherwise the test will no longer be valid.	
  1.2242 +	const TInt KScanLineLength = 256;
  1.2243 +	const TInt KRgbSize = 4;
  1.2244 +	TUint8 maskBuffer[KScanLineLength];
  1.2245 +
  1.2246 +	TUint8 sourceBuffer[KScanLineLength*KRgbSize];
  1.2247 +	TPtr8 sourceDes(sourceBuffer,KScanLineLength*KRgbSize,KScanLineLength*KRgbSize);
  1.2248 +
  1.2249 +	const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
  1.2250 +	TDrawMode drawMode = aInvertMask ? EDrawModeAND : EDrawModeANDNOT;
  1.2251 +	// If the source bitmap and the mask bitmap are same, draw the source bitmap either
  1.2252 +	// with EDrawModeAND or EDrawModeOR based on aInvertMask parameter.
  1.2253 +	if (aSourceBitmap == aMaskBitmap)
  1.2254 +		{
  1.2255 +		drawMode = aInvertMask ? EDrawModeAND : EDrawModeOR;
  1.2256 +		}
  1.2257 +
  1.2258 +	TLinearDDA xLine;
  1.2259 +	TInt bitmapXStart = 0;
  1.2260 +	xLine.Construct(TPoint(aSourceRect.iTl.iX,aDestRect.iTl.iX),
  1.2261 +					TPoint(aSourceRect.iBr.iX,aDestRect.iBr.iX),TLinearDDA::ELeft);
  1.2262 +	xLine.JumpToYCoord2(bitmapXStart,clippedDestRect.iTl.iX);
  1.2263 +
  1.2264 +	TLinearDDA yLine;
  1.2265 +	TPoint yCoord(aSourceRect.iTl.iY,aDestRect.iTl.iY);
  1.2266 +	yLine.Construct(yCoord,TPoint(aSourceRect.iBr.iY,aDestRect.iBr.iY),TLinearDDA::ELeft);
  1.2267 +	TInt dummy;
  1.2268 +	yLine.JumpToYCoord2(dummy,clippedDestRect.iTl.iY);
  1.2269 +	yCoord.SetXY(dummy,clippedDestRect.iTl.iY);
  1.2270 +
  1.2271 +	TPoint ditherOrigin(aDitherOrigin + clippedDestRect.iTl);
  1.2272 +	const TInt srceWidth = aSourceRect.Width();
  1.2273 +	const TInt destWidth = aDestRect.Width();
  1.2274 +	const TInt clipWidth = clippedDestRect.Width();
  1.2275 +	const TInt clipStrch = clippedDestRect.iTl.iX - aDestRect.iTl.iX;
  1.2276 +	const TInt sourceBmpWidth = aSourceBitmap->SizeInPixels().iWidth;
  1.2277 +	const TInt maskWidth = aMaskBitmap->SizeInPixels().iWidth;
  1.2278 +	const TInt maskHeight = aMaskBitmap->SizeInPixels().iHeight;
  1.2279 +
  1.2280 +	TLineScanningPosition lineScanPos(aSourceBase);
  1.2281 +	TLineScanningPosition lineScanPos2(aSourceBase);
  1.2282 +	TLineScanningPosition lineScanPosMask(aMaskBase);
  1.2283 +
  1.2284 +	HBufC8* alphaBuffer = NULL;
  1.2285 +	TPtr8 alphaBufferDes(NULL, 0);
  1.2286 +	const TDisplayMode maskDisplayMode = aMaskBitmap->DisplayMode();
  1.2287 +
  1.2288 +	// Mask inversion is not supported if the original source mask format is EGray256.
  1.2289 +	// Note that this is only used for pre-multiplied alpha targets.
  1.2290 +	TUint8 maskInverter = (aInvertMask && maskDisplayMode != EGray256) ? 0xFF : 0x00;
  1.2291 +
  1.2292 +	if (aSourceBitmap != aMaskBitmap)
  1.2293 +		{
  1.2294 +		// Get buffer to be used to convert non-EGray256 masks to EGray256 when display mode is EColor16MAP
  1.2295 +		// or to tile the mask when the mask width is smaller than the source bitmap width.
  1.2296 +		if (maskDisplayMode != EGray256 && (dispMode == EColor16MAP || maskWidth < sourceBmpWidth))
  1.2297 +			{
  1.2298 +			alphaBuffer = CFbsBitmap::GetExtraBuffer(CFbsBitmap::ScanLineLength(maskWidth, EGray256));
  1.2299 +			if (!alphaBuffer)
  1.2300 +				{
  1.2301 +				return;  // Out of memory so do not draw anything 
  1.2302 +				}
  1.2303 +			alphaBufferDes.Set(alphaBuffer->Des());
  1.2304 +			}
  1.2305 +
  1.2306 +		// Get buffer to be used for decompressing compressed masks when mask is EGray256
  1.2307 +		if (maskDisplayMode == EGray256 && aMaskBitmap->IsCompressed())
  1.2308 +			{
  1.2309 +			HBufC8* hBuf= CFbsBitmap::GetDecompressionBuffer(aMaskBitmap->DataStride());
  1.2310 +			if (!hBuf)
  1.2311 +				{
  1.2312 +				return;  // Out of memory so do not draw anything
  1.2313 +				}
  1.2314 +			lineScanPosMask.iScanLineBuffer = hBuf;
  1.2315 +			}
  1.2316 +		}
  1.2317 +
  1.2318 +	while (yCoord.iY < clippedDestRect.iBr.iY)
  1.2319 +		{
  1.2320 +		// Draw only the source bitmap, if the source bitmap and the mask bitmap are same.
  1.2321 +		// else draw both the bitmaps
  1.2322 +		if (aSourceBitmap == aMaskBitmap)
  1.2323 +			{
  1.2324 +			aSourceBitmap->StretchScanLine(scanLineDes,TPoint(bitmapXStart,yCoord.iX),
  1.2325 +								 clipStrch,clipWidth,destWidth,aSourceRect.iTl.iX,
  1.2326 +								 srceWidth,ditherOrigin,dispMode,aSourceBase,lineScanPos);
  1.2327 +			if (yCoord.iY==clippedDestRect.iTl.iY)
  1.2328 +				aSourceBitmap->SetCompressionBookmark(lineScanPos,aSourceBase,NULL);
  1.2329 +			drawDevice->WriteLine(clippedDestRect.iTl.iX,yCoord.iY,clipWidth,scanLineBuffer,drawMode);
  1.2330 +			}
  1.2331 +		else if ((maskDisplayMode == EGray256) || (dispMode == EColor16MAP))
  1.2332 +			{
  1.2333 +			// Stretch the source bitmap and the mask bitmap for KScanLineLength as stretch length
  1.2334 +			// then do alpha blending for this length. If the length is more then KScanLineLength
  1.2335 +			// repeat it till you stretch complete destination length.
  1.2336 +			const TPoint startPt(bitmapXStart,yCoord.iX);
  1.2337 +			TInt clipWidthPart = clippedDestRect.Width();
  1.2338 +			TBool loopLast = ETrue;
  1.2339 +			if(clipWidthPart > KScanLineLength)
  1.2340 +				{
  1.2341 +				clipWidthPart = KScanLineLength;
  1.2342 +				loopLast = EFalse;
  1.2343 +				}
  1.2344 +			TInt clipIncStrch = clippedDestRect.iTl.iX - aDestRect.iTl.iX;
  1.2345 +			TInt startClip=clippedDestRect.iTl.iX;
  1.2346 +			TPoint sourceDestXCoords(bitmapXStart,clippedDestRect.iTl.iX);
  1.2347 +			xLine.Construct(TPoint(aSourceRect.iTl.iX,aDestRect.iTl.iX),
  1.2348 +							TPoint(aSourceRect.iBr.iX,aDestRect.iBr.iX),TLinearDDA::ELeft);
  1.2349 +			xLine.JumpToYCoord2(sourceDestXCoords.iX,sourceDestXCoords.iY);
  1.2350 +			TPoint srcPixel(bitmapXStart % maskWidth,yCoord.iX % maskHeight);
  1.2351 +			TInt spaceLeft = 0;
  1.2352 +			TRgb maskRgbValue;
  1.2353 +			TUint32* maskScanLinePtr32 = NULL;
  1.2354 +			TPoint currentYValue(0,srcPixel.iY);
  1.2355 +			aMaskBitmap->GetScanLinePtr(maskScanLinePtr32, currentYValue, maskWidth, aMaskBase, lineScanPosMask);
  1.2356 +			// To implement non EGray256 mask support with EColor16MAP display mode, we convert
  1.2357 +			// the mask to EGray256.
  1.2358 +			if (maskDisplayMode != EGray256) // Convert scan-line to EGray256 and set maskScanLinePtr32 to the conversion.
  1.2359 +				{
  1.2360 +				aMaskBitmap->GetScanLine(maskScanLinePtr32, alphaBufferDes, currentYValue, maskWidth, EFalse, TPoint(0, 0), EGray256);
  1.2361 +				maskScanLinePtr32 = (TUint32*)alphaBuffer->Ptr();
  1.2362 +				}
  1.2363 +			TUint8* maskScanLinePtr = reinterpret_cast<TUint8*>(maskScanLinePtr32);
  1.2364 +
  1.2365 +			// Outer loop over all KScanLineLengths
  1.2366 +			FOREVER
  1.2367 +				{
  1.2368 +				aSourceBitmap->StretchScanLine(sourceDes,startPt,clipIncStrch,clipWidthPart,destWidth,
  1.2369 +								aSourceRect.iTl.iX,srceWidth,ditherOrigin,EColor16MU,aSourceBase,lineScanPos);
  1.2370 +				// Inner loop to tile the mask if necessary
  1.2371 +				spaceLeft = clipWidthPart;
  1.2372 +	
  1.2373 +				do	{
  1.2374 +					srcPixel.iX = sourceDestXCoords.iX % maskWidth;
  1.2375 +			
  1.2376 +					// Invert the mask using the inversion mask.
  1.2377 +					maskBuffer[(sourceDestXCoords.iY-clippedDestRect.iTl.iX)%KScanLineLength]=
  1.2378 +						maskInverter^maskScanLinePtr[srcPixel.iX];
  1.2379 +					xLine.NextStep(sourceDestXCoords);
  1.2380 +					} while (--spaceLeft>0);
  1.2381 +				
  1.2382 +				if (yCoord.iY == clippedDestRect.iTl.iY && startClip == clippedDestRect.iTl.iX)
  1.2383 +					{
  1.2384 +					aSourceBitmap->SetCompressionBookmark(lineScanPos,aSourceBase,NULL);
  1.2385 +					aMaskBitmap->SetCompressionBookmark(lineScanPosMask,aMaskBase,NULL);
  1.2386 +					}
  1.2387 +				drawDevice->WriteRgbAlphaLine(startClip,yCoord.iY,clipWidthPart,sourceBuffer,maskBuffer,iDrawMode);
  1.2388 +				if (loopLast)
  1.2389 +					{
  1.2390 +					break;
  1.2391 +					}
  1.2392 +				startClip+=KScanLineLength;
  1.2393 +				if (clippedDestRect.iBr.iX - startClip <= KScanLineLength)
  1.2394 + 					{
  1.2395 +					loopLast = ETrue;
  1.2396 +					clipWidthPart = clippedDestRect.iBr.iX - startClip;
  1.2397 +					}
  1.2398 +				clipIncStrch += KScanLineLength;
  1.2399 +				}
  1.2400 +			}
  1.2401 +		else
  1.2402 +			{
  1.2403 +			aSourceBitmap->StretchScanLine(scanLineDes,TPoint(bitmapXStart,yCoord.iX),
  1.2404 +									 clipStrch,clipWidth,destWidth,aSourceRect.iTl.iX,
  1.2405 +									 srceWidth,ditherOrigin,dispMode,aSourceBase,lineScanPos2);
  1.2406 +			drawDevice->WriteLine(clippedDestRect.iTl.iX,yCoord.iY,clipWidth,scanLineBuffer,EDrawModeXOR);
  1.2407 +
  1.2408 +			TInt maskXStart = bitmapXStart % maskWidth;
  1.2409 +			if(maskWidth < sourceBmpWidth)
  1.2410 +				{
  1.2411 +				TPoint sourceDestXCoords(bitmapXStart,clippedDestRect.iTl.iX);
  1.2412 +				xLine.Construct(TPoint(aSourceRect.iTl.iX,aDestRect.iTl.iX),
  1.2413 +								TPoint(aSourceRect.iBr.iX,aDestRect.iBr.iX),TLinearDDA::ELeft);
  1.2414 +				xLine.JumpToYCoord2(sourceDestXCoords.iX,sourceDestXCoords.iY);
  1.2415 +				TPoint srcPixel(maskXStart,yCoord.iX % maskHeight);
  1.2416 +				TInt spaceLeft = clipWidth;
  1.2417 +				TPoint prevSourceDestXCoords(-1,-1);
  1.2418 +				TRgb maskRgbValue;
  1.2419 +				aMaskBitmap->GetScanLine(alphaBufferDes, TPoint(0,srcPixel.iY), maskWidth, EFalse, TPoint(0, 0), EGray256, aMaskBase, lineScanPosMask);
  1.2420 +
  1.2421 +				// Loop to tile the mask
  1.2422 +				do	{
  1.2423 +					if (sourceDestXCoords.iY != prevSourceDestXCoords.iY)
  1.2424 +						{
  1.2425 +						if (sourceDestXCoords.iX != prevSourceDestXCoords.iX)
  1.2426 +							{
  1.2427 +							srcPixel.iX = sourceDestXCoords.iX % maskWidth;
  1.2428 +							if (srcPixel.iX < 0)
  1.2429 +								srcPixel.iX += maskWidth;
  1.2430 +							maskRgbValue = TRgb::Gray256((*alphaBuffer)[srcPixel.iX]);
  1.2431 +							}
  1.2432 +						drawDevice->WriteRgb(sourceDestXCoords.iY,yCoord.iY,maskRgbValue,drawMode);
  1.2433 +						spaceLeft--;
  1.2434 +						}
  1.2435 +					prevSourceDestXCoords = sourceDestXCoords;
  1.2436 +					xLine.SingleStep(sourceDestXCoords);
  1.2437 +					} while (spaceLeft > 0);
  1.2438 +				}
  1.2439 +			else
  1.2440 +				{
  1.2441 +				// No need to tile the mask
  1.2442 +				aMaskBitmap->StretchScanLine(scanLineDes,TPoint(maskXStart,yCoord.iX % maskHeight),
  1.2443 +										clipStrch,clipWidth,destWidth,aSourceRect.iTl.iX,
  1.2444 +										srceWidth,ditherOrigin,dispMode,aMaskBase,lineScanPosMask);
  1.2445 +				drawDevice->WriteLine(clippedDestRect.iTl.iX,yCoord.iY,clipWidth,scanLineBuffer,drawMode);
  1.2446 +				// Redo stretching of the aSourceBitmap scanline
  1.2447 +				aSourceBitmap->StretchScanLine(scanLineDes,TPoint(bitmapXStart,yCoord.iX),
  1.2448 +									 	clipStrch,clipWidth,destWidth,aSourceRect.iTl.iX,
  1.2449 +									 	srceWidth,ditherOrigin,dispMode,aSourceBase,lineScanPos2);
  1.2450 +				}
  1.2451 +
  1.2452 +			if (yCoord.iY==clippedDestRect.iTl.iY)
  1.2453 +				{
  1.2454 +				aSourceBitmap->SetCompressionBookmark(lineScanPos2,aSourceBase,NULL);
  1.2455 +				aMaskBitmap->SetCompressionBookmark(lineScanPosMask,aMaskBase,NULL);
  1.2456 +				}
  1.2457 +
  1.2458 +			drawDevice->WriteLine(clippedDestRect.iTl.iX,yCoord.iY,clipWidth,scanLineBuffer,EDrawModeXOR);
  1.2459 +			}
  1.2460 +		yLine.NextStep(yCoord);
  1.2461 +		ditherOrigin.iY++;
  1.2462 +		}
  1.2463 +	}
  1.2464 +
  1.2465 +EXPORT_C TInt CFbsBitGc::AlphaBlendBitmaps(const TPoint& aDestPt,
  1.2466 +											const CWsBitmap* aSrcBmp,
  1.2467 +											const TRect& aSrcRect,
  1.2468 +											const CWsBitmap* aAlphaBmp,
  1.2469 +											const TPoint& aAlphaPt)
  1.2470 +	{
  1.2471 +	return AlphaBlendBitmaps(aDestPt, REINTERPRET_CAST(const CFbsBitmap*, aSrcBmp), aSrcRect, REINTERPRET_CAST(const CFbsBitmap*, aAlphaBmp), aAlphaPt);
  1.2472 +	}
  1.2473 +
  1.2474 +TInt CFbsBitGc::FastBlendInterface(const CBitwiseBitmap* aSource, const CBitwiseBitmap* aMask, MFastBlend*& aFastBlend) const
  1.2475 +	{
  1.2476 +#if defined(__ALLOW_FAST_BLEND_DISABLE__)
  1.2477 +	if (iFastBlendDisabled)
  1.2478 +		return(KErrNotSupported);
  1.2479 +#endif
  1.2480 +	if ((aSource && aSource->IsCompressed()) || (aMask && aMask->IsCompressed()))
  1.2481 +		return(KErrNotSupported);
  1.2482 +	TAny* interface=NULL;
  1.2483 +	TInt ret=iDevice->iDrawDevice->GetInterface(KFastBlendInterfaceID, interface);
  1.2484 +	aFastBlend=(MFastBlend*)interface;
  1.2485 +	return(ret);
  1.2486 +	}
  1.2487 +
  1.2488 +/*
  1.2489 +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.
  1.2490 +
  1.2491 +@see CBitwiseBitmap::GetScanLine()
  1.2492 +@see CBitwiseBitmap::GetVerticalScanLine()
  1.2493 +@see CBitwiseBitmap::StretchScanLine()
  1.2494 +@see CFbsDrawDevice::WriteLine()
  1.2495 +@internalComponent
  1.2496 +*/
  1.2497 +TDisplayMode CFbsBitGc::ScanLineBufferDisplayMode(CFbsDrawDevice* aDrawDevice)
  1.2498 +	{
  1.2499 +	return iDrawMode == EDrawModeWriteAlpha ? aDrawDevice->DisplayMode() : aDrawDevice->ScanLineDisplayMode();
  1.2500 +	}
  1.2501 +
  1.2502 +/** Prepares the rasterizer to retrieve scan lines from a bitmap if it is an
  1.2503 +extended bitmap. No region of interest is passed to the rasterizer.
  1.2504 +This function calls CFbsRasterizer::BeginBitmap() with the appropriate
  1.2505 +parameters. When finished retrieving scan lines from the extended bitmap,
  1.2506 +CFbsRasterizer::EndBitmap() must be called.
  1.2507 +@param aBitmap The bitmap to retrieve scan lines from.
  1.2508 +@return A pointer to the rasterizer owned by this thread's FBServ session.
  1.2509 +@return NULL if the rasterizer is not present or aBitmap is not an extended bitmap.
  1.2510 +@see CFbsRasterizer
  1.2511 +@internalComponent
  1.2512 +*/
  1.2513 +CFbsRasterizer* CFbsBitGc::PrepareRasterizerForExtendedBitmap(const CFbsBitmap& aBitmap)
  1.2514 +	{
  1.2515 +	CFbsRasterizer* rasterizer = NULL;
  1.2516 +	CFbsRasterizer::TBitmapDesc desc;
  1.2517 +	desc.iDataType = aBitmap.ExtendedBitmapType();
  1.2518 +	if (desc.iDataType != KNullUid)
  1.2519 +		{
  1.2520 +		rasterizer = CFbsBitmap::Rasterizer();
  1.2521 +		if (rasterizer)
  1.2522 +			{
  1.2523 +			desc.iSizeInPixels = aBitmap.SizeInPixels();
  1.2524 +			desc.iDispMode = aBitmap.DisplayMode();
  1.2525 +			desc.iData = aBitmap.DataAddress();
  1.2526 +			desc.iDataSize = aBitmap.DataSize();
  1.2527 +			rasterizer->BeginBitmap(aBitmap.SerialNumber(), desc, NULL);
  1.2528 +			}
  1.2529 +		}
  1.2530 +	return rasterizer;
  1.2531 +	}
  1.2532 +
  1.2533 +/** Prepares the rasterizer to retrieve scan lines from a bitmap if it is an
  1.2534 +extended bitmap. The region of interest passed to the rasterizer is the
  1.2535 +intersection of the clipping region and the specified rectangle.
  1.2536 +This function calls CFbsRasterizer::BeginBitmap() with the appropriate
  1.2537 +parameters. When finished retrieving scan lines from the extended bitmap,
  1.2538 +CFbsRasterizer::EndBitmap() must be called.
  1.2539 +@param aBitmap The bitmap to retrieve scan lines from.
  1.2540 +@param aDestRect A rectangle in coordinates relative to the graphics context that
  1.2541 +                 bounds the area that aBitmap is to be blitted onto.
  1.2542 +@param aOffset An offset that converts aDestRect into coordinates relative to
  1.2543 +               the source bitmap.
  1.2544 +@return A pointer to the rasterizer owned by this thread's FBServ session.
  1.2545 +@return NULL if the rasterizer is not present or aBitmap is not an extended bitmap.
  1.2546 +@see CFbsRasterizer
  1.2547 +@internalComponent
  1.2548 +*/
  1.2549 +CFbsRasterizer* CFbsBitGc::PrepareRasterizerForExtendedBitmap(const CFbsBitmap& aBitmap, const TRect& aDestRect, const TPoint& aOffset)
  1.2550 +	{
  1.2551 +	CFbsRasterizer* rasterizer = NULL;
  1.2552 +	CFbsRasterizer::TBitmapDesc desc;
  1.2553 +	desc.iDataType = aBitmap.ExtendedBitmapType();
  1.2554 +	if (desc.iDataType != KNullUid)
  1.2555 +		{
  1.2556 +		rasterizer = CFbsBitmap::Rasterizer();
  1.2557 +		if (rasterizer)
  1.2558 +			{
  1.2559 +			desc.iSizeInPixels = aBitmap.SizeInPixels();
  1.2560 +			desc.iDispMode = aBitmap.DisplayMode();
  1.2561 +			desc.iData = aBitmap.DataAddress();
  1.2562 +			desc.iDataSize = aBitmap.DataSize();
  1.2563 +			RRegion rgn;
  1.2564 +			rgn.Copy(*iDefaultRegionPtr);
  1.2565 +			rgn.ClipRect(aDestRect);
  1.2566 +			rgn.Offset(aOffset);
  1.2567 +			BG_ASSERT_DEBUG(rgn.IsContainedBy(desc.iSizeInPixels), EBitgdiPanicOutOfBounds);
  1.2568 +			rasterizer->BeginBitmap(aBitmap.SerialNumber(), desc, &rgn);
  1.2569 +			rgn.Close();
  1.2570 +			}
  1.2571 +		}
  1.2572 +	return rasterizer;
  1.2573 +	}
  1.2574 +
  1.2575 +/** Prepares the rasterizer to retrieve scan lines from a bitmap if it is an
  1.2576 +extended bitmap. The region of interest passed to the rasterizer is the intersection
  1.2577 +of the clipping region, the clipping rectangle and the specified rectangle.
  1.2578 +This function calls CFbsRasterizer::BeginBitmap() with the appropriate
  1.2579 +parameters. When finished retrieving scan lines from the extended bitmap,
  1.2580 +CFbsRasterizer::EndBitmap() must be called.
  1.2581 +@param aBitmap The bitmap to retrieve scan lines from.
  1.2582 +@param aDestRect A rectangle in coordinates relative to the graphics context that
  1.2583 +                 bounds the area that aBitmap is to be drawn onto.
  1.2584 +@param aSourceRect A rectangle in coordinates relative to the source bitmap that maps
  1.2585 +                   to aDestRect after scaling and translation.
  1.2586 +@return A pointer to the rasterizer owned by this thread's FBServ session.
  1.2587 +@return NULL if the rasterizer is not present or aBitmap is not an extended bitmap.
  1.2588 +@see CFbsRasterizer
  1.2589 +@internalComponent
  1.2590 +*/
  1.2591 +CFbsRasterizer* CFbsBitGc::PrepareRasterizerForExtendedBitmap(const CFbsBitmap& aBitmap, const TRect& aDestRect, const TRect& aSourceRect)
  1.2592 +	{
  1.2593 +	CFbsRasterizer* rasterizer = NULL;
  1.2594 +	CFbsRasterizer::TBitmapDesc desc;
  1.2595 +	desc.iDataType = aBitmap.ExtendedBitmapType();
  1.2596 +	if (desc.iDataType != KNullUid)
  1.2597 +		{
  1.2598 +		rasterizer = CFbsBitmap::Rasterizer();
  1.2599 +		if (rasterizer)
  1.2600 +			{
  1.2601 +			desc.iSizeInPixels = aBitmap.SizeInPixels();
  1.2602 +			desc.iDispMode = aBitmap.DisplayMode();
  1.2603 +			desc.iData = aBitmap.DataAddress();
  1.2604 +			desc.iDataSize = aBitmap.DataSize();
  1.2605 +			RRegion rgn;
  1.2606 +			// Calculate the parameters for the linear DDA algorithm used to scale the region
  1.2607 +			// of interest before entering the rectangle loop, since they are invariant.
  1.2608 +			TLinearDDA xLine0, yLine0;
  1.2609 +			xLine0.Construct(TPoint(aSourceRect.iTl.iX, aDestRect.iTl.iX),
  1.2610 +			                 TPoint(aSourceRect.iBr.iX, aDestRect.iBr.iX),
  1.2611 +			                 TLinearDDA::ELeft);
  1.2612 +			yLine0.Construct(TPoint(aSourceRect.iTl.iY, aDestRect.iTl.iY),
  1.2613 +			                 TPoint(aSourceRect.iBr.iY, aDestRect.iBr.iY),
  1.2614 +			                 TLinearDDA::ELeft);
  1.2615 +			TInt n = iDefaultRegionPtr->Count();
  1.2616 +			for (TInt i = 0; i < n; ++i)
  1.2617 +				{
  1.2618 +				TRect rect = (*iDefaultRegionPtr)[i];
  1.2619 +				if (!rect.Intersects(iUserClipRect))
  1.2620 +					{
  1.2621 +					continue;
  1.2622 +					}
  1.2623 +				rect.Intersection(iUserClipRect);
  1.2624 +				if (!rect.Intersects(aDestRect))
  1.2625 +					{
  1.2626 +					continue;
  1.2627 +					}
  1.2628 +				rect.Intersection(aDestRect);
  1.2629 +				// Scale the region of interest from coordinates relative to the graphics
  1.2630 +				// context to coordinates relative to the bitmap, one rectangle at a time.
  1.2631 +				TLinearDDA xLine(xLine0), yLine(yLine0);
  1.2632 +				TInt ax, ay, bx, by;
  1.2633 +				xLine.JumpToYCoord(ax, rect.iTl.iX);
  1.2634 +				yLine.JumpToYCoord(ay, rect.iTl.iY);
  1.2635 +				xLine.JumpToYCoord(bx, rect.iBr.iX);
  1.2636 +				yLine.JumpToYCoord(by, rect.iBr.iY);
  1.2637 +				if (ax < bx && ay < by)
  1.2638 +					{
  1.2639 +					rgn.AddRect(TRect(ax, ay, bx, by));
  1.2640 +					}
  1.2641 +				}
  1.2642 +			BG_ASSERT_DEBUG(rgn.IsContainedBy(desc.iSizeInPixels), EBitgdiPanicOutOfBounds);
  1.2643 +			rasterizer->BeginBitmap(aBitmap.SerialNumber(), desc, &rgn);
  1.2644 +			rgn.Close();
  1.2645 +			}
  1.2646 +		}
  1.2647 +	return rasterizer;
  1.2648 +	}