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