os/graphics/graphicsdeviceinterface/directgdiadaptation/swsrc/swdirectgdibitblt.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/graphics/graphicsdeviceinterface/directgdiadaptation/swsrc/swdirectgdibitblt.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,1358 @@
     1.4 +// Copyright (c) 2007-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 "swdirectgdiengine.h"
    1.20 +#include "swdirectgdidriverimpl.h"
    1.21 +#include "directgdiadapter.h"
    1.22 +#include <bitdrawinterfaceid.h>
    1.23 +#include <bmalphablend.h>
    1.24 +#include <graphics/bitmap.inl>
    1.25 +#include <graphics/gdi/gdiinline.inl>
    1.26 +
    1.27 +/** 
    1.28 +@see MDirectGdiEngine::BitBlt()
    1.29 +@panic DGDIAdapter 7, aBitmap is invalid (debug only). 
    1.30 +*/
    1.31 +void CSwDirectGdiEngine::BitBlt(const TPoint& aDestPos, 
    1.32 +								const CFbsBitmap& aBitmap,	
    1.33 +								const TRect& aSrceRect)
    1.34 +	{
    1.35 +	if (aBitmap.ExtendedBitmapType() != KNullUid)
    1.36 +		{
    1.37 +		iDriver->SetError(KErrNotSupported); // Not supported for extended bitmaps
    1.38 +		return;
    1.39 +		}
    1.40 +	
    1.41 +	TRect srceRect(aSrceRect);
    1.42 +	const TPoint destPoint(aDestPos + iOrigin + srceRect.iTl - aSrceRect.iTl);
    1.43 +	const TPoint offset(srceRect.iTl - destPoint);
    1.44 +
    1.45 +	TRect targetRect(destPoint,srceRect.Size());
    1.46 +	aBitmap.BeginDataAccess();
    1.47 +
    1.48 +	CBitwiseBitmap* srce = static_cast<const CSwDirectGdiBitmap&>(aBitmap).Address();
    1.49 +	GRAPHICS_ASSERT_DEBUG(srce,EDirectGdiPanicInvalidBitmap);
    1.50 +	
    1.51 +	const TInt limit = iDefaultRegionPtr->Count();		
    1.52 +			
    1.53 +	TBool opaqueSource = (!IsAlphaChannel(aBitmap.DisplayMode())) && (iDrawMode == DirectGdi::EDrawModePEN);	
    1.54 +
    1.55 +	TRect clipRect;
    1.56 +	for (TInt count = 0; count < limit; count++)
    1.57 +		{
    1.58 +		clipRect = (*iDefaultRegionPtr)[count];
    1.59 +		if(!clipRect.Intersects(targetRect))
    1.60 +			{
    1.61 +			continue;
    1.62 +			}
    1.63 +		
    1.64 +		clipRect.Intersection(targetRect);
    1.65 +		
    1.66 +		TRect clippedSrceRect(clipRect);
    1.67 +		clippedSrceRect.Move(offset);
    1.68 +
    1.69 +		if (opaqueSource)
    1.70 +			{
    1.71 +			iDrawMode = DirectGdi::EDrawModeWriteAlpha; // write rather than blend.
    1.72 +			}		
    1.73 +		
    1.74 +		DoBitBlt(clipRect.iTl, srce, aBitmap.DataAddress(), aBitmap.DataStride(), clippedSrceRect);
    1.75 +		
    1.76 +		if (opaqueSource)
    1.77 +			{
    1.78 +			iDrawMode = DirectGdi::EDrawModePEN; // set it back to how it was.
    1.79 +			}
    1.80 +		
    1.81 +		iDrawDevice->UpdateRegion(clipRect);
    1.82 +		}
    1.83 +	
    1.84 +	aBitmap.EndDataAccess(ETrue);	
    1.85 +	}
    1.86 +
    1.87 +/**
    1.88 +@see MDirectGdiEngine::BitBltMasked(const TPoint&, const CFbsBitmap&, const TRect&, const CFbsBitmap&, TBool)
    1.89 +@panic DGDIAdapter 7, if either aMaskBitmap or aBitmap are invalid (debug only).
    1.90 +*/
    1.91 +void CSwDirectGdiEngine::BitBltMasked(const TPoint& aDestPos,
    1.92 +			  const CFbsBitmap& aBitmap,
    1.93 +			  const TRect& aSrcRect,
    1.94 +			  const CFbsBitmap& aMaskBitmap,
    1.95 +			  TBool aInvertMask)
    1.96 +	{
    1.97 +	if ((aBitmap.ExtendedBitmapType() != KNullUid) || (aMaskBitmap.ExtendedBitmapType() != KNullUid))
    1.98 +		{
    1.99 +		iDriver->SetError(KErrNotSupported); // Not supported for extended bitmaps
   1.100 +		return;
   1.101 +		}
   1.102 +	
   1.103 +	TRect localSrcRect(aSrcRect);
   1.104 +	const TPoint destPoint(aDestPos + iOrigin + localSrcRect.iTl - aSrcRect.iTl);
   1.105 +	const TRect destRect(destPoint, localSrcRect.Size());
   1.106 +	const TPoint offset(localSrcRect.iTl - destPoint);
   1.107 +	
   1.108 +	TRect targetRect(destRect);
   1.109 +	aBitmap.BeginDataAccess();
   1.110 +	aMaskBitmap.BeginDataAccess();
   1.111 +	
   1.112 +	CBitwiseBitmap* srcebmp = static_cast<const CSwDirectGdiBitmap&>(aBitmap).Address();
   1.113 +	CBitwiseBitmap* maskbmp = static_cast<const CSwDirectGdiBitmap&>(aMaskBitmap).Address();		
   1.114 +	
   1.115 +	GRAPHICS_ASSERT_DEBUG(srcebmp,EDirectGdiPanicInvalidBitmap);
   1.116 +	GRAPHICS_ASSERT_DEBUG(maskbmp,EDirectGdiPanicInvalidBitmap);
   1.117 +	
   1.118 +	const TDisplayMode maskMode = maskbmp->DisplayMode();
   1.119 +	const TInt limit = iDefaultRegionPtr->Count();
   1.120 +	TBool opaqueSource = (!IsAlphaChannel(aBitmap.DisplayMode())) && (iDrawMode == DirectGdi::EDrawModePEN);
   1.121 +	TRect clipRect;
   1.122 +	for (TInt count = 0; count < limit; count++)
   1.123 +		{
   1.124 +		clipRect = (*iDefaultRegionPtr)[count];
   1.125 +		if (!clipRect.Intersects(targetRect))
   1.126 +			{
   1.127 +			continue;
   1.128 +			}
   1.129 +		
   1.130 +		clipRect.Intersection(targetRect);
   1.131 +		TRect clippedSrceRect(clipRect);
   1.132 +		clippedSrceRect.Move(offset);
   1.133 +		
   1.134 +		if (opaqueSource)
   1.135 +			{
   1.136 +			iDrawMode = DirectGdi::EDrawModeWriteAlpha; // ie write rather than blend
   1.137 +			}
   1.138 +		
   1.139 +		DoBitBltMasked(clipRect.iTl, srcebmp, aBitmap.DataAddress(), clippedSrceRect, maskbmp, 
   1.140 +				aMaskBitmap.DataAddress(), aInvertMask);
   1.141 +		
   1.142 +		if (opaqueSource)
   1.143 +			{
   1.144 +			iDrawMode = DirectGdi::EDrawModePEN; // set to default
   1.145 +			}
   1.146 +		iDrawDevice->UpdateRegion(clipRect);
   1.147 +		}
   1.148 +	
   1.149 +	aBitmap.EndDataAccess(ETrue);
   1.150 +	aMaskBitmap.EndDataAccess(ETrue);	
   1.151 +	}
   1.152 +
   1.153 +
   1.154 +/**
   1.155 +@see MDirectGdiEngine::BitBltMasked(const TPoint&, const CFbsBitmap&, const TRect&, const CFbsBitmap&, const TPoint&)
   1.156 +@panic DGDIAdapter 7, if either aBitmap or aMaskBitmap are invalid.
   1.157 +@panic DGDIAdapter 1022, if the top-left corner of aSrcRect is out of bounds (debug only).
   1.158 +*/
   1.159 +void CSwDirectGdiEngine::BitBltMasked(const TPoint& aDestPt,
   1.160 +		const CFbsBitmap& aBitmap, const TRect& aSrcRect,
   1.161 +		const CFbsBitmap& aMaskBitmap, const TPoint& aAlphaPt)
   1.162 +	{
   1.163 +	if ((aBitmap.ExtendedBitmapType() != KNullUid) || (aMaskBitmap.ExtendedBitmapType() != KNullUid))
   1.164 +		{
   1.165 +		iDriver->SetError(KErrNotSupported); // Not supported for extended bitmaps
   1.166 +		return;
   1.167 +		}
   1.168 +	
   1.169 +	TRect srcRect(aSrcRect);
   1.170 +	//Calculate the destination rect
   1.171 +	TPoint destPt(aDestPt + iOrigin);
   1.172 +	TRect destRect(destPt, srcRect.Size());
   1.173 +	TPoint offset(srcRect.iTl - destPt);
   1.174 +	TRect targetRect(destRect);
   1.175 +
   1.176 +	aBitmap.BeginDataAccess();
   1.177 +	aMaskBitmap.BeginDataAccess();
   1.178 +	CBitwiseBitmap* srcBmp = static_cast<const CSwDirectGdiBitmap&>(aBitmap).Address();
   1.179 +	CBitwiseBitmap* alphaBmp = static_cast<const CSwDirectGdiBitmap&>(aMaskBitmap).Address();
   1.180 +	GRAPHICS_ASSERT_DEBUG(srcBmp, EDirectGdiPanicInvalidBitmap);
   1.181 +	GRAPHICS_ASSERT_DEBUG(alphaBmp, EDirectGdiPanicInvalidBitmap);
   1.182 +	TUint32* srcDataAddr = aBitmap.DataAddress();
   1.183 +	TUint32* alphaDataAddr = aMaskBitmap.DataAddress();
   1.184 +
   1.185 +	//For each region - find the clipping rect and draw
   1.186 +	TInt limit = iDefaultRegionPtr->Count ();
   1.187 +	TRect clipRect;
   1.188 +	for (TInt count=0; count<limit;count++)
   1.189 +		{
   1.190 +		clipRect=(*iDefaultRegionPtr)[count];
   1.191 +		if ( !clipRect.Intersects(targetRect))
   1.192 +			{
   1.193 +			continue;
   1.194 +			}
   1.195 +		//targetRect was constructed from destRect. destRect was constructed from srcRect.
   1.196 +		clipRect.Intersection (targetRect);
   1.197 +		TRect clippedSrcRect(clipRect);
   1.198 +		clippedSrcRect.Move(offset);//clippedSrcRect - maps to a part of srcRect now.
   1.199 +		TPoint shift(clippedSrcRect.iTl - srcRect.iTl);
   1.200 +		GRAPHICS_ASSERT_DEBUG(shift.iX >= 0, EDirectGdiPanicNegativeShift);
   1.201 +		GRAPHICS_ASSERT_DEBUG(shift.iY >= 0, EDirectGdiPanicNegativeShift);
   1.202 +		DoBitBltAlpha (clipRect.iTl, srcBmp, srcDataAddr, clippedSrcRect,
   1.203 +				alphaBmp, alphaDataAddr, aAlphaPt + shift, EFalse);
   1.204 +		iDrawDevice->UpdateRegion (clipRect);
   1.205 +		}
   1.206 +
   1.207 +	aBitmap.EndDataAccess(ETrue);
   1.208 +	aMaskBitmap.EndDataAccess(ETrue);
   1.209 +	return;
   1.210 +	}			
   1.211 +
   1.212 +/** 
   1.213 +Calculates the position into the scanline for the given x coordinate.
   1.214 +
   1.215 +@param aX The given x-coordinate.
   1.216 +@param aDisplayMode The applied display mode.
   1.217 +@return The memory offset, or 0 if the mode is not supported.
   1.218 +@panic DGDIAdapter 1009, if aDisplayMode is not supported (debug only).
   1.219 +*/
   1.220 +TUint CSwDirectGdiEngine::MemoryOffsetForPixelPitch(TUint aX, TDisplayMode aDisplayMode) const
   1.221 +	{	
   1.222 +	switch (aDisplayMode)
   1.223 +		{
   1.224 +		case EColor16MU:
   1.225 +		case EColor16MAP:
   1.226 +			return aX << 2;
   1.227 +		case EColor64K:
   1.228 +			return aX << 1;
   1.229 +		default:
   1.230 +			GRAPHICS_PANIC_DEBUG(EDirectGdiPanicInvalidDisplayMode);
   1.231 +		}
   1.232 +	return 0;
   1.233 +	}
   1.234 +
   1.235 +TUint32* CSwDirectGdiEngine::GetScanLineOffsetPtr(CBitwiseBitmap* aSrce, TUint32*& aSlptr, 
   1.236 +		TInt aLength, TPoint aPixel, TUint32* aBase, 
   1.237 +		TLineScanningPosition& aLineScanningPosition, TUint aXOffset)
   1.238 +	{
   1.239 +	aSrce->GetScanLinePtr(aSlptr, aLength, aPixel, aBase, aLineScanningPosition);
   1.240 +	return (TUint32*)((TUint8*)aSlptr + aXOffset);
   1.241 +	}
   1.242 +
   1.243 +/**
   1.244 +Performs the actual bitblt to the device.
   1.245 +This function may also be called by DrawBitmap(), and DrawRect() when using a patterned brush, 
   1.246 +so any changes to this function may impact on them also.
   1.247 +
   1.248 +@pre aSrce A bitmap with non-zero dimensions. aSrceRect has been clipped against the target.
   1.249 +
   1.250 +@param aDest The target position on the device which will contain the top left 
   1.251 +             corner of the source bitmap.
   1.252 +@param aSrce The bitmap object that contains the pixels to draw.
   1.253 +@param aBase The address of the bitmap pixels.
   1.254 +@param aStride The length in bytes between scanlines in memory.
   1.255 +@param aSrceRect The area of the bitmap to draw from.
   1.256 +@panic DGDIAdapter 1013, if aDest is fully outside of the bounds of the target, or aSrceRect.iTl is not
   1.257 +       within the drawing area (debug only).
   1.258 +*/
   1.259 +void CSwDirectGdiEngine::DoBitBlt(const TPoint& aDest,
   1.260 +		 CBitwiseBitmap* aSrce,
   1.261 +		 TUint32* aBase,
   1.262 +		 TInt aStride,
   1.263 +		 const TRect& aSrceRect)
   1.264 +	{
   1.265 +	// Does multiple bitmap widths for painting rects only
   1.266 +	const TInt width = aSrceRect.Width ();
   1.267 +
   1.268 +#ifdef _DEBUG
   1.269 +	TRect deviceDestRect;
   1.270 +	iDrawDevice->GetDrawRect(deviceDestRect);
   1.271 +	GRAPHICS_ASSERT_DEBUG(aDest.iX >= deviceDestRect.iTl.iX, EDirectGdiPanicOutOfBounds);
   1.272 +	GRAPHICS_ASSERT_DEBUG(aDest.iY >= deviceDestRect.iTl.iY, EDirectGdiPanicOutOfBounds);
   1.273 +	GRAPHICS_ASSERT_DEBUG((aDest.iX + aSrceRect.Width()) <= deviceDestRect.iBr.iX, EDirectGdiPanicOutOfBounds);
   1.274 +	GRAPHICS_ASSERT_DEBUG((aDest.iY + aSrceRect.Height()) <= deviceDestRect.iBr.iY, EDirectGdiPanicOutOfBounds);
   1.275 +	GRAPHICS_ASSERT_DEBUG(aDest.iX >= 0 && aDest.iY >= 0, EDirectGdiPanicOutOfBounds);
   1.276 +	GRAPHICS_ASSERT_DEBUG(aSrceRect.iTl.iX >= 0 && aSrceRect.iTl.iY >= 0, EDirectGdiPanicOutOfBounds);
   1.277 +#endif
   1.278 +
   1.279 +	TSize srcSize = aSrce->SizeInPixels ();
   1.280 +	
   1.281 +	const TPoint KZeroPoint(0,0);
   1.282 +	TAny* interface = NULL;
   1.283 +	if (iDrawMode == DirectGdi::EDrawModeWriteAlpha &&
   1.284 +			aSrceRect.iBr.iX <= srcSize.iWidth && 
   1.285 +			aSrceRect.iBr.iY <= srcSize.iHeight &&
   1.286 +			!aSrce->IsCompressed() && 
   1.287 +			aSrce->DisplayMode() == iDrawDevice->DisplayMode() && 
   1.288 +			iDrawDevice->GetInterface(KFastBlit2InterfaceID, interface) == KErrNone)
   1.289 +		{
   1.290 +		// Conditions in CFbsBitGc allow for optimised blitting.
   1.291 +		// The draw device supports the optimised blitting function.
   1.292 +		// Operation may fail regardless due to unacceptable conditions in the draw device.
   1.293 +		MFastBlit2* fastBlit = reinterpret_cast<MFastBlit2*>(interface);
   1.294 +		if (fastBlit && (fastBlit->WriteBitmapBlock(aDest, aBase, aStride, srcSize, aSrceRect) == KErrNone))			
   1.295 +			{
   1.296 +			return;
   1.297 +			}			
   1.298 +		}
   1.299 +
   1.300 +	MFastBlend* fastBlend=NULL;
   1.301 +	if (FastBlendInterface(aSrce,NULL,fastBlend)==KErrNone)
   1.302 +		{
   1.303 +		if (fastBlend->FastBlendBitmap(aDest, aBase, aStride, srcSize, aSrceRect, aSrce->DisplayMode(), GcDrawMode(iDrawMode), CFbsDrawDevice::ENoShadow)== KErrNone)
   1.304 +			{
   1.305 +			return;
   1.306 +			}
   1.307 +		}
   1.308 +	
   1.309 +	const TInt scanLineBytes = iDrawDevice->ScanLineBytes();
   1.310 +	TUint32* scanLineBuffer = iDrawDevice->ScanLineBuffer();
   1.311 +	TPtr8 scanLineDes((TUint8*)scanLineBuffer, scanLineBytes, scanLineBytes);
   1.312 +
   1.313 +	const TDisplayMode dispMode = ScanLineBufferDisplayMode(iDrawDevice);
   1.314 +	
   1.315 +	const TBool useScanLinePtr = (dispMode == aSrce->DisplayMode()) && 
   1.316 +		(TDisplayModeUtils::NumDisplayModeBitsPerPixel(dispMode) >= 8);
   1.317 +
   1.318 +	TUint32* slptr = NULL;
   1.319 +	TUint offset = 0;
   1.320 +	TUint32* lastScanLine = NULL;
   1.321 +	if (useScanLinePtr)
   1.322 +		{
   1.323 +		lastScanLine = aSrce->ScanLineAddress(aBase, aSrceRect.iBr.iY-1);
   1.324 +		}
   1.325 +
   1.326 +	TInt srceWidth = srcSize.iWidth;
   1.327 +	TInt partlinestart = aSrceRect.iTl.iX % srceWidth;
   1.328 +	
   1.329 +	if (partlinestart < 0)
   1.330 +		{
   1.331 +		partlinestart += srceWidth;
   1.332 +		}
   1.333 +	
   1.334 +	const TInt partlinelength = Min(srceWidth - partlinestart, width);
   1.335 +	TInt destX = aDest.iX;
   1.336 +	const TInt destXlimit = destX+width;
   1.337 +	const CGraphicsContext::TDrawMode drawMode = GcDrawMode(iDrawMode);
   1.338 +
   1.339 +	// first part line
   1.340 +	if (partlinestart > 0 && partlinelength > 0)
   1.341 +		{
   1.342 +		TPoint srcecoord1(partlinestart, aSrceRect.iTl.iY);
   1.343 +		TInt desty = aDest.iY;
   1.344 +
   1.345 +		TLineScanningPosition lineScanPos(aBase);
   1.346 +
   1.347 +		if (useScanLinePtr)
   1.348 +			{
   1.349 +			offset = MemoryOffsetForPixelPitch(partlinestart, dispMode);
   1.350 +			if (aSrce->IsCompressed ())
   1.351 +				{
   1.352 +				
   1.353 +				while (srcecoord1.iY < aSrceRect.iBr.iY)
   1.354 +					{
   1.355 +					scanLineBuffer = GetScanLineOffsetPtr (aSrce, slptr,
   1.356 +							partlinelength, srcecoord1, aBase, lineScanPos, offset);
   1.357 +					if (srcecoord1.iY == aSrceRect.iTl.iY)
   1.358 +						{
   1.359 +						aSrce->SetCompressionBookmark(lineScanPos, aBase, NULL);
   1.360 +						}
   1.361 +					iDrawDevice->WriteLine(aDest.iX, desty, partlinelength,
   1.362 +							scanLineBuffer, drawMode);
   1.363 +					srcecoord1.iY++;
   1.364 +					desty++;				
   1.365 +					}
   1.366 +				}
   1.367 +			else
   1.368 +				{
   1.369 +				while (srcecoord1.iY < aSrceRect.iBr.iY)
   1.370 +					{
   1.371 +					scanLineBuffer = GetScanLineOffsetPtr (aSrce, slptr,
   1.372 +							partlinelength, srcecoord1, aBase, lineScanPos,
   1.373 +							offset);
   1.374 +					do
   1.375 +						{
   1.376 +						iDrawDevice->WriteLine (aDest.iX, desty,
   1.377 +								partlinelength, scanLineBuffer, drawMode);
   1.378 +						scanLineBuffer = (TUint32*)((TUint8*)scanLineBuffer + aStride);
   1.379 +						srcecoord1.iY++;
   1.380 +						desty++;
   1.381 +						}
   1.382 +					while ((srcecoord1.iY < aSrceRect.iBr.iY) && (scanLineBuffer < lastScanLine)) ;
   1.383 +					}
   1.384 +				}
   1.385 +			}
   1.386 +		else
   1.387 +			{
   1.388 +			for ( ; srcecoord1.iY < aSrceRect.iBr.iY; srcecoord1.iY++, desty++)
   1.389 +				{
   1.390 +				aSrce->GetScanLine (scanLineDes, srcecoord1, partlinelength,
   1.391 +						EFalse, KZeroPoint, dispMode, aBase, lineScanPos);
   1.392 +				if ( srcecoord1.iY==aSrceRect.iTl.iY)
   1.393 +					{
   1.394 +					aSrce->SetCompressionBookmark (lineScanPos, aBase, NULL);
   1.395 +					}
   1.396 +				iDrawDevice->WriteLine (aDest.iX, desty, partlinelength,
   1.397 +						scanLineBuffer, drawMode);
   1.398 +				}
   1.399 +			}
   1.400 +
   1.401 +		destX += partlinelength;
   1.402 +		}
   1.403 +
   1.404 +	// multiple complete lines - columns
   1.405 +	TInt numcolumns = (destXlimit - destX) / srceWidth;
   1.406 +	
   1.407 +	if (numcolumns > 0)
   1.408 +		{
   1.409 +		TPoint srcecoord2(0, aSrceRect.iTl.iY);
   1.410 +		TInt desty = aDest.iY;
   1.411 +
   1.412 +		TLineScanningPosition lineScanPos(aBase);
   1.413 +
   1.414 +		if (useScanLinePtr)
   1.415 +			{
   1.416 +			if (aSrce->IsCompressed())
   1.417 +				{
   1.418 +				while (srcecoord2.iY < aSrceRect.iBr.iY)
   1.419 +					{
   1.420 +					TPoint coord(srcecoord2);
   1.421 +					aSrce->GetScanLinePtr (slptr, srceWidth, coord, aBase, lineScanPos);
   1.422 +					if (srcecoord2.iY == aSrceRect.iTl.iY)
   1.423 +						{
   1.424 +						aSrce->SetCompressionBookmark(lineScanPos, aBase, NULL);
   1.425 +						}
   1.426 +					TInt tempdestX = destX;
   1.427 +					for (TInt count = 0; count < numcolumns; count++, tempdestX += srceWidth)
   1.428 +						{
   1.429 +						iDrawDevice->WriteLine(tempdestX, desty, srceWidth, slptr, drawMode);
   1.430 +						}
   1.431 +					srcecoord2.iY++;
   1.432 +					desty++;
   1.433 +					}
   1.434 +				}
   1.435 +			else
   1.436 +				{
   1.437 +				while (srcecoord2.iY < aSrceRect.iBr.iY)
   1.438 +					{
   1.439 +					TPoint coord(srcecoord2);
   1.440 +					aSrce->GetScanLinePtr (slptr, srceWidth, coord, aBase, lineScanPos);
   1.441 +					do
   1.442 +						{
   1.443 +						TInt tempdestX = destX;
   1.444 +						for (TInt count = 0; count < numcolumns; count++, tempdestX += srceWidth)
   1.445 +							{
   1.446 +							iDrawDevice->WriteLine (tempdestX, desty, srceWidth, slptr, drawMode);
   1.447 +							}
   1.448 +						slptr = (TUint32*)((TUint8*)slptr + aStride);
   1.449 +						srcecoord2.iY++;
   1.450 +						desty++;
   1.451 +						}
   1.452 +					while ((srcecoord2.iY < aSrceRect.iBr.iY) && (slptr < lastScanLine));
   1.453 +					}
   1.454 +				}
   1.455 +			}
   1.456 +		else
   1.457 +			{
   1.458 +			for (; srcecoord2.iY < aSrceRect.iBr.iY; srcecoord2.iY++, desty++)
   1.459 +				{
   1.460 +				TInt tempdestX = destX;
   1.461 +				TPoint coord(srcecoord2);
   1.462 +				aSrce->GetScanLinePtr (slptr, srceWidth, coord, aBase, lineScanPos);
   1.463 +				if (srcecoord2.iY == aSrceRect.iTl.iY)
   1.464 +					{
   1.465 +					aSrce->SetCompressionBookmark (lineScanPos, aBase, NULL);
   1.466 +					}
   1.467 +				for (TInt count = 0; count < numcolumns; count++, tempdestX += srceWidth)
   1.468 +					{
   1.469 +					aSrce->GetScanLine(slptr, scanLineDes, coord, srceWidth,
   1.470 +							EFalse, KZeroPoint, dispMode);
   1.471 +					iDrawDevice->WriteLine(tempdestX, desty, srceWidth, scanLineBuffer, drawMode);
   1.472 +					}
   1.473 +				}
   1.474 +			}
   1.475 +
   1.476 +		destX += numcolumns * srceWidth;
   1.477 +		}
   1.478 +
   1.479 +	// final part line
   1.480 +	if (destX < destXlimit)
   1.481 +		{
   1.482 +		const TInt restofline = destXlimit - destX;
   1.483 +		TPoint srcecoord3(0, aSrceRect.iTl.iY);
   1.484 +		TInt desty = aDest.iY;
   1.485 +
   1.486 +		TLineScanningPosition lineScanPos(aBase);
   1.487 +
   1.488 +		if (useScanLinePtr)
   1.489 +			{
   1.490 +			offset = 0;
   1.491 +			if (aSrce->IsCompressed())
   1.492 +				{
   1.493 +				while (srcecoord3.iY < aSrceRect.iBr.iY)
   1.494 +					{
   1.495 +					scanLineBuffer = GetScanLineOffsetPtr (aSrce, slptr,
   1.496 +							srceWidth, srcecoord3, aBase, lineScanPos, offset);
   1.497 +					if (srcecoord3.iY == aSrceRect.iTl.iY)
   1.498 +						{
   1.499 +						aSrce->SetCompressionBookmark (lineScanPos, aBase, NULL);
   1.500 +						}
   1.501 +					iDrawDevice->WriteLine(destX, desty, restofline, scanLineBuffer, drawMode);
   1.502 +					srcecoord3.iY++;
   1.503 +					desty++;
   1.504 +					}
   1.505 +				}
   1.506 +			else
   1.507 +				{
   1.508 +				while (srcecoord3.iY < aSrceRect.iBr.iY)
   1.509 +					{
   1.510 +					scanLineBuffer = GetScanLineOffsetPtr (aSrce, slptr,
   1.511 +							srceWidth, srcecoord3, aBase, lineScanPos, offset);
   1.512 +					do
   1.513 +						{
   1.514 +						iDrawDevice->WriteLine(destX, desty, restofline, scanLineBuffer, drawMode);
   1.515 +						scanLineBuffer = (TUint32*)((TUint8*)scanLineBuffer + aStride);
   1.516 +						srcecoord3.iY++;
   1.517 +						desty++;
   1.518 +						}
   1.519 +					while ((srcecoord3.iY < aSrceRect.iBr.iY) && (scanLineBuffer < lastScanLine));
   1.520 +					}
   1.521 +				}
   1.522 +			}
   1.523 +		else
   1.524 +			{
   1.525 +			for (; srcecoord3.iY < aSrceRect.iBr.iY; srcecoord3.iY++, desty++)
   1.526 +				{
   1.527 +				aSrce->GetScanLine (scanLineDes, srcecoord3, srceWidth, EFalse,
   1.528 +						KZeroPoint, dispMode, aBase, lineScanPos);
   1.529 +				if (srcecoord3.iY == aSrceRect.iTl.iY)
   1.530 +					{
   1.531 +					aSrce->SetCompressionBookmark (lineScanPos, aBase, NULL);
   1.532 +					}
   1.533 +				iDrawDevice->WriteLine(destX, desty, restofline, scanLineBuffer, drawMode);
   1.534 +				}
   1.535 +			}
   1.536 +		}
   1.537 +	}
   1.538 +/** 
   1.539 +Performs the masked bitblt to the device.
   1.540 +
   1.541 +@param aDest The target position on the device which will contain the top left 
   1.542 +             corner of the source bitmap.
   1.543 +@param aSourceBitmap The bitmap object that contains the pixels to draw.
   1.544 +@param aSourceBase The address of the source bitmap pixels.
   1.545 +@param aSourceRect The area of the bitmap to draw from.
   1.546 +@param aMaskBitmap The bitmap object that contains the mask.
   1.547 +@param aMaskBase The address of the mask pixels.
   1.548 +@param aInvertMask Inverts the mask if ETrue.
   1.549 +@panic DGDIAdapter 1013, if aDest is outside of the device bounds (debug only).
   1.550 +*/
   1.551 +void CSwDirectGdiEngine::DoBitBltMasked(const TPoint& aDest,
   1.552 +		   CBitwiseBitmap* aSourceBitmap,
   1.553 +		   TUint32* aSourceBase,
   1.554 +		   const TRect& aSourceRect,
   1.555 +		   CBitwiseBitmap* aMaskBitmap,
   1.556 +		   TUint32* aMaskBase,
   1.557 +		   TBool aInvertMask)
   1.558 +	{
   1.559 +#ifdef _DEBUG
   1.560 +	TRect deviceDestRect;
   1.561 +	iDrawDevice->GetDrawRect (deviceDestRect);
   1.562 +#endif
   1.563 +	
   1.564 +    GRAPHICS_ASSERT_DEBUG (aDest.iX >= deviceDestRect.iTl.iX, EDirectGdiPanicOutOfBounds);
   1.565 +	GRAPHICS_ASSERT_DEBUG (aDest.iY >= deviceDestRect.iTl.iY, EDirectGdiPanicOutOfBounds);
   1.566 +	GRAPHICS_ASSERT_DEBUG ((aDest.iX + aSourceRect.Width()) <= deviceDestRect.iBr.iX, EDirectGdiPanicOutOfBounds);
   1.567 +	GRAPHICS_ASSERT_DEBUG ((aDest.iY + aSourceRect.Height()) <= deviceDestRect.iBr.iY, EDirectGdiPanicOutOfBounds);	
   1.568 +	const TPoint KZeroPoint(0,0);
   1.569 +
   1.570 +	MFastBlend* fastBlend=NULL;
   1.571 +	if (FastBlendInterface(aSourceBitmap,aMaskBitmap,fastBlend)==KErrNone)
   1.572 +		{
   1.573 +		if (fastBlend->FastBlendBitmapMasked(aDest, aSourceBase, aSourceBitmap->DataStride(), aSourceBitmap->SizeInPixels(), aSourceRect, aSourceBitmap->DisplayMode(),
   1.574 +							aMaskBase, aMaskBitmap->DataStride(), aMaskBitmap->DisplayMode(), aMaskBitmap->SizeInPixels(), aSourceRect.iTl, aInvertMask,
   1.575 +							GcDrawMode(iDrawMode), CFbsDrawDevice::ENoShadow)==KErrNone)
   1.576 +			{
   1.577 +			return;
   1.578 +			}
   1.579 +		}
   1.580 +	
   1.581 +	if (aMaskBitmap->DisplayMode() == EGray256)
   1.582 +		{
   1.583 +		DoBitBltAlpha (aDest, aSourceBitmap, aSourceBase, aSourceRect,
   1.584 +				aMaskBitmap, aMaskBase, aSourceRect.iTl, EFalse);
   1.585 +		}
   1.586 +	// if screen driver is 16MAP we avoid logical operator pen modes by using DoBitBltAlpha() for blitting
   1.587 +	else if(iDrawDevice->ScanLineDisplayMode() == EColor16MAP)
   1.588 +		{
   1.589 +		DoBitBltAlpha (aDest, aSourceBitmap, aSourceBase, aSourceRect,
   1.590 +				aMaskBitmap, aMaskBase, aSourceRect.iTl, aInvertMask);
   1.591 +		}
   1.592 +	else if (aSourceBitmap == aMaskBitmap)
   1.593 +		{
   1.594 +		const TInt width = aSourceRect.Width();
   1.595 +		const TDisplayMode dispMode = ScanLineBufferDisplayMode(iDrawDevice);
   1.596 +		const CGraphicsContext::TDrawMode drawMode = aInvertMask ? CGraphicsContext::EDrawModeAND : CGraphicsContext::EDrawModeOR;
   1.597 +		TPoint srcePoint(aSourceRect.iTl);
   1.598 +		TInt destY = aDest.iY;
   1.599 +		
   1.600 +		TLineScanningPosition lineScanPos(aSourceBase);
   1.601 +
   1.602 +		const TBool useScanLinePtr = (dispMode == aSourceBitmap->DisplayMode() && 
   1.603 +				(TDisplayModeUtils::NumDisplayModeBitsPerPixel(dispMode)>=8));
   1.604 +
   1.605 +		if (useScanLinePtr)
   1.606 +			{
   1.607 +			TUint32* scanLineBuffer = NULL;
   1.608 +			TUint32* slptr = NULL;
   1.609 +			TUint offset = MemoryOffsetForPixelPitch (srcePoint.iX, dispMode);
   1.610 +
   1.611 +			if (aSourceBitmap->IsCompressed())
   1.612 +				{
   1.613 +				for ( ; srcePoint.iY < aSourceRect.iBr.iY; destY++,
   1.614 +						srcePoint.iY++)
   1.615 +					{
   1.616 +					scanLineBuffer = GetScanLineOffsetPtr (
   1.617 +							aSourceBitmap, slptr, width, srcePoint,
   1.618 +							aSourceBase, lineScanPos, offset);
   1.619 +					
   1.620 +					iDrawDevice->WriteLine (aDest.iX, destY, width,
   1.621 +							scanLineBuffer, drawMode);
   1.622 +					}
   1.623 +				}
   1.624 +			else
   1.625 +				{
   1.626 +				TUint stride = aSourceBitmap->DataStride ();
   1.627 +				TUint32* lastScanLine = aSourceBitmap->ScanLineAddress(aSourceBase, aSourceRect.iBr.iY-1);
   1.628 +
   1.629 +				while (srcePoint.iY < aSourceRect.iBr.iY)
   1.630 +					{
   1.631 +					scanLineBuffer = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint,
   1.632 +							aSourceBase, lineScanPos, offset);
   1.633 +					do
   1.634 +						{
   1.635 +						iDrawDevice->WriteLine (aDest.iX, destY, width, scanLineBuffer, drawMode);
   1.636 +						scanLineBuffer = (TUint32*)((TUint8*)scanLineBuffer + stride);
   1.637 +						destY++;
   1.638 +						srcePoint.iY++;
   1.639 +						}
   1.640 +					while ((srcePoint.iY < aSourceRect.iBr.iY) && (scanLineBuffer < lastScanLine));
   1.641 +					}
   1.642 +				}
   1.643 +			}
   1.644 +		else
   1.645 +			{
   1.646 +			const TInt scanLineBytes = iDrawDevice->ScanLineBytes();
   1.647 +			TUint32* scanLineBuffer = iDrawDevice->ScanLineBuffer();
   1.648 +			TPtr8 scanLineDes((TUint8*)scanLineBuffer, scanLineBytes,
   1.649 +					scanLineBytes);
   1.650 +			for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,
   1.651 +					srcePoint.iY++)
   1.652 +				{
   1.653 +				aSourceBitmap->GetScanLine (scanLineDes, srcePoint,
   1.654 +						width, EFalse, KZeroPoint, dispMode,
   1.655 +						aSourceBase, lineScanPos);
   1.656 +
   1.657 +				iDrawDevice->WriteLine (aDest.iX, destY, width,
   1.658 +						scanLineBuffer, drawMode);
   1.659 +				}
   1.660 +			}
   1.661 +		}
   1.662 +	else
   1.663 +		{
   1.664 +		DoBitBltMaskedFlicker(aDest, aSourceBitmap, aSourceBase,
   1.665 +				aSourceRect, aMaskBitmap, aMaskBase, aInvertMask);		
   1.666 +		}
   1.667 +	}
   1.668 +		
   1.669 +/**
   1.670 +@see DoBitBltMasked()
   1.671 + */
   1.672 +void CSwDirectGdiEngine::DoBitBltMaskedFlicker(const TPoint& aDest,
   1.673 +				  CBitwiseBitmap* aSourceBitmap,
   1.674 +				  TUint32* aSourceBase,
   1.675 +				  const TRect& aSourceRect,
   1.676 +				  CBitwiseBitmap* aMaskBitmap,
   1.677 +				  TUint32* aMaskBase,
   1.678 +				  TBool aInvertMask)
   1.679 +	{
   1.680 +	const TInt width = aSourceRect.Width();
   1.681 +	TInt destY = aDest.iY;
   1.682 +	TPoint srcePoint(aSourceRect.iTl);
   1.683 +	
   1.684 +	TLineScanningPosition lineScanPos(aSourceBase);
   1.685 +	TLineScanningPosition lineScanPosMask(aMaskBase);
   1.686 +	
   1.687 +	const TDisplayMode srcFormat = aSourceBitmap->DisplayMode();
   1.688 +	const TDisplayMode maskFormat = aMaskBitmap->DisplayMode();
   1.689 +	
   1.690 +	if (aMaskBitmap->IsCompressed()) 
   1.691 +		{ 
   1.692 +		HBufC8* hBuf = CFbsBitmap::GetDecompressionBuffer(aMaskBitmap->DataStride() + 4);
   1.693 +		if (!hBuf) 
   1.694 +			{
   1.695 +			iDriver->SetError(KErrNoMemory);
   1.696 +			return; // Out of memory so do not draw anything 
   1.697 +			}
   1.698 +		lineScanPosMask.iScanLineBuffer = hBuf; 
   1.699 +		} 
   1.700 +	
   1.701 +	TAny* interface = NULL;
   1.702 +	if ( (srcFormat == EColor16MU || srcFormat == EColor64K ) &&
   1.703 +			maskFormat == EGray2 && 
   1.704 +			aSourceBitmap->SizeInPixels().iWidth <= aMaskBitmap->SizeInPixels().iWidth &&
   1.705 +			aSourceBitmap->SizeInPixels().iHeight <= aMaskBitmap->SizeInPixels().iHeight &&
   1.706 +			iDrawDevice->GetInterface(KFastBlitInterfaceID, interface) == KErrNone )
   1.707 +		{
   1.708 +		// Parameters allow optimised code path
   1.709 +		TInt length = width;
   1.710 +		TUint32* srcPtr=NULL;
   1.711 +		TUint32* maskPtr=NULL;
   1.712 +		MFastBlit* fastBlit = reinterpret_cast<MFastBlit*>(interface);
   1.713 +		while (srcePoint.iY < aSourceRect.iBr.iY)
   1.714 +			{
   1.715 +			aSourceBitmap->GetScanLinePtr(srcPtr, length, srcePoint, aSourceBase, lineScanPos);
   1.716 +			aMaskBitmap->GetScanLinePtr(maskPtr, length, srcePoint, aMaskBase, lineScanPosMask);
   1.717 +			
   1.718 +			fastBlit->WriteMaskLineEx(aDest.iX,destY,length,srcePoint.iX,srcPtr,srcFormat,srcePoint.iX,maskPtr,aInvertMask);
   1.719 +			
   1.720 +			destY++;
   1.721 +			++srcePoint.iY;
   1.722 +			}
   1.723 +		return;
   1.724 +		}
   1.725 +	
   1.726 +	const TDisplayMode dispMode = ScanLineBufferDisplayMode(iDrawDevice);
   1.727 +	const CGraphicsContext::TDrawMode drawMode = aInvertMask ? CGraphicsContext::EDrawModeAND : CGraphicsContext::EDrawModeANDNOT;
   1.728 +	
   1.729 +	TUint32* scanLineBuffer = iDrawDevice->ScanLineBuffer();
   1.730 +	const TInt scanLineBytes = iDrawDevice->ScanLineBytes();
   1.731 +	TPtr8 scanLineDes((TUint8*)scanLineBuffer,scanLineBytes,scanLineBytes);
   1.732 +	TLineScanningPosition lineScanPos2(aSourceBase);
   1.733 +	const TPoint KZeroPoint(0,0);
   1.734 +	
   1.735 +	//scanline modifications required if using different modes, bits per pixel less than 8
   1.736 +	if ( (dispMode == aSourceBitmap->DisplayMode()) && 
   1.737 +			(TDisplayModeUtils::NumDisplayModeBitsPerPixel(dispMode)>=8))
   1.738 +		{
   1.739 +		TUint offset = MemoryOffsetForPixelPitch(srcePoint.iX, dispMode);
   1.740 +		TUint32* slptr=NULL;
   1.741 +		//mask scanline modifications required for EInvertPen, different screen modes
   1.742 +		if ((drawMode != CGraphicsContext::EDrawModeANDNOT) && (dispMode == aMaskBitmap->DisplayMode()))
   1.743 +			{
   1.744 +			TUint32* scanLineBufferMask = NULL;
   1.745 +			//stride jumping not possible with compressed bitmaps
   1.746 +			if (aSourceBitmap->IsCompressed() || aMaskBitmap->IsCompressed())
   1.747 +				{
   1.748 +				for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++)
   1.749 +					{
   1.750 +					scanLineBuffer = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPos, offset);
   1.751 +					iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer, CGraphicsContext::EDrawModeXOR);
   1.752 +					scanLineBufferMask = GetScanLineOffsetPtr(aMaskBitmap, slptr, width, srcePoint, aMaskBase, lineScanPosMask, offset);
   1.753 +					iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferMask,drawMode);
   1.754 +					iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer, CGraphicsContext::EDrawModeXOR);
   1.755 +					}
   1.756 +				}
   1.757 +			else
   1.758 +				{
   1.759 +				TUint strideSrc = aSourceBitmap->DataStride();
   1.760 +				TUint strideMask = aMaskBitmap->DataStride();
   1.761 +				TUint32* lastScanLineSrc = aSourceBitmap->ScanLineAddress(aSourceBase,aSourceRect.iBr.iY-1);
   1.762 +				TUint32* lastScanLineMask = aMaskBitmap->ScanLineAddress(aMaskBase,aSourceRect.iBr.iY-1);
   1.763 +
   1.764 +				while (srcePoint.iY < aSourceRect.iBr.iY)
   1.765 +					{
   1.766 +					scanLineBuffer = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPos, offset);
   1.767 +					scanLineBufferMask = GetScanLineOffsetPtr(aMaskBitmap, slptr, width, srcePoint, aMaskBase, lineScanPosMask, offset);
   1.768 +					do
   1.769 +						{
   1.770 +						iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,CGraphicsContext::EDrawModeXOR);
   1.771 +						iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferMask,drawMode);
   1.772 +						iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,CGraphicsContext::EDrawModeXOR);
   1.773 +						destY++;
   1.774 +						srcePoint.iY++;
   1.775 +						}
   1.776 +					while ((srcePoint.iY < aSourceRect.iBr.iY) && 
   1.777 +							(scanLineBuffer < lastScanLineSrc) && 
   1.778 +							(scanLineBufferMask < lastScanLineMask)	&& 
   1.779 +							((scanLineBuffer = (TUint32*)((TUint8*)scanLineBuffer + strideSrc))>(TUint32*)0) && 
   1.780 +							((scanLineBufferMask = (TUint32*)((TUint8*)scanLineBufferMask + strideMask))>(TUint32*)0) );
   1.781 +					}
   1.782 +				}
   1.783 +			}
   1.784 +		else
   1.785 +			{
   1.786 +			TUint32* scanLineBufferPtr = NULL;
   1.787 +			//stride jumping not possible with compressed bitmaps
   1.788 +			if (aSourceBitmap->IsCompressed())
   1.789 +				{
   1.790 +				for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++)
   1.791 +					{
   1.792 +					scanLineBufferPtr = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPos, offset);
   1.793 +					iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferPtr,CGraphicsContext::EDrawModeXOR);
   1.794 +					aMaskBitmap->GetScanLine(scanLineDes,srcePoint,width,EFalse , KZeroPoint, dispMode, aMaskBase, lineScanPosMask);
   1.795 +					TileScanLine(scanLineDes, width, srcePoint, aMaskBitmap, lineScanPosMask, aMaskBase, dispMode);
   1.796 +					iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,drawMode);
   1.797 +					iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferPtr,CGraphicsContext::EDrawModeXOR);
   1.798 +					}
   1.799 +				}
   1.800 +			else
   1.801 +				{
   1.802 +				TUint stride = aSourceBitmap->DataStride();
   1.803 +				TUint32* lastScanLine = aSourceBitmap->ScanLineAddress(aSourceBase,aSourceRect.iBr.iY-1);
   1.804 +				while (srcePoint.iY < aSourceRect.iBr.iY)
   1.805 +					{
   1.806 +					scanLineBufferPtr = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPos, offset);
   1.807 +					do
   1.808 +						{
   1.809 +						iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferPtr,CGraphicsContext::EDrawModeXOR);
   1.810 +						aMaskBitmap->GetScanLine(scanLineDes,srcePoint,width,EFalse, KZeroPoint, dispMode,aMaskBase, lineScanPosMask);
   1.811 +						TileScanLine(scanLineDes, width, srcePoint, aMaskBitmap, lineScanPosMask, aMaskBase, dispMode);
   1.812 +						iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,drawMode);
   1.813 +						iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferPtr,CGraphicsContext::EDrawModeXOR);
   1.814 +						destY++;
   1.815 +						srcePoint.iY++;
   1.816 +						}
   1.817 +					while ((srcePoint.iY < aSourceRect.iBr.iY) && (scanLineBufferPtr < lastScanLine) && 
   1.818 +							((scanLineBufferPtr = (TUint32*)((TUint8*)scanLineBufferPtr + stride))>(TUint32*)0));
   1.819 +					}
   1.820 +				}
   1.821 +			}
   1.822 +		}
   1.823 +	else
   1.824 +		{
   1.825 +		for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++)
   1.826 +			{
   1.827 +			aSourceBitmap->GetScanLine(scanLineDes,srcePoint,width,EFalse, KZeroPoint,
   1.828 +					dispMode,aSourceBase,lineScanPos);
   1.829 +			
   1.830 +			iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,CGraphicsContext::EDrawModeXOR);
   1.831 +			aMaskBitmap->GetScanLine(scanLineDes,srcePoint,width,EFalse , KZeroPoint, dispMode,
   1.832 +					aMaskBase, lineScanPosMask);
   1.833 +			TileScanLine(scanLineDes, width, srcePoint, aMaskBitmap, lineScanPosMask, aMaskBase, dispMode);
   1.834 +			iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,drawMode);
   1.835 +			aSourceBitmap->GetScanLine(scanLineDes,srcePoint,width,EFalse , KZeroPoint ,dispMode,
   1.836 +					aSourceBase,lineScanPos2);		
   1.837 +			
   1.838 +			iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,CGraphicsContext::EDrawModeXOR);
   1.839 +			}
   1.840 +		}
   1.841 +	}		
   1.842 +				
   1.843 +/**
   1.844 +@see DoBitBltMasked()
   1.845 + */
   1.846 +void CSwDirectGdiEngine::DoBitBltAlpha(const TPoint& aDest ,CBitwiseBitmap* aSourceBitmap,
   1.847 +		TUint32* aSourceBase, const TRect& aSourceRect,
   1.848 +		CBitwiseBitmap* aMaskBitmap, TUint32* aMaskBase,
   1.849 +		const TPoint& aAlphaPoint, TBool aInvertMask)
   1.850 +	{
   1.851 +	MFastBlend* fastBlend=NULL;
   1.852 +	if (FastBlendInterface(aSourceBitmap,aMaskBitmap,fastBlend)==KErrNone)
   1.853 +		{
   1.854 +		if (fastBlend->FastBlendBitmapMasked(aDest, aSourceBase, aSourceBitmap->DataStride(), aSourceBitmap->SizeInPixels(), aSourceRect, aSourceBitmap->DisplayMode(),
   1.855 +							aMaskBase, aMaskBitmap->DataStride(), aMaskBitmap->DisplayMode(), aMaskBitmap->SizeInPixels(), aAlphaPoint, aInvertMask,
   1.856 +							GcDrawMode(iDrawMode), CFbsDrawDevice::ENoShadow)==KErrNone)
   1.857 +			{
   1.858 +			return;
   1.859 +			}
   1.860 +		}
   1.861 +
   1.862 +	const TPoint KZeroPoint(0,0);
   1.863 +	const TInt KScanLineLength = 256;
   1.864 +	const TInt KRgbSize = 4;
   1.865 +	
   1.866 +	TUint8 srceRgbBuffer[KScanLineLength * KRgbSize];
   1.867 +	TUint8 maskBuffer[KScanLineLength];
   1.868 +	TUint8* srceRgbBufferPtr(srceRgbBuffer);
   1.869 +	
   1.870 +	TPtr8 srceRgbDes(srceRgbBuffer, KScanLineLength * KRgbSize, KScanLineLength * KRgbSize);
   1.871 +	TPtr8 maskDes(maskBuffer, KScanLineLength, KScanLineLength);	
   1.872 +	
   1.873 +	TInt srceY = aSourceRect.iTl.iY;
   1.874 +	TInt destY = aDest.iY;
   1.875 +	TInt alphaY = aAlphaPoint.iY;
   1.876 +	
   1.877 +	TLineScanningPosition lineScanPosSrc(aSourceBase);
   1.878 +	TLineScanningPosition lineScanPosMask(aMaskBase);
   1.879 +	TDisplayMode sourceMode = aSourceBitmap->DisplayMode();
   1.880 +	
   1.881 +	if (aMaskBitmap->IsCompressed())
   1.882 +		{
   1.883 +		HBufC8* hBuf= CFbsBitmap::GetDecompressionBuffer(aMaskBitmap->DataStride());
   1.884 +		if (hBuf == NULL)
   1.885 +			{
   1.886 +			iDriver->SetError(KErrNoMemory); // Out of memory so do not draw anything
   1.887 +			return;
   1.888 +			}
   1.889 +		lineScanPosMask.iScanLineBuffer = hBuf;
   1.890 +		}
   1.891 +	
   1.892 +	TAny* interface = NULL;
   1.893 +	if ( (sourceMode == EColor16MU || sourceMode == EColor64K) &&
   1.894 +		aMaskBitmap->DisplayMode() == EGray256 && // ensure a monochrome mask isn't passed in as an alpha channel
   1.895 +		aSourceBitmap->SizeInPixels().iWidth <= aMaskBitmap->SizeInPixels().iWidth &&
   1.896 +		aSourceBitmap->SizeInPixels().iHeight <= aMaskBitmap->SizeInPixels().iHeight &&
   1.897 +		iDrawDevice->GetInterface(KFastBlitInterfaceID, interface) == KErrNone )
   1.898 +		{
   1.899 +		TInt length = aSourceRect.Width();
   1.900 +		const TInt srceX = aSourceRect.iTl.iX;
   1.901 +		const TInt alphaX = aAlphaPoint.iX;
   1.902 +		const TInt destX = aDest.iX;
   1.903 +		MFastBlit* fastBlit = reinterpret_cast<MFastBlit*>(interface);
   1.904 +		
   1.905 +		while (srceY < aSourceRect.iBr.iY)
   1.906 +			{
   1.907 +			TUint32* srcPtr;
   1.908 +			TUint32* maskPtr;
   1.909 +			TPoint srcPoint(srceX, srceY);
   1.910 +			TPoint maskPoint(alphaX, alphaY);
   1.911 +			
   1.912 +			aSourceBitmap->GetScanLinePtr(srcPtr, length, srcPoint, aSourceBase, lineScanPosSrc);
   1.913 +			aMaskBitmap->GetScanLinePtr(maskPtr, length, maskPoint, aMaskBase, lineScanPosMask);
   1.914 +			
   1.915 +			fastBlit->WriteAlphaLineEx(destX, destY, length, srceX, srcPtr,
   1.916 +					sourceMode, alphaX, maskPtr, MAlphaBlend::EShdwBefore);
   1.917 +			srceY++;
   1.918 +			destY++;
   1.919 +			alphaY++;
   1.920 +			}
   1.921 +		
   1.922 +		return;
   1.923 +		}
   1.924 +	
   1.925 +	const TBool useScanLinePtr = ( (EColor16MA == aSourceBitmap->DisplayMode()));
   1.926 +	TUint32* slptr = NULL;
   1.927 +	TUint offset = 0;
   1.928 +	
   1.929 +	while (srceY < aSourceRect.iBr.iY)
   1.930 +		{
   1.931 +		TInt srceX = aSourceRect.iTl.iX;
   1.932 +		TInt destX = aDest.iX;
   1.933 +		TInt alphaX = aAlphaPoint.iX;
   1.934 +		
   1.935 +		while (srceX < aSourceRect.iBr.iX)
   1.936 +			{
   1.937 +			TPoint srcePoint(srceX,srceY);
   1.938 +			TPoint alphaPoint(alphaX,alphaY);
   1.939 +			const TInt width = Min(KScanLineLength, aSourceRect.iBr.iX - srceX);
   1.940 +			
   1.941 +			if (useScanLinePtr)
   1.942 +				{
   1.943 +				offset = MemoryOffsetForPixelPitch(srceX, EColor16MU);
   1.944 +				srceRgbBufferPtr = (TUint8*)GetScanLineOffsetPtr(aSourceBitmap, slptr, width, 
   1.945 +						                       srcePoint, aSourceBase, lineScanPosSrc, offset);
   1.946 +				}
   1.947 +			else
   1.948 +				{
   1.949 +				aSourceBitmap->GetScanLine(srceRgbDes,srcePoint,width,EFalse,KZeroPoint,
   1.950 +						               ERgb,aSourceBase,lineScanPosSrc);
   1.951 +				}
   1.952 +			
   1.953 +			aMaskBitmap->GetScanLine(maskDes, alphaPoint, width, EFalse, KZeroPoint,
   1.954 +					                EGray256, aMaskBase, lineScanPosMask);
   1.955 +			TileScanLine(maskDes, width, alphaPoint, aMaskBitmap, lineScanPosMask, aMaskBase, EGray256);
   1.956 +			
   1.957 +			// aInvertMask is not used for alpha channels (EGray256 mask)
   1.958 +			if (aInvertMask && aMaskBitmap->DisplayMode() != EGray256)
   1.959 +				{
   1.960 +				for (TInt i = 0; i < width; ++i)
   1.961 +					{
   1.962 +					maskBuffer[i] = ~maskBuffer[i];
   1.963 +					}
   1.964 +				}
   1.965 +			
   1.966 +			iDrawDevice->WriteRgbAlphaLine(destX, destY, width, srceRgbBufferPtr, maskBuffer, GcDrawMode(iDrawMode));
   1.967 +			
   1.968 +			srceX += KScanLineLength;
   1.969 +			destX += KScanLineLength;
   1.970 +			alphaX += KScanLineLength;
   1.971 +			}
   1.972 +		
   1.973 +		srceY++;
   1.974 +		destY++;
   1.975 +		alphaY++;
   1.976 +		}		
   1.977 +	}
   1.978 +
   1.979 +/**
   1.980 +Tiles the scan line if its length in pixels is less than aLengthInPixels.
   1.981 +
   1.982 +@param aScanLine A pointer to the scan line buffer.
   1.983 +@param aLengthInPixels The scan line size in pixels.
   1.984 +@param aSrcPt Position of the first pixel in aMaskBitmap that should be used as a source
   1.985 +              for the pixels in scan line buffer.
   1.986 +@param aMaskBitmap Any additional pixels for the scan line buffer will be taken from here.
   1.987 +@param aScanLinePos This argument is used for some internal optimisations. It should not be
   1.988 +                    modified by the caller.
   1.989 +@param aMaskBase The base address of aMaskBitmap data.
   1.990 +@param aDisplayMode Any additional pixels should be taken from aMaskBitmap using aDisplayMode
   1.991 +                    as an argument for GetScanLine() call.
   1.992 +@panic DGDIAdapter 1021, if the memory required for the scanline is greater than the size of aScanLine (debug only).
   1.993 +*/
   1.994 +void CSwDirectGdiEngine::TileScanLine(TPtr8& aScanLine,
   1.995 +						  TInt aLengthInPixels,
   1.996 +						  const TPoint& aSrcPt,
   1.997 +						  const CBitwiseBitmap* aMaskBitmap,
   1.998 +						  TLineScanningPosition& aScanLinePos,
   1.999 +						  TUint32* aMaskBase,
  1.1000 +						  TDisplayMode aDisplayMode
  1.1001 +						  )
  1.1002 +	{
  1.1003 +	TInt lengthInBytes = CFbsBitmap::ScanLineLength(aLengthInPixels, aDisplayMode);
  1.1004 +	GRAPHICS_ASSERT_DEBUG(lengthInBytes <= aScanLine.MaxLength(), EDirectGdiPanicInvalidArg);
  1.1005 +	TInt scanLineLength = aScanLine.Length();
  1.1006 +	if(scanLineLength < lengthInBytes && aSrcPt.iX > 0)
  1.1007 +		{
  1.1008 +		//If, for example, src bmp is 100 pixels width, mask bmp is 20 pixels width and src
  1.1009 +		//rect is (10, 0, 100, 1) -> We will read only pixels 10..19 from the first scan line
  1.1010 +		//of the mask bmp. We have to have 90 mask bmp pixels.
  1.1011 +		//So we have to make a second mask bmp read startig from pixel 0 - 10 pixels length.
  1.1012 +		TInt maxLen = Min(aScanLine.MaxLength() - scanLineLength, aSrcPt.iX);
  1.1013 +		TPtr8 maskDes2(const_cast <TUint8*> (aScanLine.Ptr()) + scanLineLength, maxLen, maxLen);
  1.1014 +		TPoint srcPt(0, aSrcPt.iY);
  1.1015 +		TPoint zeroPt(0, 0);
  1.1016 +		aMaskBitmap->GetScanLine(maskDes2, srcPt, maxLen, EFalse, zeroPt, aDisplayMode, aMaskBase, aScanLinePos);
  1.1017 +		aScanLine.SetLength(scanLineLength + maskDes2.Length());
  1.1018 +		scanLineLength = aScanLine.Length();
  1.1019 +		}
  1.1020 +	if(scanLineLength >= lengthInBytes || scanLineLength == 0)
  1.1021 +		{
  1.1022 +		return;
  1.1023 +		}
  1.1024 +	//If we still don't have enough mask bmp pixels - we have to tile the scan line
  1.1025 +	TInt repeatCnt = lengthInBytes / scanLineLength - 1;
  1.1026 +	TInt bytesLeft = lengthInBytes % scanLineLength;
  1.1027 +	const TUint8* src = aScanLine.Ptr();
  1.1028 +	TUint8* dest = const_cast <TUint8*> (src) + scanLineLength;
  1.1029 +	for(;repeatCnt>0;dest+=scanLineLength,repeatCnt--)
  1.1030 +		{
  1.1031 +		Mem::Copy(dest, src, scanLineLength);
  1.1032 +		}
  1.1033 +	if(bytesLeft)
  1.1034 +		{
  1.1035 +		Mem::Copy(dest, src, bytesLeft);
  1.1036 +		}
  1.1037 +	aScanLine.SetLength(lengthInBytes);
  1.1038 +	}
  1.1039 +
  1.1040 +/**
  1.1041 +Draws a masked rectangular section of the source bitmap and does a compress/stretch to 
  1.1042 +fit a given destination rectangle. It uses DoBitBltMasked() if no stretching is involved. 
  1.1043 +
  1.1044 +@see DrawBitmapMasked()
  1.1045 +
  1.1046 +@param aDestRect The target position on the device containing the top left corner of the source bitmap.
  1.1047 +@param aSourceBitmap The bitmap object that contains the pixels to draw.
  1.1048 +@param aSourceBase The address of the source bitmap pixels.
  1.1049 +@param aSourceRect The area of the bitmap to draw from.
  1.1050 +@param aMaskBitmap The bitmap object that contains the mask.
  1.1051 +@param aMaskBase The address of the mask pixels.
  1.1052 +@param aInvertMask Inverts the mask if ETrue.
  1.1053 +@param aClipRect A clipping rectangle.
  1.1054 +@panic DGDIAdapter 1013, if the clipping rectangle is fully outside of the device bounds (debug only).
  1.1055 +*/
  1.1056 +void CSwDirectGdiEngine::DoDrawBitmapMasked(const TRect& aDestRect,
  1.1057 +							   CBitwiseBitmap* aSourceBitmap,
  1.1058 +							   TUint32* aSourceBase,
  1.1059 +							   const TRect& aSourceRect,
  1.1060 +							   CBitwiseBitmap* aMaskBitmap,
  1.1061 +							   TUint32* aMaskBase,
  1.1062 +							   TBool aInvertMask,
  1.1063 +							   const TRect& aClipRect)
  1.1064 +	{
  1.1065 +	CFbsDrawDevice* drawDevice = iDrawDevice;
  1.1066 +#ifdef _DEBUG
  1.1067 +	TRect deviceDestRect;
  1.1068 +	drawDevice->GetDrawRect(deviceDestRect);
  1.1069 +	GRAPHICS_ASSERT_DEBUG(aClipRect.iTl.iX >= deviceDestRect.iTl.iX, EDirectGdiPanicOutOfBounds);
  1.1070 +	GRAPHICS_ASSERT_DEBUG(aClipRect.iTl.iY >= deviceDestRect.iTl.iY, EDirectGdiPanicOutOfBounds);
  1.1071 +	GRAPHICS_ASSERT_DEBUG(aClipRect.iBr.iX <= deviceDestRect.iBr.iX, EDirectGdiPanicOutOfBounds);
  1.1072 +	GRAPHICS_ASSERT_DEBUG(aClipRect.iBr.iY <= deviceDestRect.iBr.iY, EDirectGdiPanicOutOfBounds);
  1.1073 +#endif
  1.1074 +
  1.1075 +	// The clipped version of the destination rectangle
  1.1076 +	TRect clippedDestRect(aDestRect);
  1.1077 +	clippedDestRect.Intersection(aClipRect);
  1.1078 +
  1.1079 +	// If the source rectangle and the destination rectangle are same,
  1.1080 +	// no stretch/compress operation required, just do BitBltMasked
  1.1081 +	if (aDestRect.Size() == aSourceRect.Size())
  1.1082 +		{
  1.1083 +		if (!clippedDestRect.IsEmpty())
  1.1084 +			{
  1.1085 +			const TPoint destPoint(clippedDestRect.iTl);
  1.1086 +			clippedDestRect.Move(aSourceRect.iTl - aDestRect.iTl);
  1.1087 +			DoBitBltMasked(destPoint,
  1.1088 +						   aSourceBitmap,
  1.1089 +						   aSourceBase,
  1.1090 +						   clippedDestRect,
  1.1091 +						   aMaskBitmap,
  1.1092 +						   aMaskBase,
  1.1093 +						   aInvertMask);
  1.1094 +			}
  1.1095 +		return;
  1.1096 +		}
  1.1097 +
  1.1098 +	MFastBlend* fastBlend=NULL;
  1.1099 +	if (FastBlendInterface(aSourceBitmap,aMaskBitmap,fastBlend)==KErrNone)
  1.1100 +		{
  1.1101 +		if (fastBlend->FastBlendBitmapMaskedScaled(aClipRect, aDestRect, aSourceRect, aSourceBase, aSourceBitmap->DataStride(),
  1.1102 +				aSourceBitmap->DisplayMode(),aSourceBitmap->SizeInPixels(), 
  1.1103 +				aMaskBase, aMaskBitmap->DataStride(), aMaskBitmap->DisplayMode(), aMaskBitmap->SizeInPixels(), aInvertMask, 
  1.1104 +				GcDrawMode(iDrawMode), CFbsDrawDevice::ENoShadow)==KErrNone)
  1.1105 +			{
  1.1106 +			return;
  1.1107 +			}
  1.1108 +		}
  1.1109 +	
  1.1110 +	TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
  1.1111 +	const TInt scanLineBytes = drawDevice->ScanLineBytes();
  1.1112 +	TPtr8 scanLineDes(reinterpret_cast<TUint8*>(scanLineBuffer),scanLineBytes,scanLineBytes);
  1.1113 +
  1.1114 +	const TInt KScanLineLength = 256;
  1.1115 +	const TInt KRgbSize = 4;
  1.1116 +	TUint8 maskBuffer[KScanLineLength];
  1.1117 +
  1.1118 +	TUint8 sourceBuffer[KScanLineLength*KRgbSize];
  1.1119 +	TPtr8 sourceDes(sourceBuffer,KScanLineLength*KRgbSize,KScanLineLength*KRgbSize);
  1.1120 +
  1.1121 +	const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
  1.1122 +	CGraphicsContext::TDrawMode drawMode = aInvertMask ? CGraphicsContext::EDrawModeAND : CGraphicsContext::EDrawModeANDNOT;
  1.1123 +	// If the source bitmap and the mask bitmap are same, draw the source bitmap either
  1.1124 +	// with EDrawModeAND or EDrawModeOR based on aInvertMask parameter.
  1.1125 +	if (aSourceBitmap == aMaskBitmap)
  1.1126 +		{
  1.1127 +		drawMode = aInvertMask ? CGraphicsContext::EDrawModeAND : CGraphicsContext::EDrawModeOR;
  1.1128 +		}
  1.1129 +
  1.1130 +	TLinearDDA xLine;
  1.1131 +	TInt bitmapXStart = 0;
  1.1132 +	xLine.Construct(TPoint(aSourceRect.iTl.iX,aDestRect.iTl.iX),
  1.1133 +					TPoint(aSourceRect.iBr.iX,aDestRect.iBr.iX),TLinearDDA::ELeft);
  1.1134 +	xLine.JumpToYCoord2(bitmapXStart,clippedDestRect.iTl.iX);
  1.1135 +
  1.1136 +	TLinearDDA yLine;
  1.1137 +	TPoint yCoord(aSourceRect.iTl.iY,aDestRect.iTl.iY);
  1.1138 +	yLine.Construct(yCoord,TPoint(aSourceRect.iBr.iY,aDestRect.iBr.iY),TLinearDDA::ELeft);
  1.1139 +	TInt dummy;
  1.1140 +	yLine.JumpToYCoord2(dummy,clippedDestRect.iTl.iY);
  1.1141 +	yCoord.SetXY(dummy,clippedDestRect.iTl.iY);
  1.1142 +
  1.1143 +	const TInt srceWidth = aSourceRect.Width();
  1.1144 +	const TInt destWidth = aDestRect.Width();
  1.1145 +	const TInt clipWidth = clippedDestRect.Width();
  1.1146 +	const TInt clipStrch = clippedDestRect.iTl.iX - aDestRect.iTl.iX;
  1.1147 +	const TInt sourceBmpWidth = aSourceBitmap->SizeInPixels().iWidth;
  1.1148 +	const TInt maskWidth = aMaskBitmap->SizeInPixels().iWidth;
  1.1149 +	const TInt maskHeight = aMaskBitmap->SizeInPixels().iHeight;
  1.1150 +
  1.1151 +	TLineScanningPosition lineScanPos(aSourceBase);
  1.1152 +	TLineScanningPosition lineScanPos2(aSourceBase);
  1.1153 +	TLineScanningPosition lineScanPosMask(aMaskBase);
  1.1154 +
  1.1155 +	HBufC8* alphaBuffer = NULL;
  1.1156 +	TPtr8 alphaBufferDes(NULL, 0);
  1.1157 +	const TDisplayMode maskDisplayMode = aMaskBitmap->DisplayMode();
  1.1158 +
  1.1159 +	// Mask inversion is not supported if the original source mask format is EGray256.
  1.1160 +	// Note that this is only used for pre-multiplied alpha targets.
  1.1161 +	TUint8 maskInverter = (aInvertMask && maskDisplayMode != EGray256) ? 0xFF : 0x00;
  1.1162 +
  1.1163 +	if (aSourceBitmap != aMaskBitmap)
  1.1164 +		{
  1.1165 +		// Get buffer to be used to convert non-EGray256 masks to EGray256 when display mode is EColor16MAP
  1.1166 +		// or to tile the mask when the mask width is smaller than the source bitmap width.
  1.1167 +		if (maskDisplayMode != EGray256 && (dispMode == EColor16MAP || maskWidth < sourceBmpWidth))
  1.1168 +			{
  1.1169 +			alphaBuffer = CFbsBitmap::GetExtraBuffer(CFbsBitmap::ScanLineLength(maskWidth, EGray256));
  1.1170 +			if (!alphaBuffer)
  1.1171 +				{
  1.1172 +				return;  // Out of memory so do not draw anything 
  1.1173 +				}
  1.1174 +			alphaBufferDes.Set(alphaBuffer->Des());
  1.1175 +			}
  1.1176 +
  1.1177 +		// Get buffer to be used for decompressing compressed masks when mask is EGray256
  1.1178 +		if (maskDisplayMode == EGray256 && aMaskBitmap->IsCompressed())
  1.1179 +			{
  1.1180 +			HBufC8* hBuf= CFbsBitmap::GetDecompressionBuffer(aMaskBitmap->DataStride());
  1.1181 +			if (!hBuf)
  1.1182 +				{
  1.1183 +				return;  // Out of memory so do not draw anything
  1.1184 +				}
  1.1185 +			lineScanPosMask.iScanLineBuffer = hBuf;
  1.1186 +			}
  1.1187 +		}
  1.1188 +	const TPoint KZeroPoint(0,0);
  1.1189 +
  1.1190 +	while (yCoord.iY < clippedDestRect.iBr.iY)
  1.1191 +		{
  1.1192 +		// Draw only the source bitmap, if the source bitmap and the mask bitmap are same.
  1.1193 +		// else draw both the bitmaps
  1.1194 +		if (aSourceBitmap == aMaskBitmap)
  1.1195 +			{
  1.1196 +			aSourceBitmap->StretchScanLine(scanLineDes,TPoint(bitmapXStart,yCoord.iX),
  1.1197 +								 clipStrch,clipWidth,destWidth,aSourceRect.iTl.iX,
  1.1198 +								 srceWidth, KZeroPoint,dispMode,aSourceBase,lineScanPos);
  1.1199 +			if (yCoord.iY==clippedDestRect.iTl.iY)
  1.1200 +				aSourceBitmap->SetCompressionBookmark(lineScanPos,aSourceBase,NULL);
  1.1201 +			drawDevice->WriteLine(clippedDestRect.iTl.iX,yCoord.iY,clipWidth,scanLineBuffer,drawMode);
  1.1202 +			}
  1.1203 +		else if ((maskDisplayMode == EGray256) || (dispMode == EColor16MAP))
  1.1204 +			{
  1.1205 +			// Stretch the source bitmap and the mask bitmap for KScanLineLength as stretch length
  1.1206 +			// then do alpha blending for this length. If the length is more then KScanLineLength
  1.1207 +			// repeat it till you stretch complete destination length.
  1.1208 +			const TPoint startPt(bitmapXStart,yCoord.iX);
  1.1209 +			TInt clipWidthPart = clippedDestRect.Width();
  1.1210 +			TBool loopLast = ETrue;
  1.1211 +			if(clipWidthPart > KScanLineLength)
  1.1212 +				{
  1.1213 +				clipWidthPart = KScanLineLength;
  1.1214 +				loopLast = EFalse;
  1.1215 +				}
  1.1216 +			TInt clipIncStrch = clippedDestRect.iTl.iX - aDestRect.iTl.iX;
  1.1217 +			TInt startClip=clippedDestRect.iTl.iX;
  1.1218 +			TPoint sourceDestXCoords(bitmapXStart,clippedDestRect.iTl.iX);
  1.1219 +			xLine.Construct(TPoint(aSourceRect.iTl.iX,aDestRect.iTl.iX),
  1.1220 +							TPoint(aSourceRect.iBr.iX,aDestRect.iBr.iX),TLinearDDA::ELeft);
  1.1221 +			xLine.JumpToYCoord2(sourceDestXCoords.iX,sourceDestXCoords.iY);
  1.1222 +			TPoint srcPixel(bitmapXStart % maskWidth,yCoord.iX % maskHeight);
  1.1223 +			TInt spaceLeft = 0;
  1.1224 +			TRgb maskRgbValue;
  1.1225 +			TUint32* maskScanLinePtr32 = NULL;
  1.1226 +			TPoint currentYValue(0,srcPixel.iY);
  1.1227 +			aMaskBitmap->GetScanLinePtr(maskScanLinePtr32, currentYValue, maskWidth, aMaskBase, lineScanPosMask);
  1.1228 +			// To implement non EGray256 mask support with EColor16MAP display mode, we convert
  1.1229 +			// the mask to EGray256.
  1.1230 +			if (maskDisplayMode != EGray256) // Convert scan-line to EGray256 and set maskScanLinePtr32 to the conversion.
  1.1231 +				{
  1.1232 +				aMaskBitmap->GetScanLine(maskScanLinePtr32, alphaBufferDes, currentYValue, maskWidth, EFalse, TPoint(0, 0), EGray256);
  1.1233 +				maskScanLinePtr32 = (TUint32*)alphaBuffer->Ptr();
  1.1234 +				}
  1.1235 +			TUint8* maskScanLinePtr = reinterpret_cast<TUint8*>(maskScanLinePtr32);
  1.1236 +
  1.1237 +			// Outer loop over all KScanLineLengths
  1.1238 +			FOREVER
  1.1239 +				{
  1.1240 +				aSourceBitmap->StretchScanLine(sourceDes,startPt,clipIncStrch,clipWidthPart,destWidth,
  1.1241 +								aSourceRect.iTl.iX,srceWidth, KZeroPoint ,EColor16MU,aSourceBase,lineScanPos);
  1.1242 +				// Inner loop to tile the mask if necessary
  1.1243 +				spaceLeft = clipWidthPart;
  1.1244 +				do	{
  1.1245 +					srcPixel.iX = sourceDestXCoords.iX % maskWidth;
  1.1246 +			
  1.1247 +					// Invert the mask using the inversion mask.
  1.1248 +					maskBuffer[(sourceDestXCoords.iY-clippedDestRect.iTl.iX)%KScanLineLength]=
  1.1249 +						maskInverter^maskScanLinePtr[srcPixel.iX];
  1.1250 +					xLine.NextStep(sourceDestXCoords);
  1.1251 +					} while (--spaceLeft>0);
  1.1252 +				
  1.1253 +				if (yCoord.iY == clippedDestRect.iTl.iY && startClip == clippedDestRect.iTl.iX)
  1.1254 +					{
  1.1255 +					aSourceBitmap->SetCompressionBookmark(lineScanPos,aSourceBase,NULL);
  1.1256 +					aMaskBitmap->SetCompressionBookmark(lineScanPosMask,aMaskBase,NULL);
  1.1257 +					}
  1.1258 +				drawDevice->WriteRgbAlphaLine(startClip,yCoord.iY,clipWidthPart,sourceBuffer,maskBuffer, GcDrawMode(iDrawMode));
  1.1259 +				if (loopLast)
  1.1260 +					{
  1.1261 +					break;
  1.1262 +					}
  1.1263 +				startClip+=KScanLineLength;
  1.1264 +				if (clippedDestRect.iBr.iX - startClip <= KScanLineLength)
  1.1265 + 					{
  1.1266 +					loopLast = ETrue;
  1.1267 +					clipWidthPart = clippedDestRect.iBr.iX - startClip;
  1.1268 +					}
  1.1269 +				clipIncStrch += KScanLineLength;
  1.1270 +				}
  1.1271 +			}
  1.1272 +		else
  1.1273 +			{
  1.1274 +			aSourceBitmap->StretchScanLine(scanLineDes,TPoint(bitmapXStart,yCoord.iX),
  1.1275 +									 clipStrch,clipWidth,destWidth,aSourceRect.iTl.iX,
  1.1276 +									 srceWidth, KZeroPoint ,dispMode,aSourceBase,lineScanPos2);
  1.1277 +			drawDevice->WriteLine(clippedDestRect.iTl.iX,yCoord.iY,clipWidth,scanLineBuffer,CGraphicsContext::EDrawModeXOR);
  1.1278 +
  1.1279 +			TInt maskXStart = bitmapXStart % maskWidth;
  1.1280 +			if(maskWidth < sourceBmpWidth)
  1.1281 +				{
  1.1282 +				TPoint sourceDestXCoords(bitmapXStart,clippedDestRect.iTl.iX);
  1.1283 +				xLine.Construct(TPoint(aSourceRect.iTl.iX,aDestRect.iTl.iX),
  1.1284 +								TPoint(aSourceRect.iBr.iX,aDestRect.iBr.iX),TLinearDDA::ELeft);
  1.1285 +				xLine.JumpToYCoord2(sourceDestXCoords.iX,sourceDestXCoords.iY);
  1.1286 +				TPoint srcPixel(maskXStart,yCoord.iX % maskHeight);
  1.1287 +				TInt spaceLeft = clipWidth;
  1.1288 +				TPoint prevSourceDestXCoords(-1,-1);
  1.1289 +				TRgb maskRgbValue;
  1.1290 +				aMaskBitmap->GetScanLine(alphaBufferDes, TPoint(0,srcPixel.iY), maskWidth, EFalse, TPoint(0, 0), EGray256, aMaskBase, lineScanPosMask);
  1.1291 +
  1.1292 +				// Loop to tile the mask
  1.1293 +				do	{
  1.1294 +					if (sourceDestXCoords.iY != prevSourceDestXCoords.iY)
  1.1295 +						{
  1.1296 +						if (sourceDestXCoords.iX != prevSourceDestXCoords.iX)
  1.1297 +							{
  1.1298 +							srcPixel.iX = sourceDestXCoords.iX % maskWidth;
  1.1299 +							if (srcPixel.iX < 0)
  1.1300 +								srcPixel.iX += maskWidth;
  1.1301 +							maskRgbValue = TRgb::Gray256((*alphaBuffer)[srcPixel.iX]);
  1.1302 +							}
  1.1303 +						drawDevice->WriteRgb(sourceDestXCoords.iY,yCoord.iY,maskRgbValue,drawMode);
  1.1304 +						spaceLeft--;
  1.1305 +						}
  1.1306 +					prevSourceDestXCoords = sourceDestXCoords;
  1.1307 +					xLine.SingleStep(sourceDestXCoords);
  1.1308 +					} while (spaceLeft > 0);
  1.1309 +				}
  1.1310 +			else
  1.1311 +				{
  1.1312 +				// No need to tile the mask
  1.1313 +				aMaskBitmap->StretchScanLine(scanLineDes,TPoint(maskXStart,yCoord.iX % maskHeight),
  1.1314 +										clipStrch,clipWidth,destWidth,aSourceRect.iTl.iX,
  1.1315 +										srceWidth, KZeroPoint ,dispMode,aMaskBase,lineScanPosMask);
  1.1316 +				drawDevice->WriteLine(clippedDestRect.iTl.iX,yCoord.iY,clipWidth,scanLineBuffer,drawMode);
  1.1317 +				// Redo stretching of the aSourceBitmap scanline
  1.1318 +				aSourceBitmap->StretchScanLine(scanLineDes,TPoint(bitmapXStart,yCoord.iX),
  1.1319 +									 	clipStrch,clipWidth,destWidth,aSourceRect.iTl.iX,
  1.1320 +									 	srceWidth, KZeroPoint ,dispMode,aSourceBase,lineScanPos2);
  1.1321 +				}
  1.1322 +
  1.1323 +			if (yCoord.iY==clippedDestRect.iTl.iY)
  1.1324 +				{
  1.1325 +				aSourceBitmap->SetCompressionBookmark(lineScanPos2,aSourceBase,NULL);
  1.1326 +				aMaskBitmap->SetCompressionBookmark(lineScanPosMask,aMaskBase,NULL);
  1.1327 +				}
  1.1328 +
  1.1329 +			drawDevice->WriteLine(clippedDestRect.iTl.iX,yCoord.iY,clipWidth,scanLineBuffer,CGraphicsContext::EDrawModeXOR);
  1.1330 +			}
  1.1331 +		yLine.NextStep(yCoord);
  1.1332 +		}
  1.1333 +	}
  1.1334 +
  1.1335 +TInt CSwDirectGdiEngine::FastBlendInterface(const CBitwiseBitmap* aSource, const CBitwiseBitmap* aMask, MFastBlend*& aFastBlend) const
  1.1336 +	{
  1.1337 +	#if defined(__ALLOW_FAST_BLEND_DISABLE__)
  1.1338 +	if (iFastBlendDisabled)
  1.1339 +		return(KErrNotSupported);
  1.1340 +	#endif
  1.1341 +	if ((aSource && aSource->IsCompressed()) || (aMask && aMask->IsCompressed()))
  1.1342 +		return(KErrNotSupported);
  1.1343 +	TAny* interface=NULL;
  1.1344 +	TInt ret= iDrawDevice->GetInterface(KFastBlendInterfaceID, interface);
  1.1345 +	aFastBlend=(MFastBlend*)interface;
  1.1346 +	return(ret);
  1.1347 +	}
  1.1348 +
  1.1349 +/*
  1.1350 +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.1351 +
  1.1352 +@see CBitwiseBitmap::GetScanLine()
  1.1353 +@see CBitwiseBitmap::GetVerticalScanLine()
  1.1354 +@see CBitwiseBitmap::StretchScanLine()
  1.1355 +@see CFbsDrawDevice::WriteLine()
  1.1356 +@internalComponent
  1.1357 +*/
  1.1358 +TDisplayMode CSwDirectGdiEngine::ScanLineBufferDisplayMode(CFbsDrawDevice* aDrawDevice)
  1.1359 +	{
  1.1360 +	return iDrawMode == DirectGdi::EDrawModeWriteAlpha ? aDrawDevice->DisplayMode() : aDrawDevice->ScanLineDisplayMode();
  1.1361 +	}