graphicsdeviceinterface/directgdiadaptation/swsrc/swdirectgdibitblt.cpp
changeset 0 5d03bc08d59c
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "swdirectgdiengine.h"
       
    17 #include "swdirectgdidriverimpl.h"
       
    18 #include "directgdiadapter.h"
       
    19 #include <bitdrawinterfaceid.h>
       
    20 #include <bmalphablend.h>
       
    21 #include <graphics/bitmap.inl>
       
    22 #include <graphics/gdi/gdiinline.inl>
       
    23 
       
    24 /** 
       
    25 @see MDirectGdiEngine::BitBlt()
       
    26 @panic DGDIAdapter 7, aBitmap is invalid (debug only). 
       
    27 */
       
    28 void CSwDirectGdiEngine::BitBlt(const TPoint& aDestPos, 
       
    29 								const CFbsBitmap& aBitmap,	
       
    30 								const TRect& aSrceRect)
       
    31 	{
       
    32 	if (aBitmap.ExtendedBitmapType() != KNullUid)
       
    33 		{
       
    34 		iDriver->SetError(KErrNotSupported); // Not supported for extended bitmaps
       
    35 		return;
       
    36 		}
       
    37 	
       
    38 	TRect srceRect(aSrceRect);
       
    39 	const TPoint destPoint(aDestPos + iOrigin + srceRect.iTl - aSrceRect.iTl);
       
    40 	const TPoint offset(srceRect.iTl - destPoint);
       
    41 
       
    42 	TRect targetRect(destPoint,srceRect.Size());
       
    43 	aBitmap.BeginDataAccess();
       
    44 
       
    45 	CBitwiseBitmap* srce = static_cast<const CSwDirectGdiBitmap&>(aBitmap).Address();
       
    46 	GRAPHICS_ASSERT_DEBUG(srce,EDirectGdiPanicInvalidBitmap);
       
    47 	
       
    48 	const TInt limit = iDefaultRegionPtr->Count();		
       
    49 			
       
    50 	TBool opaqueSource = (!IsAlphaChannel(aBitmap.DisplayMode())) && (iDrawMode == DirectGdi::EDrawModePEN);	
       
    51 
       
    52 	TRect clipRect;
       
    53 	for (TInt count = 0; count < limit; count++)
       
    54 		{
       
    55 		clipRect = (*iDefaultRegionPtr)[count];
       
    56 		if(!clipRect.Intersects(targetRect))
       
    57 			{
       
    58 			continue;
       
    59 			}
       
    60 		
       
    61 		clipRect.Intersection(targetRect);
       
    62 		
       
    63 		TRect clippedSrceRect(clipRect);
       
    64 		clippedSrceRect.Move(offset);
       
    65 
       
    66 		if (opaqueSource)
       
    67 			{
       
    68 			iDrawMode = DirectGdi::EDrawModeWriteAlpha; // write rather than blend.
       
    69 			}		
       
    70 		
       
    71 		DoBitBlt(clipRect.iTl, srce, aBitmap.DataAddress(), aBitmap.DataStride(), clippedSrceRect);
       
    72 		
       
    73 		if (opaqueSource)
       
    74 			{
       
    75 			iDrawMode = DirectGdi::EDrawModePEN; // set it back to how it was.
       
    76 			}
       
    77 		
       
    78 		iDrawDevice->UpdateRegion(clipRect);
       
    79 		}
       
    80 	
       
    81 	aBitmap.EndDataAccess(ETrue);	
       
    82 	}
       
    83 
       
    84 /**
       
    85 @see MDirectGdiEngine::BitBltMasked(const TPoint&, const CFbsBitmap&, const TRect&, const CFbsBitmap&, TBool)
       
    86 @panic DGDIAdapter 7, if either aMaskBitmap or aBitmap are invalid (debug only).
       
    87 */
       
    88 void CSwDirectGdiEngine::BitBltMasked(const TPoint& aDestPos,
       
    89 			  const CFbsBitmap& aBitmap,
       
    90 			  const TRect& aSrcRect,
       
    91 			  const CFbsBitmap& aMaskBitmap,
       
    92 			  TBool aInvertMask)
       
    93 	{
       
    94 	if ((aBitmap.ExtendedBitmapType() != KNullUid) || (aMaskBitmap.ExtendedBitmapType() != KNullUid))
       
    95 		{
       
    96 		iDriver->SetError(KErrNotSupported); // Not supported for extended bitmaps
       
    97 		return;
       
    98 		}
       
    99 	
       
   100 	TRect localSrcRect(aSrcRect);
       
   101 	const TPoint destPoint(aDestPos + iOrigin + localSrcRect.iTl - aSrcRect.iTl);
       
   102 	const TRect destRect(destPoint, localSrcRect.Size());
       
   103 	const TPoint offset(localSrcRect.iTl - destPoint);
       
   104 	
       
   105 	TRect targetRect(destRect);
       
   106 	aBitmap.BeginDataAccess();
       
   107 	aMaskBitmap.BeginDataAccess();
       
   108 	
       
   109 	CBitwiseBitmap* srcebmp = static_cast<const CSwDirectGdiBitmap&>(aBitmap).Address();
       
   110 	CBitwiseBitmap* maskbmp = static_cast<const CSwDirectGdiBitmap&>(aMaskBitmap).Address();		
       
   111 	
       
   112 	GRAPHICS_ASSERT_DEBUG(srcebmp,EDirectGdiPanicInvalidBitmap);
       
   113 	GRAPHICS_ASSERT_DEBUG(maskbmp,EDirectGdiPanicInvalidBitmap);
       
   114 	
       
   115 	const TDisplayMode maskMode = maskbmp->DisplayMode();
       
   116 	const TInt limit = iDefaultRegionPtr->Count();
       
   117 	TBool opaqueSource = (!IsAlphaChannel(aBitmap.DisplayMode())) && (iDrawMode == DirectGdi::EDrawModePEN);
       
   118 	TRect clipRect;
       
   119 	for (TInt count = 0; count < limit; count++)
       
   120 		{
       
   121 		clipRect = (*iDefaultRegionPtr)[count];
       
   122 		if (!clipRect.Intersects(targetRect))
       
   123 			{
       
   124 			continue;
       
   125 			}
       
   126 		
       
   127 		clipRect.Intersection(targetRect);
       
   128 		TRect clippedSrceRect(clipRect);
       
   129 		clippedSrceRect.Move(offset);
       
   130 		
       
   131 		if (opaqueSource)
       
   132 			{
       
   133 			iDrawMode = DirectGdi::EDrawModeWriteAlpha; // ie write rather than blend
       
   134 			}
       
   135 		
       
   136 		DoBitBltMasked(clipRect.iTl, srcebmp, aBitmap.DataAddress(), clippedSrceRect, maskbmp, 
       
   137 				aMaskBitmap.DataAddress(), aInvertMask);
       
   138 		
       
   139 		if (opaqueSource)
       
   140 			{
       
   141 			iDrawMode = DirectGdi::EDrawModePEN; // set to default
       
   142 			}
       
   143 		iDrawDevice->UpdateRegion(clipRect);
       
   144 		}
       
   145 	
       
   146 	aBitmap.EndDataAccess(ETrue);
       
   147 	aMaskBitmap.EndDataAccess(ETrue);	
       
   148 	}
       
   149 
       
   150 
       
   151 /**
       
   152 @see MDirectGdiEngine::BitBltMasked(const TPoint&, const CFbsBitmap&, const TRect&, const CFbsBitmap&, const TPoint&)
       
   153 @panic DGDIAdapter 7, if either aBitmap or aMaskBitmap are invalid.
       
   154 @panic DGDIAdapter 1022, if the top-left corner of aSrcRect is out of bounds (debug only).
       
   155 */
       
   156 void CSwDirectGdiEngine::BitBltMasked(const TPoint& aDestPt,
       
   157 		const CFbsBitmap& aBitmap, const TRect& aSrcRect,
       
   158 		const CFbsBitmap& aMaskBitmap, const TPoint& aAlphaPt)
       
   159 	{
       
   160 	if ((aBitmap.ExtendedBitmapType() != KNullUid) || (aMaskBitmap.ExtendedBitmapType() != KNullUid))
       
   161 		{
       
   162 		iDriver->SetError(KErrNotSupported); // Not supported for extended bitmaps
       
   163 		return;
       
   164 		}
       
   165 	
       
   166 	TRect srcRect(aSrcRect);
       
   167 	//Calculate the destination rect
       
   168 	TPoint destPt(aDestPt + iOrigin);
       
   169 	TRect destRect(destPt, srcRect.Size());
       
   170 	TPoint offset(srcRect.iTl - destPt);
       
   171 	TRect targetRect(destRect);
       
   172 
       
   173 	aBitmap.BeginDataAccess();
       
   174 	aMaskBitmap.BeginDataAccess();
       
   175 	CBitwiseBitmap* srcBmp = static_cast<const CSwDirectGdiBitmap&>(aBitmap).Address();
       
   176 	CBitwiseBitmap* alphaBmp = static_cast<const CSwDirectGdiBitmap&>(aMaskBitmap).Address();
       
   177 	GRAPHICS_ASSERT_DEBUG(srcBmp, EDirectGdiPanicInvalidBitmap);
       
   178 	GRAPHICS_ASSERT_DEBUG(alphaBmp, EDirectGdiPanicInvalidBitmap);
       
   179 	TUint32* srcDataAddr = aBitmap.DataAddress();
       
   180 	TUint32* alphaDataAddr = aMaskBitmap.DataAddress();
       
   181 
       
   182 	//For each region - find the clipping rect and draw
       
   183 	TInt limit = iDefaultRegionPtr->Count ();
       
   184 	TRect clipRect;
       
   185 	for (TInt count=0; count<limit;count++)
       
   186 		{
       
   187 		clipRect=(*iDefaultRegionPtr)[count];
       
   188 		if ( !clipRect.Intersects(targetRect))
       
   189 			{
       
   190 			continue;
       
   191 			}
       
   192 		//targetRect was constructed from destRect. destRect was constructed from srcRect.
       
   193 		clipRect.Intersection (targetRect);
       
   194 		TRect clippedSrcRect(clipRect);
       
   195 		clippedSrcRect.Move(offset);//clippedSrcRect - maps to a part of srcRect now.
       
   196 		TPoint shift(clippedSrcRect.iTl - srcRect.iTl);
       
   197 		GRAPHICS_ASSERT_DEBUG(shift.iX >= 0, EDirectGdiPanicNegativeShift);
       
   198 		GRAPHICS_ASSERT_DEBUG(shift.iY >= 0, EDirectGdiPanicNegativeShift);
       
   199 		DoBitBltAlpha (clipRect.iTl, srcBmp, srcDataAddr, clippedSrcRect,
       
   200 				alphaBmp, alphaDataAddr, aAlphaPt + shift, EFalse);
       
   201 		iDrawDevice->UpdateRegion (clipRect);
       
   202 		}
       
   203 
       
   204 	aBitmap.EndDataAccess(ETrue);
       
   205 	aMaskBitmap.EndDataAccess(ETrue);
       
   206 	return;
       
   207 	}			
       
   208 
       
   209 /** 
       
   210 Calculates the position into the scanline for the given x coordinate.
       
   211 
       
   212 @param aX The given x-coordinate.
       
   213 @param aDisplayMode The applied display mode.
       
   214 @return The memory offset, or 0 if the mode is not supported.
       
   215 @panic DGDIAdapter 1009, if aDisplayMode is not supported (debug only).
       
   216 */
       
   217 TUint CSwDirectGdiEngine::MemoryOffsetForPixelPitch(TUint aX, TDisplayMode aDisplayMode) const
       
   218 	{	
       
   219 	switch (aDisplayMode)
       
   220 		{
       
   221 		case EColor16MU:
       
   222 		case EColor16MAP:
       
   223 			return aX << 2;
       
   224 		case EColor64K:
       
   225 			return aX << 1;
       
   226 		default:
       
   227 			GRAPHICS_PANIC_DEBUG(EDirectGdiPanicInvalidDisplayMode);
       
   228 		}
       
   229 	return 0;
       
   230 	}
       
   231 
       
   232 TUint32* CSwDirectGdiEngine::GetScanLineOffsetPtr(CBitwiseBitmap* aSrce, TUint32*& aSlptr, 
       
   233 		TInt aLength, TPoint aPixel, TUint32* aBase, 
       
   234 		TLineScanningPosition& aLineScanningPosition, TUint aXOffset)
       
   235 	{
       
   236 	aSrce->GetScanLinePtr(aSlptr, aLength, aPixel, aBase, aLineScanningPosition);
       
   237 	return (TUint32*)((TUint8*)aSlptr + aXOffset);
       
   238 	}
       
   239 
       
   240 /**
       
   241 Performs the actual bitblt to the device.
       
   242 This function may also be called by DrawBitmap(), and DrawRect() when using a patterned brush, 
       
   243 so any changes to this function may impact on them also.
       
   244 
       
   245 @pre aSrce A bitmap with non-zero dimensions. aSrceRect has been clipped against the target.
       
   246 
       
   247 @param aDest The target position on the device which will contain the top left 
       
   248              corner of the source bitmap.
       
   249 @param aSrce The bitmap object that contains the pixels to draw.
       
   250 @param aBase The address of the bitmap pixels.
       
   251 @param aStride The length in bytes between scanlines in memory.
       
   252 @param aSrceRect The area of the bitmap to draw from.
       
   253 @panic DGDIAdapter 1013, if aDest is fully outside of the bounds of the target, or aSrceRect.iTl is not
       
   254        within the drawing area (debug only).
       
   255 */
       
   256 void CSwDirectGdiEngine::DoBitBlt(const TPoint& aDest,
       
   257 		 CBitwiseBitmap* aSrce,
       
   258 		 TUint32* aBase,
       
   259 		 TInt aStride,
       
   260 		 const TRect& aSrceRect)
       
   261 	{
       
   262 	// Does multiple bitmap widths for painting rects only
       
   263 	const TInt width = aSrceRect.Width ();
       
   264 
       
   265 #ifdef _DEBUG
       
   266 	TRect deviceDestRect;
       
   267 	iDrawDevice->GetDrawRect(deviceDestRect);
       
   268 	GRAPHICS_ASSERT_DEBUG(aDest.iX >= deviceDestRect.iTl.iX, EDirectGdiPanicOutOfBounds);
       
   269 	GRAPHICS_ASSERT_DEBUG(aDest.iY >= deviceDestRect.iTl.iY, EDirectGdiPanicOutOfBounds);
       
   270 	GRAPHICS_ASSERT_DEBUG((aDest.iX + aSrceRect.Width()) <= deviceDestRect.iBr.iX, EDirectGdiPanicOutOfBounds);
       
   271 	GRAPHICS_ASSERT_DEBUG((aDest.iY + aSrceRect.Height()) <= deviceDestRect.iBr.iY, EDirectGdiPanicOutOfBounds);
       
   272 	GRAPHICS_ASSERT_DEBUG(aDest.iX >= 0 && aDest.iY >= 0, EDirectGdiPanicOutOfBounds);
       
   273 	GRAPHICS_ASSERT_DEBUG(aSrceRect.iTl.iX >= 0 && aSrceRect.iTl.iY >= 0, EDirectGdiPanicOutOfBounds);
       
   274 #endif
       
   275 
       
   276 	TSize srcSize = aSrce->SizeInPixels ();
       
   277 	
       
   278 	const TPoint KZeroPoint(0,0);
       
   279 	TAny* interface = NULL;
       
   280 	if (iDrawMode == DirectGdi::EDrawModeWriteAlpha &&
       
   281 			aSrceRect.iBr.iX <= srcSize.iWidth && 
       
   282 			aSrceRect.iBr.iY <= srcSize.iHeight &&
       
   283 			!aSrce->IsCompressed() && 
       
   284 			aSrce->DisplayMode() == iDrawDevice->DisplayMode() && 
       
   285 			iDrawDevice->GetInterface(KFastBlit2InterfaceID, interface) == KErrNone)
       
   286 		{
       
   287 		// Conditions in CFbsBitGc allow for optimised blitting.
       
   288 		// The draw device supports the optimised blitting function.
       
   289 		// Operation may fail regardless due to unacceptable conditions in the draw device.
       
   290 		MFastBlit2* fastBlit = reinterpret_cast<MFastBlit2*>(interface);
       
   291 		if (fastBlit && (fastBlit->WriteBitmapBlock(aDest, aBase, aStride, srcSize, aSrceRect) == KErrNone))			
       
   292 			{
       
   293 			return;
       
   294 			}			
       
   295 		}
       
   296 
       
   297 	MFastBlend* fastBlend=NULL;
       
   298 	if (FastBlendInterface(aSrce,NULL,fastBlend)==KErrNone)
       
   299 		{
       
   300 		if (fastBlend->FastBlendBitmap(aDest, aBase, aStride, srcSize, aSrceRect, aSrce->DisplayMode(), GcDrawMode(iDrawMode), CFbsDrawDevice::ENoShadow)== KErrNone)
       
   301 			{
       
   302 			return;
       
   303 			}
       
   304 		}
       
   305 	
       
   306 	const TInt scanLineBytes = iDrawDevice->ScanLineBytes();
       
   307 	TUint32* scanLineBuffer = iDrawDevice->ScanLineBuffer();
       
   308 	TPtr8 scanLineDes((TUint8*)scanLineBuffer, scanLineBytes, scanLineBytes);
       
   309 
       
   310 	const TDisplayMode dispMode = ScanLineBufferDisplayMode(iDrawDevice);
       
   311 	
       
   312 	const TBool useScanLinePtr = (dispMode == aSrce->DisplayMode()) && 
       
   313 		(TDisplayModeUtils::NumDisplayModeBitsPerPixel(dispMode) >= 8);
       
   314 
       
   315 	TUint32* slptr = NULL;
       
   316 	TUint offset = 0;
       
   317 	TUint32* lastScanLine = NULL;
       
   318 	if (useScanLinePtr)
       
   319 		{
       
   320 		lastScanLine = aSrce->ScanLineAddress(aBase, aSrceRect.iBr.iY-1);
       
   321 		}
       
   322 
       
   323 	TInt srceWidth = srcSize.iWidth;
       
   324 	TInt partlinestart = aSrceRect.iTl.iX % srceWidth;
       
   325 	
       
   326 	if (partlinestart < 0)
       
   327 		{
       
   328 		partlinestart += srceWidth;
       
   329 		}
       
   330 	
       
   331 	const TInt partlinelength = Min(srceWidth - partlinestart, width);
       
   332 	TInt destX = aDest.iX;
       
   333 	const TInt destXlimit = destX+width;
       
   334 	const CGraphicsContext::TDrawMode drawMode = GcDrawMode(iDrawMode);
       
   335 
       
   336 	// first part line
       
   337 	if (partlinestart > 0 && partlinelength > 0)
       
   338 		{
       
   339 		TPoint srcecoord1(partlinestart, aSrceRect.iTl.iY);
       
   340 		TInt desty = aDest.iY;
       
   341 
       
   342 		TLineScanningPosition lineScanPos(aBase);
       
   343 
       
   344 		if (useScanLinePtr)
       
   345 			{
       
   346 			offset = MemoryOffsetForPixelPitch(partlinestart, dispMode);
       
   347 			if (aSrce->IsCompressed ())
       
   348 				{
       
   349 				
       
   350 				while (srcecoord1.iY < aSrceRect.iBr.iY)
       
   351 					{
       
   352 					scanLineBuffer = GetScanLineOffsetPtr (aSrce, slptr,
       
   353 							partlinelength, srcecoord1, aBase, lineScanPos, offset);
       
   354 					if (srcecoord1.iY == aSrceRect.iTl.iY)
       
   355 						{
       
   356 						aSrce->SetCompressionBookmark(lineScanPos, aBase, NULL);
       
   357 						}
       
   358 					iDrawDevice->WriteLine(aDest.iX, desty, partlinelength,
       
   359 							scanLineBuffer, drawMode);
       
   360 					srcecoord1.iY++;
       
   361 					desty++;				
       
   362 					}
       
   363 				}
       
   364 			else
       
   365 				{
       
   366 				while (srcecoord1.iY < aSrceRect.iBr.iY)
       
   367 					{
       
   368 					scanLineBuffer = GetScanLineOffsetPtr (aSrce, slptr,
       
   369 							partlinelength, srcecoord1, aBase, lineScanPos,
       
   370 							offset);
       
   371 					do
       
   372 						{
       
   373 						iDrawDevice->WriteLine (aDest.iX, desty,
       
   374 								partlinelength, scanLineBuffer, drawMode);
       
   375 						scanLineBuffer = (TUint32*)((TUint8*)scanLineBuffer + aStride);
       
   376 						srcecoord1.iY++;
       
   377 						desty++;
       
   378 						}
       
   379 					while ((srcecoord1.iY < aSrceRect.iBr.iY) && (scanLineBuffer < lastScanLine)) ;
       
   380 					}
       
   381 				}
       
   382 			}
       
   383 		else
       
   384 			{
       
   385 			for ( ; srcecoord1.iY < aSrceRect.iBr.iY; srcecoord1.iY++, desty++)
       
   386 				{
       
   387 				aSrce->GetScanLine (scanLineDes, srcecoord1, partlinelength,
       
   388 						EFalse, KZeroPoint, dispMode, aBase, lineScanPos);
       
   389 				if ( srcecoord1.iY==aSrceRect.iTl.iY)
       
   390 					{
       
   391 					aSrce->SetCompressionBookmark (lineScanPos, aBase, NULL);
       
   392 					}
       
   393 				iDrawDevice->WriteLine (aDest.iX, desty, partlinelength,
       
   394 						scanLineBuffer, drawMode);
       
   395 				}
       
   396 			}
       
   397 
       
   398 		destX += partlinelength;
       
   399 		}
       
   400 
       
   401 	// multiple complete lines - columns
       
   402 	TInt numcolumns = (destXlimit - destX) / srceWidth;
       
   403 	
       
   404 	if (numcolumns > 0)
       
   405 		{
       
   406 		TPoint srcecoord2(0, aSrceRect.iTl.iY);
       
   407 		TInt desty = aDest.iY;
       
   408 
       
   409 		TLineScanningPosition lineScanPos(aBase);
       
   410 
       
   411 		if (useScanLinePtr)
       
   412 			{
       
   413 			if (aSrce->IsCompressed())
       
   414 				{
       
   415 				while (srcecoord2.iY < aSrceRect.iBr.iY)
       
   416 					{
       
   417 					TPoint coord(srcecoord2);
       
   418 					aSrce->GetScanLinePtr (slptr, srceWidth, coord, aBase, lineScanPos);
       
   419 					if (srcecoord2.iY == aSrceRect.iTl.iY)
       
   420 						{
       
   421 						aSrce->SetCompressionBookmark(lineScanPos, aBase, NULL);
       
   422 						}
       
   423 					TInt tempdestX = destX;
       
   424 					for (TInt count = 0; count < numcolumns; count++, tempdestX += srceWidth)
       
   425 						{
       
   426 						iDrawDevice->WriteLine(tempdestX, desty, srceWidth, slptr, drawMode);
       
   427 						}
       
   428 					srcecoord2.iY++;
       
   429 					desty++;
       
   430 					}
       
   431 				}
       
   432 			else
       
   433 				{
       
   434 				while (srcecoord2.iY < aSrceRect.iBr.iY)
       
   435 					{
       
   436 					TPoint coord(srcecoord2);
       
   437 					aSrce->GetScanLinePtr (slptr, srceWidth, coord, aBase, lineScanPos);
       
   438 					do
       
   439 						{
       
   440 						TInt tempdestX = destX;
       
   441 						for (TInt count = 0; count < numcolumns; count++, tempdestX += srceWidth)
       
   442 							{
       
   443 							iDrawDevice->WriteLine (tempdestX, desty, srceWidth, slptr, drawMode);
       
   444 							}
       
   445 						slptr = (TUint32*)((TUint8*)slptr + aStride);
       
   446 						srcecoord2.iY++;
       
   447 						desty++;
       
   448 						}
       
   449 					while ((srcecoord2.iY < aSrceRect.iBr.iY) && (slptr < lastScanLine));
       
   450 					}
       
   451 				}
       
   452 			}
       
   453 		else
       
   454 			{
       
   455 			for (; srcecoord2.iY < aSrceRect.iBr.iY; srcecoord2.iY++, desty++)
       
   456 				{
       
   457 				TInt tempdestX = destX;
       
   458 				TPoint coord(srcecoord2);
       
   459 				aSrce->GetScanLinePtr (slptr, srceWidth, coord, aBase, lineScanPos);
       
   460 				if (srcecoord2.iY == aSrceRect.iTl.iY)
       
   461 					{
       
   462 					aSrce->SetCompressionBookmark (lineScanPos, aBase, NULL);
       
   463 					}
       
   464 				for (TInt count = 0; count < numcolumns; count++, tempdestX += srceWidth)
       
   465 					{
       
   466 					aSrce->GetScanLine(slptr, scanLineDes, coord, srceWidth,
       
   467 							EFalse, KZeroPoint, dispMode);
       
   468 					iDrawDevice->WriteLine(tempdestX, desty, srceWidth, scanLineBuffer, drawMode);
       
   469 					}
       
   470 				}
       
   471 			}
       
   472 
       
   473 		destX += numcolumns * srceWidth;
       
   474 		}
       
   475 
       
   476 	// final part line
       
   477 	if (destX < destXlimit)
       
   478 		{
       
   479 		const TInt restofline = destXlimit - destX;
       
   480 		TPoint srcecoord3(0, aSrceRect.iTl.iY);
       
   481 		TInt desty = aDest.iY;
       
   482 
       
   483 		TLineScanningPosition lineScanPos(aBase);
       
   484 
       
   485 		if (useScanLinePtr)
       
   486 			{
       
   487 			offset = 0;
       
   488 			if (aSrce->IsCompressed())
       
   489 				{
       
   490 				while (srcecoord3.iY < aSrceRect.iBr.iY)
       
   491 					{
       
   492 					scanLineBuffer = GetScanLineOffsetPtr (aSrce, slptr,
       
   493 							srceWidth, srcecoord3, aBase, lineScanPos, offset);
       
   494 					if (srcecoord3.iY == aSrceRect.iTl.iY)
       
   495 						{
       
   496 						aSrce->SetCompressionBookmark (lineScanPos, aBase, NULL);
       
   497 						}
       
   498 					iDrawDevice->WriteLine(destX, desty, restofline, scanLineBuffer, drawMode);
       
   499 					srcecoord3.iY++;
       
   500 					desty++;
       
   501 					}
       
   502 				}
       
   503 			else
       
   504 				{
       
   505 				while (srcecoord3.iY < aSrceRect.iBr.iY)
       
   506 					{
       
   507 					scanLineBuffer = GetScanLineOffsetPtr (aSrce, slptr,
       
   508 							srceWidth, srcecoord3, aBase, lineScanPos, offset);
       
   509 					do
       
   510 						{
       
   511 						iDrawDevice->WriteLine(destX, desty, restofline, scanLineBuffer, drawMode);
       
   512 						scanLineBuffer = (TUint32*)((TUint8*)scanLineBuffer + aStride);
       
   513 						srcecoord3.iY++;
       
   514 						desty++;
       
   515 						}
       
   516 					while ((srcecoord3.iY < aSrceRect.iBr.iY) && (scanLineBuffer < lastScanLine));
       
   517 					}
       
   518 				}
       
   519 			}
       
   520 		else
       
   521 			{
       
   522 			for (; srcecoord3.iY < aSrceRect.iBr.iY; srcecoord3.iY++, desty++)
       
   523 				{
       
   524 				aSrce->GetScanLine (scanLineDes, srcecoord3, srceWidth, EFalse,
       
   525 						KZeroPoint, dispMode, aBase, lineScanPos);
       
   526 				if (srcecoord3.iY == aSrceRect.iTl.iY)
       
   527 					{
       
   528 					aSrce->SetCompressionBookmark (lineScanPos, aBase, NULL);
       
   529 					}
       
   530 				iDrawDevice->WriteLine(destX, desty, restofline, scanLineBuffer, drawMode);
       
   531 				}
       
   532 			}
       
   533 		}
       
   534 	}
       
   535 /** 
       
   536 Performs the masked bitblt to the device.
       
   537 
       
   538 @param aDest The target position on the device which will contain the top left 
       
   539              corner of the source bitmap.
       
   540 @param aSourceBitmap The bitmap object that contains the pixels to draw.
       
   541 @param aSourceBase The address of the source bitmap pixels.
       
   542 @param aSourceRect The area of the bitmap to draw from.
       
   543 @param aMaskBitmap The bitmap object that contains the mask.
       
   544 @param aMaskBase The address of the mask pixels.
       
   545 @param aInvertMask Inverts the mask if ETrue.
       
   546 @panic DGDIAdapter 1013, if aDest is outside of the device bounds (debug only).
       
   547 */
       
   548 void CSwDirectGdiEngine::DoBitBltMasked(const TPoint& aDest,
       
   549 		   CBitwiseBitmap* aSourceBitmap,
       
   550 		   TUint32* aSourceBase,
       
   551 		   const TRect& aSourceRect,
       
   552 		   CBitwiseBitmap* aMaskBitmap,
       
   553 		   TUint32* aMaskBase,
       
   554 		   TBool aInvertMask)
       
   555 	{
       
   556 #ifdef _DEBUG
       
   557 	TRect deviceDestRect;
       
   558 	iDrawDevice->GetDrawRect (deviceDestRect);
       
   559 #endif
       
   560 	
       
   561     GRAPHICS_ASSERT_DEBUG (aDest.iX >= deviceDestRect.iTl.iX, EDirectGdiPanicOutOfBounds);
       
   562 	GRAPHICS_ASSERT_DEBUG (aDest.iY >= deviceDestRect.iTl.iY, EDirectGdiPanicOutOfBounds);
       
   563 	GRAPHICS_ASSERT_DEBUG ((aDest.iX + aSourceRect.Width()) <= deviceDestRect.iBr.iX, EDirectGdiPanicOutOfBounds);
       
   564 	GRAPHICS_ASSERT_DEBUG ((aDest.iY + aSourceRect.Height()) <= deviceDestRect.iBr.iY, EDirectGdiPanicOutOfBounds);	
       
   565 	const TPoint KZeroPoint(0,0);
       
   566 
       
   567 	MFastBlend* fastBlend=NULL;
       
   568 	if (FastBlendInterface(aSourceBitmap,aMaskBitmap,fastBlend)==KErrNone)
       
   569 		{
       
   570 		if (fastBlend->FastBlendBitmapMasked(aDest, aSourceBase, aSourceBitmap->DataStride(), aSourceBitmap->SizeInPixels(), aSourceRect, aSourceBitmap->DisplayMode(),
       
   571 							aMaskBase, aMaskBitmap->DataStride(), aMaskBitmap->DisplayMode(), aMaskBitmap->SizeInPixels(), aSourceRect.iTl, aInvertMask,
       
   572 							GcDrawMode(iDrawMode), CFbsDrawDevice::ENoShadow)==KErrNone)
       
   573 			{
       
   574 			return;
       
   575 			}
       
   576 		}
       
   577 	
       
   578 	if (aMaskBitmap->DisplayMode() == EGray256)
       
   579 		{
       
   580 		DoBitBltAlpha (aDest, aSourceBitmap, aSourceBase, aSourceRect,
       
   581 				aMaskBitmap, aMaskBase, aSourceRect.iTl, EFalse);
       
   582 		}
       
   583 	// if screen driver is 16MAP we avoid logical operator pen modes by using DoBitBltAlpha() for blitting
       
   584 	else if(iDrawDevice->ScanLineDisplayMode() == EColor16MAP)
       
   585 		{
       
   586 		DoBitBltAlpha (aDest, aSourceBitmap, aSourceBase, aSourceRect,
       
   587 				aMaskBitmap, aMaskBase, aSourceRect.iTl, aInvertMask);
       
   588 		}
       
   589 	else if (aSourceBitmap == aMaskBitmap)
       
   590 		{
       
   591 		const TInt width = aSourceRect.Width();
       
   592 		const TDisplayMode dispMode = ScanLineBufferDisplayMode(iDrawDevice);
       
   593 		const CGraphicsContext::TDrawMode drawMode = aInvertMask ? CGraphicsContext::EDrawModeAND : CGraphicsContext::EDrawModeOR;
       
   594 		TPoint srcePoint(aSourceRect.iTl);
       
   595 		TInt destY = aDest.iY;
       
   596 		
       
   597 		TLineScanningPosition lineScanPos(aSourceBase);
       
   598 
       
   599 		const TBool useScanLinePtr = (dispMode == aSourceBitmap->DisplayMode() && 
       
   600 				(TDisplayModeUtils::NumDisplayModeBitsPerPixel(dispMode)>=8));
       
   601 
       
   602 		if (useScanLinePtr)
       
   603 			{
       
   604 			TUint32* scanLineBuffer = NULL;
       
   605 			TUint32* slptr = NULL;
       
   606 			TUint offset = MemoryOffsetForPixelPitch (srcePoint.iX, dispMode);
       
   607 
       
   608 			if (aSourceBitmap->IsCompressed())
       
   609 				{
       
   610 				for ( ; srcePoint.iY < aSourceRect.iBr.iY; destY++,
       
   611 						srcePoint.iY++)
       
   612 					{
       
   613 					scanLineBuffer = GetScanLineOffsetPtr (
       
   614 							aSourceBitmap, slptr, width, srcePoint,
       
   615 							aSourceBase, lineScanPos, offset);
       
   616 					
       
   617 					iDrawDevice->WriteLine (aDest.iX, destY, width,
       
   618 							scanLineBuffer, drawMode);
       
   619 					}
       
   620 				}
       
   621 			else
       
   622 				{
       
   623 				TUint stride = aSourceBitmap->DataStride ();
       
   624 				TUint32* lastScanLine = aSourceBitmap->ScanLineAddress(aSourceBase, aSourceRect.iBr.iY-1);
       
   625 
       
   626 				while (srcePoint.iY < aSourceRect.iBr.iY)
       
   627 					{
       
   628 					scanLineBuffer = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint,
       
   629 							aSourceBase, lineScanPos, offset);
       
   630 					do
       
   631 						{
       
   632 						iDrawDevice->WriteLine (aDest.iX, destY, width, scanLineBuffer, drawMode);
       
   633 						scanLineBuffer = (TUint32*)((TUint8*)scanLineBuffer + stride);
       
   634 						destY++;
       
   635 						srcePoint.iY++;
       
   636 						}
       
   637 					while ((srcePoint.iY < aSourceRect.iBr.iY) && (scanLineBuffer < lastScanLine));
       
   638 					}
       
   639 				}
       
   640 			}
       
   641 		else
       
   642 			{
       
   643 			const TInt scanLineBytes = iDrawDevice->ScanLineBytes();
       
   644 			TUint32* scanLineBuffer = iDrawDevice->ScanLineBuffer();
       
   645 			TPtr8 scanLineDes((TUint8*)scanLineBuffer, scanLineBytes,
       
   646 					scanLineBytes);
       
   647 			for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,
       
   648 					srcePoint.iY++)
       
   649 				{
       
   650 				aSourceBitmap->GetScanLine (scanLineDes, srcePoint,
       
   651 						width, EFalse, KZeroPoint, dispMode,
       
   652 						aSourceBase, lineScanPos);
       
   653 
       
   654 				iDrawDevice->WriteLine (aDest.iX, destY, width,
       
   655 						scanLineBuffer, drawMode);
       
   656 				}
       
   657 			}
       
   658 		}
       
   659 	else
       
   660 		{
       
   661 		DoBitBltMaskedFlicker(aDest, aSourceBitmap, aSourceBase,
       
   662 				aSourceRect, aMaskBitmap, aMaskBase, aInvertMask);		
       
   663 		}
       
   664 	}
       
   665 		
       
   666 /**
       
   667 @see DoBitBltMasked()
       
   668  */
       
   669 void CSwDirectGdiEngine::DoBitBltMaskedFlicker(const TPoint& aDest,
       
   670 				  CBitwiseBitmap* aSourceBitmap,
       
   671 				  TUint32* aSourceBase,
       
   672 				  const TRect& aSourceRect,
       
   673 				  CBitwiseBitmap* aMaskBitmap,
       
   674 				  TUint32* aMaskBase,
       
   675 				  TBool aInvertMask)
       
   676 	{
       
   677 	const TInt width = aSourceRect.Width();
       
   678 	TInt destY = aDest.iY;
       
   679 	TPoint srcePoint(aSourceRect.iTl);
       
   680 	
       
   681 	TLineScanningPosition lineScanPos(aSourceBase);
       
   682 	TLineScanningPosition lineScanPosMask(aMaskBase);
       
   683 	
       
   684 	const TDisplayMode srcFormat = aSourceBitmap->DisplayMode();
       
   685 	const TDisplayMode maskFormat = aMaskBitmap->DisplayMode();
       
   686 	
       
   687 	if (aMaskBitmap->IsCompressed()) 
       
   688 		{ 
       
   689 		HBufC8* hBuf = CFbsBitmap::GetDecompressionBuffer(aMaskBitmap->DataStride() + 4);
       
   690 		if (!hBuf) 
       
   691 			{
       
   692 			iDriver->SetError(KErrNoMemory);
       
   693 			return; // Out of memory so do not draw anything 
       
   694 			}
       
   695 		lineScanPosMask.iScanLineBuffer = hBuf; 
       
   696 		} 
       
   697 	
       
   698 	TAny* interface = NULL;
       
   699 	if ( (srcFormat == EColor16MU || srcFormat == EColor64K ) &&
       
   700 			maskFormat == EGray2 && 
       
   701 			aSourceBitmap->SizeInPixels().iWidth <= aMaskBitmap->SizeInPixels().iWidth &&
       
   702 			aSourceBitmap->SizeInPixels().iHeight <= aMaskBitmap->SizeInPixels().iHeight &&
       
   703 			iDrawDevice->GetInterface(KFastBlitInterfaceID, interface) == KErrNone )
       
   704 		{
       
   705 		// Parameters allow optimised code path
       
   706 		TInt length = width;
       
   707 		TUint32* srcPtr=NULL;
       
   708 		TUint32* maskPtr=NULL;
       
   709 		MFastBlit* fastBlit = reinterpret_cast<MFastBlit*>(interface);
       
   710 		while (srcePoint.iY < aSourceRect.iBr.iY)
       
   711 			{
       
   712 			aSourceBitmap->GetScanLinePtr(srcPtr, length, srcePoint, aSourceBase, lineScanPos);
       
   713 			aMaskBitmap->GetScanLinePtr(maskPtr, length, srcePoint, aMaskBase, lineScanPosMask);
       
   714 			
       
   715 			fastBlit->WriteMaskLineEx(aDest.iX,destY,length,srcePoint.iX,srcPtr,srcFormat,srcePoint.iX,maskPtr,aInvertMask);
       
   716 			
       
   717 			destY++;
       
   718 			++srcePoint.iY;
       
   719 			}
       
   720 		return;
       
   721 		}
       
   722 	
       
   723 	const TDisplayMode dispMode = ScanLineBufferDisplayMode(iDrawDevice);
       
   724 	const CGraphicsContext::TDrawMode drawMode = aInvertMask ? CGraphicsContext::EDrawModeAND : CGraphicsContext::EDrawModeANDNOT;
       
   725 	
       
   726 	TUint32* scanLineBuffer = iDrawDevice->ScanLineBuffer();
       
   727 	const TInt scanLineBytes = iDrawDevice->ScanLineBytes();
       
   728 	TPtr8 scanLineDes((TUint8*)scanLineBuffer,scanLineBytes,scanLineBytes);
       
   729 	TLineScanningPosition lineScanPos2(aSourceBase);
       
   730 	const TPoint KZeroPoint(0,0);
       
   731 	
       
   732 	//scanline modifications required if using different modes, bits per pixel less than 8
       
   733 	if ( (dispMode == aSourceBitmap->DisplayMode()) && 
       
   734 			(TDisplayModeUtils::NumDisplayModeBitsPerPixel(dispMode)>=8))
       
   735 		{
       
   736 		TUint offset = MemoryOffsetForPixelPitch(srcePoint.iX, dispMode);
       
   737 		TUint32* slptr=NULL;
       
   738 		//mask scanline modifications required for EInvertPen, different screen modes
       
   739 		if ((drawMode != CGraphicsContext::EDrawModeANDNOT) && (dispMode == aMaskBitmap->DisplayMode()))
       
   740 			{
       
   741 			TUint32* scanLineBufferMask = NULL;
       
   742 			//stride jumping not possible with compressed bitmaps
       
   743 			if (aSourceBitmap->IsCompressed() || aMaskBitmap->IsCompressed())
       
   744 				{
       
   745 				for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++)
       
   746 					{
       
   747 					scanLineBuffer = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPos, offset);
       
   748 					iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer, CGraphicsContext::EDrawModeXOR);
       
   749 					scanLineBufferMask = GetScanLineOffsetPtr(aMaskBitmap, slptr, width, srcePoint, aMaskBase, lineScanPosMask, offset);
       
   750 					iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferMask,drawMode);
       
   751 					iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer, CGraphicsContext::EDrawModeXOR);
       
   752 					}
       
   753 				}
       
   754 			else
       
   755 				{
       
   756 				TUint strideSrc = aSourceBitmap->DataStride();
       
   757 				TUint strideMask = aMaskBitmap->DataStride();
       
   758 				TUint32* lastScanLineSrc = aSourceBitmap->ScanLineAddress(aSourceBase,aSourceRect.iBr.iY-1);
       
   759 				TUint32* lastScanLineMask = aMaskBitmap->ScanLineAddress(aMaskBase,aSourceRect.iBr.iY-1);
       
   760 
       
   761 				while (srcePoint.iY < aSourceRect.iBr.iY)
       
   762 					{
       
   763 					scanLineBuffer = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPos, offset);
       
   764 					scanLineBufferMask = GetScanLineOffsetPtr(aMaskBitmap, slptr, width, srcePoint, aMaskBase, lineScanPosMask, offset);
       
   765 					do
       
   766 						{
       
   767 						iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,CGraphicsContext::EDrawModeXOR);
       
   768 						iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferMask,drawMode);
       
   769 						iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,CGraphicsContext::EDrawModeXOR);
       
   770 						destY++;
       
   771 						srcePoint.iY++;
       
   772 						}
       
   773 					while ((srcePoint.iY < aSourceRect.iBr.iY) && 
       
   774 							(scanLineBuffer < lastScanLineSrc) && 
       
   775 							(scanLineBufferMask < lastScanLineMask)	&& 
       
   776 							((scanLineBuffer = (TUint32*)((TUint8*)scanLineBuffer + strideSrc))>(TUint32*)0) && 
       
   777 							((scanLineBufferMask = (TUint32*)((TUint8*)scanLineBufferMask + strideMask))>(TUint32*)0) );
       
   778 					}
       
   779 				}
       
   780 			}
       
   781 		else
       
   782 			{
       
   783 			TUint32* scanLineBufferPtr = NULL;
       
   784 			//stride jumping not possible with compressed bitmaps
       
   785 			if (aSourceBitmap->IsCompressed())
       
   786 				{
       
   787 				for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++)
       
   788 					{
       
   789 					scanLineBufferPtr = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPos, offset);
       
   790 					iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferPtr,CGraphicsContext::EDrawModeXOR);
       
   791 					aMaskBitmap->GetScanLine(scanLineDes,srcePoint,width,EFalse , KZeroPoint, dispMode, aMaskBase, lineScanPosMask);
       
   792 					TileScanLine(scanLineDes, width, srcePoint, aMaskBitmap, lineScanPosMask, aMaskBase, dispMode);
       
   793 					iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,drawMode);
       
   794 					iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferPtr,CGraphicsContext::EDrawModeXOR);
       
   795 					}
       
   796 				}
       
   797 			else
       
   798 				{
       
   799 				TUint stride = aSourceBitmap->DataStride();
       
   800 				TUint32* lastScanLine = aSourceBitmap->ScanLineAddress(aSourceBase,aSourceRect.iBr.iY-1);
       
   801 				while (srcePoint.iY < aSourceRect.iBr.iY)
       
   802 					{
       
   803 					scanLineBufferPtr = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPos, offset);
       
   804 					do
       
   805 						{
       
   806 						iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferPtr,CGraphicsContext::EDrawModeXOR);
       
   807 						aMaskBitmap->GetScanLine(scanLineDes,srcePoint,width,EFalse, KZeroPoint, dispMode,aMaskBase, lineScanPosMask);
       
   808 						TileScanLine(scanLineDes, width, srcePoint, aMaskBitmap, lineScanPosMask, aMaskBase, dispMode);
       
   809 						iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,drawMode);
       
   810 						iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferPtr,CGraphicsContext::EDrawModeXOR);
       
   811 						destY++;
       
   812 						srcePoint.iY++;
       
   813 						}
       
   814 					while ((srcePoint.iY < aSourceRect.iBr.iY) && (scanLineBufferPtr < lastScanLine) && 
       
   815 							((scanLineBufferPtr = (TUint32*)((TUint8*)scanLineBufferPtr + stride))>(TUint32*)0));
       
   816 					}
       
   817 				}
       
   818 			}
       
   819 		}
       
   820 	else
       
   821 		{
       
   822 		for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++)
       
   823 			{
       
   824 			aSourceBitmap->GetScanLine(scanLineDes,srcePoint,width,EFalse, KZeroPoint,
       
   825 					dispMode,aSourceBase,lineScanPos);
       
   826 			
       
   827 			iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,CGraphicsContext::EDrawModeXOR);
       
   828 			aMaskBitmap->GetScanLine(scanLineDes,srcePoint,width,EFalse , KZeroPoint, dispMode,
       
   829 					aMaskBase, lineScanPosMask);
       
   830 			TileScanLine(scanLineDes, width, srcePoint, aMaskBitmap, lineScanPosMask, aMaskBase, dispMode);
       
   831 			iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,drawMode);
       
   832 			aSourceBitmap->GetScanLine(scanLineDes,srcePoint,width,EFalse , KZeroPoint ,dispMode,
       
   833 					aSourceBase,lineScanPos2);		
       
   834 			
       
   835 			iDrawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,CGraphicsContext::EDrawModeXOR);
       
   836 			}
       
   837 		}
       
   838 	}		
       
   839 				
       
   840 /**
       
   841 @see DoBitBltMasked()
       
   842  */
       
   843 void CSwDirectGdiEngine::DoBitBltAlpha(const TPoint& aDest ,CBitwiseBitmap* aSourceBitmap,
       
   844 		TUint32* aSourceBase, const TRect& aSourceRect,
       
   845 		CBitwiseBitmap* aMaskBitmap, TUint32* aMaskBase,
       
   846 		const TPoint& aAlphaPoint, TBool aInvertMask)
       
   847 	{
       
   848 	MFastBlend* fastBlend=NULL;
       
   849 	if (FastBlendInterface(aSourceBitmap,aMaskBitmap,fastBlend)==KErrNone)
       
   850 		{
       
   851 		if (fastBlend->FastBlendBitmapMasked(aDest, aSourceBase, aSourceBitmap->DataStride(), aSourceBitmap->SizeInPixels(), aSourceRect, aSourceBitmap->DisplayMode(),
       
   852 							aMaskBase, aMaskBitmap->DataStride(), aMaskBitmap->DisplayMode(), aMaskBitmap->SizeInPixels(), aAlphaPoint, aInvertMask,
       
   853 							GcDrawMode(iDrawMode), CFbsDrawDevice::ENoShadow)==KErrNone)
       
   854 			{
       
   855 			return;
       
   856 			}
       
   857 		}
       
   858 
       
   859 	const TPoint KZeroPoint(0,0);
       
   860 	const TInt KScanLineLength = 256;
       
   861 	const TInt KRgbSize = 4;
       
   862 	
       
   863 	TUint8 srceRgbBuffer[KScanLineLength * KRgbSize];
       
   864 	TUint8 maskBuffer[KScanLineLength];
       
   865 	TUint8* srceRgbBufferPtr(srceRgbBuffer);
       
   866 	
       
   867 	TPtr8 srceRgbDes(srceRgbBuffer, KScanLineLength * KRgbSize, KScanLineLength * KRgbSize);
       
   868 	TPtr8 maskDes(maskBuffer, KScanLineLength, KScanLineLength);	
       
   869 	
       
   870 	TInt srceY = aSourceRect.iTl.iY;
       
   871 	TInt destY = aDest.iY;
       
   872 	TInt alphaY = aAlphaPoint.iY;
       
   873 	
       
   874 	TLineScanningPosition lineScanPosSrc(aSourceBase);
       
   875 	TLineScanningPosition lineScanPosMask(aMaskBase);
       
   876 	TDisplayMode sourceMode = aSourceBitmap->DisplayMode();
       
   877 	
       
   878 	if (aMaskBitmap->IsCompressed())
       
   879 		{
       
   880 		HBufC8* hBuf= CFbsBitmap::GetDecompressionBuffer(aMaskBitmap->DataStride());
       
   881 		if (hBuf == NULL)
       
   882 			{
       
   883 			iDriver->SetError(KErrNoMemory); // Out of memory so do not draw anything
       
   884 			return;
       
   885 			}
       
   886 		lineScanPosMask.iScanLineBuffer = hBuf;
       
   887 		}
       
   888 	
       
   889 	TAny* interface = NULL;
       
   890 	if ( (sourceMode == EColor16MU || sourceMode == EColor64K) &&
       
   891 		aMaskBitmap->DisplayMode() == EGray256 && // ensure a monochrome mask isn't passed in as an alpha channel
       
   892 		aSourceBitmap->SizeInPixels().iWidth <= aMaskBitmap->SizeInPixels().iWidth &&
       
   893 		aSourceBitmap->SizeInPixels().iHeight <= aMaskBitmap->SizeInPixels().iHeight &&
       
   894 		iDrawDevice->GetInterface(KFastBlitInterfaceID, interface) == KErrNone )
       
   895 		{
       
   896 		TInt length = aSourceRect.Width();
       
   897 		const TInt srceX = aSourceRect.iTl.iX;
       
   898 		const TInt alphaX = aAlphaPoint.iX;
       
   899 		const TInt destX = aDest.iX;
       
   900 		MFastBlit* fastBlit = reinterpret_cast<MFastBlit*>(interface);
       
   901 		
       
   902 		while (srceY < aSourceRect.iBr.iY)
       
   903 			{
       
   904 			TUint32* srcPtr;
       
   905 			TUint32* maskPtr;
       
   906 			TPoint srcPoint(srceX, srceY);
       
   907 			TPoint maskPoint(alphaX, alphaY);
       
   908 			
       
   909 			aSourceBitmap->GetScanLinePtr(srcPtr, length, srcPoint, aSourceBase, lineScanPosSrc);
       
   910 			aMaskBitmap->GetScanLinePtr(maskPtr, length, maskPoint, aMaskBase, lineScanPosMask);
       
   911 			
       
   912 			fastBlit->WriteAlphaLineEx(destX, destY, length, srceX, srcPtr,
       
   913 					sourceMode, alphaX, maskPtr, MAlphaBlend::EShdwBefore);
       
   914 			srceY++;
       
   915 			destY++;
       
   916 			alphaY++;
       
   917 			}
       
   918 		
       
   919 		return;
       
   920 		}
       
   921 	
       
   922 	const TBool useScanLinePtr = ( (EColor16MA == aSourceBitmap->DisplayMode()));
       
   923 	TUint32* slptr = NULL;
       
   924 	TUint offset = 0;
       
   925 	
       
   926 	while (srceY < aSourceRect.iBr.iY)
       
   927 		{
       
   928 		TInt srceX = aSourceRect.iTl.iX;
       
   929 		TInt destX = aDest.iX;
       
   930 		TInt alphaX = aAlphaPoint.iX;
       
   931 		
       
   932 		while (srceX < aSourceRect.iBr.iX)
       
   933 			{
       
   934 			TPoint srcePoint(srceX,srceY);
       
   935 			TPoint alphaPoint(alphaX,alphaY);
       
   936 			const TInt width = Min(KScanLineLength, aSourceRect.iBr.iX - srceX);
       
   937 			
       
   938 			if (useScanLinePtr)
       
   939 				{
       
   940 				offset = MemoryOffsetForPixelPitch(srceX, EColor16MU);
       
   941 				srceRgbBufferPtr = (TUint8*)GetScanLineOffsetPtr(aSourceBitmap, slptr, width, 
       
   942 						                       srcePoint, aSourceBase, lineScanPosSrc, offset);
       
   943 				}
       
   944 			else
       
   945 				{
       
   946 				aSourceBitmap->GetScanLine(srceRgbDes,srcePoint,width,EFalse,KZeroPoint,
       
   947 						               ERgb,aSourceBase,lineScanPosSrc);
       
   948 				}
       
   949 			
       
   950 			aMaskBitmap->GetScanLine(maskDes, alphaPoint, width, EFalse, KZeroPoint,
       
   951 					                EGray256, aMaskBase, lineScanPosMask);
       
   952 			TileScanLine(maskDes, width, alphaPoint, aMaskBitmap, lineScanPosMask, aMaskBase, EGray256);
       
   953 			
       
   954 			// aInvertMask is not used for alpha channels (EGray256 mask)
       
   955 			if (aInvertMask && aMaskBitmap->DisplayMode() != EGray256)
       
   956 				{
       
   957 				for (TInt i = 0; i < width; ++i)
       
   958 					{
       
   959 					maskBuffer[i] = ~maskBuffer[i];
       
   960 					}
       
   961 				}
       
   962 			
       
   963 			iDrawDevice->WriteRgbAlphaLine(destX, destY, width, srceRgbBufferPtr, maskBuffer, GcDrawMode(iDrawMode));
       
   964 			
       
   965 			srceX += KScanLineLength;
       
   966 			destX += KScanLineLength;
       
   967 			alphaX += KScanLineLength;
       
   968 			}
       
   969 		
       
   970 		srceY++;
       
   971 		destY++;
       
   972 		alphaY++;
       
   973 		}		
       
   974 	}
       
   975 
       
   976 /**
       
   977 Tiles the scan line if its length in pixels is less than aLengthInPixels.
       
   978 
       
   979 @param aScanLine A pointer to the scan line buffer.
       
   980 @param aLengthInPixels The scan line size in pixels.
       
   981 @param aSrcPt Position of the first pixel in aMaskBitmap that should be used as a source
       
   982               for the pixels in scan line buffer.
       
   983 @param aMaskBitmap Any additional pixels for the scan line buffer will be taken from here.
       
   984 @param aScanLinePos This argument is used for some internal optimisations. It should not be
       
   985                     modified by the caller.
       
   986 @param aMaskBase The base address of aMaskBitmap data.
       
   987 @param aDisplayMode Any additional pixels should be taken from aMaskBitmap using aDisplayMode
       
   988                     as an argument for GetScanLine() call.
       
   989 @panic DGDIAdapter 1021, if the memory required for the scanline is greater than the size of aScanLine (debug only).
       
   990 */
       
   991 void CSwDirectGdiEngine::TileScanLine(TPtr8& aScanLine,
       
   992 						  TInt aLengthInPixels,
       
   993 						  const TPoint& aSrcPt,
       
   994 						  const CBitwiseBitmap* aMaskBitmap,
       
   995 						  TLineScanningPosition& aScanLinePos,
       
   996 						  TUint32* aMaskBase,
       
   997 						  TDisplayMode aDisplayMode
       
   998 						  )
       
   999 	{
       
  1000 	TInt lengthInBytes = CFbsBitmap::ScanLineLength(aLengthInPixels, aDisplayMode);
       
  1001 	GRAPHICS_ASSERT_DEBUG(lengthInBytes <= aScanLine.MaxLength(), EDirectGdiPanicInvalidArg);
       
  1002 	TInt scanLineLength = aScanLine.Length();
       
  1003 	if(scanLineLength < lengthInBytes && aSrcPt.iX > 0)
       
  1004 		{
       
  1005 		//If, for example, src bmp is 100 pixels width, mask bmp is 20 pixels width and src
       
  1006 		//rect is (10, 0, 100, 1) -> We will read only pixels 10..19 from the first scan line
       
  1007 		//of the mask bmp. We have to have 90 mask bmp pixels.
       
  1008 		//So we have to make a second mask bmp read startig from pixel 0 - 10 pixels length.
       
  1009 		TInt maxLen = Min(aScanLine.MaxLength() - scanLineLength, aSrcPt.iX);
       
  1010 		TPtr8 maskDes2(const_cast <TUint8*> (aScanLine.Ptr()) + scanLineLength, maxLen, maxLen);
       
  1011 		TPoint srcPt(0, aSrcPt.iY);
       
  1012 		TPoint zeroPt(0, 0);
       
  1013 		aMaskBitmap->GetScanLine(maskDes2, srcPt, maxLen, EFalse, zeroPt, aDisplayMode, aMaskBase, aScanLinePos);
       
  1014 		aScanLine.SetLength(scanLineLength + maskDes2.Length());
       
  1015 		scanLineLength = aScanLine.Length();
       
  1016 		}
       
  1017 	if(scanLineLength >= lengthInBytes || scanLineLength == 0)
       
  1018 		{
       
  1019 		return;
       
  1020 		}
       
  1021 	//If we still don't have enough mask bmp pixels - we have to tile the scan line
       
  1022 	TInt repeatCnt = lengthInBytes / scanLineLength - 1;
       
  1023 	TInt bytesLeft = lengthInBytes % scanLineLength;
       
  1024 	const TUint8* src = aScanLine.Ptr();
       
  1025 	TUint8* dest = const_cast <TUint8*> (src) + scanLineLength;
       
  1026 	for(;repeatCnt>0;dest+=scanLineLength,repeatCnt--)
       
  1027 		{
       
  1028 		Mem::Copy(dest, src, scanLineLength);
       
  1029 		}
       
  1030 	if(bytesLeft)
       
  1031 		{
       
  1032 		Mem::Copy(dest, src, bytesLeft);
       
  1033 		}
       
  1034 	aScanLine.SetLength(lengthInBytes);
       
  1035 	}
       
  1036 
       
  1037 /**
       
  1038 Draws a masked rectangular section of the source bitmap and does a compress/stretch to 
       
  1039 fit a given destination rectangle. It uses DoBitBltMasked() if no stretching is involved. 
       
  1040 
       
  1041 @see DrawBitmapMasked()
       
  1042 
       
  1043 @param aDestRect The target position on the device containing the top left corner of the source bitmap.
       
  1044 @param aSourceBitmap The bitmap object that contains the pixels to draw.
       
  1045 @param aSourceBase The address of the source bitmap pixels.
       
  1046 @param aSourceRect The area of the bitmap to draw from.
       
  1047 @param aMaskBitmap The bitmap object that contains the mask.
       
  1048 @param aMaskBase The address of the mask pixels.
       
  1049 @param aInvertMask Inverts the mask if ETrue.
       
  1050 @param aClipRect A clipping rectangle.
       
  1051 @panic DGDIAdapter 1013, if the clipping rectangle is fully outside of the device bounds (debug only).
       
  1052 */
       
  1053 void CSwDirectGdiEngine::DoDrawBitmapMasked(const TRect& aDestRect,
       
  1054 							   CBitwiseBitmap* aSourceBitmap,
       
  1055 							   TUint32* aSourceBase,
       
  1056 							   const TRect& aSourceRect,
       
  1057 							   CBitwiseBitmap* aMaskBitmap,
       
  1058 							   TUint32* aMaskBase,
       
  1059 							   TBool aInvertMask,
       
  1060 							   const TRect& aClipRect)
       
  1061 	{
       
  1062 	CFbsDrawDevice* drawDevice = iDrawDevice;
       
  1063 #ifdef _DEBUG
       
  1064 	TRect deviceDestRect;
       
  1065 	drawDevice->GetDrawRect(deviceDestRect);
       
  1066 	GRAPHICS_ASSERT_DEBUG(aClipRect.iTl.iX >= deviceDestRect.iTl.iX, EDirectGdiPanicOutOfBounds);
       
  1067 	GRAPHICS_ASSERT_DEBUG(aClipRect.iTl.iY >= deviceDestRect.iTl.iY, EDirectGdiPanicOutOfBounds);
       
  1068 	GRAPHICS_ASSERT_DEBUG(aClipRect.iBr.iX <= deviceDestRect.iBr.iX, EDirectGdiPanicOutOfBounds);
       
  1069 	GRAPHICS_ASSERT_DEBUG(aClipRect.iBr.iY <= deviceDestRect.iBr.iY, EDirectGdiPanicOutOfBounds);
       
  1070 #endif
       
  1071 
       
  1072 	// The clipped version of the destination rectangle
       
  1073 	TRect clippedDestRect(aDestRect);
       
  1074 	clippedDestRect.Intersection(aClipRect);
       
  1075 
       
  1076 	// If the source rectangle and the destination rectangle are same,
       
  1077 	// no stretch/compress operation required, just do BitBltMasked
       
  1078 	if (aDestRect.Size() == aSourceRect.Size())
       
  1079 		{
       
  1080 		if (!clippedDestRect.IsEmpty())
       
  1081 			{
       
  1082 			const TPoint destPoint(clippedDestRect.iTl);
       
  1083 			clippedDestRect.Move(aSourceRect.iTl - aDestRect.iTl);
       
  1084 			DoBitBltMasked(destPoint,
       
  1085 						   aSourceBitmap,
       
  1086 						   aSourceBase,
       
  1087 						   clippedDestRect,
       
  1088 						   aMaskBitmap,
       
  1089 						   aMaskBase,
       
  1090 						   aInvertMask);
       
  1091 			}
       
  1092 		return;
       
  1093 		}
       
  1094 
       
  1095 	MFastBlend* fastBlend=NULL;
       
  1096 	if (FastBlendInterface(aSourceBitmap,aMaskBitmap,fastBlend)==KErrNone)
       
  1097 		{
       
  1098 		if (fastBlend->FastBlendBitmapMaskedScaled(aClipRect, aDestRect, aSourceRect, aSourceBase, aSourceBitmap->DataStride(),
       
  1099 				aSourceBitmap->DisplayMode(),aSourceBitmap->SizeInPixels(), 
       
  1100 				aMaskBase, aMaskBitmap->DataStride(), aMaskBitmap->DisplayMode(), aMaskBitmap->SizeInPixels(), aInvertMask, 
       
  1101 				GcDrawMode(iDrawMode), CFbsDrawDevice::ENoShadow)==KErrNone)
       
  1102 			{
       
  1103 			return;
       
  1104 			}
       
  1105 		}
       
  1106 	
       
  1107 	TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
       
  1108 	const TInt scanLineBytes = drawDevice->ScanLineBytes();
       
  1109 	TPtr8 scanLineDes(reinterpret_cast<TUint8*>(scanLineBuffer),scanLineBytes,scanLineBytes);
       
  1110 
       
  1111 	const TInt KScanLineLength = 256;
       
  1112 	const TInt KRgbSize = 4;
       
  1113 	TUint8 maskBuffer[KScanLineLength];
       
  1114 
       
  1115 	TUint8 sourceBuffer[KScanLineLength*KRgbSize];
       
  1116 	TPtr8 sourceDes(sourceBuffer,KScanLineLength*KRgbSize,KScanLineLength*KRgbSize);
       
  1117 
       
  1118 	const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
       
  1119 	CGraphicsContext::TDrawMode drawMode = aInvertMask ? CGraphicsContext::EDrawModeAND : CGraphicsContext::EDrawModeANDNOT;
       
  1120 	// If the source bitmap and the mask bitmap are same, draw the source bitmap either
       
  1121 	// with EDrawModeAND or EDrawModeOR based on aInvertMask parameter.
       
  1122 	if (aSourceBitmap == aMaskBitmap)
       
  1123 		{
       
  1124 		drawMode = aInvertMask ? CGraphicsContext::EDrawModeAND : CGraphicsContext::EDrawModeOR;
       
  1125 		}
       
  1126 
       
  1127 	TLinearDDA xLine;
       
  1128 	TInt bitmapXStart = 0;
       
  1129 	xLine.Construct(TPoint(aSourceRect.iTl.iX,aDestRect.iTl.iX),
       
  1130 					TPoint(aSourceRect.iBr.iX,aDestRect.iBr.iX),TLinearDDA::ELeft);
       
  1131 	xLine.JumpToYCoord2(bitmapXStart,clippedDestRect.iTl.iX);
       
  1132 
       
  1133 	TLinearDDA yLine;
       
  1134 	TPoint yCoord(aSourceRect.iTl.iY,aDestRect.iTl.iY);
       
  1135 	yLine.Construct(yCoord,TPoint(aSourceRect.iBr.iY,aDestRect.iBr.iY),TLinearDDA::ELeft);
       
  1136 	TInt dummy;
       
  1137 	yLine.JumpToYCoord2(dummy,clippedDestRect.iTl.iY);
       
  1138 	yCoord.SetXY(dummy,clippedDestRect.iTl.iY);
       
  1139 
       
  1140 	const TInt srceWidth = aSourceRect.Width();
       
  1141 	const TInt destWidth = aDestRect.Width();
       
  1142 	const TInt clipWidth = clippedDestRect.Width();
       
  1143 	const TInt clipStrch = clippedDestRect.iTl.iX - aDestRect.iTl.iX;
       
  1144 	const TInt sourceBmpWidth = aSourceBitmap->SizeInPixels().iWidth;
       
  1145 	const TInt maskWidth = aMaskBitmap->SizeInPixels().iWidth;
       
  1146 	const TInt maskHeight = aMaskBitmap->SizeInPixels().iHeight;
       
  1147 
       
  1148 	TLineScanningPosition lineScanPos(aSourceBase);
       
  1149 	TLineScanningPosition lineScanPos2(aSourceBase);
       
  1150 	TLineScanningPosition lineScanPosMask(aMaskBase);
       
  1151 
       
  1152 	HBufC8* alphaBuffer = NULL;
       
  1153 	TPtr8 alphaBufferDes(NULL, 0);
       
  1154 	const TDisplayMode maskDisplayMode = aMaskBitmap->DisplayMode();
       
  1155 
       
  1156 	// Mask inversion is not supported if the original source mask format is EGray256.
       
  1157 	// Note that this is only used for pre-multiplied alpha targets.
       
  1158 	TUint8 maskInverter = (aInvertMask && maskDisplayMode != EGray256) ? 0xFF : 0x00;
       
  1159 
       
  1160 	if (aSourceBitmap != aMaskBitmap)
       
  1161 		{
       
  1162 		// Get buffer to be used to convert non-EGray256 masks to EGray256 when display mode is EColor16MAP
       
  1163 		// or to tile the mask when the mask width is smaller than the source bitmap width.
       
  1164 		if (maskDisplayMode != EGray256 && (dispMode == EColor16MAP || maskWidth < sourceBmpWidth))
       
  1165 			{
       
  1166 			alphaBuffer = CFbsBitmap::GetExtraBuffer(CFbsBitmap::ScanLineLength(maskWidth, EGray256));
       
  1167 			if (!alphaBuffer)
       
  1168 				{
       
  1169 				return;  // Out of memory so do not draw anything 
       
  1170 				}
       
  1171 			alphaBufferDes.Set(alphaBuffer->Des());
       
  1172 			}
       
  1173 
       
  1174 		// Get buffer to be used for decompressing compressed masks when mask is EGray256
       
  1175 		if (maskDisplayMode == EGray256 && aMaskBitmap->IsCompressed())
       
  1176 			{
       
  1177 			HBufC8* hBuf= CFbsBitmap::GetDecompressionBuffer(aMaskBitmap->DataStride());
       
  1178 			if (!hBuf)
       
  1179 				{
       
  1180 				return;  // Out of memory so do not draw anything
       
  1181 				}
       
  1182 			lineScanPosMask.iScanLineBuffer = hBuf;
       
  1183 			}
       
  1184 		}
       
  1185 	const TPoint KZeroPoint(0,0);
       
  1186 
       
  1187 	while (yCoord.iY < clippedDestRect.iBr.iY)
       
  1188 		{
       
  1189 		// Draw only the source bitmap, if the source bitmap and the mask bitmap are same.
       
  1190 		// else draw both the bitmaps
       
  1191 		if (aSourceBitmap == aMaskBitmap)
       
  1192 			{
       
  1193 			aSourceBitmap->StretchScanLine(scanLineDes,TPoint(bitmapXStart,yCoord.iX),
       
  1194 								 clipStrch,clipWidth,destWidth,aSourceRect.iTl.iX,
       
  1195 								 srceWidth, KZeroPoint,dispMode,aSourceBase,lineScanPos);
       
  1196 			if (yCoord.iY==clippedDestRect.iTl.iY)
       
  1197 				aSourceBitmap->SetCompressionBookmark(lineScanPos,aSourceBase,NULL);
       
  1198 			drawDevice->WriteLine(clippedDestRect.iTl.iX,yCoord.iY,clipWidth,scanLineBuffer,drawMode);
       
  1199 			}
       
  1200 		else if ((maskDisplayMode == EGray256) || (dispMode == EColor16MAP))
       
  1201 			{
       
  1202 			// Stretch the source bitmap and the mask bitmap for KScanLineLength as stretch length
       
  1203 			// then do alpha blending for this length. If the length is more then KScanLineLength
       
  1204 			// repeat it till you stretch complete destination length.
       
  1205 			const TPoint startPt(bitmapXStart,yCoord.iX);
       
  1206 			TInt clipWidthPart = clippedDestRect.Width();
       
  1207 			TBool loopLast = ETrue;
       
  1208 			if(clipWidthPart > KScanLineLength)
       
  1209 				{
       
  1210 				clipWidthPart = KScanLineLength;
       
  1211 				loopLast = EFalse;
       
  1212 				}
       
  1213 			TInt clipIncStrch = clippedDestRect.iTl.iX - aDestRect.iTl.iX;
       
  1214 			TInt startClip=clippedDestRect.iTl.iX;
       
  1215 			TPoint sourceDestXCoords(bitmapXStart,clippedDestRect.iTl.iX);
       
  1216 			xLine.Construct(TPoint(aSourceRect.iTl.iX,aDestRect.iTl.iX),
       
  1217 							TPoint(aSourceRect.iBr.iX,aDestRect.iBr.iX),TLinearDDA::ELeft);
       
  1218 			xLine.JumpToYCoord2(sourceDestXCoords.iX,sourceDestXCoords.iY);
       
  1219 			TPoint srcPixel(bitmapXStart % maskWidth,yCoord.iX % maskHeight);
       
  1220 			TInt spaceLeft = 0;
       
  1221 			TRgb maskRgbValue;
       
  1222 			TUint32* maskScanLinePtr32 = NULL;
       
  1223 			TPoint currentYValue(0,srcPixel.iY);
       
  1224 			aMaskBitmap->GetScanLinePtr(maskScanLinePtr32, currentYValue, maskWidth, aMaskBase, lineScanPosMask);
       
  1225 			// To implement non EGray256 mask support with EColor16MAP display mode, we convert
       
  1226 			// the mask to EGray256.
       
  1227 			if (maskDisplayMode != EGray256) // Convert scan-line to EGray256 and set maskScanLinePtr32 to the conversion.
       
  1228 				{
       
  1229 				aMaskBitmap->GetScanLine(maskScanLinePtr32, alphaBufferDes, currentYValue, maskWidth, EFalse, TPoint(0, 0), EGray256);
       
  1230 				maskScanLinePtr32 = (TUint32*)alphaBuffer->Ptr();
       
  1231 				}
       
  1232 			TUint8* maskScanLinePtr = reinterpret_cast<TUint8*>(maskScanLinePtr32);
       
  1233 
       
  1234 			// Outer loop over all KScanLineLengths
       
  1235 			FOREVER
       
  1236 				{
       
  1237 				aSourceBitmap->StretchScanLine(sourceDes,startPt,clipIncStrch,clipWidthPart,destWidth,
       
  1238 								aSourceRect.iTl.iX,srceWidth, KZeroPoint ,EColor16MU,aSourceBase,lineScanPos);
       
  1239 				// Inner loop to tile the mask if necessary
       
  1240 				spaceLeft = clipWidthPart;
       
  1241 				do	{
       
  1242 					srcPixel.iX = sourceDestXCoords.iX % maskWidth;
       
  1243 			
       
  1244 					// Invert the mask using the inversion mask.
       
  1245 					maskBuffer[(sourceDestXCoords.iY-clippedDestRect.iTl.iX)%KScanLineLength]=
       
  1246 						maskInverter^maskScanLinePtr[srcPixel.iX];
       
  1247 					xLine.NextStep(sourceDestXCoords);
       
  1248 					} while (--spaceLeft>0);
       
  1249 				
       
  1250 				if (yCoord.iY == clippedDestRect.iTl.iY && startClip == clippedDestRect.iTl.iX)
       
  1251 					{
       
  1252 					aSourceBitmap->SetCompressionBookmark(lineScanPos,aSourceBase,NULL);
       
  1253 					aMaskBitmap->SetCompressionBookmark(lineScanPosMask,aMaskBase,NULL);
       
  1254 					}
       
  1255 				drawDevice->WriteRgbAlphaLine(startClip,yCoord.iY,clipWidthPart,sourceBuffer,maskBuffer, GcDrawMode(iDrawMode));
       
  1256 				if (loopLast)
       
  1257 					{
       
  1258 					break;
       
  1259 					}
       
  1260 				startClip+=KScanLineLength;
       
  1261 				if (clippedDestRect.iBr.iX - startClip <= KScanLineLength)
       
  1262  					{
       
  1263 					loopLast = ETrue;
       
  1264 					clipWidthPart = clippedDestRect.iBr.iX - startClip;
       
  1265 					}
       
  1266 				clipIncStrch += KScanLineLength;
       
  1267 				}
       
  1268 			}
       
  1269 		else
       
  1270 			{
       
  1271 			aSourceBitmap->StretchScanLine(scanLineDes,TPoint(bitmapXStart,yCoord.iX),
       
  1272 									 clipStrch,clipWidth,destWidth,aSourceRect.iTl.iX,
       
  1273 									 srceWidth, KZeroPoint ,dispMode,aSourceBase,lineScanPos2);
       
  1274 			drawDevice->WriteLine(clippedDestRect.iTl.iX,yCoord.iY,clipWidth,scanLineBuffer,CGraphicsContext::EDrawModeXOR);
       
  1275 
       
  1276 			TInt maskXStart = bitmapXStart % maskWidth;
       
  1277 			if(maskWidth < sourceBmpWidth)
       
  1278 				{
       
  1279 				TPoint sourceDestXCoords(bitmapXStart,clippedDestRect.iTl.iX);
       
  1280 				xLine.Construct(TPoint(aSourceRect.iTl.iX,aDestRect.iTl.iX),
       
  1281 								TPoint(aSourceRect.iBr.iX,aDestRect.iBr.iX),TLinearDDA::ELeft);
       
  1282 				xLine.JumpToYCoord2(sourceDestXCoords.iX,sourceDestXCoords.iY);
       
  1283 				TPoint srcPixel(maskXStart,yCoord.iX % maskHeight);
       
  1284 				TInt spaceLeft = clipWidth;
       
  1285 				TPoint prevSourceDestXCoords(-1,-1);
       
  1286 				TRgb maskRgbValue;
       
  1287 				aMaskBitmap->GetScanLine(alphaBufferDes, TPoint(0,srcPixel.iY), maskWidth, EFalse, TPoint(0, 0), EGray256, aMaskBase, lineScanPosMask);
       
  1288 
       
  1289 				// Loop to tile the mask
       
  1290 				do	{
       
  1291 					if (sourceDestXCoords.iY != prevSourceDestXCoords.iY)
       
  1292 						{
       
  1293 						if (sourceDestXCoords.iX != prevSourceDestXCoords.iX)
       
  1294 							{
       
  1295 							srcPixel.iX = sourceDestXCoords.iX % maskWidth;
       
  1296 							if (srcPixel.iX < 0)
       
  1297 								srcPixel.iX += maskWidth;
       
  1298 							maskRgbValue = TRgb::Gray256((*alphaBuffer)[srcPixel.iX]);
       
  1299 							}
       
  1300 						drawDevice->WriteRgb(sourceDestXCoords.iY,yCoord.iY,maskRgbValue,drawMode);
       
  1301 						spaceLeft--;
       
  1302 						}
       
  1303 					prevSourceDestXCoords = sourceDestXCoords;
       
  1304 					xLine.SingleStep(sourceDestXCoords);
       
  1305 					} while (spaceLeft > 0);
       
  1306 				}
       
  1307 			else
       
  1308 				{
       
  1309 				// No need to tile the mask
       
  1310 				aMaskBitmap->StretchScanLine(scanLineDes,TPoint(maskXStart,yCoord.iX % maskHeight),
       
  1311 										clipStrch,clipWidth,destWidth,aSourceRect.iTl.iX,
       
  1312 										srceWidth, KZeroPoint ,dispMode,aMaskBase,lineScanPosMask);
       
  1313 				drawDevice->WriteLine(clippedDestRect.iTl.iX,yCoord.iY,clipWidth,scanLineBuffer,drawMode);
       
  1314 				// Redo stretching of the aSourceBitmap scanline
       
  1315 				aSourceBitmap->StretchScanLine(scanLineDes,TPoint(bitmapXStart,yCoord.iX),
       
  1316 									 	clipStrch,clipWidth,destWidth,aSourceRect.iTl.iX,
       
  1317 									 	srceWidth, KZeroPoint ,dispMode,aSourceBase,lineScanPos2);
       
  1318 				}
       
  1319 
       
  1320 			if (yCoord.iY==clippedDestRect.iTl.iY)
       
  1321 				{
       
  1322 				aSourceBitmap->SetCompressionBookmark(lineScanPos2,aSourceBase,NULL);
       
  1323 				aMaskBitmap->SetCompressionBookmark(lineScanPosMask,aMaskBase,NULL);
       
  1324 				}
       
  1325 
       
  1326 			drawDevice->WriteLine(clippedDestRect.iTl.iX,yCoord.iY,clipWidth,scanLineBuffer,CGraphicsContext::EDrawModeXOR);
       
  1327 			}
       
  1328 		yLine.NextStep(yCoord);
       
  1329 		}
       
  1330 	}
       
  1331 
       
  1332 TInt CSwDirectGdiEngine::FastBlendInterface(const CBitwiseBitmap* aSource, const CBitwiseBitmap* aMask, MFastBlend*& aFastBlend) const
       
  1333 	{
       
  1334 	#if defined(__ALLOW_FAST_BLEND_DISABLE__)
       
  1335 	if (iFastBlendDisabled)
       
  1336 		return(KErrNotSupported);
       
  1337 	#endif
       
  1338 	if ((aSource && aSource->IsCompressed()) || (aMask && aMask->IsCompressed()))
       
  1339 		return(KErrNotSupported);
       
  1340 	TAny* interface=NULL;
       
  1341 	TInt ret= iDrawDevice->GetInterface(KFastBlendInterfaceID, interface);
       
  1342 	aFastBlend=(MFastBlend*)interface;
       
  1343 	return(ret);
       
  1344 	}
       
  1345 
       
  1346 /*
       
  1347 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.
       
  1348 
       
  1349 @see CBitwiseBitmap::GetScanLine()
       
  1350 @see CBitwiseBitmap::GetVerticalScanLine()
       
  1351 @see CBitwiseBitmap::StretchScanLine()
       
  1352 @see CFbsDrawDevice::WriteLine()
       
  1353 @internalComponent
       
  1354 */
       
  1355 TDisplayMode CSwDirectGdiEngine::ScanLineBufferDisplayMode(CFbsDrawDevice* aDrawDevice)
       
  1356 	{
       
  1357 	return iDrawMode == DirectGdi::EDrawModeWriteAlpha ? aDrawDevice->DisplayMode() : aDrawDevice->ScanLineDisplayMode();
       
  1358 	}