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