os/graphics/graphicsdeviceinterface/directgdiadaptation/swsrc/swdirectgdidrawbmp.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/graphics/graphicsdeviceinterface/directgdiadaptation/swsrc/swdirectgdidrawbmp.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,218 @@
     1.4 +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +//
    1.18 +
    1.19 +#include "swdirectgdiengine.h"
    1.20 +#include "swdirectgdibitmap.h"
    1.21 +#include "swdirectgdidriverimpl.h"
    1.22 +#include <bmalphablend.h>
    1.23 +#include <graphics/bitmap.inl>
    1.24 +#include <graphics/gdi/gdiinline.inl>
    1.25 +
    1.26 +/**
    1.27 +@see MDirectGdiEngine::DrawBitmap(cosnt TRect&, const CFbsBitmap&, const TRect&)
    1.28 +@panic DGDIAdapter 7, if the bitmap is invalid (debug only). 
    1.29 +*/
    1.30 +void CSwDirectGdiEngine::DrawBitmap(const TRect& aDestRect,
    1.31 +									const CFbsBitmap& aSource,
    1.32 +									const TRect& aSourceRect)
    1.33 +	{
    1.34 +	if (aSource.ExtendedBitmapType() != KNullUid)
    1.35 +		{
    1.36 +		iDriver->SetError(KErrNotSupported); // Not supported for extended bitmaps
    1.37 +		return;
    1.38 +		}
    1.39 +	
    1.40 +	TRect destRect(aDestRect);
    1.41 +	destRect.Move(iOrigin);
    1.42 +	TRect targetRect(destRect);		 
    1.43 +	const CSwDirectGdiBitmap& srce = static_cast<const CSwDirectGdiBitmap&>(aSource);	
    1.44 +
    1.45 +	CBitwiseBitmap* bmp = srce.Address();
    1.46 +	GRAPHICS_ASSERT_DEBUG(bmp,EDirectGdiPanicInvalidBitmap);
    1.47 +
    1.48 +	const TInt limit = iDefaultRegionPtr->Count();
    1.49 +	const TBool opaqueSource = (!IsAlphaChannel(aSource.DisplayMode())) && (iDrawMode == DirectGdi::EDrawModePEN);
    1.50 +	if (opaqueSource)
    1.51 +		{
    1.52 +		iDrawMode = DirectGdi::EDrawModeWriteAlpha;
    1.53 +		}
    1.54 +
    1.55 +	TRect clipRect(0,0,0,0);
    1.56 +	for (TInt count = 0; count < limit; count++)
    1.57 +		{
    1.58 +		clipRect = (*iDefaultRegionPtr)[count];
    1.59 +		if (!clipRect.Intersects(targetRect))
    1.60 +			{
    1.61 +			continue;
    1.62 +			}
    1.63 +
    1.64 +		clipRect.Intersection(targetRect);
    1.65 +		DoDrawBitmap(destRect,bmp,aSource.DataAddress(),aSource.DataStride(),aSourceRect, clipRect);
    1.66 +
    1.67 +		iDrawDevice->UpdateRegion(clipRect);
    1.68 +		}
    1.69 +	if (opaqueSource)
    1.70 +		{
    1.71 +		iDrawMode = DirectGdi::EDrawModePEN;
    1.72 +		}
    1.73 +	}
    1.74 +
    1.75 +/*
    1.76 +Draws the bitmap. If aSrceRect equals aDestRect, a DoBitBlt() is performed instead.
    1.77 +@panic DGDIAdapter 1013, if the clipping rectangle is dully outside the destination bounds (debug only).
    1.78 +*/
    1.79 +void CSwDirectGdiEngine::DoDrawBitmap(const TRect& aDestRect,
    1.80 +							 CBitwiseBitmap* aBitmap,
    1.81 +							 TUint32* aBase,
    1.82 +							 TInt aStride,
    1.83 +							 const TRect& aSrceRect,
    1.84 +							 const TRect& aClipRect)
    1.85 +	{
    1.86 +#ifdef _DEBUG
    1.87 +	TRect deviceDestRect;
    1.88 +	iDrawDevice->GetDrawRect(deviceDestRect);
    1.89 +	GRAPHICS_ASSERT_DEBUG(aClipRect.iTl.iX >= deviceDestRect.iTl.iX, EDirectGdiPanicOutOfBounds);
    1.90 +	GRAPHICS_ASSERT_DEBUG(aClipRect.iTl.iY >= deviceDestRect.iTl.iY, EDirectGdiPanicOutOfBounds);
    1.91 +	GRAPHICS_ASSERT_DEBUG(aClipRect.iBr.iX <= deviceDestRect.iBr.iX, EDirectGdiPanicOutOfBounds);
    1.92 +	GRAPHICS_ASSERT_DEBUG(aClipRect.iBr.iY <= deviceDestRect.iBr.iY, EDirectGdiPanicOutOfBounds);
    1.93 +#endif
    1.94 +
    1.95 +	if (aDestRect.Size() == aSrceRect.Size())
    1.96 +		{
    1.97 +		TRect clippedRect(aDestRect);
    1.98 +		clippedRect.Intersection(aClipRect);
    1.99 +
   1.100 +		const TPoint destPoint(clippedRect.iTl);
   1.101 +		clippedRect.Move(aSrceRect.iTl - aDestRect.iTl);
   1.102 +		DoBitBlt(destPoint,aBitmap,aBase,aStride,clippedRect);
   1.103 +
   1.104 +		return;
   1.105 +		}
   1.106 +
   1.107 +	MFastBlend* fastBlend=NULL;
   1.108 +	if (FastBlendInterface(aBitmap,NULL,fastBlend)==KErrNone)
   1.109 +		{
   1.110 +		if (fastBlend->FastBlendBitmapScaled(aClipRect, aDestRect, aSrceRect, aBase, aStride, aBitmap->DisplayMode(), aBitmap->SizeInPixels(), GcDrawMode(iDrawMode), CFbsDrawDevice::ENoShadow)== KErrNone)
   1.111 +			{
   1.112 +			return;
   1.113 +			}
   1.114 +		}
   1.115 +	
   1.116 +	TUint32* scanLineBuffer = iDrawDevice->ScanLineBuffer();
   1.117 +	const TInt scanLineBytes = iDrawDevice->ScanLineBytes();
   1.118 +	TPtr8 scanLineDes(reinterpret_cast<TUint8*>(scanLineBuffer), scanLineBytes, scanLineBytes);
   1.119 +
   1.120 +	// For EColor16MU targets, don't use EColor16MAP when draw mode is EDrawModeWriteAlpha.
   1.121 +	// Format conversion provides no performance gain and WriteLine expects EColor16MU 
   1.122 +	// in this case.
   1.123 +	const TDisplayMode dispMode = iDrawDevice->DisplayMode() == EColor16MU && iDrawMode == DirectGdi::EDrawModeWriteAlpha ? EColor16MU : iDrawDevice->ScanLineDisplayMode();
   1.124 +
   1.125 +	TLinearDDA xLine;
   1.126 +	TInt bitmapXStart = 0;
   1.127 +	xLine.Construct(TPoint(aSrceRect.iTl.iX,aDestRect.iTl.iX),
   1.128 +					TPoint(aSrceRect.iBr.iX,aDestRect.iBr.iX),TLinearDDA::ELeft);
   1.129 +	xLine.JumpToYCoord(bitmapXStart,aClipRect.iTl.iX);
   1.130 +
   1.131 +	TLinearDDA yLine;
   1.132 +	TPoint yCoord(aSrceRect.iTl.iY,aDestRect.iTl.iY);
   1.133 +	yLine.Construct(yCoord,TPoint(aSrceRect.iBr.iY,aDestRect.iBr.iY),TLinearDDA::ELeft);
   1.134 +	TInt dummy;
   1.135 +	yLine.JumpToYCoord2(dummy,aClipRect.iTl.iY);
   1.136 +	yCoord.SetXY(dummy,aClipRect.iTl.iY);
   1.137 +
   1.138 +	const TInt srceWidth = aSrceRect.Width();
   1.139 +	const TInt destWidth = aDestRect.Width();
   1.140 +	const TInt clipWidth = aClipRect.Width();
   1.141 +	const TInt clipStrch = aClipRect.iTl.iX - aDestRect.iTl.iX;
   1.142 +
   1.143 +	TLineScanningPosition lineScanPos(aBase);
   1.144 +	TBool finished = EFalse;
   1.145 +	const TPoint KZeroPoint(0,0);
   1.146 +	const CGraphicsContext::TDrawMode drawMode = GcDrawMode(iDrawMode);
   1.147 +	while (yCoord.iY < aClipRect.iBr.iY && !finished)
   1.148 +		{
   1.149 +		aBitmap->StretchScanLine(scanLineDes,TPoint(bitmapXStart,yCoord.iX),
   1.150 +								 clipStrch,clipWidth,destWidth,aSrceRect.iTl.iX,
   1.151 +								 srceWidth,KZeroPoint,dispMode,aBase,lineScanPos);
   1.152 +		if (yCoord.iY == aClipRect.iTl.iY)
   1.153 +			{
   1.154 +			aBitmap->SetCompressionBookmark(lineScanPos, aBase,NULL);
   1.155 +			}
   1.156 +		iDrawDevice->WriteLine(aClipRect.iTl.iX,yCoord.iY,clipWidth, scanLineBuffer, drawMode);
   1.157 +		finished = yLine.NextStep(yCoord);
   1.158 +		}
   1.159 +	}
   1.160 +
   1.161 +/**
   1.162 +@see MDirectGdiEngine::DrawMaskedBitmap(cosnt TRect&, const CFbsBitmap&, const TRect&, const CFbsBitmap&, TBool)
   1.163 +@panic DGDIAdapter 7, if the source or mask bitmap is invalid (debug only).
   1.164 +*/
   1.165 +void CSwDirectGdiEngine::DrawBitmapMasked(const TRect& aDestRect,
   1.166 +						 const CFbsBitmap& aBitmap,
   1.167 +						 const TRect& aSourceRect,
   1.168 +						 const CFbsBitmap& aMaskBitmap,
   1.169 +						 TBool aInvertMask)
   1.170 +	{
   1.171 +	if ((aBitmap.ExtendedBitmapType() != KNullUid) || (aMaskBitmap.ExtendedBitmapType() != KNullUid))
   1.172 +		{
   1.173 +		iDriver->SetError(KErrNotSupported); // Not supported for extended bitmaps
   1.174 +		return;
   1.175 +		}
   1.176 +
   1.177 +	aBitmap.BeginDataAccess();
   1.178 +	aMaskBitmap.BeginDataAccess();
   1.179 +	
   1.180 +	TRect destRect(aDestRect);
   1.181 +	destRect.Move(iOrigin);
   1.182 +	TRect targetRect(destRect);	
   1.183 +	const TBool opaqueSource = (!IsAlphaChannel(aBitmap.DisplayMode())) && (iDrawMode == DirectGdi::EDrawModePEN);
   1.184 +	
   1.185 +	CBitwiseBitmap* srcebmp = ((CSwDirectGdiBitmap&)aBitmap).Address();
   1.186 +	CBitwiseBitmap* maskbmp = ((CSwDirectGdiBitmap&)aMaskBitmap).Address();
   1.187 +	GRAPHICS_ASSERT_DEBUG(srcebmp,EDirectGdiPanicInvalidBitmap);
   1.188 +	GRAPHICS_ASSERT_DEBUG(maskbmp,EDirectGdiPanicInvalidBitmap);
   1.189 +
   1.190 +	const TInt limit = iDefaultRegionPtr->Count();
   1.191 +	if (opaqueSource)
   1.192 +		{
   1.193 +		iDrawMode = DirectGdi::EDrawModeWriteAlpha;
   1.194 +		}
   1.195 +	TRect clipRect(0,0,0,0);
   1.196 +	for (TInt count = 0; count < limit; count++)
   1.197 +		{
   1.198 +		clipRect = (*iDefaultRegionPtr)[count];
   1.199 +		if (!clipRect.Intersects(targetRect))
   1.200 +			{
   1.201 +			continue;
   1.202 +			}
   1.203 +		clipRect.Intersection(targetRect);
   1.204 +		DoDrawBitmapMasked(destRect,
   1.205 +					   srcebmp,
   1.206 +					   aBitmap.DataAddress(),
   1.207 +					   aSourceRect,
   1.208 +					   maskbmp,
   1.209 +					   aMaskBitmap.DataAddress(),
   1.210 +					   aInvertMask,
   1.211 +					   clipRect);
   1.212 +		iDrawDevice->UpdateRegion(clipRect);
   1.213 +		}
   1.214 +	if (opaqueSource)
   1.215 +		{
   1.216 +		iDrawMode = DirectGdi::EDrawModePEN;
   1.217 +		}
   1.218 +
   1.219 +	aBitmap.EndDataAccess(ETrue);
   1.220 +	aMaskBitmap.EndDataAccess(ETrue);
   1.221 +	}