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