graphicsdeviceinterface/directgdiadaptation/swsrc/swdirectgdidrawbmp.cpp
changeset 0 5d03bc08d59c
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "swdirectgdiengine.h"
       
    17 #include "swdirectgdibitmap.h"
       
    18 #include "swdirectgdidriverimpl.h"
       
    19 #include <bmalphablend.h>
       
    20 #include <graphics/bitmap.inl>
       
    21 #include <graphics/gdi/gdiinline.inl>
       
    22 
       
    23 /**
       
    24 @see MDirectGdiEngine::DrawBitmap(cosnt TRect&, const CFbsBitmap&, const TRect&)
       
    25 @panic DGDIAdapter 7, if the bitmap is invalid (debug only). 
       
    26 */
       
    27 void CSwDirectGdiEngine::DrawBitmap(const TRect& aDestRect,
       
    28 									const CFbsBitmap& aSource,
       
    29 									const TRect& aSourceRect)
       
    30 	{
       
    31 	if (aSource.ExtendedBitmapType() != KNullUid)
       
    32 		{
       
    33 		iDriver->SetError(KErrNotSupported); // Not supported for extended bitmaps
       
    34 		return;
       
    35 		}
       
    36 	
       
    37 	TRect destRect(aDestRect);
       
    38 	destRect.Move(iOrigin);
       
    39 	TRect targetRect(destRect);		 
       
    40 	const CSwDirectGdiBitmap& srce = static_cast<const CSwDirectGdiBitmap&>(aSource);	
       
    41 
       
    42 	CBitwiseBitmap* bmp = srce.Address();
       
    43 	GRAPHICS_ASSERT_DEBUG(bmp,EDirectGdiPanicInvalidBitmap);
       
    44 
       
    45 	const TInt limit = iDefaultRegionPtr->Count();
       
    46 	const TBool opaqueSource = (!IsAlphaChannel(aSource.DisplayMode())) && (iDrawMode == DirectGdi::EDrawModePEN);
       
    47 	if (opaqueSource)
       
    48 		{
       
    49 		iDrawMode = DirectGdi::EDrawModeWriteAlpha;
       
    50 		}
       
    51 
       
    52 	TRect clipRect(0,0,0,0);
       
    53 	for (TInt count = 0; count < limit; count++)
       
    54 		{
       
    55 		clipRect = (*iDefaultRegionPtr)[count];
       
    56 		if (!clipRect.Intersects(targetRect))
       
    57 			{
       
    58 			continue;
       
    59 			}
       
    60 
       
    61 		clipRect.Intersection(targetRect);
       
    62 		DoDrawBitmap(destRect,bmp,aSource.DataAddress(),aSource.DataStride(),aSourceRect, clipRect);
       
    63 
       
    64 		iDrawDevice->UpdateRegion(clipRect);
       
    65 		}
       
    66 	if (opaqueSource)
       
    67 		{
       
    68 		iDrawMode = DirectGdi::EDrawModePEN;
       
    69 		}
       
    70 	}
       
    71 
       
    72 /*
       
    73 Draws the bitmap. If aSrceRect equals aDestRect, a DoBitBlt() is performed instead.
       
    74 @panic DGDIAdapter 1013, if the clipping rectangle is dully outside the destination bounds (debug only).
       
    75 */
       
    76 void CSwDirectGdiEngine::DoDrawBitmap(const TRect& aDestRect,
       
    77 							 CBitwiseBitmap* aBitmap,
       
    78 							 TUint32* aBase,
       
    79 							 TInt aStride,
       
    80 							 const TRect& aSrceRect,
       
    81 							 const TRect& aClipRect)
       
    82 	{
       
    83 #ifdef _DEBUG
       
    84 	TRect deviceDestRect;
       
    85 	iDrawDevice->GetDrawRect(deviceDestRect);
       
    86 	GRAPHICS_ASSERT_DEBUG(aClipRect.iTl.iX >= deviceDestRect.iTl.iX, EDirectGdiPanicOutOfBounds);
       
    87 	GRAPHICS_ASSERT_DEBUG(aClipRect.iTl.iY >= deviceDestRect.iTl.iY, EDirectGdiPanicOutOfBounds);
       
    88 	GRAPHICS_ASSERT_DEBUG(aClipRect.iBr.iX <= deviceDestRect.iBr.iX, EDirectGdiPanicOutOfBounds);
       
    89 	GRAPHICS_ASSERT_DEBUG(aClipRect.iBr.iY <= deviceDestRect.iBr.iY, EDirectGdiPanicOutOfBounds);
       
    90 #endif
       
    91 
       
    92 	if (aDestRect.Size() == aSrceRect.Size())
       
    93 		{
       
    94 		TRect clippedRect(aDestRect);
       
    95 		clippedRect.Intersection(aClipRect);
       
    96 
       
    97 		const TPoint destPoint(clippedRect.iTl);
       
    98 		clippedRect.Move(aSrceRect.iTl - aDestRect.iTl);
       
    99 		DoBitBlt(destPoint,aBitmap,aBase,aStride,clippedRect);
       
   100 
       
   101 		return;
       
   102 		}
       
   103 
       
   104 	MFastBlend* fastBlend=NULL;
       
   105 	if (FastBlendInterface(aBitmap,NULL,fastBlend)==KErrNone)
       
   106 		{
       
   107 		if (fastBlend->FastBlendBitmapScaled(aClipRect, aDestRect, aSrceRect, aBase, aStride, aBitmap->DisplayMode(), aBitmap->SizeInPixels(), GcDrawMode(iDrawMode), CFbsDrawDevice::ENoShadow)== KErrNone)
       
   108 			{
       
   109 			return;
       
   110 			}
       
   111 		}
       
   112 	
       
   113 	TUint32* scanLineBuffer = iDrawDevice->ScanLineBuffer();
       
   114 	const TInt scanLineBytes = iDrawDevice->ScanLineBytes();
       
   115 	TPtr8 scanLineDes(reinterpret_cast<TUint8*>(scanLineBuffer), scanLineBytes, scanLineBytes);
       
   116 
       
   117 	// For EColor16MU targets, don't use EColor16MAP when draw mode is EDrawModeWriteAlpha.
       
   118 	// Format conversion provides no performance gain and WriteLine expects EColor16MU 
       
   119 	// in this case.
       
   120 	const TDisplayMode dispMode = iDrawDevice->DisplayMode() == EColor16MU && iDrawMode == DirectGdi::EDrawModeWriteAlpha ? EColor16MU : iDrawDevice->ScanLineDisplayMode();
       
   121 
       
   122 	TLinearDDA xLine;
       
   123 	TInt bitmapXStart = 0;
       
   124 	xLine.Construct(TPoint(aSrceRect.iTl.iX,aDestRect.iTl.iX),
       
   125 					TPoint(aSrceRect.iBr.iX,aDestRect.iBr.iX),TLinearDDA::ELeft);
       
   126 	xLine.JumpToYCoord(bitmapXStart,aClipRect.iTl.iX);
       
   127 
       
   128 	TLinearDDA yLine;
       
   129 	TPoint yCoord(aSrceRect.iTl.iY,aDestRect.iTl.iY);
       
   130 	yLine.Construct(yCoord,TPoint(aSrceRect.iBr.iY,aDestRect.iBr.iY),TLinearDDA::ELeft);
       
   131 	TInt dummy;
       
   132 	yLine.JumpToYCoord2(dummy,aClipRect.iTl.iY);
       
   133 	yCoord.SetXY(dummy,aClipRect.iTl.iY);
       
   134 
       
   135 	const TInt srceWidth = aSrceRect.Width();
       
   136 	const TInt destWidth = aDestRect.Width();
       
   137 	const TInt clipWidth = aClipRect.Width();
       
   138 	const TInt clipStrch = aClipRect.iTl.iX - aDestRect.iTl.iX;
       
   139 
       
   140 	TLineScanningPosition lineScanPos(aBase);
       
   141 	TBool finished = EFalse;
       
   142 	const TPoint KZeroPoint(0,0);
       
   143 	const CGraphicsContext::TDrawMode drawMode = GcDrawMode(iDrawMode);
       
   144 	while (yCoord.iY < aClipRect.iBr.iY && !finished)
       
   145 		{
       
   146 		aBitmap->StretchScanLine(scanLineDes,TPoint(bitmapXStart,yCoord.iX),
       
   147 								 clipStrch,clipWidth,destWidth,aSrceRect.iTl.iX,
       
   148 								 srceWidth,KZeroPoint,dispMode,aBase,lineScanPos);
       
   149 		if (yCoord.iY == aClipRect.iTl.iY)
       
   150 			{
       
   151 			aBitmap->SetCompressionBookmark(lineScanPos, aBase,NULL);
       
   152 			}
       
   153 		iDrawDevice->WriteLine(aClipRect.iTl.iX,yCoord.iY,clipWidth, scanLineBuffer, drawMode);
       
   154 		finished = yLine.NextStep(yCoord);
       
   155 		}
       
   156 	}
       
   157 
       
   158 /**
       
   159 @see MDirectGdiEngine::DrawMaskedBitmap(cosnt TRect&, const CFbsBitmap&, const TRect&, const CFbsBitmap&, TBool)
       
   160 @panic DGDIAdapter 7, if the source or mask bitmap is invalid (debug only).
       
   161 */
       
   162 void CSwDirectGdiEngine::DrawBitmapMasked(const TRect& aDestRect,
       
   163 						 const CFbsBitmap& aBitmap,
       
   164 						 const TRect& aSourceRect,
       
   165 						 const CFbsBitmap& aMaskBitmap,
       
   166 						 TBool aInvertMask)
       
   167 	{
       
   168 	if ((aBitmap.ExtendedBitmapType() != KNullUid) || (aMaskBitmap.ExtendedBitmapType() != KNullUid))
       
   169 		{
       
   170 		iDriver->SetError(KErrNotSupported); // Not supported for extended bitmaps
       
   171 		return;
       
   172 		}
       
   173 
       
   174 	aBitmap.BeginDataAccess();
       
   175 	aMaskBitmap.BeginDataAccess();
       
   176 	
       
   177 	TRect destRect(aDestRect);
       
   178 	destRect.Move(iOrigin);
       
   179 	TRect targetRect(destRect);	
       
   180 	const TBool opaqueSource = (!IsAlphaChannel(aBitmap.DisplayMode())) && (iDrawMode == DirectGdi::EDrawModePEN);
       
   181 	
       
   182 	CBitwiseBitmap* srcebmp = ((CSwDirectGdiBitmap&)aBitmap).Address();
       
   183 	CBitwiseBitmap* maskbmp = ((CSwDirectGdiBitmap&)aMaskBitmap).Address();
       
   184 	GRAPHICS_ASSERT_DEBUG(srcebmp,EDirectGdiPanicInvalidBitmap);
       
   185 	GRAPHICS_ASSERT_DEBUG(maskbmp,EDirectGdiPanicInvalidBitmap);
       
   186 
       
   187 	const TInt limit = iDefaultRegionPtr->Count();
       
   188 	if (opaqueSource)
       
   189 		{
       
   190 		iDrawMode = DirectGdi::EDrawModeWriteAlpha;
       
   191 		}
       
   192 	TRect clipRect(0,0,0,0);
       
   193 	for (TInt count = 0; count < limit; count++)
       
   194 		{
       
   195 		clipRect = (*iDefaultRegionPtr)[count];
       
   196 		if (!clipRect.Intersects(targetRect))
       
   197 			{
       
   198 			continue;
       
   199 			}
       
   200 		clipRect.Intersection(targetRect);
       
   201 		DoDrawBitmapMasked(destRect,
       
   202 					   srcebmp,
       
   203 					   aBitmap.DataAddress(),
       
   204 					   aSourceRect,
       
   205 					   maskbmp,
       
   206 					   aMaskBitmap.DataAddress(),
       
   207 					   aInvertMask,
       
   208 					   clipRect);
       
   209 		iDrawDevice->UpdateRegion(clipRect);
       
   210 		}
       
   211 	if (opaqueSource)
       
   212 		{
       
   213 		iDrawMode = DirectGdi::EDrawModePEN;
       
   214 		}
       
   215 
       
   216 	aBitmap.EndDataAccess(ETrue);
       
   217 	aMaskBitmap.EndDataAccess(ETrue);
       
   218 	}