graphicsdeviceinterface/bitgdi/sbit/DRAWBMP.CPP
changeset 0 5d03bc08d59c
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 // Copyright (c) 1997-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 <fntstore.h>
       
    17 #include <bitmap.h>
       
    18 #include <bitstd.h>
       
    19 #include <bitdev.h>
       
    20 #include "BITPANIC.H"
       
    21 #include <bitdrawinterfaceid.h>
       
    22 #include <bmalphablend.h>
       
    23 #include <bitdraw.h>
       
    24 #include <graphics/fbsrasterizer.h>
       
    25 #include <graphics/bitmap.inl>
       
    26 #include <graphics/gdi/gdiinline.inl>
       
    27 
       
    28 /**
       
    29 Draws a bitmap.
       
    30 
       
    31 The function has 3 overloads. The first draws the bitmap given the top
       
    32 left hand corner, doing a compress/stretch based on its internally
       
    33 stored size in twips. The second does a compress/stretch to fit a
       
    34 given rectangle. The third takes a rectangular section of the source
       
    35 bitmap and does a compress/stretch to fit a given destination
       
    36 rectangle.The functions provide a concrete implementation of the pure
       
    37 virtual function <code>CGraphicsContext::DrawBitmap()</code>. The
       
    38 function behaviour is the same as documented in that class.
       
    39 */
       
    40 EXPORT_C void CFbsBitGc::DrawBitmap(const TPoint& aPos,const CFbsBitmap* aSource)
       
    41 	{
       
    42 	if (aSource == NULL || !aSource->Handle())
       
    43 		return;
       
    44 
       
    45 	aSource->BeginDataAccess();
       
    46 	const TSize bitmapTwips = aSource->SizeInTwips();
       
    47 	if (bitmapTwips.iWidth == 0 || bitmapTwips.iHeight == 0)
       
    48 		{
       
    49 		aSource->EndDataAccess(ETrue);
       
    50 		return;
       
    51 		}
       
    52 
       
    53 	TSize scrpixels;
       
    54 	scrpixels.iWidth = iDevice->HorizontalTwipsToPixels(bitmapTwips.iWidth);
       
    55 	scrpixels.iHeight = iDevice->VerticalTwipsToPixels(bitmapTwips.iHeight);
       
    56 
       
    57 	DrawBitmap(TRect(aPos, scrpixels), aSource, TRect(aSource->SizeInPixels()));
       
    58 	aSource->EndDataAccess(ETrue);
       
    59 	}
       
    60 
       
    61 EXPORT_C void CFbsBitGc::DrawBitmap(const TRect& aDestRect,const CFbsBitmap* aSource)
       
    62 	{
       
    63 	if (aSource == NULL || !aSource->Handle())
       
    64 		return;
       
    65 
       
    66 	aSource->BeginDataAccess();
       
    67 	DrawBitmap(aDestRect, aSource, TRect(aSource->SizeInPixels()));
       
    68 	aSource->EndDataAccess(ETrue);
       
    69 	}
       
    70 
       
    71 EXPORT_C void CFbsBitGc::DrawBitmap(const TRect& aDestRect,
       
    72 									const CFbsBitmap* aSource,
       
    73 									const TRect& aSourceRect)
       
    74 	{
       
    75 	if (CheckDevice(aDestRect) || aSourceRect.IsEmpty() || aSource == NULL || !aSource->Handle())
       
    76 		return;
       
    77 	
       
    78 	aSource->BeginDataAccess();
       
    79 	//aSourceRect should be in the bounds of the bitmap
       
    80 	TSize bitmapSize(aSource->SizeInPixels());
       
    81 	if ( aSourceRect.iTl.iX < 0
       
    82 			|| aSourceRect.iTl.iY < 0
       
    83 			|| aSourceRect.iBr.iX > bitmapSize.iWidth
       
    84 			|| aSourceRect.iBr.iY > bitmapSize.iHeight)
       
    85 		{
       
    86 		aSource->EndDataAccess(ETrue);
       
    87 		return;
       
    88 		}
       
    89 
       
    90 	TRect destRect(aDestRect);
       
    91 	destRect.Move(iOrigin);
       
    92 	AddRect(destRect);
       
    93 
       
    94 	TRect clippedDestRect(destRect);
       
    95 	if (UserClipRect(clippedDestRect))
       
    96 		{
       
    97 		aSource->EndDataAccess(ETrue);
       
    98 		return;
       
    99 		}
       
   100 
       
   101 	CFbsBitGcBitmap* srce = (CFbsBitGcBitmap*)aSource;
       
   102 	SetupDevice();
       
   103 	iDevice->DrawingBegin();
       
   104 
       
   105 	CBitwiseBitmap* bmp = srce->Address();
       
   106 	BG_ASSERT_DEBUG(bmp,EBitgdiPanicInvalidBitmap);
       
   107 
       
   108 	CFbsRasterizer* rasterizer = PrepareRasterizerForExtendedBitmap(*aSource, destRect, aSourceRect);
       
   109 
       
   110 	const TPoint ditherOrigin(iDitherOrigin + aDestRect.iTl);
       
   111 
       
   112 	const TInt limit = iDefaultRegionPtr->Count();
       
   113 	CGraphicsAccelerator* ga = GraphicsAccelerator();
       
   114 	if (ga && iShadowMode==CFbsDrawDevice::ENoShadow && iDrawMode==EDrawModePEN)
       
   115 		{
       
   116 		TInt gaOperationResult = KErrUnknown;
       
   117 		TAcceleratedBitmapSpec bitmapSpec(const_cast<CFbsBitmap*>(aSource));
       
   118 		iDevice->DrawingEnd();
       
   119 
       
   120 		if (destRect.Size() == aSourceRect.Size())
       
   121 			{
       
   122 			const TPoint offset(aSourceRect.iTl - destRect.iTl);
       
   123 			for(TInt count=0;count<limit;count++)
       
   124 				{
       
   125 				iClipRect=(*iDefaultRegionPtr)[count];
       
   126 				if(!iClipRect.Intersects(clippedDestRect))
       
   127 					continue;
       
   128 				iClipRect.Intersection(clippedDestRect);
       
   129 
       
   130 				TRect clippedSrceRect(iClipRect);
       
   131 				clippedSrceRect.Move(offset);
       
   132 				gaOperationResult = ga->Operation(TGopBitBlt(iClipRect.iTl,bitmapSpec,clippedSrceRect));
       
   133 				if (gaOperationResult!=KErrNone)
       
   134 					break;
       
   135 				}
       
   136 			iDevice->iDrawDevice->UpdateRegion(iClipRect);
       
   137 			}
       
   138 		else
       
   139 			{
       
   140 			RRegion clippedRegion;
       
   141 			for(TInt clipIt=0;clipIt<limit;clipIt++)
       
   142 				{
       
   143 				TRect clipRect((*iDefaultRegionPtr)[clipIt]);
       
   144 				clipRect.Intersection(clippedDestRect);
       
   145 				if (!clipRect.IsEmpty())
       
   146 					clippedRegion.AddRect(clipRect);
       
   147 				}
       
   148 			TRect srcCopy(aSourceRect);	// Needed because TGopScaledBitBlt takes a non-const value
       
   149 			// const_cast needed because Operation takes a non-const region ptr :(
       
   150 			gaOperationResult = ga->Operation(TGopScaledBitBlt(destRect,bitmapSpec,srcCopy),clippedRegion.Count(),const_cast<TRect*>(clippedRegion.RectangleList()));
       
   151 			if (gaOperationResult==KErrNone) 	 
       
   152 				iDevice->iDrawDevice->Update(clippedRegion);
       
   153 			clippedRegion.Close();
       
   154 			}
       
   155 		if(gaOperationResult == KErrNone)
       
   156 			goto finish;
       
   157 		iDevice->DrawingBegin();
       
   158 		
       
   159 		}
       
   160 //
       
   161 	{	// to stop error from gccxml build about previous jump to finish skipping initialisation of opaqueSource 
       
   162 	const TBool opaqueSource = (!IsAlphaChannel(aSource->DisplayMode())) && (iDrawMode == EDrawModePEN);
       
   163 	if (opaqueSource)
       
   164 		{
       
   165 		iDrawMode = EDrawModeWriteAlpha;
       
   166 		}
       
   167 
       
   168 	for (TInt count = 0; count < limit; count++)
       
   169 		{
       
   170 		iClipRect = (*iDefaultRegionPtr)[count];
       
   171 		if (!iClipRect.Intersects(clippedDestRect))
       
   172 			continue;
       
   173 
       
   174 		iClipRect.Intersection(clippedDestRect);
       
   175 		DoDrawBitmap(destRect,bmp,aSource->DataAddress(),aSource->DataStride(),aSourceRect,ditherOrigin);
       
   176 
       
   177 		iDevice->iDrawDevice->UpdateRegion(iClipRect);
       
   178 		}
       
   179 	if (opaqueSource)
       
   180 		{
       
   181 		iDrawMode = EDrawModePEN;
       
   182 		}
       
   183 
       
   184 	}
       
   185 	iDevice->DrawingEnd();
       
   186 	
       
   187 finish:
       
   188 	if (rasterizer)
       
   189 		{
       
   190 		rasterizer->EndBitmap(aSource->SerialNumber());
       
   191 		}
       
   192 	aSource->EndDataAccess(ETrue);
       
   193 	}
       
   194 
       
   195 
       
   196 void CFbsBitGc::DoDrawBitmap(const TRect& aDestRect,
       
   197 							 CBitwiseBitmap* aBitmap,
       
   198 							 TUint32* aBase,
       
   199 							 TInt aStride,
       
   200 							 const TRect& aSrceRect,
       
   201 							 const TPoint& aDitherOrigin)
       
   202 	{
       
   203 	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
       
   204 #ifdef _DEBUG
       
   205 	TRect deviceDestRect;
       
   206 	drawDevice->GetDrawRect(deviceDestRect);
       
   207 #endif
       
   208 	BG_ASSERT_DEBUG(iClipRect.iTl.iX >= deviceDestRect.iTl.iX, EBitgdiPanicOutOfBounds);
       
   209 	BG_ASSERT_DEBUG(iClipRect.iTl.iY >= deviceDestRect.iTl.iY, EBitgdiPanicOutOfBounds);
       
   210 	BG_ASSERT_DEBUG(iClipRect.iBr.iX <= deviceDestRect.iBr.iX, EBitgdiPanicOutOfBounds);
       
   211 	BG_ASSERT_DEBUG(iClipRect.iBr.iY <= deviceDestRect.iBr.iY, EBitgdiPanicOutOfBounds);
       
   212 
       
   213 	if (aDestRect.Size() == aSrceRect.Size())
       
   214 		{
       
   215 		TRect clippedRect(aDestRect);
       
   216 		clippedRect.Intersection(iClipRect);
       
   217 
       
   218 		if (!clippedRect.IsEmpty())
       
   219 			{
       
   220 			const TPoint destPoint(clippedRect.iTl);
       
   221 			clippedRect.Move(aSrceRect.iTl - aDestRect.iTl);
       
   222 			DoBitBlt(destPoint,aBitmap,aBase,aStride,clippedRect);
       
   223 			}
       
   224 
       
   225 		return;
       
   226 		}
       
   227 	MFastBlend* fastBlend=NULL;
       
   228 	if (FastBlendInterface(aBitmap,NULL,fastBlend)==KErrNone)
       
   229 		{
       
   230 		if (fastBlend->FastBlendBitmapScaled(iClipRect, aDestRect, aSrceRect, aBase, aStride, aBitmap->DisplayMode(), aBitmap->SizeInPixels(), iDrawMode, iShadowMode)== KErrNone)
       
   231 			{
       
   232 			return;
       
   233 			}
       
   234 		}
       
   235 
       
   236 	TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
       
   237 	const TInt scanLineBytes = drawDevice->ScanLineBytes();
       
   238 	TPtr8 scanLineDes(REINTERPRET_CAST(TUint8*,scanLineBuffer),scanLineBytes,scanLineBytes);
       
   239 
       
   240 	// For EColor16MU targets, don't use EColor16MAP when draw mode is EDrawModeWriteAlpha.
       
   241 	// Format conversion provides no performance gain and WriteLine expects EColor16MU 
       
   242 	// in this case.
       
   243 	const TDisplayMode dispMode = drawDevice->DisplayMode() == EColor16MU && iDrawMode == EDrawModeWriteAlpha ? EColor16MU : drawDevice->ScanLineDisplayMode();
       
   244 
       
   245 	TLinearDDA xLine;
       
   246 	TInt bitmapXStart = 0;
       
   247 	xLine.Construct(TPoint(aSrceRect.iTl.iX,aDestRect.iTl.iX),
       
   248 					TPoint(aSrceRect.iBr.iX,aDestRect.iBr.iX),TLinearDDA::ELeft);
       
   249 	xLine.JumpToYCoord(bitmapXStart,iClipRect.iTl.iX);
       
   250 
       
   251 	TLinearDDA yLine;
       
   252 	TPoint yCoord(aSrceRect.iTl.iY,aDestRect.iTl.iY);
       
   253 	yLine.Construct(yCoord,TPoint(aSrceRect.iBr.iY,aDestRect.iBr.iY),TLinearDDA::ELeft);
       
   254 	TInt dummy;
       
   255 	yLine.JumpToYCoord2(dummy,iClipRect.iTl.iY);
       
   256 	yCoord.SetXY(dummy,iClipRect.iTl.iY);
       
   257 
       
   258 	TBool finished = EFalse;
       
   259 	TPoint ditherOrigin(aDitherOrigin + iClipRect.iTl);
       
   260 	const TInt srceWidth = aSrceRect.Width();
       
   261 	const TInt destWidth = aDestRect.Width();
       
   262 	const TInt clipWidth = iClipRect.Width();
       
   263 	const TInt clipStrch = iClipRect.iTl.iX - aDestRect.iTl.iX;
       
   264 
       
   265 	TLineScanningPosition lineScanPos(aBase);
       
   266 	while (yCoord.iY < iClipRect.iBr.iY && !finished)
       
   267 		{
       
   268 		aBitmap->StretchScanLine(scanLineDes,TPoint(bitmapXStart,yCoord.iX),
       
   269 								 clipStrch,clipWidth,destWidth,aSrceRect.iTl.iX,
       
   270 								 srceWidth,ditherOrigin,dispMode,aBase,lineScanPos);
       
   271 		if (yCoord.iY==iClipRect.iTl.iY)
       
   272 			aBitmap->SetCompressionBookmark(lineScanPos, aBase,NULL);
       
   273 		drawDevice->WriteLine(iClipRect.iTl.iX,yCoord.iY,clipWidth, scanLineBuffer,iDrawMode);
       
   274 		finished = yLine.NextStep(yCoord);
       
   275 		ditherOrigin.iY++;
       
   276 		}
       
   277 	}
       
   278 
       
   279 /** The method draws a specified rectangle from a bitmap and
       
   280 its mask into another rectangle and does a compress/stretch
       
   281 to fit a given destination rectangle.
       
   282 
       
   283 @note When using this function with a 256 Mask bitmap, it blends.
       
   284 Otherwise (e.g. with a 4bpp mask), this function masks rather than blends.
       
   285 If a user wants to blend the source into the destination they should use
       
   286 CFbsBitGc::AlphaBlendBitmaps() instead.
       
   287 
       
   288 @publishedAll
       
   289 @released
       
   290 
       
   291 @param aDestRect The rectangle within which the masked bitmap is to be drawn.
       
   292 @param aBitmap A pointer to the source bitmap.
       
   293 @param aSourceRect The rectangle in the source bitmap that is copied to the
       
   294 destination rectangle.
       
   295 @param aMaskBitmap A pointer to the mask bitmap.
       
   296 @param aInvertMask If false, a source pixel that is masked by a black pixel
       
   297 is not transferred to the destination rectangle. If true, then a source pixel
       
   298 that is masked by a white pixel is not transferred to the destination rectangle.
       
   299 
       
   300 @pre aBitmap != NULL
       
   301 @pre aBitmap->Handle() != 0
       
   302 @pre aMaskBitmap != NULL
       
   303 @pre aMaskBitmap->Handle() != 0
       
   304 @pre !aSourceRect.IsEmpty()
       
   305 @pre aSourceRect should be in the bounds of the bitmap
       
   306 */
       
   307 EXPORT_C void CFbsBitGc::DrawBitmapMasked(const TRect& aDestRect,
       
   308 						 const CFbsBitmap* aBitmap,
       
   309 						 const TRect& aSourceRect,
       
   310 						 const CFbsBitmap* aMaskBitmap,
       
   311 						 TBool aInvertMask)
       
   312 	{
       
   313 	if (aBitmap == NULL || !aBitmap->Handle() || aMaskBitmap == NULL ||
       
   314 		!aMaskBitmap->Handle() || aSourceRect.IsEmpty() || CheckDevice(aDestRect))
       
   315 		{
       
   316 		return;
       
   317 		}
       
   318 	
       
   319 	aBitmap->BeginDataAccess();
       
   320 	aMaskBitmap->BeginDataAccess();
       
   321 	
       
   322 	//aSourceRect should be in the bounds of the bitmap
       
   323 	TSize bitmapSize(aBitmap->SizeInPixels());
       
   324 	if ( aSourceRect.iTl.iX < 0
       
   325 			|| aSourceRect.iTl.iY < 0
       
   326 			|| aSourceRect.iBr.iX > bitmapSize.iWidth
       
   327 			|| aSourceRect.iBr.iY > bitmapSize.iHeight)
       
   328 		{
       
   329 		aBitmap->EndDataAccess(ETrue);
       
   330 		aMaskBitmap->EndDataAccess(ETrue);
       
   331 		return;
       
   332 		}   		
       
   333 	
       
   334 	TRect destRect(aDestRect);
       
   335 	destRect.Move(iOrigin);
       
   336 	AddRect(destRect);
       
   337 	TRect clippedDestRect(destRect);
       
   338 	if (UserClipRect(clippedDestRect))
       
   339 		{
       
   340 		aBitmap->EndDataAccess(ETrue);
       
   341 		aMaskBitmap->EndDataAccess(ETrue);
       
   342 		return;
       
   343 		}
       
   344 
       
   345 	SetupDevice();
       
   346 	const TBool opaqueSource = (!IsAlphaChannel(aBitmap->DisplayMode())) && (iDrawMode == EDrawModePEN);
       
   347 	iDevice->DrawingBegin();
       
   348 
       
   349 	CBitwiseBitmap* srcebmp = ((CFbsBitGcBitmap*)aBitmap)->Address();
       
   350 	CBitwiseBitmap* maskbmp = ((CFbsBitGcBitmap*)aMaskBitmap)->Address();
       
   351 	BG_ASSERT_DEBUG(srcebmp,EBitgdiPanicInvalidBitmap);
       
   352 	BG_ASSERT_DEBUG(maskbmp,EBitgdiPanicInvalidBitmap);
       
   353 
       
   354 	CFbsRasterizer* rasterizer = PrepareRasterizerForExtendedBitmap(*aBitmap, destRect, aSourceRect);
       
   355 	CFbsRasterizer* maskRasterizer = NULL;
       
   356 	if (srcebmp != maskbmp)
       
   357 		{
       
   358 		if (aMaskBitmap->SizeInPixels().iWidth >= aBitmap->SizeInPixels().iWidth
       
   359 			&& aMaskBitmap->SizeInPixels().iHeight >= aBitmap->SizeInPixels().iHeight)
       
   360 			{
       
   361 			// Mask is not tiled. Pass same region of interest as source bitmap to rasterizer.
       
   362 			maskRasterizer = PrepareRasterizerForExtendedBitmap(*aMaskBitmap, destRect, aSourceRect);
       
   363 			}
       
   364 		else
       
   365 			{
       
   366 			// Mask is tiled. Do not pass any region of interest to rasterizer.
       
   367 			maskRasterizer = PrepareRasterizerForExtendedBitmap(*aMaskBitmap);
       
   368 			}
       
   369 		}
       
   370 
       
   371 	const TPoint ditherOrigin(iDitherOrigin + aDestRect.iTl);
       
   372 	const TInt limit = iDefaultRegionPtr->Count();
       
   373 //
       
   374 	CGraphicsAccelerator* ga = GraphicsAccelerator();
       
   375 	if (ga && iShadowMode==CFbsDrawDevice::ENoShadow && (aMaskBitmap->DisplayMode()!=EGray2 || !aInvertMask) && iDrawMode==EDrawModePEN)
       
   376 		{
       
   377 		TInt gaOperationResult = KErrUnknown;
       
   378 		TAcceleratedBitmapSpec bitmapSpec(const_cast<CFbsBitmap*>(aBitmap));
       
   379 		iDevice->DrawingEnd();
       
   380 		TAcceleratedBitmapSpec maskSpec(const_cast<CFbsBitmap*>(aMaskBitmap));
       
   381 		const TPoint offset(aSourceRect.iTl - destRect.iTl);
       
   382 
       
   383 		if (destRect.Size() == aSourceRect.Size())
       
   384 			{
       
   385 			for(TInt count=0;count<limit;count++)
       
   386 				{
       
   387 				iClipRect=(*iDefaultRegionPtr)[count];
       
   388 				if(!iClipRect.Intersects(clippedDestRect))
       
   389 					continue;
       
   390 				iClipRect.Intersection(clippedDestRect);
       
   391 
       
   392 				TRect clippedSrceRect(iClipRect);
       
   393 				clippedSrceRect.Move(offset);
       
   394 
       
   395 				gaOperationResult = ga->Operation(TGopBitBltMasked(iClipRect.iTl,bitmapSpec,clippedSrceRect,maskSpec)); 	 
       
   396 				if (gaOperationResult!=KErrNone) 	 
       
   397 					break; 	 
       
   398 				iDevice->iDrawDevice->UpdateRegion(iClipRect);
       
   399 				}
       
   400 			}
       
   401 		else
       
   402 			{
       
   403 			RRegion clippedRegion;
       
   404 			for(TInt clipIt=0;clipIt<limit;clipIt++)
       
   405 				{
       
   406 				TRect clipRect((*iDefaultRegionPtr)[clipIt]);
       
   407 				clipRect.Intersection(clippedDestRect);
       
   408 				if (!clipRect.IsEmpty())
       
   409 					clippedRegion.AddRect(clipRect);
       
   410 				}
       
   411 			TRect srcCopy(aSourceRect);	// Needed because TGopScaledBitBltMasked takes a non-const value
       
   412 			// const_cast needed because Operation takes a non-const region ptr :(
       
   413 			gaOperationResult = ga->Operation(TGopScaledBitBltMasked(destRect,bitmapSpec,srcCopy,maskSpec),clippedRegion.Count(),const_cast<TRect*>(clippedRegion.RectangleList()));
       
   414 			if (gaOperationResult==KErrNone) 	 
       
   415 				iDevice->iDrawDevice->Update(clippedRegion);
       
   416 			clippedRegion.Close();
       
   417 			} 	 
       
   418 		if (gaOperationResult==KErrNone) 	 
       
   419 			goto finish;
       
   420 		iDevice->DrawingBegin(); 	 
       
   421 		}
       
   422 //
       
   423 	if (opaqueSource)
       
   424 		iDrawMode = EDrawModeWriteAlpha;
       
   425 	for (TInt count = 0; count < limit; count++)
       
   426 		{
       
   427 		iClipRect = (*iDefaultRegionPtr)[count];
       
   428 		if (!iClipRect.Intersects(clippedDestRect))
       
   429 			continue;
       
   430 		iClipRect.Intersection(clippedDestRect);
       
   431 		DoDrawBitmapMasked(destRect,
       
   432 					   srcebmp,
       
   433 					   aBitmap->DataAddress(),
       
   434 					   aSourceRect,
       
   435 					   maskbmp,
       
   436 					   aMaskBitmap->DataAddress(),
       
   437 					   aInvertMask, ditherOrigin);
       
   438 		iDevice->iDrawDevice->UpdateRegion(iClipRect);
       
   439 		}
       
   440 	if (opaqueSource)
       
   441 		iDrawMode = EDrawModePEN;
       
   442 	iDevice->DrawingEnd();
       
   443 finish:
       
   444 	if (rasterizer)
       
   445 		{
       
   446 		rasterizer->EndBitmap(aBitmap->SerialNumber());
       
   447 		}
       
   448 	if (maskRasterizer)
       
   449 		{
       
   450 		maskRasterizer->EndBitmap(aMaskBitmap->SerialNumber());
       
   451 		}
       
   452 	aBitmap->EndDataAccess(ETrue);
       
   453 	aMaskBitmap->EndDataAccess(ETrue);
       
   454 	}
       
   455 
       
   456 /** The method draws a specified rectangle from a bitmap and
       
   457 its mask into another rectangle and does a compress/stretch
       
   458 to fit a given destination rectangle.
       
   459 
       
   460 This is an overload, which takes CWsBitmap* as argument, which
       
   461 in turn calls the other overload.
       
   462 
       
   463 Note: A pointer to CWsBitmap must have the same pointer value as a pointer
       
   464 to the associated CFbsBitmap, otherwise code in BitGdi component will be
       
   465 Broken.
       
   466 
       
   467 @note When using this function with a 256 Mask bitmap, it blends.
       
   468 Otherwise (e.g. with a 4bpp mask), this function masks rather than blends.
       
   469 If a user wants to blend the source into the destination they should use
       
   470 CFbsBitGc::AlphaBlendBitmaps() instead.
       
   471 
       
   472 @publishedAll
       
   473 @released
       
   474 
       
   475 @param aDestRect The rectangle within which the masked bitmap is to be drawn.
       
   476 @param aBitmap A pointer to the source bitmap.
       
   477 @param aSourceRect The rectangle in the source bitmap that is copied to the
       
   478 destination rectangle.
       
   479 @param aMaskBitmap A pointer to the mask bitmap.
       
   480 @param aInvertMask If false, a source pixel that is masked by a black pixel
       
   481 is not transferred to the destination rectangle. If true, then a source pixel
       
   482 that is masked by a white pixel is not transferred to the destination rectangle.
       
   483 
       
   484 @pre aBitmap != NULL
       
   485 @pre aBitmap->Handle() != 0
       
   486 @pre aMaskBitmap != NULL
       
   487 @pre aMaskBitmap->Handle() != 0
       
   488 @pre !aSourceRect.IsEmpty()
       
   489 */
       
   490 EXPORT_C void CFbsBitGc::DrawBitmapMasked(const TRect& aDestRect,
       
   491 						 const CWsBitmap* aBitmap,
       
   492 						 const TRect& aSourceRect,
       
   493 						 const CWsBitmap* aMaskBitmap,
       
   494 						 TBool aInvertMask)
       
   495 	{
       
   496 	DrawBitmapMasked(aDestRect,REINTERPRET_CAST(const CFbsBitmap*,aBitmap),aSourceRect,REINTERPRET_CAST(const CFbsBitmap*,aMaskBitmap),aInvertMask);
       
   497 	}