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.
     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 	}