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