Update contrib.
1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
22 #include <bitdrawscaling.h>
23 #include <bitdrawinterfaceid.h>
24 #include <bmalphablend.h>
25 #include <graphics/fbsrasterizer.h>
26 #include <graphics/bitmap.inl>
27 #include <graphics/gdi/gdiinline.inl>
29 GLREF_C void XorBuffers(TUint32* aDestBuffer,const TUint32* aSrceBuffer,TInt aNumBytes);
30 GLREF_C void AndBuffers(TUint32* aDestBuffer,const TUint32* aSrceBuffer,TInt aNumBytes);
31 GLREF_C void InvertBuffer(TUint32* aDestBuffer,TInt aNumBytes);
32 GLREF_C void InvertBuffer(TUint8* aDestBuffer,TInt aNumBytes);
33 LOCAL_C void TileScanLine(TPtr8& aScanLine,
36 const CBitwiseBitmap* aMaskBitmap,
37 TLineScanningPosition& aScanLinePos,
39 TDisplayMode aDisplayMode
42 /** Draws from another CFbsBitGc.
44 @param aPoint The position to draw the top left corner of the piece of bitmap
45 @param aGc The source bitmap graphics context */
46 EXPORT_C void CFbsBitGc::BitBlt(const TPoint& aDest,const CFbsBitGc& aGc)
49 aGc.iDevice->iDrawDevice->GetDrawRect(deviceRect);
50 BitBlt(aDest,aGc,deviceRect);
53 /** Draws a particular rectangle from another CFbsBitGc.
55 @param aPoint The position to draw the top left corner of the piece of bitmap.
56 @param aGc The source bitmap graphics context.
57 @param aSrceRect A rectangle defining the piece of the source to be drawn. */
58 EXPORT_C void CFbsBitGc::BitBlt(const TPoint& aDest,
60 const TRect& aSrceRect)
62 if (CheckDevice(aSrceRect))
65 CFbsDevice* srceDevice = aGc.iDevice;
69 TRect srceRect(aSrceRect);
71 srceDevice->GetDrawRect(deviceRect);
72 if (!srceRect.Intersects(deviceRect))
74 srceRect.Intersection(deviceRect);
76 const TPoint destPoint(aDest + iOrigin + srceRect.iTl - aSrceRect.iTl);
77 const TRect destRect(destPoint,srceRect.Size());
78 const TPoint offset(srceRect.iTl - destPoint);
80 TRect clippedDestRect(destRect);
81 AddRect(clippedDestRect);
82 if (UserClipRect(clippedDestRect))
86 aGc.iDevice->DrawingBegin();
87 iDevice->DrawingBegin();
89 const TInt limit = iDefaultRegionPtr->Count();
90 TBool opaqueSource = (!IsAlphaChannel(srceDevice->DisplayMode())) && (iDrawMode == EDrawModePEN);
91 for(TInt count=0;count<limit;count++)
93 iClipRect=(*iDefaultRegionPtr)[count];
94 if(!iClipRect.Intersects(clippedDestRect))
96 iClipRect.Intersection(clippedDestRect);
98 TRect clippedSrceRect(iClipRect);
99 clippedSrceRect.Move(offset);
102 iDrawMode = EDrawModeWriteAlpha;// ie write rather then blend
103 DoBitBlt(iClipRect.iTl,srceDevice,clippedSrceRect);
105 iDrawMode = EDrawModePEN;// set it back how it was
106 iDevice->iDrawDevice->UpdateRegion(iClipRect);
109 aGc.iDevice->DrawingEnd();
110 iDevice->DrawingEnd();
114 /** Draws the whole of a CFbsBitmap.
116 @param aDest The position to draw the top left corner of the bitmap.
117 @param aBitmap The source bitmap. */
118 EXPORT_C void CFbsBitGc::BitBlt(const TPoint& aDest,const CFbsBitmap* aBitmap)
120 if (aBitmap == NULL || !aBitmap->Handle())
123 aBitmap->BeginDataAccess();
124 BitBlt(aDest,aBitmap,TRect(aBitmap->SizeInPixels()));
125 aBitmap->EndDataAccess(ETrue);
129 /** Draws a particular rectangle from a CFbsBitmap.
131 @param aDest The position to draw the top left corner of the bitmap.
132 @param aBitmap The source bitmap.
133 @param aSrceRect A rectangle defining the piece of the source to be drawn. */
134 EXPORT_C void CFbsBitGc::BitBlt(const TPoint& aDest,
135 const CFbsBitmap* aBitmap,
136 const TRect& aSrceRect)
138 if (aBitmap == NULL || !aBitmap->Handle()|| CheckDevice(aSrceRect))
141 aBitmap->BeginDataAccess();
143 TRect srceRect(aSrceRect);
144 const TRect area(aBitmap->SizeInPixels());
145 if (!srceRect.Intersects(area))
147 aBitmap->EndDataAccess(ETrue);
150 srceRect.Intersection(area);
152 const TPoint destPoint(aDest + iOrigin + srceRect.iTl - aSrceRect.iTl);
153 const TPoint offset(srceRect.iTl - destPoint);
155 TRect targetRect(destPoint,srceRect.Size());
157 if (UserClipRect(targetRect))
159 aBitmap->EndDataAccess(ETrue);
164 iDevice->DrawingBegin();
166 CBitwiseBitmap* srce = ((CFbsBitGcBitmap*)aBitmap)->Address();
167 BG_ASSERT_DEBUG(srce,EBitgdiPanicInvalidBitmap);
169 CFbsRasterizer* rasterizer = PrepareRasterizerForExtendedBitmap(*aBitmap, targetRect, offset);
172 const TInt limit = iDefaultRegionPtr->Count();
173 CGraphicsAccelerator* ga = GraphicsAccelerator();
174 TBool opaqueSource = (!IsAlphaChannel(aBitmap->DisplayMode())) && (iDrawMode == EDrawModePEN);
176 if(ga && (iShadowMode == CFbsDrawDevice::ENoShadow))
178 TInt gaOperationResult = KErrUnknown;
179 TAcceleratedBitmapSpec bitmapSpec(const_cast<CFbsBitmap*>(aBitmap));
180 iDevice->DrawingEnd();
182 for(count=0;count<limit;count++)
185 iClipRect=(*iDefaultRegionPtr)[count];
186 if(!iClipRect.Intersects(targetRect))
188 iClipRect.Intersection(targetRect);
190 TRect clippedSrceRect(iClipRect);
191 clippedSrceRect.Move(offset);
193 gaOperationResult = ga->Operation(TGopBitBlt(iClipRect.iTl,bitmapSpec,clippedSrceRect));
194 if(gaOperationResult != KErrNone)
196 iDevice->iDrawDevice->UpdateRegion(iClipRect);
198 if(gaOperationResult == KErrNone)
200 iDevice->DrawingBegin();
203 for(count=0;count<limit;count++)
205 iClipRect=(*iDefaultRegionPtr)[count];
206 if(!iClipRect.Intersects(targetRect))
208 iClipRect.Intersection(targetRect);
210 TRect clippedSrceRect(iClipRect);
211 clippedSrceRect.Move(offset);
214 iDrawMode = EDrawModeWriteAlpha;// ie write rather then blend
215 DoBitBlt(iClipRect.iTl,srce,aBitmap->DataAddress(),aBitmap->DataStride(),clippedSrceRect);
217 iDrawMode = EDrawModePEN;// set it back how it was
218 iDevice->iDrawDevice->UpdateRegion(iClipRect);
221 iDevice->DrawingEnd();
225 rasterizer->EndBitmap(aBitmap->SerialNumber());
227 aBitmap->EndDataAccess(ETrue);
231 /** Performs a masked bitmap block transfer.
233 The function provides a concrete implementation of the pure virtual
234 function CBitmapContext::BitBltMasked(). The function
235 behaviour is the same as documented in that class.
237 There are several points to note about this implementation of
240 1.For best performance the aMaskBitmap and source aBitmap should
241 have the same display mode as the destination device/bitmap.
243 2.For performance reasons this implementation does not validate
244 the contents of the aMaskBitmap. The caller must ensure the mask
245 pixels are either black or white otherwise undefined blitting causing
246 unpredictable discoloration will result. This is especially true
247 for index (where pixel is palette entry) display modes (e.g. EColor16).
248 It is up to the caller to decide if they wish to utilise
249 CFbsBitmap::IsMonochrome().
251 3.Alpha blending is used when the display mode of the mask bitmap aMaskBitmap
254 @see CBitmapContext::BitBltMasked() */
255 EXPORT_C void CFbsBitGc::BitBltMasked(const TPoint& aDest,
256 const CFbsBitmap* aBitmap,
257 const TRect& aSourceRect,
258 const CFbsBitmap* aMaskBitmap,
261 if (aBitmap == NULL || !aBitmap->Handle() ||
262 aMaskBitmap == NULL || !aMaskBitmap->Handle() ||
263 CheckDevice(aSourceRect))
266 aBitmap->BeginDataAccess();
267 aMaskBitmap->BeginDataAccess();
269 TRect srceRect(aSourceRect);
270 const TRect area(aBitmap->SizeInPixels());
271 if (!srceRect.Intersects(area))
273 aBitmap->EndDataAccess(ETrue);
274 aMaskBitmap->EndDataAccess(ETrue);
277 srceRect.Intersection(area);
279 const TPoint destPoint(aDest + iOrigin + srceRect.iTl - aSourceRect.iTl);
280 const TRect destRect(destPoint,srceRect.Size());
281 const TPoint offset(srceRect.iTl - destPoint);
282 const TPoint ditherorigin(iDitherOrigin + aDest);
284 TRect clippedDestRect(destRect);
285 AddRect(clippedDestRect);
286 if (UserClipRect(clippedDestRect))
288 aBitmap->EndDataAccess(ETrue);
289 aMaskBitmap->EndDataAccess(ETrue);
294 iDevice->DrawingBegin();
297 CBitwiseBitmap* srcebmp = ((CFbsBitGcBitmap*)aBitmap)->Address();
298 CBitwiseBitmap* maskbmp = ((CFbsBitGcBitmap*)aMaskBitmap)->Address();
299 BG_ASSERT_DEBUG(srcebmp,EBitgdiPanicInvalidBitmap);
300 BG_ASSERT_DEBUG(maskbmp,EBitgdiPanicInvalidBitmap);
302 const TDisplayMode maskMode = maskbmp->DisplayMode();
304 // Do the background fill the lazy way with flicker if any of the following are true:
305 // 1. There is no anti-flicker buffer
306 // 2. The source and mask bitmaps are the same
307 // 3. The brush style is patterned and the mask is an alpha mask
308 // 4. The brush style is not null or solid or patterned
310 if (!iDevice->iBitBltMaskedBuffer ||
311 srcebmp == maskbmp ||
312 (maskMode == EGray256 && iBrushStyle == EPatternedBrush) ||
313 iBrushStyle > EPatternedBrush)
315 iBrushBitmap.BeginDataAccess();
316 CFbsRasterizer* brushRasterizer = PrepareRasterizerForExtendedBitmap(iBrushBitmap);
320 brushRasterizer->EndBitmap(iBrushBitmap.SerialNumber());
322 iBrushBitmap.EndDataAccess(ETrue);
325 const TInt8 shadowMode = iShadowMode;
326 iShadowMode = CFbsDrawDevice::ENoShadow;
329 CFbsRasterizer* rasterizer = PrepareRasterizerForExtendedBitmap(*aBitmap, clippedDestRect, offset);
330 CFbsRasterizer* maskRasterizer = NULL;
331 if (srcebmp != maskbmp)
333 if (aMaskBitmap->SizeInPixels().iWidth >= aBitmap->SizeInPixels().iWidth
334 && aMaskBitmap->SizeInPixels().iHeight >= aBitmap->SizeInPixels().iHeight)
336 // Mask is not tiled. Pass same region of interest as source bitmap to rasterizer.
337 maskRasterizer = PrepareRasterizerForExtendedBitmap(*aMaskBitmap, clippedDestRect, offset);
341 // Mask is tiled. Do not pass any region of interest to rasterizer.
342 maskRasterizer = PrepareRasterizerForExtendedBitmap(*aMaskBitmap);
347 const TInt limit = iDefaultRegionPtr->Count();
348 CGraphicsAccelerator* ga = GraphicsAccelerator();
349 TBool opaqueSource = (!IsAlphaChannel(aBitmap->DisplayMode())) && (iDrawMode == EDrawModePEN);
353 if((iBrushStyle == ENullBrush) && aInvertMask &&
354 (shadowMode == CFbsDrawDevice::ENoShadow))
356 TInt gaOperationResult = KErrUnknown;
357 TAcceleratedBitmapSpec bitmapSpec(const_cast<CFbsBitmap*>(aBitmap));
358 TAcceleratedBitmapSpec bitmapMaskSpec(const_cast<CFbsBitmap*>(aMaskBitmap));
359 iDevice->DrawingEnd();
361 for(count=0;count<limit;count++)
363 iClipRect=(*iDefaultRegionPtr)[count];
364 if(!iClipRect.Intersects(clippedDestRect))
366 iClipRect.Intersection(clippedDestRect);
367 TRect clippedSrceRect(iClipRect);
368 clippedSrceRect.Move(offset);
370 if(maskbmp->DisplayMode() == EGray256)
371 gaOperationResult = ga->Operation(TGopBitBltAlphaBitmap(iClipRect.iTl,
376 gaOperationResult = ga->Operation(TGopBitBltMasked(iClipRect.iTl,
381 if(gaOperationResult != KErrNone)
383 iDevice->iDrawDevice->UpdateRegion(iClipRect);
385 if(gaOperationResult == KErrNone)
387 iDevice->DrawingBegin();
391 for(count=0;count<limit;count++)
393 iClipRect=(*iDefaultRegionPtr)[count];
394 if (!iClipRect.Intersects(clippedDestRect))
396 iClipRect.Intersection(clippedDestRect);
398 TRect clippedSrceRect(iClipRect);
399 clippedSrceRect.Move(offset);
402 iDrawMode = EDrawModeWriteAlpha;// ie write rather then blend
403 DoBitBltMasked(iClipRect.iTl,
405 aBitmap->DataAddress(),
408 aMaskBitmap->DataAddress(),
413 iDrawMode = EDrawModePEN;// set it back how it was
414 iDevice->iDrawDevice->UpdateRegion(iClipRect);
417 iDevice->DrawingEnd();
421 rasterizer->EndBitmap(aBitmap->SerialNumber());
425 maskRasterizer->EndBitmap(aMaskBitmap->SerialNumber());
427 aBitmap->EndDataAccess(ETrue);
428 aMaskBitmap->EndDataAccess(ETrue);
429 iShadowMode = shadowMode;
432 Does BitBlt operation of source and bitmap per scanline.
435 void CFbsBitGc::DoBitBlt(const TPoint& aDest,CFbsDevice* aSrce,const TRect& aSrceRect)
437 const TInt width = aSrceRect.Width();
438 CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
441 aSrce->iDrawDevice->GetDrawRect(deviceSrcRect);
442 TRect deviceDestRect;
443 drawDevice->GetDrawRect(deviceDestRect);
445 BG_ASSERT_DEBUG(aSrceRect.iTl.iX >= deviceSrcRect.iTl.iX, EBitgdiPanicOutOfBounds);
446 BG_ASSERT_DEBUG(aSrceRect.iTl.iY >= deviceSrcRect.iTl.iY, EBitgdiPanicOutOfBounds);
447 BG_ASSERT_DEBUG(aSrceRect.iBr.iX <= deviceSrcRect.iBr.iX, EBitgdiPanicOutOfBounds);
448 BG_ASSERT_DEBUG(aSrceRect.iBr.iY <= deviceSrcRect.iBr.iY, EBitgdiPanicOutOfBounds);
449 BG_ASSERT_DEBUG(aDest.iX >= deviceDestRect.iTl.iX, EBitgdiPanicOutOfBounds);
450 BG_ASSERT_DEBUG(aDest.iY >= deviceDestRect.iTl.iY, EBitgdiPanicOutOfBounds);
451 BG_ASSERT_DEBUG((aDest.iX + aSrceRect.Width()) <= deviceDestRect.iBr.iX, EBitgdiPanicOutOfBounds);
452 BG_ASSERT_DEBUG((aDest.iY + aSrceRect.Height()) <= deviceDestRect.iBr.iY, EBitgdiPanicOutOfBounds);
454 CFbsDrawDevice* srcDrawDevice = aSrce->iDrawDevice;
455 TAny* interface=NULL;
456 if (iDrawMode==EDrawModeWriteAlpha &&
457 iShadowMode == CFbsDrawDevice::ENoShadow &&
458 (aSrceRect.iTl.iX >= 0) && (aSrceRect.iTl.iY >= 0) &&
459 (aDest.iX >= 0) && (aDest.iY >= 0) &&
460 srcDrawDevice->DisplayMode() == drawDevice->DisplayMode() &&
461 drawDevice->GetInterface(KFastBlit2InterfaceID, interface) == KErrNone)
463 // Conditions in CFbsBitGc allow for optimised blitting.
464 // The draw device supports the optimised blitting function.
465 // Operation may fail regardless due to unacceptable conditions in the draw device.
466 BG_ASSERT_DEBUG(interface!=NULL, EBitgdiPanicNullPointer);
467 MFastBlit2* fastBlit = reinterpret_cast<MFastBlit2*>(interface);
468 if (fastBlit->WriteBitmapBlock(aDest, srcDrawDevice, aSrceRect) == KErrNone)
473 MFastBlend* fastBlend=NULL;
474 if (FastBlendInterface(NULL,NULL,fastBlend)==KErrNone)
476 if (fastBlend->FastBlendBitmap(aDest, srcDrawDevice, aSrceRect, iDrawMode, iShadowMode)==KErrNone)
481 //scanLineBuffer is destination scanline buffer.
482 TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
483 const TInt scanLineBytes = drawDevice->ScanLineBytes();
484 TPtr8 scanLineDes((TUint8*)scanLineBuffer,scanLineBytes,scanLineBytes);
485 //dispMode is destination display mode.
486 const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
487 TInt destY = aDest.iY;
488 //Gets the scanline from the source, into the buffer scanLineDes.
489 //The DoGetScanLine operation is also responsible for converting
490 // the buffer pixel format to destination display format.
492 for (TInt row = aSrceRect.iTl.iY; row < aSrceRect.iBr.iY; row++,destY++)
494 aSrce->DoGetScanLine(scanLineDes,TPoint(aSrceRect.iTl.iX,row),width,dispMode);
495 drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,iDrawMode);
500 Calculates the position into the scanline for the given x coordinate
502 TUint CFbsBitGc::MemoryOffsetForPixelPitch(TUint aX, TDisplayMode aDisplayMode)
504 switch (aDisplayMode)
523 BG_PANIC_DEBUG(EBitgdiPanicInvalidDisplayMode);
530 Gets the scanline pointer with the offset
532 TUint32* CFbsBitGc::GetScanLineOffsetPtr(CBitwiseBitmap* aSrce, TUint32*& aSlptr, TInt aLength, TPoint aPixel,TUint32* aBase, TLineScanningPosition& aLineScanningPosition, TUint aXOffset)
534 aSrce->GetScanLinePtr(aSlptr, aLength, aPixel, aBase, aLineScanningPosition);
535 return (TUint32*)((TUint8*)aSlptr + aXOffset);
538 void CFbsBitGc::DoBitBlt(const TPoint& aDest,
539 CBitwiseBitmap* aSrce,
542 const TRect& aSrceRect)
544 // Does multiple bitmap widths for painting rects only
545 const TInt width = aSrceRect.Width();
546 CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
548 TRect deviceDestRect;
549 drawDevice->GetDrawRect(deviceDestRect);
551 BG_ASSERT_DEBUG(aDest.iX >= deviceDestRect.iTl.iX, EBitgdiPanicOutOfBounds);
552 BG_ASSERT_DEBUG(aDest.iY >= deviceDestRect.iTl.iY, EBitgdiPanicOutOfBounds);
553 BG_ASSERT_DEBUG((aDest.iX + aSrceRect.Width()) <= deviceDestRect.iBr.iX, EBitgdiPanicOutOfBounds);
554 BG_ASSERT_DEBUG((aDest.iY + aSrceRect.Height()) <= deviceDestRect.iBr.iY, EBitgdiPanicOutOfBounds);
556 TSize srcSize = aSrce->SizeInPixels();
557 if (srcSize.iWidth == 0 || srcSize.iHeight == 0)
558 return; //no point doing anything if asked to draw zero size bitmap
560 TAny* interface=NULL;
561 if (iDrawMode==EDrawModeWriteAlpha &&
562 iShadowMode == CFbsDrawDevice::ENoShadow &&
563 aSrceRect.iTl.iX >= 0 &&
564 aSrceRect.iTl.iY >= 0 &&
565 aSrceRect.iBr.iX <= srcSize.iWidth &&
566 aSrceRect.iBr.iY <= srcSize.iHeight &&
567 (aDest.iX >= 0) && (aDest.iY >= 0) &&
568 !aSrce->IsCompressed() &&
569 aSrce->DisplayMode() == drawDevice->DisplayMode() &&
570 drawDevice->GetInterface(KFastBlit2InterfaceID, interface) == KErrNone)
572 // Conditions in CFbsBitGc allow for optimised blitting.
573 // The draw device supports the optimised blitting function.
574 // Operation may fail regardless due to unacceptable conditions in the draw device.
575 BG_ASSERT_DEBUG(interface!=NULL, EBitgdiPanicNullPointer);
576 MFastBlit2* fastBlit = reinterpret_cast<MFastBlit2*>(interface);
577 if (fastBlit && (fastBlit->WriteBitmapBlock(aDest, aBase, aStride, srcSize, aSrceRect) == KErrNone))
582 MFastBlend* fastBlend=NULL;
583 if (FastBlendInterface(aSrce,NULL,fastBlend)==KErrNone)
585 if (fastBlend->FastBlendBitmap(aDest, aBase, aStride, srcSize, aSrceRect, aSrce->DisplayMode(), iDrawMode, iShadowMode)== KErrNone)
591 const TInt scanLineBytes = drawDevice->ScanLineBytes();
592 TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
593 TPtr8 scanLineDes((TUint8*)scanLineBuffer,scanLineBytes,scanLineBytes);
595 const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
597 const TBool useScanLinePtr = (!iShadowMode) && (dispMode == aSrce->DisplayMode()) && (TDisplayModeUtils::NumDisplayModeBitsPerPixel(dispMode)>=8);
600 TUint32* lastScanLine = NULL;
602 lastScanLine = aSrce->ScanLineAddress(aBase,aSrceRect.iBr.iY-1);
604 TInt srceWidth = srcSize.iWidth;
605 TInt partlinestart = 0;
606 partlinestart = aSrceRect.iTl.iX % srceWidth;
607 if (partlinestart < 0)
608 partlinestart += srceWidth;
609 const TInt partlinelength = Min(srceWidth - partlinestart,width);
610 TInt destX = aDest.iX;
611 const TInt destXlimit=destX+width;
614 if (partlinestart > 0 && partlinelength > 0)
616 TPoint srcecoord1(partlinestart,aSrceRect.iTl.iY);
617 TInt desty = aDest.iY;
618 TPoint ditherorigin(iDitherOrigin);
619 ditherorigin.iX += aDest.iX;
620 ditherorigin.iY += desty;
622 TLineScanningPosition lineScanPos(aBase);
626 offset = MemoryOffsetForPixelPitch(partlinestart, dispMode);
627 if (aSrce->IsCompressed())
629 while (srcecoord1.iY < aSrceRect.iBr.iY)
631 scanLineBuffer = GetScanLineOffsetPtr(aSrce, slptr, partlinelength, srcecoord1, aBase, lineScanPos, offset);
632 if (srcecoord1.iY==aSrceRect.iTl.iY)
634 aSrce->SetCompressionBookmark(lineScanPos,aBase,NULL);
636 drawDevice->WriteLine(aDest.iX,desty,partlinelength, scanLineBuffer,iDrawMode);
637 srcecoord1.iY++,desty++,ditherorigin.iY++;
642 while (srcecoord1.iY < aSrceRect.iBr.iY)
644 scanLineBuffer = GetScanLineOffsetPtr(aSrce, slptr, partlinelength, srcecoord1, aBase, lineScanPos, offset);
647 drawDevice->WriteLine(aDest.iX,desty,partlinelength, scanLineBuffer,iDrawMode);
648 scanLineBuffer = (TUint32*)((TUint8*)scanLineBuffer + aStride);
649 srcecoord1.iY++,desty++,ditherorigin.iY++;
651 while ((srcecoord1.iY < aSrceRect.iBr.iY) && (scanLineBuffer < lastScanLine));
657 for (; srcecoord1.iY < aSrceRect.iBr.iY; srcecoord1.iY++,desty++,ditherorigin.iY++)
659 aSrce->GetScanLine(scanLineDes,srcecoord1,partlinelength,ETrue,
660 ditherorigin,dispMode,aBase, lineScanPos);
661 if (srcecoord1.iY==aSrceRect.iTl.iY)
663 aSrce->SetCompressionBookmark(lineScanPos,aBase,NULL);
665 drawDevice->WriteLine(aDest.iX,desty,partlinelength, scanLineBuffer,iDrawMode);
669 destX+=partlinelength;
672 // multiple complete lines - columns
674 numcolumns = (destXlimit - destX) / srceWidth;
677 TPoint srcecoord2(0,aSrceRect.iTl.iY);
678 TInt desty = aDest.iY;
679 TPoint ditherorigin(iDitherOrigin);
680 ditherorigin.iX += destX;
681 ditherorigin.iY += desty;
683 TLineScanningPosition lineScanPos(aBase);
687 if (aSrce->IsCompressed())
689 while (srcecoord2.iY < aSrceRect.iBr.iY)
691 TPoint coord(srcecoord2);
692 aSrce->GetScanLinePtr(slptr, srceWidth, coord,aBase, lineScanPos);
693 if (srcecoord2.iY==aSrceRect.iTl.iY)
695 aSrce->SetCompressionBookmark(lineScanPos, aBase,NULL);
697 TInt tempdestX = destX;
698 for (TInt count = 0; count < numcolumns; count++,tempdestX+=srceWidth)
700 drawDevice->WriteLine(tempdestX,desty,srceWidth, slptr,iDrawMode);
701 ditherorigin.iX += srceWidth;
703 srcecoord2.iY++,desty++,ditherorigin.iY++;
708 while (srcecoord2.iY < aSrceRect.iBr.iY)
710 TPoint coord(srcecoord2);
711 aSrce->GetScanLinePtr(slptr, srceWidth, coord,aBase, lineScanPos);
714 TInt tempdestX = destX;
715 for (TInt count = 0; count < numcolumns; count++,tempdestX+=srceWidth)
717 drawDevice->WriteLine(tempdestX,desty,srceWidth, slptr,iDrawMode);
718 ditherorigin.iX += srceWidth;
720 slptr = (TUint32*)((TUint8*)slptr + aStride);
721 srcecoord2.iY++,desty++,ditherorigin.iY++;
723 while ((srcecoord2.iY < aSrceRect.iBr.iY) && (slptr < lastScanLine));
729 for (; srcecoord2.iY < aSrceRect.iBr.iY; srcecoord2.iY++,desty++,ditherorigin.iY++)
731 TInt tempdestX = destX;
732 TPoint coord(srcecoord2);
733 aSrce->GetScanLinePtr(slptr, srceWidth, coord,aBase, lineScanPos);
734 if (srcecoord2.iY==aSrceRect.iTl.iY)
736 aSrce->SetCompressionBookmark(lineScanPos, aBase,NULL);
738 for (TInt count = 0; count < numcolumns; count++,tempdestX+=srceWidth)
740 aSrce->GetScanLine(slptr, scanLineDes,coord,srceWidth,ETrue,
741 ditherorigin,dispMode);
742 drawDevice->WriteLine(tempdestX,desty,srceWidth, scanLineBuffer,iDrawMode);
743 ditherorigin.iX += srceWidth;
748 destX += numcolumns * srceWidth;
752 if (destX < destXlimit)
754 const TInt restofline = destXlimit - destX;
755 TPoint srcecoord3(0,aSrceRect.iTl.iY);
756 TInt desty = aDest.iY;
757 TPoint ditherorigin(iDitherOrigin);
758 ditherorigin.iX += destX;
759 ditherorigin.iY += desty;
761 TLineScanningPosition lineScanPos(aBase);
766 if (aSrce->IsCompressed())
768 while (srcecoord3.iY < aSrceRect.iBr.iY)
770 scanLineBuffer = GetScanLineOffsetPtr(aSrce, slptr, srceWidth, srcecoord3, aBase, lineScanPos, offset);
771 if (srcecoord3.iY==aSrceRect.iTl.iY)
773 aSrce->SetCompressionBookmark(lineScanPos,aBase,NULL);
775 drawDevice->WriteLine(destX,desty,restofline,scanLineBuffer,iDrawMode);
776 srcecoord3.iY++,desty++,ditherorigin.iY++;
781 while (srcecoord3.iY < aSrceRect.iBr.iY)
783 scanLineBuffer = GetScanLineOffsetPtr(aSrce, slptr, srceWidth, srcecoord3, aBase, lineScanPos, offset);
786 drawDevice->WriteLine(destX,desty,restofline,scanLineBuffer,iDrawMode);
787 scanLineBuffer = (TUint32*)((TUint8*)scanLineBuffer + aStride);
788 srcecoord3.iY++,desty++,ditherorigin.iY++;
790 while ((srcecoord3.iY < aSrceRect.iBr.iY) && (scanLineBuffer < lastScanLine));
796 for (; srcecoord3.iY < aSrceRect.iBr.iY; srcecoord3.iY++,desty++,ditherorigin.iY++)
798 aSrce->GetScanLine(scanLineDes,srcecoord3,srceWidth,ETrue,
799 ditherorigin,dispMode,aBase,lineScanPos);
800 if (srcecoord3.iY==aSrceRect.iTl.iY)
802 aSrce->SetCompressionBookmark(lineScanPos, aBase,NULL);
804 drawDevice->WriteLine(destX,desty,restofline,scanLineBuffer,iDrawMode);
810 void CFbsBitGc::DoBitBltMasked(const TPoint& aDest,
811 CBitwiseBitmap* aSourceBitmap,
812 TUint32* aSourceBase,
813 const TRect& aSourceRect,
814 CBitwiseBitmap* aMaskBitmap,
817 const TPoint& aDitherOrigin,
820 CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
822 TRect deviceDestRect;
823 drawDevice->GetDrawRect(deviceDestRect);
825 BG_ASSERT_DEBUG(aDest.iX >= deviceDestRect.iTl.iX, EBitgdiPanicOutOfBounds);
826 BG_ASSERT_DEBUG(aDest.iY >= deviceDestRect.iTl.iY, EBitgdiPanicOutOfBounds);
827 BG_ASSERT_DEBUG((aDest.iX + aSourceRect.Width()) <= deviceDestRect.iBr.iX, EBitgdiPanicOutOfBounds);
828 BG_ASSERT_DEBUG((aDest.iY + aSourceRect.Height()) <= deviceDestRect.iBr.iY, EBitgdiPanicOutOfBounds);
830 MFastBlend* fastBlend=NULL;
831 if (FastBlendInterface(aSourceBitmap,aMaskBitmap,fastBlend)==KErrNone)
833 if (fastBlend->FastBlendBitmapMasked(aDest, aSourceBase, aSourceBitmap->DataStride(), aSourceBitmap->SizeInPixels(), aSourceRect, aSourceBitmap->DisplayMode(),
834 aMaskBase, aMaskBitmap->DataStride(), aMaskBitmap->DisplayMode(), aMaskBitmap->SizeInPixels(), aSourceRect.iTl, aInvertMask,
835 iDrawMode, aShadowMode)==KErrNone)
841 const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
842 if (aMaskBitmap->DisplayMode() == EGray256)
844 DoBitBltAlpha(aDest,aSourceBitmap,aSourceBase,aSourceRect,
845 aMaskBitmap,aMaskBase,aSourceRect.iTl,aShadowMode, EFalse);
847 // if screen driver is 16MAP we avoid logical operator pen modes by using DoBitBltAlpha() for blitting
848 else if (dispMode == EColor16MAP)
850 DoBitBltAlpha(aDest,aSourceBitmap,aSourceBase,aSourceRect,
851 aMaskBitmap,aMaskBase,aSourceRect.iTl,aShadowMode, aInvertMask);
854 else if (aSourceBitmap == aMaskBitmap)
856 const TInt width = aSourceRect.Width();
857 TPoint ditherOrigin(aDitherOrigin + aDest);
858 const TDrawMode drawMode = aInvertMask ? EDrawModeAND : EDrawModeOR;
859 TPoint srcePoint(aSourceRect.iTl);
860 TInt destY = aDest.iY;
862 TLineScanningPosition lineScanPos(aSourceBase);
864 const TBool useScanLinePtr = (!aShadowMode) && (dispMode == aSourceBitmap->DisplayMode() && (TDisplayModeUtils::NumDisplayModeBitsPerPixel(dispMode)>=8));
867 TUint32* scanLineBuffer = NULL;
869 TUint offset = MemoryOffsetForPixelPitch(srcePoint.iX, dispMode);
871 if (aSourceBitmap->IsCompressed())
873 for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++,ditherOrigin.iY++)
875 scanLineBuffer = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPos, offset);
876 drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,drawMode);
881 TUint stride = aSourceBitmap->DataStride();
882 TUint32* lastScanLine = aSourceBitmap->ScanLineAddress(aSourceBase,aSourceRect.iBr.iY-1);
884 while (srcePoint.iY < aSourceRect.iBr.iY)
886 scanLineBuffer = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPos, offset);
889 drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,drawMode);
890 scanLineBuffer = (TUint32*)((TUint8*)scanLineBuffer + stride);
891 destY++,srcePoint.iY++,ditherOrigin.iY++;
893 while ((srcePoint.iY < aSourceRect.iBr.iY) && (scanLineBuffer < lastScanLine));
899 const TInt scanLineBytes = drawDevice->ScanLineBytes();
900 TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
901 TPtr8 scanLineDes((TUint8*)scanLineBuffer,scanLineBytes,scanLineBytes);
902 for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++,ditherOrigin.iY++)
904 aSourceBitmap->GetScanLine(scanLineDes,srcePoint,width,
905 ETrue,ditherOrigin,dispMode,aSourceBase,lineScanPos);
909 drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
910 drawDevice->ShadowBuffer(width,scanLineBuffer);
911 drawDevice->SetShadowMode(CFbsDrawDevice::ENoShadow);
914 drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,drawMode);
920 if (iDevice->iBitBltMaskedBuffer)
922 if (iBrushStyle == ESolidBrush)
923 DoBitBltMaskedNonFlickerSolid(aDest,aSourceBitmap,aSourceBase,aSourceRect,
924 aMaskBitmap,aMaskBase,aInvertMask,aDitherOrigin,
926 else if (iBrushStyle == EPatternedBrush)
927 DoBitBltMaskedNonFlickerPatterned(aDest,aSourceBitmap,aSourceBase,aSourceRect,
928 aMaskBitmap,aMaskBase,aInvertMask,
929 aDitherOrigin,aShadowMode);
931 DoBitBltMaskedNonFlicker(aDest,aSourceBitmap,aSourceBase,aSourceRect,
932 aMaskBitmap,aMaskBase,aInvertMask,aDitherOrigin,
936 DoBitBltMaskedFlicker(aDest,aSourceBitmap,aSourceBase,aSourceRect,aMaskBitmap,
937 aMaskBase,aInvertMask,aDitherOrigin,aShadowMode);
941 void CFbsBitGc::DoBitBltMaskedFlicker(const TPoint& aDest,
942 CBitwiseBitmap* aSourceBitmap,
943 TUint32* aSourceBase,
944 const TRect& aSourceRect,
945 CBitwiseBitmap* aMaskBitmap,
948 const TPoint& aDitherOrigin,
951 CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
953 const TInt width = aSourceRect.Width();
954 TInt destY = aDest.iY;
955 TPoint srcePoint(aSourceRect.iTl);
957 TLineScanningPosition lineScanPos(aSourceBase);
958 TLineScanningPosition lineScanPosMask(aMaskBase);
960 const TDisplayMode srcFormat = aSourceBitmap->DisplayMode();
961 const TDisplayMode maskFormat = aMaskBitmap->DisplayMode();
963 if (aMaskBitmap->IsCompressed())
965 HBufC8* hBuf= CFbsBitmap::GetDecompressionBuffer(aMaskBitmap->DataStride() + 4);
967 return; // Out of memory so do not draw anything
968 lineScanPosMask.iScanLineBuffer = hBuf;
971 TAny* interface=NULL;
972 if ( (srcFormat == EColor16MU || srcFormat == EColor64K ) &&
973 maskFormat == EGray2 &&
975 aSourceBitmap->SizeInPixels().iWidth <= aMaskBitmap->SizeInPixels().iWidth &&
976 aSourceBitmap->SizeInPixels().iHeight <= aMaskBitmap->SizeInPixels().iHeight &&
977 drawDevice->GetInterface(KFastBlitInterfaceID, interface) == KErrNone )
979 // Parameters allow optimised code path
981 TUint32* srcPtr=NULL;
982 TUint32* maskPtr=NULL;
983 MFastBlit* fastBlit = reinterpret_cast<MFastBlit*>(interface);
985 while (srcePoint.iY < aSourceRect.iBr.iY)
987 aSourceBitmap->GetScanLinePtr(srcPtr, length, srcePoint, aSourceBase, lineScanPos);
988 aMaskBitmap->GetScanLinePtr(maskPtr, length, srcePoint, aMaskBase, lineScanPosMask);
990 fastBlit->WriteMaskLineEx(aDest.iX,destY,length,srcePoint.iX,srcPtr,srcFormat,srcePoint.iX,maskPtr,aInvertMask);
998 TPoint ditherOrigin(aDitherOrigin + aDest);
999 const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
1000 const TDrawMode drawMode = aInvertMask ? EDrawModeAND : EDrawModeANDNOT;
1002 TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
1003 const TInt scanLineBytes = drawDevice->ScanLineBytes();
1004 TPtr8 scanLineDes((TUint8*)scanLineBuffer,scanLineBytes,scanLineBytes);
1006 TLineScanningPosition lineScanPos2(aSourceBase);
1008 //scanline modifications required if using shadows, different modes, bits per pixel less than 8
1009 if ((!aShadowMode) && (dispMode == aSourceBitmap->DisplayMode()) && (TDisplayModeUtils::NumDisplayModeBitsPerPixel(dispMode)>=8))
1011 TUint offset = MemoryOffsetForPixelPitch(srcePoint.iX, dispMode);
1012 TUint32* slptr=NULL;
1013 //mask scanline modifications required for EInvertPen, different screen modes
1014 if ((drawMode != EDrawModeANDNOT) && (dispMode == aMaskBitmap->DisplayMode()))
1016 TUint32* scanLineBufferMask = NULL;
1017 //stride jumping not possible with compressed bitmaps
1018 if (aSourceBitmap->IsCompressed() || aMaskBitmap->IsCompressed())
1020 for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++,ditherOrigin.iY++)
1022 scanLineBuffer = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPos, offset);
1023 drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,EDrawModeXOR);
1024 scanLineBufferMask = GetScanLineOffsetPtr(aMaskBitmap, slptr, width, srcePoint, aMaskBase, lineScanPosMask, offset);
1025 drawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferMask,drawMode);
1026 drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,EDrawModeXOR);
1031 TUint strideSrc = aSourceBitmap->DataStride();
1032 TUint strideMask = aMaskBitmap->DataStride();
1033 TUint32* lastScanLineSrc = aSourceBitmap->ScanLineAddress(aSourceBase,aSourceRect.iBr.iY-1);
1034 TUint32* lastScanLineMask = aMaskBitmap->ScanLineAddress(aMaskBase,aSourceRect.iBr.iY-1);
1036 while (srcePoint.iY < aSourceRect.iBr.iY)
1038 scanLineBuffer = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPos, offset);
1039 scanLineBufferMask = GetScanLineOffsetPtr(aMaskBitmap, slptr, width, srcePoint, aMaskBase, lineScanPosMask, offset);
1043 drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,EDrawModeXOR);
1044 drawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferMask,drawMode);
1045 drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,EDrawModeXOR);
1046 destY++,srcePoint.iY++,ditherOrigin.iY++;
1048 while ((srcePoint.iY < aSourceRect.iBr.iY) && (scanLineBuffer < lastScanLineSrc) && (scanLineBufferMask < lastScanLineMask)
1049 && ((scanLineBuffer = (TUint32*)((TUint8*)scanLineBuffer + strideSrc))>(TUint32*)0)
1050 && ((scanLineBufferMask = (TUint32*)((TUint8*)scanLineBufferMask + strideMask))>(TUint32*)0)
1057 TUint32* scanLineBufferPtr = NULL;
1058 //stride jumping not possible with compressed bitmaps
1059 if (aSourceBitmap->IsCompressed())
1061 for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++,ditherOrigin.iY++)
1063 scanLineBufferPtr = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPos, offset);
1064 drawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferPtr,EDrawModeXOR);
1065 aMaskBitmap->GetScanLine(scanLineDes,srcePoint,width,EFalse,ditherOrigin,dispMode, aMaskBase, lineScanPosMask);
1066 ::TileScanLine(scanLineDes, width, srcePoint, aMaskBitmap, lineScanPosMask, aMaskBase, dispMode);
1067 drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,drawMode);
1068 drawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferPtr,EDrawModeXOR);
1073 TUint stride = aSourceBitmap->DataStride();
1074 TUint32* lastScanLine = aSourceBitmap->ScanLineAddress(aSourceBase,aSourceRect.iBr.iY-1);
1075 while (srcePoint.iY < aSourceRect.iBr.iY)
1077 scanLineBufferPtr = GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPos, offset);
1080 drawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferPtr,EDrawModeXOR);
1081 aMaskBitmap->GetScanLine(scanLineDes,srcePoint,width,EFalse,ditherOrigin,dispMode,aMaskBase, lineScanPosMask);
1082 ::TileScanLine(scanLineDes, width, srcePoint, aMaskBitmap, lineScanPosMask, aMaskBase, dispMode);
1083 drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,drawMode);
1084 drawDevice->WriteLine(aDest.iX,destY,width,scanLineBufferPtr,EDrawModeXOR);
1085 destY++,srcePoint.iY++,ditherOrigin.iY++;
1087 while ((srcePoint.iY < aSourceRect.iBr.iY) && (scanLineBufferPtr < lastScanLine)
1088 && ((scanLineBufferPtr = (TUint32*)((TUint8*)scanLineBufferPtr + stride))>(TUint32*)0));
1095 for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++,ditherOrigin.iY++)
1097 aSourceBitmap->GetScanLine(scanLineDes,srcePoint,width,ETrue,ditherOrigin,
1098 dispMode,aSourceBase,lineScanPos);
1102 drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
1103 drawDevice->ShadowBuffer(width,scanLineBuffer);
1104 drawDevice->SetShadowMode(CFbsDrawDevice::ENoShadow);
1107 drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,EDrawModeXOR);
1109 aMaskBitmap->GetScanLine(scanLineDes,srcePoint,width,EFalse,ditherOrigin,dispMode,
1110 aMaskBase, lineScanPosMask);
1111 ::TileScanLine(scanLineDes, width, srcePoint, aMaskBitmap, lineScanPosMask,
1112 aMaskBase, dispMode);
1113 drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,drawMode);
1115 aSourceBitmap->GetScanLine(scanLineDes,srcePoint,width,ETrue,ditherOrigin,dispMode,
1116 aSourceBase,lineScanPos2);
1120 drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
1121 drawDevice->ShadowBuffer(width,scanLineBuffer);
1122 drawDevice->SetShadowMode(CFbsDrawDevice::ENoShadow);
1125 drawDevice->WriteLine(aDest.iX,destY,width,scanLineBuffer,EDrawModeXOR);
1130 void CFbsBitGc::DoBitBltMaskedNonFlicker(const TPoint& aDest,
1131 CBitwiseBitmap* aSourceBitmap,
1132 TUint32* aSourceBase,
1133 const TRect& aSourceRect,
1134 CBitwiseBitmap* aMaskBitmap,
1137 const TPoint& aDitherOrigin,
1140 CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
1142 const TInt width = aSourceRect.Width();
1143 TInt destY = aDest.iY;
1144 TPoint srcePoint(aSourceRect.iTl);
1146 TLineScanningPosition lineScanPos(aSourceBase);
1147 TLineScanningPosition lineScanPosMask(aMaskBase);
1149 const TDisplayMode srcFormat = aSourceBitmap->DisplayMode();
1150 const TDisplayMode maskFormat = aMaskBitmap->DisplayMode();
1152 if (aMaskBitmap->IsCompressed())
1154 HBufC8* hBuf= CFbsBitmap::GetDecompressionBuffer(aMaskBitmap->DataStride() + 4);
1156 return; // Out of memory so do not draw anything
1157 lineScanPosMask.iScanLineBuffer = hBuf;
1160 TAny* interface=NULL;
1161 if ( (srcFormat == EColor16MU || srcFormat == EColor64K ) &&
1162 maskFormat == EGray2 &&
1164 aSourceBitmap->SizeInPixels().iWidth <= aMaskBitmap->SizeInPixels().iWidth &&
1165 aSourceBitmap->SizeInPixels().iHeight <= aMaskBitmap->SizeInPixels().iHeight &&
1166 drawDevice->GetInterface(KFastBlitInterfaceID, interface) == KErrNone )
1168 // Parameters allow optimised code path
1169 TInt length = width;
1170 TUint32* srcPtr=NULL;
1171 TUint32* maskPtr=NULL;
1172 MFastBlit* fastBlit = reinterpret_cast<MFastBlit*>(interface);
1174 while (srcePoint.iY < aSourceRect.iBr.iY)
1176 aSourceBitmap->GetScanLinePtr(srcPtr, length, srcePoint, aSourceBase, lineScanPos);
1177 aMaskBitmap->GetScanLinePtr(maskPtr, length, srcePoint, aMaskBase, lineScanPosMask);
1179 fastBlit->WriteMaskLineEx(aDest.iX,destY,length,srcePoint.iX,srcPtr,srcFormat,srcePoint.iX,maskPtr,aInvertMask);
1188 TPoint ditherOrigin(aDitherOrigin + aDest);
1190 TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
1191 const TInt scanLineBytes = drawDevice->ScanLineBytes();
1192 TPtr8 scanLineDes((TUint8*)scanLineBuffer,scanLineBytes,scanLineBytes);
1194 TUint32* bitBltBuffer = (TUint32*)iDevice->iBitBltMaskedBuffer;
1195 const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
1196 const TInt bufferBytes = CFbsBitmap::ScanLineLength(width, dispMode);
1197 TUint32* scanLineCopy = (TUint32*) new TUint8[bufferBytes];
1199 TLineScanningPosition lineScanPos2(aSourceBase);
1200 for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++,ditherOrigin.iY++)
1202 drawDevice->ReadLine(aDest.iX,destY,width,bitBltBuffer,dispMode);
1203 aSourceBitmap->GetScanLine(scanLineDes,srcePoint,width,ETrue,ditherOrigin,dispMode,
1204 aSourceBase,lineScanPos);
1208 Mem::Copy(scanLineCopy,scanLineBuffer,bufferBytes);
1213 drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
1214 drawDevice->ShadowBuffer(width,scanLineBuffer);
1215 drawDevice->SetShadowMode(CFbsDrawDevice::ENoShadow);
1218 XorBuffers(bitBltBuffer,scanLineBuffer,bufferBytes);
1220 aMaskBitmap->GetScanLine(scanLineDes,srcePoint,width,EFalse,ditherOrigin,dispMode,
1221 aMaskBase,lineScanPosMask);
1222 ::TileScanLine(scanLineDes, width, srcePoint, aMaskBitmap, lineScanPosMask,
1223 aMaskBase, dispMode);
1226 InvertBuffer(scanLineBuffer,bufferBytes);
1227 AndBuffers(bitBltBuffer,scanLineBuffer,bufferBytes);
1229 // Slow call when memory low?
1233 aSourceBitmap->GetScanLine(scanLineDes,srcePoint,width,ETrue,ditherOrigin,
1234 dispMode,aSourceBase,lineScanPos2);
1235 scanLine = scanLineBuffer;
1238 scanLine = scanLineCopy;
1242 drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
1243 drawDevice->ShadowBuffer(width,scanLine);
1244 drawDevice->SetShadowMode(CFbsDrawDevice::ENoShadow);
1247 XorBuffers(bitBltBuffer,scanLine,bufferBytes);
1249 drawDevice->WriteLine(aDest.iX,destY,width,bitBltBuffer,iDrawMode);
1253 delete[] scanLineCopy;
1257 void CFbsBitGc::DoBitBltMaskedNonFlickerSolid(const TPoint& aDest,
1258 CBitwiseBitmap* aSourceBitmap,
1259 TUint32* aSourceBase,
1260 const TRect& aSourceRect,
1261 CBitwiseBitmap* aMaskBitmap,
1264 const TPoint& aDitherOrigin,
1267 CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
1268 const TInt width = aSourceRect.Width();
1269 TPoint ditherOrigin(aDitherOrigin + aDest);
1270 const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
1271 TInt destY = aDest.iY;
1272 TPoint srcePoint(aSourceRect.iTl);
1274 TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
1275 const TInt scanLineBytes = drawDevice->ScanLineBytes();
1276 TPtr8 scanLineDes((TUint8*)scanLineBuffer,scanLineBytes,scanLineBytes);
1278 TUint32* bitBltBuffer = (TUint32*)iDevice->iBitBltMaskedBuffer;
1279 TUint32* backgroundBuffer = (TUint32*)(iDevice->iBitBltMaskedBuffer + scanLineBytes);
1280 const TInt bufferBytes = CFbsBitmap::ScanLineLength(width, dispMode);
1282 drawDevice->WriteRgbMulti(aDest.iX,aDest.iY,width,1,iBrushColor,iDrawMode);
1283 drawDevice->ReadLine(aDest.iX,destY,width,backgroundBuffer,dispMode);
1285 TLineScanningPosition lineScanPos(aSourceBase);
1286 TLineScanningPosition lineScanPos2(aSourceBase);
1287 TLineScanningPosition lineScanPosMask(aMaskBase);
1289 for (; srcePoint.iY < aSourceRect.iBr.iY; destY++,srcePoint.iY++,ditherOrigin.iY++)
1291 Mem::Copy(bitBltBuffer,backgroundBuffer,bufferBytes);
1293 aSourceBitmap->GetScanLine(scanLineDes,srcePoint,width,ETrue,ditherOrigin,dispMode,
1294 aSourceBase,lineScanPos);
1295 XorBuffers(bitBltBuffer,scanLineBuffer,bufferBytes);
1297 aMaskBitmap->GetScanLine(scanLineDes,srcePoint,width,EFalse,ditherOrigin,dispMode,
1298 aMaskBase,lineScanPosMask);
1299 ::TileScanLine(scanLineDes, width, srcePoint, aMaskBitmap, lineScanPosMask,
1300 aMaskBase, dispMode);
1303 InvertBuffer(scanLineBuffer,bufferBytes);
1304 AndBuffers(bitBltBuffer,scanLineBuffer,bufferBytes);
1305 aSourceBitmap->GetScanLine(scanLineDes,srcePoint,width,ETrue,ditherOrigin,
1306 dispMode,aSourceBase,lineScanPos2);
1308 XorBuffers(bitBltBuffer,scanLineBuffer,bufferBytes);
1311 drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
1313 drawDevice->WriteLine(aDest.iX,destY,width,bitBltBuffer,iDrawMode);
1316 drawDevice->SetShadowMode(CFbsDrawDevice::ENoShadow);
1320 void CFbsBitGc::DoBitBltMaskedNonFlickerPatterned(const TPoint& aDest,
1321 CBitwiseBitmap* aSourceBitmap,
1322 TUint32* aSourceBase,
1323 const TRect& aSourceRect,
1324 CBitwiseBitmap* aMaskBitmap,
1327 const TPoint& aDitherOrigin,
1330 CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
1331 const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
1333 drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
1335 iBrushBitmap.BeginDataAccess();
1336 CBitwiseBitmap* brushBitmap = iBrushBitmap.Address();
1337 BG_ASSERT_ALWAYS(iBrushUsed, EBitgdiPanicInvalidBitmap);
1338 BG_ASSERT_ALWAYS(brushBitmap != NULL, EBitgdiPanicInvalidBitmap);
1340 CFbsRasterizer* brushRasterizer = PrepareRasterizerForExtendedBitmap(iBrushBitmap);
1341 TUint32* brushData = iBrushBitmap.DataAddress();
1342 TPoint brushSourcePoint(aDest - iBrushOrigin - iOrigin);
1343 const TSize brushSize(iBrushBitmap.SizeInPixels());
1344 if (brushSourcePoint.iX < 0 || brushSourcePoint.iX >= brushSize.iWidth)
1345 brushSourcePoint.iX %= brushSize.iWidth;
1346 if (brushSourcePoint.iX < 0)
1347 brushSourcePoint.iX += brushSize.iWidth;
1349 TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
1350 const TInt scanLineBytes = drawDevice->ScanLineBytes();
1351 TPtr8 scanLineDes((TUint8*)scanLineBuffer,scanLineBytes,scanLineBytes);
1353 TUint32* bitBltBuffer = (TUint32*)iDevice->iBitBltMaskedBuffer;
1354 TPtr8 bitBltDes(iDevice->iBitBltMaskedBuffer, scanLineBytes, scanLineBytes);
1356 TInt widthRemaining = aSourceRect.Width();
1357 TPoint sourcePoint(aSourceRect.iTl);
1358 TInt destX = aDest.iX;
1360 TInt width = Min(widthRemaining,brushSize.iWidth);
1362 if (brushSourcePoint.iX + widthRemaining > brushSize.iWidth)
1363 width = brushSize.iWidth - brushSourcePoint.iX;
1365 while (widthRemaining > 0)
1367 TInt destY = aDest.iY;
1368 sourcePoint.iY = aSourceRect.iTl.iY;
1369 brushSourcePoint.iY = aDest.iY - iBrushOrigin.iY - iOrigin.iY;
1370 TPoint ditherOrigin(aDitherOrigin + TPoint(destX,aDest.iY));
1371 const TInt bufferBytes = CFbsBitmap::ScanLineLength(width, dispMode);
1373 TLineScanningPosition lineScanPosBrush(brushData);
1374 TLineScanningPosition lineScanPosMask(aMaskBase);
1375 TLineScanningPosition lineScanPosSrc(aSourceBase);
1376 TLineScanningPosition lineScanPosSrc2(aSourceBase);
1378 for ( ;sourcePoint.iY < aSourceRect.iBr.iY;
1379 destY++,sourcePoint.iY++,ditherOrigin.iY++,brushSourcePoint.iY++)
1381 brushBitmap->GetScanLine(bitBltDes,brushSourcePoint,width,ETrue,ditherOrigin,
1382 dispMode,brushData,lineScanPosBrush);
1383 aSourceBitmap->GetScanLine(scanLineDes,sourcePoint,width,ETrue,ditherOrigin,
1384 dispMode,aSourceBase,lineScanPosSrc);
1385 XorBuffers(bitBltBuffer,scanLineBuffer,scanLineBytes);
1387 aMaskBitmap->GetScanLine(scanLineDes,sourcePoint,width,EFalse,ditherOrigin,
1388 dispMode,aMaskBase,lineScanPosMask);
1389 ::TileScanLine(scanLineDes, width, sourcePoint, aMaskBitmap, lineScanPosMask,
1390 aMaskBase, dispMode);
1393 InvertBuffer(scanLineBuffer,bufferBytes);
1394 AndBuffers(bitBltBuffer,scanLineBuffer,bufferBytes);
1396 aSourceBitmap->GetScanLine(scanLineDes,sourcePoint,width,ETrue,ditherOrigin,
1397 dispMode,aSourceBase,lineScanPosSrc2);
1398 XorBuffers(bitBltBuffer,scanLineBuffer,bufferBytes);
1400 drawDevice->WriteLine(destX,destY,width,bitBltBuffer,iDrawMode);
1403 widthRemaining -= width;
1404 sourcePoint.iX += width;
1405 brushSourcePoint.iX += width;
1408 width = Min(widthRemaining,brushSize.iWidth);
1410 if (brushRasterizer)
1412 brushRasterizer->EndBitmap(iBrushBitmap.SerialNumber());
1414 iBrushBitmap.EndDataAccess(ETrue);
1417 void CFbsBitGc::DoBitBltAlpha(const TPoint& aDest,CBitwiseBitmap* aSourceBitmap,
1418 TUint32* aSourceBase,const TRect& aSourceRect,
1419 CBitwiseBitmap* aMaskBitmap,TUint32* aMaskBase,
1420 const TPoint& aAlphaPoint,TInt aShadowMode, TBool aInvertMask)
1422 MFastBlend* fastBlend=NULL;
1423 if (FastBlendInterface(aSourceBitmap,aMaskBitmap,fastBlend)==KErrNone)
1425 if (fastBlend->FastBlendBitmapMasked(aDest, aSourceBase, aSourceBitmap->DataStride(), aSourceBitmap->SizeInPixels(), aSourceRect, aSourceBitmap->DisplayMode(),
1426 aMaskBase, aMaskBitmap->DataStride(), aMaskBitmap->DisplayMode(), aMaskBitmap->SizeInPixels(), aAlphaPoint, aInvertMask,
1427 iDrawMode, aShadowMode)==KErrNone)
1432 CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
1434 const TPoint KZeroPoint(0,0);
1435 const TInt KScanLineLength = 256;
1436 const TInt KRgbSize = 4;
1438 TUint8 srceRgbBuffer[KScanLineLength * KRgbSize];
1439 TUint8 maskBuffer[KScanLineLength];
1440 TUint8* srceRgbBufferPtr(srceRgbBuffer);
1442 TPtr8 srceRgbDes(srceRgbBuffer,KScanLineLength * KRgbSize,KScanLineLength * KRgbSize);
1443 TPtr8 maskDes(maskBuffer,KScanLineLength,KScanLineLength);
1445 drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
1447 const TSize sourceSize = aSourceBitmap->SizeInPixels();
1448 // Convert negative or large offsets into sensible positive ones.
1449 TPoint alphaOffset(aAlphaPoint.iX % sourceSize.iWidth, aAlphaPoint.iY % sourceSize.iHeight);
1450 if ( alphaOffset.iX < 0 )
1451 alphaOffset.iX += sourceSize.iWidth;
1452 if ( alphaOffset.iY < 0 )
1453 alphaOffset.iY += sourceSize.iHeight;
1455 TInt srceY = aSourceRect.iTl.iY;
1456 TInt destY = aDest.iY;
1457 TInt alphaY = alphaOffset.iY;
1459 TLineScanningPosition lineScanPosSrc(aSourceBase);
1460 TLineScanningPosition lineScanPosMask(aMaskBase);
1462 TDisplayMode sourceMode = aSourceBitmap->DisplayMode();
1464 if (aMaskBitmap->IsCompressed())
1466 HBufC8* hBuf= CFbsBitmap::GetDecompressionBuffer(aMaskBitmap->DataStride());
1469 return; // Out of memory so do not draw anything
1471 lineScanPosMask.iScanLineBuffer = hBuf;
1474 TAny* interface=NULL;
1475 if ( (sourceMode == EColor16MU || sourceMode == EColor64K) &&
1476 aMaskBitmap->DisplayMode() == EGray256 && // ensure a monochrome mask isn't passed in as an alpha channel
1477 aSourceBitmap->SizeInPixels().iWidth <= aMaskBitmap->SizeInPixels().iWidth &&
1478 aSourceBitmap->SizeInPixels().iHeight <= aMaskBitmap->SizeInPixels().iHeight &&
1479 drawDevice->GetInterface(KFastBlitInterfaceID, interface) == KErrNone )
1481 TInt length = aSourceRect.Width();
1482 const TInt srceX = aSourceRect.iTl.iX;
1483 const TInt alphaX = alphaOffset.iX;
1484 const TInt destX = aDest.iX;
1485 MFastBlit* fastBlit = reinterpret_cast<MFastBlit*>(interface);
1487 while (srceY < aSourceRect.iBr.iY)
1491 TPoint srcPoint(srceX, srceY);
1492 TPoint maskPoint(alphaX, alphaY);
1494 aSourceBitmap->GetScanLinePtr(srcPtr, length, srcPoint, aSourceBase, lineScanPosSrc);
1495 aMaskBitmap->GetScanLinePtr(maskPtr, length, maskPoint, aMaskBase, lineScanPosMask);
1497 fastBlit->WriteAlphaLineEx(destX,destY,length,srceX,srcPtr,sourceMode,alphaX,maskPtr,MAlphaBlend::EShdwBefore);
1506 const TBool useScanLinePtr = ((!aShadowMode) && (EColor16MA == aSourceBitmap->DisplayMode()));
1507 TUint32* slptr=NULL;
1509 TDisplayMode srcMode = ERgb;
1511 while (srceY < aSourceRect.iBr.iY)
1513 TInt srceX = aSourceRect.iTl.iX;
1514 TInt destX = aDest.iX;
1515 TInt alphaX = alphaOffset.iX;
1517 while (srceX < aSourceRect.iBr.iX)
1519 TPoint srcePoint(srceX,srceY);
1520 TPoint alphaPoint(alphaX,alphaY);
1521 const TInt width = Min(KScanLineLength,aSourceRect.iBr.iX - srceX);
1525 offset = MemoryOffsetForPixelPitch(srceX, EColor16MU);
1526 srceRgbBufferPtr = (TUint8*)GetScanLineOffsetPtr(aSourceBitmap, slptr, width, srcePoint, aSourceBase, lineScanPosSrc, offset);
1530 aSourceBitmap->GetScanLine(srceRgbDes,srcePoint,width,EFalse,KZeroPoint,
1531 srcMode,aSourceBase,lineScanPosSrc);
1534 aMaskBitmap->GetScanLine(maskDes,alphaPoint,width,EFalse,KZeroPoint,
1535 EGray256,aMaskBase,lineScanPosMask);
1536 ::TileScanLine(maskDes, width, alphaPoint, aMaskBitmap, lineScanPosMask,
1537 aMaskBase, EGray256);
1538 // aInvertMask is not used for alpha channels (EGray256 mask)
1539 if (aInvertMask && aMaskBitmap->DisplayMode() != EGray256)
1541 for (TInt i = 0; i < width; ++i)
1542 maskBuffer[i] = ~maskBuffer[i];
1544 drawDevice->WriteRgbAlphaLine(destX,destY,width,srceRgbBufferPtr,maskBuffer,iDrawMode);
1546 srceX += KScanLineLength;
1547 destX += KScanLineLength;
1548 alphaX += KScanLineLength;
1558 The method performs an alpha blending of the source data - aSrcBmp1 and aSrcBmp2, using
1559 the data from aAlphaBmp as an alpha blending factor.
1561 @see CFbsBitGc::AlphaBlendBitmaps.
1563 void CFbsBitGc::DoBitBltAlpha(const TPoint& aDestPt,
1564 const CBitwiseBitmap* aSrcBmp1,
1565 TUint32* aSrcBmpDataAddr1,
1566 const CBitwiseBitmap* aSrcBmp2,
1567 TUint32* aSrcBmpDataAddr2,
1568 const CBitwiseBitmap* aAlphaBmp,
1569 TUint32* aAlphaBmpDataAddr,
1570 const TRect& aSrcRect1,
1571 const TPoint& aSrcPt2,
1572 const TPoint& aAlphaPt,
1575 CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
1577 TRect deviceDestRect;
1578 drawDevice->GetDrawRect(deviceDestRect);
1580 //Check the destination point.
1581 BG_ASSERT_DEBUG(aDestPt.iX >= deviceDestRect.iTl.iX, EBitgdiPanicOutOfBounds);
1582 BG_ASSERT_DEBUG(aDestPt.iY >= deviceDestRect.iTl.iY, EBitgdiPanicOutOfBounds);
1583 BG_ASSERT_DEBUG((aDestPt.iX + aSrcRect1.Width()) <= deviceDestRect.iBr.iX, EBitgdiPanicOutOfBounds);
1584 BG_ASSERT_DEBUG((aDestPt.iY + aSrcRect1.Height()) <= deviceDestRect.iBr.iY, EBitgdiPanicOutOfBounds);
1586 const TPoint KZeroPoint(0,0);
1587 const TInt KScanLineLength = 256;//128 is not enough to fill buffer for 16MA and 16MU display modes
1588 const TInt KRgbSize = 4;
1590 TUint8 srceRgbBuffer1[KScanLineLength * KRgbSize];
1591 TUint8 srceBuffer2[KScanLineLength * KRgbSize];
1592 TUint8 alphaBuffer[KScanLineLength];
1594 TPtr8 srceRgbDes1(srceRgbBuffer1,KScanLineLength * KRgbSize,KScanLineLength * KRgbSize);
1595 TPtr8 srceDes2(srceBuffer2,KScanLineLength * KRgbSize,KScanLineLength * KRgbSize);
1596 TPtr8 alphaDes(alphaBuffer,KScanLineLength,KScanLineLength);
1598 const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
1599 drawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(aShadowMode));
1601 TInt srceY1 = aSrcRect1.iTl.iY;
1602 TInt srceY2 = aSrcPt2.iY;
1603 TInt alphaY = aAlphaPt.iY;
1604 TInt destY = aDestPt.iY;
1606 TLineScanningPosition lineScanPosSrc1(aSrcBmpDataAddr1);
1607 TLineScanningPosition lineScanPosSrc2(aSrcBmpDataAddr2);
1608 TLineScanningPosition lineScanPosAlpha(aAlphaBmpDataAddr);
1610 while (srceY1 < aSrcRect1.iBr.iY)
1612 TInt srceX1 = aSrcRect1.iTl.iX;
1613 TInt srceX2 = aSrcPt2.iX;
1614 TInt alphaX = aAlphaPt.iX;
1615 TInt destX = aDestPt.iX;
1617 while (srceX1 < aSrcRect1.iBr.iX)
1619 TPoint srcePoint1(srceX1,srceY1);
1620 TPoint srcePoint2(srceX2,srceY2);
1621 TPoint alphaPoint(alphaX,alphaY);
1622 const TInt width = Min(KScanLineLength,aSrcRect1.iBr.iX - srceX1);
1624 aSrcBmp1->GetScanLine(srceRgbDes1,srcePoint1,width,EFalse,KZeroPoint,EColor16MU,
1625 aSrcBmpDataAddr1,lineScanPosSrc1);
1626 aSrcBmp2->GetScanLine(srceDes2,srcePoint2,width,EFalse,KZeroPoint,dispMode,
1627 aSrcBmpDataAddr2,lineScanPosSrc2);
1628 aAlphaBmp->GetScanLine(alphaDes,alphaPoint,width,EFalse,KZeroPoint,EGray256,
1629 aAlphaBmpDataAddr,lineScanPosAlpha);
1630 ::TileScanLine(alphaDes, width, alphaPoint, aAlphaBmp, lineScanPosAlpha, aAlphaBmpDataAddr, EGray256);
1632 drawDevice->WriteRgbAlphaLine(destX,
1640 srceX1 += KScanLineLength;
1641 srceX2 += KScanLineLength;
1642 alphaX += KScanLineLength;
1643 destX += KScanLineLength;
1654 The method performs an alpha blending of the source data - aSrcBmp1 and aSrcBmp2, using
1655 the data from aAlphaBmp as an alpha blending factor.
1656 The formula used for that, is:
1657 (C1 * A + C2 * (255 - A)) / 255, where:
1658 - C1 - a pixel from aSrcBmp1;
1659 - C2 - a pixel from aSrcBmp2;
1660 - A - a pixel from aAlphaBmp;
1661 The content of source and alpha bitmap is preserved.
1662 The calculated alpha blended pixels are written to the destination - the screen or a bitmap.
1665 @param aDestPt Position in the target the result should be drawn to.
1666 @param aSrcBmp1 A pointer to the source bitmap 1.
1667 @param aSrcBmp2 A pointer to the source bitmap 2.
1668 @param aAlphaBmp A pointer to the bitmap used as an alpha blending factor.
1669 @param aSrcRect1 A part of bitmap 1 that should be used as a source for the alpha blending.
1670 @param aSrcPt2 Position of the first pixel in bitmap 2 that should be used as a source
1671 for the alpha blending. The size of the area is the same as the
1672 bitmap 1 area - aSrcRect1 parameter.
1673 @param aAlphaPt Position of the first pixel in the alpha bitmap that should be used as a source
1674 for the alpha blending. The size of the area is the same as the
1675 bitmap 1 area - aSrcRect1 parameter.
1676 @pre !aSrcRect1.IsEmpty()
1677 @pre aSrcBmp1 != NULL
1678 @pre aSrcBmp1->Handle() != NULL
1679 @pre aSrcBmp2 != NULL
1680 @pre aSrcBmp2->Handle() != NULL
1681 @pre aAlphaBmp != NULL
1682 @pre aAlphaBmp->Handle() != NULL
1683 @pre aAlphaBmp->DisplayMode() <= EGray256
1684 @return KErrNone If the call is successful, KErrArgument otherwise.
1686 EXPORT_C TInt CFbsBitGc::AlphaBlendBitmaps(const TPoint& aDestPt,
1687 const CFbsBitmap* aSrcBmp1,
1688 const CFbsBitmap* aSrcBmp2,
1689 const TRect& aSrcRect1,
1690 const TPoint& aSrcPt2,
1691 const CFbsBitmap* aAlphaBmp,
1692 const TPoint& aAlphaPt)
1694 //Check the bitmap pointers and handles. Check the CFbsDevice instance -
1695 //it shouldn't be NULL - that means - CFbsBitGc instance (this pointer)
1696 //should be created either using CFbsDevice::CreateContext() or CFbsBitGc::Activate() -
1697 //before the method was called.
1698 if(!aSrcBmp1 || !aSrcBmp1->Handle() || !aSrcBmp2 || !aSrcBmp2->Handle() ||
1699 !aAlphaBmp || !aAlphaBmp->Handle() || CheckDevice(aSrcRect1))
1701 return KErrArgument;
1704 aSrcBmp1->BeginDataAccess();
1705 aSrcBmp2->BeginDataAccess();
1706 aAlphaBmp->BeginDataAccess();
1708 //Check display mode of the alpha bitmap. Bitmaps which display mode is greater than
1709 //EGray256 can't be used as alpha bitmaps.
1710 if(aAlphaBmp->DisplayMode() > EGray256)
1712 aSrcBmp1->EndDataAccess(ETrue);
1713 aSrcBmp2->EndDataAccess(ETrue);
1714 aAlphaBmp->EndDataAccess(ETrue);
1715 return KErrArgument;
1717 //Check source rect 1. Bitmap 1 must contain the whole source rect 1.
1718 TRect srcRect1(aSrcRect1);
1719 TRect area1(aSrcBmp1->SizeInPixels());
1720 srcRect1.Intersection(area1);
1721 if(srcRect1 != aSrcRect1)
1723 aSrcBmp1->EndDataAccess(ETrue);
1724 aSrcBmp2->EndDataAccess(ETrue);
1725 aAlphaBmp->EndDataAccess(ETrue);
1726 return KErrArgument;
1728 //Create and check source rect 2. Bitmap 2 must contain the whole source rect 2.
1729 TRect srcRect2(TSize(aSrcRect1.Width(), aSrcRect1.Height()));
1730 srcRect2.Move(aSrcPt2);
1731 TRect srcRect2t(srcRect2);
1732 TRect area2(aSrcBmp2->SizeInPixels());
1733 srcRect2.Intersection(area2);
1734 if(srcRect2 != srcRect2t)
1736 aSrcBmp1->EndDataAccess(ETrue);
1737 aSrcBmp2->EndDataAccess(ETrue);
1738 aAlphaBmp->EndDataAccess(ETrue);
1739 return KErrArgument;
1741 //Calculate the destination rect
1742 TPoint destPt(aDestPt + iOrigin);
1743 TRect destRect(destPt, srcRect1.Size());
1744 TPoint offset(srcRect1.iTl - destPt);
1745 TPoint offset2(srcRect2.iTl - destPt);
1746 TRect clippedDestRect(destRect);
1747 AddRect(clippedDestRect);
1748 if(UserClipRect(clippedDestRect))
1750 aSrcBmp1->EndDataAccess(ETrue);
1751 aSrcBmp2->EndDataAccess(ETrue);
1752 aAlphaBmp->EndDataAccess(ETrue);
1753 return KErrArgument;
1755 //Save current shadow mode
1756 TInt8 shadowMode = iShadowMode;
1757 iShadowMode = CFbsDrawDevice::ENoShadow;
1758 //Setup the device and prevent the bitmaps from being cleaned away by client code.
1761 iDevice->DrawingBegin();
1762 CBitwiseBitmap* srcBmp1 = ((CFbsBitGcBitmap*)aSrcBmp1)->Address();
1763 CBitwiseBitmap* srcBmp2 = ((CFbsBitGcBitmap*)aSrcBmp2)->Address();
1764 CBitwiseBitmap* alphaBmp = ((CFbsBitGcBitmap*)aAlphaBmp)->Address();
1765 BG_ASSERT_DEBUG(srcBmp1, EBitgdiPanicInvalidBitmap);
1766 BG_ASSERT_DEBUG(srcBmp2, EBitgdiPanicInvalidBitmap);
1767 BG_ASSERT_DEBUG(alphaBmp, EBitgdiPanicInvalidBitmap);
1769 TUint32* srcDataAddr1 = aSrcBmp1->DataAddress();
1770 TUint32* srcDataAddr2 = aSrcBmp2->DataAddress();
1771 TUint32* alphaDataAddr = aAlphaBmp->DataAddress();
1773 CFbsRasterizer* rasterizer1 = PrepareRasterizerForExtendedBitmap(*aSrcBmp1, clippedDestRect, offset);
1774 CFbsRasterizer* rasterizer2 = PrepareRasterizerForExtendedBitmap(*aSrcBmp2, clippedDestRect, offset2);
1775 CFbsRasterizer* alphaRasterizer;
1776 if (aAlphaPt.iX >= 0 && aAlphaPt.iY >= 0
1777 && aAlphaPt.iX + aSrcRect1.Width() <= aAlphaBmp->SizeInPixels().iWidth
1778 && aAlphaPt.iY + aSrcRect1.Height() <= aAlphaBmp->SizeInPixels().iHeight)
1780 // Alpha blending bitmap is not tiled. Pass same region of interest as source bitmaps to rasterizer.
1781 alphaRasterizer = PrepareRasterizerForExtendedBitmap(*aAlphaBmp, clippedDestRect, aAlphaPt - destPt);
1785 // Alpha blending bitmap is tiled. Do not pass any region of interest to rasterizer.
1786 alphaRasterizer = PrepareRasterizerForExtendedBitmap(*aAlphaBmp);
1789 //For each region - find the clipping rect and draw
1790 TInt limit = iDefaultRegionPtr->Count();
1791 CGraphicsAccelerator* ga = GraphicsAccelerator();
1792 // Code for Graphics Accelerated Drawing
1793 if(ga && (shadowMode == CFbsDrawDevice::ENoShadow))
1795 TInt gaOperationResult = KErrUnknown;
1796 TAcceleratedBitmapSpec srcBmp1Spec(const_cast<CFbsBitmap*>(aSrcBmp1));
1797 TAcceleratedBitmapSpec srcBmp2Spec(const_cast<CFbsBitmap*>(aSrcBmp2));
1798 TAcceleratedBitmapSpec alphaBmpSpec(const_cast<CFbsBitmap*>(aAlphaBmp));
1799 iDevice->DrawingEnd();
1801 for(TInt count=0;count<limit;count++)
1803 iClipRect=(*iDefaultRegionPtr)[count];
1804 if(!iClipRect.Intersects(clippedDestRect))
1808 //clippedDestRect was constructed from destRect. destRect was constructed from srcRect1.
1809 iClipRect.Intersection(clippedDestRect);
1810 TRect clippedSrcRect(iClipRect);
1811 clippedSrcRect.Move(offset);//clippedSrcRect - maps to a part of srcRect1 now.
1812 TPoint shift(clippedSrcRect.iTl - srcRect1.iTl);
1813 BG_ASSERT_DEBUG(shift.iX >= 0, EBitgdiPanicNegativeShift);
1814 BG_ASSERT_DEBUG(shift.iY >= 0, EBitgdiPanicNegativeShift);
1816 gaOperationResult = ga->Operation(TGopAlphaBlendTwoBitmaps(iClipRect.iTl,srcBmp1Spec,srcBmp2Spec,clippedSrcRect,aSrcPt2 + shift,alphaBmpSpec,aAlphaPt + shift));
1817 if(gaOperationResult != KErrNone)
1819 iDevice->iDrawDevice->UpdateRegion(iClipRect);
1821 if(gaOperationResult == KErrNone)
1823 iDevice->DrawingBegin();
1826 // Code for non- Graphics Accelerated Drawing
1827 for(TInt count=0;count<limit;count++)
1829 iClipRect=(*iDefaultRegionPtr)[count];
1830 if(!iClipRect.Intersects(clippedDestRect))
1834 //clippedDestRect was constructed from destRect. destRect was constructed from srcRect1.
1835 iClipRect.Intersection(clippedDestRect);
1836 TRect clippedSrcRect(iClipRect);
1837 clippedSrcRect.Move(offset);//clippedSrcRect - maps to a part of srcRect1 now.
1838 TPoint shift(clippedSrcRect.iTl - srcRect1.iTl);
1839 BG_ASSERT_DEBUG(shift.iX >= 0, EBitgdiPanicNegativeShift);
1840 BG_ASSERT_DEBUG(shift.iY >= 0, EBitgdiPanicNegativeShift);
1842 TDrawMode drawMode = iDrawMode;
1843 iDrawMode = EDrawModeWriteAlpha; // this is the only mode currently supported
1844 DoBitBltAlpha(iClipRect.iTl,
1855 iDrawMode = drawMode; // restore the previous draw mode
1857 iDevice->iDrawDevice->UpdateRegion(iClipRect);
1860 //Drawig ends. Restore the previous shadow mode
1861 iDevice->DrawingEnd();
1865 rasterizer1->EndBitmap(aSrcBmp1->SerialNumber());
1869 rasterizer2->EndBitmap(aSrcBmp2->SerialNumber());
1871 if (alphaRasterizer)
1873 alphaRasterizer->EndBitmap(aAlphaBmp->SerialNumber());
1875 aSrcBmp1->EndDataAccess(ETrue);
1876 aSrcBmp2->EndDataAccess(ETrue);
1877 aAlphaBmp->EndDataAccess(ETrue);
1878 iShadowMode = shadowMode;
1884 The method performs an alpha blending of the source data - aSrcBmp - with the existing image, using
1885 the data from aAlphaBmp as an alpha blending factor.
1886 The formula used for that, is:
1887 (C * A + D * (255 - A)) / 255, where:
1888 - C - a pixel from aSrcBmp;
1889 - D - a pixel from the destination;
1890 - A - a pixel from aAlphaBmp;
1891 The content of source and alpha bitmap is preserved.
1892 The calculated alpha blended pixels are written to the destination - the screen or a bitmap.
1895 @param aDestPt Position in the target the result should be drawn to.
1896 @param aSrcBmp A pointer to the source bitmap.
1897 @param aAlphaBmp A pointer to the bitmap used as an alpha blending factor.
1898 @param aSrcRect A part of aSrcBmp that should be used as a source for the alpha blending.
1899 DISCLAIMER: if aSrcRect is bigger (width and/or height) the behaviour is undefined
1900 @param aAlphaPt Position of the first pixel in the alpha bitmap that should be used as a source
1901 for the alpha blending. The size of the area is
1902 the same as the aSrcRect parameter (read DISCLAIMER above).
1903 @pre !aSrcRect.IsEmpty()
1904 @pre aSrcBmp != NULL
1905 @pre aSrcBmp->Handle() != NULL
1906 @pre aAlphaBmp != NULL
1907 @pre aAlphaBmp->Handle() != NULL
1908 @pre aAlphaBmp->DisplayMode() <= EGray256
1909 @return KErrNone If the call is successfull, KErrArgument otherwise.
1911 EXPORT_C TInt CFbsBitGc::AlphaBlendBitmaps(const TPoint& aDestPt,
1912 const CFbsBitmap* aSrcBmp,
1913 const TRect& aSrcRect,
1914 const CFbsBitmap* aAlphaBmp,
1915 const TPoint& aAlphaPt)
1917 //Check the bitmap pointers and handles. Check the CFbsDevice instance -
1918 //it shouldn't be NULL - that means - CFbsBitGc instance (this pointer)
1919 //should be created either using CFbsDevice::CreateContext() or CFbsBitGc::Activate() -
1920 //before the method was called.
1921 if(!aSrcBmp || !aSrcBmp->Handle() ||
1922 !aAlphaBmp || !aAlphaBmp->Handle() || CheckDevice(aSrcRect))
1924 return KErrArgument;
1927 aSrcBmp->BeginDataAccess();
1928 aAlphaBmp->BeginDataAccess();
1930 //Check display mode of the alpha bitmap. Bitmaps which display mode is greater than
1931 //EGray256 can't be used as alpha bitmaps.
1932 if(aAlphaBmp->DisplayMode() > EGray256)
1934 aSrcBmp->EndDataAccess(ETrue);
1935 aAlphaBmp->EndDataAccess(ETrue);
1936 return KErrArgument;
1938 //Taking the actual part of the source rect contained in the Bitmap.
1939 TRect srcRect(aSrcRect);
1940 TRect area(aSrcBmp->SizeInPixels());
1941 if(!srcRect.Intersects(area))
1943 aSrcBmp->EndDataAccess(ETrue);
1944 aAlphaBmp->EndDataAccess(ETrue);
1945 return KErrArgument;
1947 srcRect.Intersection(area);
1948 //Calculate the destination rect
1949 TPoint destPt(aDestPt + iOrigin);
1950 TRect destRect(destPt, srcRect.Size());
1951 TPoint offset(srcRect.iTl - destPt);
1952 TRect clippedDestRect(destRect);
1953 AddRect(clippedDestRect);
1954 if(UserClipRect(clippedDestRect))
1956 aSrcBmp->EndDataAccess(ETrue);
1957 aAlphaBmp->EndDataAccess(ETrue);
1958 return KErrArgument;
1960 //Save current shadow mode
1961 TInt8 shadowMode = iShadowMode;
1962 iShadowMode = CFbsDrawDevice::ENoShadow;
1963 //Setup the device and prevent the bitmaps from being cleaned away by client code.
1966 iDevice->DrawingBegin();
1968 CBitwiseBitmap* srcBmp = ((CFbsBitGcBitmap*)aSrcBmp)->Address();
1969 CBitwiseBitmap* alphaBmp = ((CFbsBitGcBitmap*)aAlphaBmp)->Address();
1970 BG_ASSERT_DEBUG(srcBmp, EBitgdiPanicInvalidBitmap);
1971 BG_ASSERT_DEBUG(alphaBmp, EBitgdiPanicInvalidBitmap);
1972 TUint32* srcDataAddr = aSrcBmp->DataAddress();
1973 TUint32* alphaDataAddr = aAlphaBmp->DataAddress();
1975 CFbsRasterizer* rasterizer = PrepareRasterizerForExtendedBitmap(*aSrcBmp, clippedDestRect, offset);
1976 CFbsRasterizer* alphaRasterizer;
1977 if (aAlphaPt.iX >= 0 && aAlphaPt.iY >= 0
1978 && aAlphaPt.iX + srcRect.Width() <= aAlphaBmp->SizeInPixels().iWidth
1979 && aAlphaPt.iY + srcRect.Height() <= aAlphaBmp->SizeInPixels().iHeight)
1981 // Alpha blending bitmap is not tiled. Pass same region of interest as source bitmap to rasterizer.
1982 alphaRasterizer = PrepareRasterizerForExtendedBitmap(*aAlphaBmp, clippedDestRect, aAlphaPt - destPt);
1986 // Alpha blending bitmap is tiled. Do not pass any region of interest to rasterizer.
1987 alphaRasterizer = PrepareRasterizerForExtendedBitmap(*aAlphaBmp);
1990 //For each region - find the clipping rect and draw
1991 TInt limit = iDefaultRegionPtr->Count();
1992 CGraphicsAccelerator* ga = GraphicsAccelerator();
1993 // Code for Graphics Accelerated Drawing
1994 if(ga && (shadowMode == CFbsDrawDevice::ENoShadow))
1996 TInt gaOperationResult = KErrUnknown;
1997 TAcceleratedBitmapSpec srcBmpSpec(const_cast<CFbsBitmap*>(aSrcBmp));
1998 TAcceleratedBitmapSpec alphaBmpSpec(const_cast<CFbsBitmap*>(aAlphaBmp));
1999 iDevice->DrawingEnd();
2001 for(TInt count=0;count<limit;count++)
2003 iClipRect=(*iDefaultRegionPtr)[count];
2004 if(!iClipRect.Intersects(clippedDestRect))
2008 //clippedDestRect was constructed from destRect. destRect was constructed from srcRect.
2009 iClipRect.Intersection(clippedDestRect);
2010 TRect clippedSrcRect(iClipRect);
2011 clippedSrcRect.Move(offset);//clippedSrcRect - maps to a part of srcRect now.
2012 TPoint shift(clippedSrcRect.iTl - srcRect.iTl);
2013 BG_ASSERT_DEBUG(shift.iX >= 0, EBitgdiPanicNegativeShift);
2014 BG_ASSERT_DEBUG(shift.iY >= 0, EBitgdiPanicNegativeShift);
2016 gaOperationResult = ga->Operation(TGopAlphaBlendOneBitmap(iClipRect.iTl,srcBmpSpec,clippedSrcRect,alphaBmpSpec,aAlphaPt + shift));
2017 if(gaOperationResult != KErrNone)
2019 iDevice->iDrawDevice->UpdateRegion(iClipRect);
2021 if(gaOperationResult == KErrNone)
2023 iDevice->DrawingBegin();
2026 // Code for non- Graphics Accelerated Drawing
2027 for(TInt count=0;count<limit;count++)
2029 iClipRect=(*iDefaultRegionPtr)[count];
2030 if(!iClipRect.Intersects(clippedDestRect))
2034 //clippedDestRect was constructed from destRect. destRect was constructed from srcRect.
2035 iClipRect.Intersection(clippedDestRect);
2036 TRect clippedSrcRect(iClipRect);
2037 clippedSrcRect.Move(offset);//clippedSrcRect - maps to a part of srcRect now.
2038 TPoint shift(clippedSrcRect.iTl - srcRect.iTl);
2039 BG_ASSERT_DEBUG(shift.iX >= 0, EBitgdiPanicNegativeShift);
2040 BG_ASSERT_DEBUG(shift.iY >= 0, EBitgdiPanicNegativeShift);
2041 DoBitBltAlpha(iClipRect.iTl,
2050 iDevice->iDrawDevice->UpdateRegion(iClipRect);
2053 // Drawing ends. Restore the previous shadow mode.
2054 iDevice->DrawingEnd();
2058 rasterizer->EndBitmap(aSrcBmp->SerialNumber());
2060 if (alphaRasterizer)
2062 alphaRasterizer->EndBitmap(aAlphaBmp->SerialNumber());
2064 aSrcBmp->EndDataAccess(ETrue);
2065 aAlphaBmp->EndDataAccess(ETrue);
2066 iShadowMode = shadowMode;
2071 GLDEF_C void XorBuffers(TUint32* aDestBuffer,const TUint32* aSrceBuffer,TInt aNumBytes)
2073 // Round up to nearest word boundary
2074 const TUint32* const destBufferLimit = aDestBuffer + ((aNumBytes + sizeof(TUint32) - 1) / sizeof(TUint32));
2076 while (aDestBuffer < destBufferLimit)
2077 *aDestBuffer++ ^= *aSrceBuffer++;
2080 GLDEF_C void AndBuffers(TUint32* aDestBuffer,const TUint32* aSrceBuffer,TInt aNumBytes)
2082 // Round up to nearest word boundary
2083 const TUint32* const destBufferLimit = aDestBuffer + ((aNumBytes + sizeof(TUint32) - 1) / sizeof(TUint32));
2085 while (aDestBuffer < destBufferLimit)
2086 *aDestBuffer++ &= *aSrceBuffer++;
2089 GLDEF_C void InvertBuffer(TUint32* aDestBuffer,TInt aNumBytes)
2091 // Round up to nearest word boundary
2092 const TUint32* const destBufferLimit = aDestBuffer + ((aNumBytes + sizeof(TUint32) - 1) / sizeof(TUint32));
2094 while (aDestBuffer < destBufferLimit)
2096 *aDestBuffer = *aDestBuffer ^ KMaxTUint32;
2101 GLDEF_C void InvertBuffer(TUint8* aDestBuffer,TInt aNumBytes)
2103 const TUint8* const destBufferLimit = aDestBuffer + aNumBytes;
2105 while (aDestBuffer < destBufferLimit)
2107 *aDestBuffer = static_cast<TUint8>(*aDestBuffer ^ KMaxTUint8);
2113 The method tiles the scan line if its length in pixels is less than
2114 aLengthInPixels argument.
2116 @param aScanLine A pointer to the scan line buffer.
2117 @param aLengthInPixels The scan line buffer should have that count of pixels after the method call.
2118 @param aSrcPt Position of the first pixel in aMaskBitmap that should be used as a source
2119 for the pixels in scan line buffer.
2120 @param aMaskBitmap Any additional pixels for the scan line buffer will be taken from here.
2121 @param aScanLinePos This argument is used for some internal optimizations. It should not be
2122 modified by the caller.
2123 @param aMaskBase The base address of aMaskBitmap data.
2124 @param aDisplayMode Any additional pixels should be taken from aMaskBitmap using aDisplayMode
2125 as an argument for GetScanLine() call.
2127 LOCAL_C void TileScanLine(TPtr8& aScanLine,
2128 TInt aLengthInPixels,
2129 const TPoint& aSrcPt,
2130 const CBitwiseBitmap* aMaskBitmap,
2131 TLineScanningPosition& aScanLinePos,
2133 TDisplayMode aDisplayMode
2136 TInt lengthInBytes = CFbsBitmap::ScanLineLength(aLengthInPixels, aDisplayMode);
2137 BG_ASSERT_DEBUG(lengthInBytes <= aScanLine.MaxLength(), EBitgdiPanicInvalidArg);
2138 TInt scanLineLength = aScanLine.Length();
2139 if(scanLineLength < lengthInBytes && aSrcPt.iX > 0)
2141 //If, for example, src bmp is 100 pixels width, mask bmp is 20 pixels width and src
2142 //rect is (10, 0, 100, 1) -> We will read only pixels 10..19 from the first scan line
2143 //of the mask bmp. We have to have 90 mask bmp pixels.
2144 //So we have to make a second mask bmp read startig from pixel 0 - 10 pixels length.
2145 TInt maxLen = Min(aScanLine.MaxLength() - scanLineLength, aSrcPt.iX);
2146 TPtr8 maskDes2(const_cast <TUint8*> (aScanLine.Ptr()) + scanLineLength, maxLen, maxLen);
2147 TPoint srcPt(0, aSrcPt.iY);
2148 TPoint zeroPt(0, 0);
2149 aMaskBitmap->GetScanLine(maskDes2, srcPt, maxLen, EFalse, zeroPt, aDisplayMode, aMaskBase, aScanLinePos);
2150 aScanLine.SetLength(scanLineLength + maskDes2.Length());
2151 scanLineLength = aScanLine.Length();
2153 if(scanLineLength >= lengthInBytes || scanLineLength == 0)
2157 //If we still don't have enough mask bmp pixels - we have to tile the scan line
2158 TInt repeatCnt = lengthInBytes / scanLineLength - 1;
2159 TInt bytesLeft = lengthInBytes % scanLineLength;
2160 const TUint8* src = aScanLine.Ptr();
2161 TUint8* dest = const_cast <TUint8*> (src) + scanLineLength;
2162 for(;repeatCnt>0;dest+=scanLineLength,repeatCnt--)
2164 Mem::Copy(dest, src, scanLineLength);
2168 Mem::Copy(dest, src, bytesLeft);
2170 aScanLine.SetLength(lengthInBytes);
2174 The method draws a masked rectangular section of the source
2175 bitmap and does a compress/stretch to fit a given destination
2179 void CFbsBitGc::DoDrawBitmapMasked(const TRect& aDestRect,
2180 CBitwiseBitmap* aSourceBitmap,
2181 TUint32* aSourceBase,
2182 const TRect& aSourceRect,
2183 CBitwiseBitmap* aMaskBitmap,
2185 TBool aInvertMask, const TPoint& aDitherOrigin)
2187 CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
2189 TRect deviceDestRect;
2190 drawDevice->GetDrawRect(deviceDestRect);
2191 BG_ASSERT_DEBUG(iClipRect.iTl.iX >= deviceDestRect.iTl.iX, EBitgdiPanicOutOfBounds);
2192 BG_ASSERT_DEBUG(iClipRect.iTl.iY >= deviceDestRect.iTl.iY, EBitgdiPanicOutOfBounds);
2193 BG_ASSERT_DEBUG(iClipRect.iBr.iX <= deviceDestRect.iBr.iX, EBitgdiPanicOutOfBounds);
2194 BG_ASSERT_DEBUG(iClipRect.iBr.iY <= deviceDestRect.iBr.iY, EBitgdiPanicOutOfBounds);
2197 // The clipped version of the destination rectangle
2198 TRect clippedDestRect(aDestRect);
2199 clippedDestRect.Intersection(iClipRect);
2201 // If the source rectangle and the destination rectangle are same,
2202 // no stretch/compress operation required, just do BitBltMasked
2203 if (aDestRect.Size() == aSourceRect.Size())
2205 if (!clippedDestRect.IsEmpty())
2207 const TPoint destPoint(clippedDestRect.iTl);
2208 clippedDestRect.Move(aSourceRect.iTl - aDestRect.iTl);
2209 DoBitBltMasked(destPoint,
2217 CFbsDrawDevice::ENoShadow);
2221 MFastBlend* fastBlend=NULL;
2222 if (FastBlendInterface(aSourceBitmap,aMaskBitmap,fastBlend)==KErrNone)
2224 if (fastBlend->FastBlendBitmapMaskedScaled(iClipRect, aDestRect, aSourceRect, aSourceBase, aSourceBitmap->DataStride(),
2225 aSourceBitmap->DisplayMode(),aSourceBitmap->SizeInPixels(),
2226 aMaskBase, aMaskBitmap->DataStride(), aMaskBitmap->DisplayMode(), aMaskBitmap->SizeInPixels(), aInvertMask,
2227 iDrawMode, iShadowMode)==KErrNone)
2233 TUint32* scanLineBuffer = drawDevice->ScanLineBuffer();
2234 const TInt scanLineBytes = drawDevice->ScanLineBytes();
2235 TPtr8 scanLineDes(REINTERPRET_CAST(TUint8*,scanLineBuffer),scanLineBytes,scanLineBytes);
2237 // This constant is associated to the value used in TestGdi::DoDrawBitmapMaskedL, case #24.
2238 // If this value is changed, then that one must be updated as well otherwise the test will no longer be valid.
2239 const TInt KScanLineLength = 256;
2240 const TInt KRgbSize = 4;
2241 TUint8 maskBuffer[KScanLineLength];
2243 TUint8 sourceBuffer[KScanLineLength*KRgbSize];
2244 TPtr8 sourceDes(sourceBuffer,KScanLineLength*KRgbSize,KScanLineLength*KRgbSize);
2246 const TDisplayMode dispMode = ScanLineBufferDisplayMode(drawDevice);
2247 TDrawMode drawMode = aInvertMask ? EDrawModeAND : EDrawModeANDNOT;
2248 // If the source bitmap and the mask bitmap are same, draw the source bitmap either
2249 // with EDrawModeAND or EDrawModeOR based on aInvertMask parameter.
2250 if (aSourceBitmap == aMaskBitmap)
2252 drawMode = aInvertMask ? EDrawModeAND : EDrawModeOR;
2256 TInt bitmapXStart = 0;
2257 xLine.Construct(TPoint(aSourceRect.iTl.iX,aDestRect.iTl.iX),
2258 TPoint(aSourceRect.iBr.iX,aDestRect.iBr.iX),TLinearDDA::ELeft);
2259 xLine.JumpToYCoord2(bitmapXStart,clippedDestRect.iTl.iX);
2262 TPoint yCoord(aSourceRect.iTl.iY,aDestRect.iTl.iY);
2263 yLine.Construct(yCoord,TPoint(aSourceRect.iBr.iY,aDestRect.iBr.iY),TLinearDDA::ELeft);
2265 yLine.JumpToYCoord2(dummy,clippedDestRect.iTl.iY);
2266 yCoord.SetXY(dummy,clippedDestRect.iTl.iY);
2268 TPoint ditherOrigin(aDitherOrigin + clippedDestRect.iTl);
2269 const TInt srceWidth = aSourceRect.Width();
2270 const TInt destWidth = aDestRect.Width();
2271 const TInt clipWidth = clippedDestRect.Width();
2272 const TInt clipStrch = clippedDestRect.iTl.iX - aDestRect.iTl.iX;
2273 const TInt sourceBmpWidth = aSourceBitmap->SizeInPixels().iWidth;
2274 const TInt maskWidth = aMaskBitmap->SizeInPixels().iWidth;
2275 const TInt maskHeight = aMaskBitmap->SizeInPixels().iHeight;
2277 TLineScanningPosition lineScanPos(aSourceBase);
2278 TLineScanningPosition lineScanPos2(aSourceBase);
2279 TLineScanningPosition lineScanPosMask(aMaskBase);
2281 HBufC8* alphaBuffer = NULL;
2282 TPtr8 alphaBufferDes(NULL, 0);
2283 const TDisplayMode maskDisplayMode = aMaskBitmap->DisplayMode();
2285 // Mask inversion is not supported if the original source mask format is EGray256.
2286 // Note that this is only used for pre-multiplied alpha targets.
2287 TUint8 maskInverter = (aInvertMask && maskDisplayMode != EGray256) ? 0xFF : 0x00;
2289 if (aSourceBitmap != aMaskBitmap)
2291 // Get buffer to be used to convert non-EGray256 masks to EGray256 when display mode is EColor16MAP
2292 // or to tile the mask when the mask width is smaller than the source bitmap width.
2293 if (maskDisplayMode != EGray256 && (dispMode == EColor16MAP || maskWidth < sourceBmpWidth))
2295 alphaBuffer = CFbsBitmap::GetExtraBuffer(CFbsBitmap::ScanLineLength(maskWidth, EGray256));
2298 return; // Out of memory so do not draw anything
2300 alphaBufferDes.Set(alphaBuffer->Des());
2303 // Get buffer to be used for decompressing compressed masks when mask is EGray256
2304 if (maskDisplayMode == EGray256 && aMaskBitmap->IsCompressed())
2306 HBufC8* hBuf= CFbsBitmap::GetDecompressionBuffer(aMaskBitmap->DataStride());
2309 return; // Out of memory so do not draw anything
2311 lineScanPosMask.iScanLineBuffer = hBuf;
2315 while (yCoord.iY < clippedDestRect.iBr.iY)
2317 // Draw only the source bitmap, if the source bitmap and the mask bitmap are same.
2318 // else draw both the bitmaps
2319 if (aSourceBitmap == aMaskBitmap)
2321 aSourceBitmap->StretchScanLine(scanLineDes,TPoint(bitmapXStart,yCoord.iX),
2322 clipStrch,clipWidth,destWidth,aSourceRect.iTl.iX,
2323 srceWidth,ditherOrigin,dispMode,aSourceBase,lineScanPos);
2324 if (yCoord.iY==clippedDestRect.iTl.iY)
2325 aSourceBitmap->SetCompressionBookmark(lineScanPos,aSourceBase,NULL);
2326 drawDevice->WriteLine(clippedDestRect.iTl.iX,yCoord.iY,clipWidth,scanLineBuffer,drawMode);
2328 else if ((maskDisplayMode == EGray256) || (dispMode == EColor16MAP))
2330 // Stretch the source bitmap and the mask bitmap for KScanLineLength as stretch length
2331 // then do alpha blending for this length. If the length is more then KScanLineLength
2332 // repeat it till you stretch complete destination length.
2333 const TPoint startPt(bitmapXStart,yCoord.iX);
2334 TInt clipWidthPart = clippedDestRect.Width();
2335 TBool loopLast = ETrue;
2336 if(clipWidthPart > KScanLineLength)
2338 clipWidthPart = KScanLineLength;
2341 TInt clipIncStrch = clippedDestRect.iTl.iX - aDestRect.iTl.iX;
2342 TInt startClip=clippedDestRect.iTl.iX;
2343 TPoint sourceDestXCoords(bitmapXStart,clippedDestRect.iTl.iX);
2344 xLine.Construct(TPoint(aSourceRect.iTl.iX,aDestRect.iTl.iX),
2345 TPoint(aSourceRect.iBr.iX,aDestRect.iBr.iX),TLinearDDA::ELeft);
2346 xLine.JumpToYCoord2(sourceDestXCoords.iX,sourceDestXCoords.iY);
2347 TPoint srcPixel(bitmapXStart % maskWidth,yCoord.iX % maskHeight);
2350 TUint32* maskScanLinePtr32 = NULL;
2351 TPoint currentYValue(0,srcPixel.iY);
2352 aMaskBitmap->GetScanLinePtr(maskScanLinePtr32, currentYValue, maskWidth, aMaskBase, lineScanPosMask);
2353 // To implement non EGray256 mask support with EColor16MAP display mode, we convert
2354 // the mask to EGray256.
2355 if (maskDisplayMode != EGray256) // Convert scan-line to EGray256 and set maskScanLinePtr32 to the conversion.
2357 aMaskBitmap->GetScanLine(maskScanLinePtr32, alphaBufferDes, currentYValue, maskWidth, EFalse, TPoint(0, 0), EGray256);
2358 maskScanLinePtr32 = (TUint32*)alphaBuffer->Ptr();
2360 TUint8* maskScanLinePtr = reinterpret_cast<TUint8*>(maskScanLinePtr32);
2362 // Outer loop over all KScanLineLengths
2365 aSourceBitmap->StretchScanLine(sourceDes,startPt,clipIncStrch,clipWidthPart,destWidth,
2366 aSourceRect.iTl.iX,srceWidth,ditherOrigin,EColor16MU,aSourceBase,lineScanPos);
2367 // Inner loop to tile the mask if necessary
2368 spaceLeft = clipWidthPart;
2371 srcPixel.iX = sourceDestXCoords.iX % maskWidth;
2373 // Invert the mask using the inversion mask.
2374 maskBuffer[(sourceDestXCoords.iY-clippedDestRect.iTl.iX)%KScanLineLength]=
2375 maskInverter^maskScanLinePtr[srcPixel.iX];
2376 xLine.NextStep(sourceDestXCoords);
2377 } while (--spaceLeft>0);
2379 if (yCoord.iY == clippedDestRect.iTl.iY && startClip == clippedDestRect.iTl.iX)
2381 aSourceBitmap->SetCompressionBookmark(lineScanPos,aSourceBase,NULL);
2382 aMaskBitmap->SetCompressionBookmark(lineScanPosMask,aMaskBase,NULL);
2384 drawDevice->WriteRgbAlphaLine(startClip,yCoord.iY,clipWidthPart,sourceBuffer,maskBuffer,iDrawMode);
2389 startClip+=KScanLineLength;
2390 if (clippedDestRect.iBr.iX - startClip <= KScanLineLength)
2393 clipWidthPart = clippedDestRect.iBr.iX - startClip;
2395 clipIncStrch += KScanLineLength;
2400 aSourceBitmap->StretchScanLine(scanLineDes,TPoint(bitmapXStart,yCoord.iX),
2401 clipStrch,clipWidth,destWidth,aSourceRect.iTl.iX,
2402 srceWidth,ditherOrigin,dispMode,aSourceBase,lineScanPos2);
2403 drawDevice->WriteLine(clippedDestRect.iTl.iX,yCoord.iY,clipWidth,scanLineBuffer,EDrawModeXOR);
2405 TInt maskXStart = bitmapXStart % maskWidth;
2406 if(maskWidth < sourceBmpWidth)
2408 TPoint sourceDestXCoords(bitmapXStart,clippedDestRect.iTl.iX);
2409 xLine.Construct(TPoint(aSourceRect.iTl.iX,aDestRect.iTl.iX),
2410 TPoint(aSourceRect.iBr.iX,aDestRect.iBr.iX),TLinearDDA::ELeft);
2411 xLine.JumpToYCoord2(sourceDestXCoords.iX,sourceDestXCoords.iY);
2412 TPoint srcPixel(maskXStart,yCoord.iX % maskHeight);
2413 TInt spaceLeft = clipWidth;
2414 TPoint prevSourceDestXCoords(-1,-1);
2416 aMaskBitmap->GetScanLine(alphaBufferDes, TPoint(0,srcPixel.iY), maskWidth, EFalse, TPoint(0, 0), EGray256, aMaskBase, lineScanPosMask);
2418 // Loop to tile the mask
2420 if (sourceDestXCoords.iY != prevSourceDestXCoords.iY)
2422 if (sourceDestXCoords.iX != prevSourceDestXCoords.iX)
2424 srcPixel.iX = sourceDestXCoords.iX % maskWidth;
2425 if (srcPixel.iX < 0)
2426 srcPixel.iX += maskWidth;
2427 maskRgbValue = TRgb::Gray256((*alphaBuffer)[srcPixel.iX]);
2429 drawDevice->WriteRgb(sourceDestXCoords.iY,yCoord.iY,maskRgbValue,drawMode);
2432 prevSourceDestXCoords = sourceDestXCoords;
2433 xLine.SingleStep(sourceDestXCoords);
2434 } while (spaceLeft > 0);
2438 // No need to tile the mask
2439 aMaskBitmap->StretchScanLine(scanLineDes,TPoint(maskXStart,yCoord.iX % maskHeight),
2440 clipStrch,clipWidth,destWidth,aSourceRect.iTl.iX,
2441 srceWidth,ditherOrigin,dispMode,aMaskBase,lineScanPosMask);
2442 drawDevice->WriteLine(clippedDestRect.iTl.iX,yCoord.iY,clipWidth,scanLineBuffer,drawMode);
2443 // Redo stretching of the aSourceBitmap scanline
2444 aSourceBitmap->StretchScanLine(scanLineDes,TPoint(bitmapXStart,yCoord.iX),
2445 clipStrch,clipWidth,destWidth,aSourceRect.iTl.iX,
2446 srceWidth,ditherOrigin,dispMode,aSourceBase,lineScanPos2);
2449 if (yCoord.iY==clippedDestRect.iTl.iY)
2451 aSourceBitmap->SetCompressionBookmark(lineScanPos2,aSourceBase,NULL);
2452 aMaskBitmap->SetCompressionBookmark(lineScanPosMask,aMaskBase,NULL);
2455 drawDevice->WriteLine(clippedDestRect.iTl.iX,yCoord.iY,clipWidth,scanLineBuffer,EDrawModeXOR);
2457 yLine.NextStep(yCoord);
2462 EXPORT_C TInt CFbsBitGc::AlphaBlendBitmaps(const TPoint& aDestPt,
2463 const CWsBitmap* aSrcBmp,
2464 const TRect& aSrcRect,
2465 const CWsBitmap* aAlphaBmp,
2466 const TPoint& aAlphaPt)
2468 return AlphaBlendBitmaps(aDestPt, REINTERPRET_CAST(const CFbsBitmap*, aSrcBmp), aSrcRect, REINTERPRET_CAST(const CFbsBitmap*, aAlphaBmp), aAlphaPt);
2471 TInt CFbsBitGc::FastBlendInterface(const CBitwiseBitmap* aSource, const CBitwiseBitmap* aMask, MFastBlend*& aFastBlend) const
2473 #if defined(__ALLOW_FAST_BLEND_DISABLE__)
2474 if (iFastBlendDisabled)
2475 return(KErrNotSupported);
2477 if ((aSource && aSource->IsCompressed()) || (aMask && aMask->IsCompressed()))
2478 return(KErrNotSupported);
2479 TAny* interface=NULL;
2480 TInt ret=iDevice->iDrawDevice->GetInterface(KFastBlendInterfaceID, interface);
2481 aFastBlend=(MFastBlend*)interface;
2486 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.
2488 @see CBitwiseBitmap::GetScanLine()
2489 @see CBitwiseBitmap::GetVerticalScanLine()
2490 @see CBitwiseBitmap::StretchScanLine()
2491 @see CFbsDrawDevice::WriteLine()
2494 TDisplayMode CFbsBitGc::ScanLineBufferDisplayMode(CFbsDrawDevice* aDrawDevice)
2496 return iDrawMode == EDrawModeWriteAlpha ? aDrawDevice->DisplayMode() : aDrawDevice->ScanLineDisplayMode();
2499 /** Prepares the rasterizer to retrieve scan lines from a bitmap if it is an
2500 extended bitmap. No region of interest is passed to the rasterizer.
2501 This function calls CFbsRasterizer::BeginBitmap() with the appropriate
2502 parameters. When finished retrieving scan lines from the extended bitmap,
2503 CFbsRasterizer::EndBitmap() must be called.
2504 @param aBitmap The bitmap to retrieve scan lines from.
2505 @return A pointer to the rasterizer owned by this thread's FBServ session.
2506 @return NULL if the rasterizer is not present or aBitmap is not an extended bitmap.
2510 CFbsRasterizer* CFbsBitGc::PrepareRasterizerForExtendedBitmap(const CFbsBitmap& aBitmap)
2512 CFbsRasterizer* rasterizer = NULL;
2513 CFbsRasterizer::TBitmapDesc desc;
2514 desc.iDataType = aBitmap.ExtendedBitmapType();
2515 if (desc.iDataType != KNullUid)
2517 rasterizer = CFbsBitmap::Rasterizer();
2520 desc.iSizeInPixels = aBitmap.SizeInPixels();
2521 desc.iDispMode = aBitmap.DisplayMode();
2522 desc.iData = aBitmap.DataAddress();
2523 desc.iDataSize = aBitmap.DataSize();
2524 rasterizer->BeginBitmap(aBitmap.SerialNumber(), desc, NULL);
2530 /** Prepares the rasterizer to retrieve scan lines from a bitmap if it is an
2531 extended bitmap. The region of interest passed to the rasterizer is the
2532 intersection of the clipping region and the specified rectangle.
2533 This function calls CFbsRasterizer::BeginBitmap() with the appropriate
2534 parameters. When finished retrieving scan lines from the extended bitmap,
2535 CFbsRasterizer::EndBitmap() must be called.
2536 @param aBitmap The bitmap to retrieve scan lines from.
2537 @param aDestRect A rectangle in coordinates relative to the graphics context that
2538 bounds the area that aBitmap is to be blitted onto.
2539 @param aOffset An offset that converts aDestRect into coordinates relative to
2541 @return A pointer to the rasterizer owned by this thread's FBServ session.
2542 @return NULL if the rasterizer is not present or aBitmap is not an extended bitmap.
2546 CFbsRasterizer* CFbsBitGc::PrepareRasterizerForExtendedBitmap(const CFbsBitmap& aBitmap, const TRect& aDestRect, const TPoint& aOffset)
2548 CFbsRasterizer* rasterizer = NULL;
2549 CFbsRasterizer::TBitmapDesc desc;
2550 desc.iDataType = aBitmap.ExtendedBitmapType();
2551 if (desc.iDataType != KNullUid)
2553 rasterizer = CFbsBitmap::Rasterizer();
2556 desc.iSizeInPixels = aBitmap.SizeInPixels();
2557 desc.iDispMode = aBitmap.DisplayMode();
2558 desc.iData = aBitmap.DataAddress();
2559 desc.iDataSize = aBitmap.DataSize();
2561 rgn.Copy(*iDefaultRegionPtr);
2562 rgn.ClipRect(aDestRect);
2563 rgn.Offset(aOffset);
2564 BG_ASSERT_DEBUG(rgn.IsContainedBy(desc.iSizeInPixels), EBitgdiPanicOutOfBounds);
2565 rasterizer->BeginBitmap(aBitmap.SerialNumber(), desc, &rgn);
2572 /** Prepares the rasterizer to retrieve scan lines from a bitmap if it is an
2573 extended bitmap. The region of interest passed to the rasterizer is the intersection
2574 of the clipping region, the clipping rectangle and the specified rectangle.
2575 This function calls CFbsRasterizer::BeginBitmap() with the appropriate
2576 parameters. When finished retrieving scan lines from the extended bitmap,
2577 CFbsRasterizer::EndBitmap() must be called.
2578 @param aBitmap The bitmap to retrieve scan lines from.
2579 @param aDestRect A rectangle in coordinates relative to the graphics context that
2580 bounds the area that aBitmap is to be drawn onto.
2581 @param aSourceRect A rectangle in coordinates relative to the source bitmap that maps
2582 to aDestRect after scaling and translation.
2583 @return A pointer to the rasterizer owned by this thread's FBServ session.
2584 @return NULL if the rasterizer is not present or aBitmap is not an extended bitmap.
2588 CFbsRasterizer* CFbsBitGc::PrepareRasterizerForExtendedBitmap(const CFbsBitmap& aBitmap, const TRect& aDestRect, const TRect& aSourceRect)
2590 CFbsRasterizer* rasterizer = NULL;
2591 CFbsRasterizer::TBitmapDesc desc;
2592 desc.iDataType = aBitmap.ExtendedBitmapType();
2593 if (desc.iDataType != KNullUid)
2595 rasterizer = CFbsBitmap::Rasterizer();
2598 desc.iSizeInPixels = aBitmap.SizeInPixels();
2599 desc.iDispMode = aBitmap.DisplayMode();
2600 desc.iData = aBitmap.DataAddress();
2601 desc.iDataSize = aBitmap.DataSize();
2603 // Calculate the parameters for the linear DDA algorithm used to scale the region
2604 // of interest before entering the rectangle loop, since they are invariant.
2605 TLinearDDA xLine0, yLine0;
2606 xLine0.Construct(TPoint(aSourceRect.iTl.iX, aDestRect.iTl.iX),
2607 TPoint(aSourceRect.iBr.iX, aDestRect.iBr.iX),
2609 yLine0.Construct(TPoint(aSourceRect.iTl.iY, aDestRect.iTl.iY),
2610 TPoint(aSourceRect.iBr.iY, aDestRect.iBr.iY),
2612 TInt n = iDefaultRegionPtr->Count();
2613 for (TInt i = 0; i < n; ++i)
2615 TRect rect = (*iDefaultRegionPtr)[i];
2616 if (!rect.Intersects(iUserClipRect))
2620 rect.Intersection(iUserClipRect);
2621 if (!rect.Intersects(aDestRect))
2625 rect.Intersection(aDestRect);
2626 // Scale the region of interest from coordinates relative to the graphics
2627 // context to coordinates relative to the bitmap, one rectangle at a time.
2628 TLinearDDA xLine(xLine0), yLine(yLine0);
2629 TInt ax, ay, bx, by;
2630 xLine.JumpToYCoord(ax, rect.iTl.iX);
2631 yLine.JumpToYCoord(ay, rect.iTl.iY);
2632 xLine.JumpToYCoord(bx, rect.iBr.iX);
2633 yLine.JumpToYCoord(by, rect.iBr.iY);
2634 if (ax < bx && ay < by)
2636 rgn.AddRect(TRect(ax, ay, bx, by));
2639 BG_ASSERT_DEBUG(rgn.IsContainedBy(desc.iSizeInPixels), EBitgdiPanicOutOfBounds);
2640 rasterizer->BeginBitmap(aBitmap.SerialNumber(), desc, &rgn);