graphicsdeviceinterface/bitgdi/sbit/GRAPHICS.CPP
changeset 0 5d03bc08d59c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicsdeviceinterface/bitgdi/sbit/GRAPHICS.CPP	Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,546 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <fntstore.h>
+#include <bitmap.h>
+#include <bitstd.h>
+#include <bitdev.h>
+#include "BITPANIC.H"
+#include <bitdraw.h>
+#include <graphics/fbsrasterizer.h>
+#include "bitgcextradata.h"
+
+
+/** Clears a rectangular area.
+
+The cleared area is filled with the current brush colour.The function
+provides a concrete implementation of the pure virtual function
+CBitmapContext::Clear(const TRect& aRect). The function
+behaviour is the same as documented in that class. */	
+EXPORT_C void CFbsBitGc::Clear(const TRect& aRect)
+    {
+	if (CheckDevice(aRect))
+		return;
+
+	TRect rcpy(aRect);
+	rcpy.Move(iOrigin);
+	if (UserClipRect(rcpy))
+		return;
+
+	TBrushStyle tempbrushstyle = iBrushStyle;
+	iBrushStyle = ESolidBrush;
+
+	SetupDevice();
+	iDevice->DrawingBegin();
+	RectFill(rcpy);
+	iDevice->DrawingEnd();
+
+	iBrushStyle = tempbrushstyle;
+	}
+
+
+
+/** Clears the whole bitmap or a rectangular area of a bitmap.
+
+The cleared area is filled with the current brush colour.
+
+The function provides a concrete implementation of the pure virtual function 
+CBitmapContext::Clear(). The function behaviour is the same as documented 
+in that class. 
+
+@see CBitmapContext::Clear() */
+EXPORT_C void CFbsBitGc::Clear()
+	{
+	TRect deviceRect;
+	iDevice->iDrawDevice->GetDrawRect(deviceRect);
+	if ((iOrigin.iX!=0) || (iOrigin.iY!=0))
+		{
+		deviceRect.Move(-iOrigin);
+		}
+	Clear(deviceRect);
+	}
+
+/** Draws a single point.
+
+The point is drawn with the current pen settings using the current
+drawing mode.The function provides a concrete implementation of the
+pure virtual function CGraphicsContext::Plot(). The
+function behaviour is the same as documented in that class. */
+EXPORT_C void CFbsBitGc::Plot(const TPoint& aPoint)
+	{
+	if (iPenStyle == ENullPen || (iPenSize.iWidth == 0 && iPenSize.iHeight == 0))
+		return;
+
+	CheckDevice();
+
+	TRect plotRect(aPoint + iOrigin,TSize(1,1));
+	plotRect.Grow((iPenSize.iWidth >> 1) + 1,(iPenSize.iHeight >> 1) + 1);
+	if (!plotRect.Intersects(iUserClipRect))
+		return;
+
+	SetupDevice();
+	iDevice->DrawingBegin();
+	DoPlot(aPoint);
+	iDevice->DrawingEnd();
+	}
+
+void CFbsBitGc::DoPlot(const TPoint& aPoint)
+	{
+	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
+
+	const TSize oneByOne(1,1);
+	const TPoint point(aPoint + iOrigin);
+
+	TRect temp(point,oneByOne);
+	if (iPenSize.iWidth > 1 || iPenSize.iHeight > 1)
+		temp.Grow(iPenSize.iWidth >> 1,iPenSize.iHeight >> 1);
+	AddRect(temp);
+
+	const CGraphicsContext::TPenStyle penStyle = iPenStyle;
+	iPenStyle = CGraphicsContext::ESolidPen;
+
+#if defined(_DEBUG)
+	TRect deviceRect;
+	drawDevice->GetDrawRect(deviceRect);
+#endif
+
+	const TInt limit = iDefaultRegionPtr->Count();
+	for (TInt count = 0; count < limit; count++)
+		{
+		iClipRect = (*iDefaultRegionPtr)[count];
+		if (!iClipRect.Intersects(temp))
+			continue;
+
+		iClipRect.Intersection(temp);
+		if (UserClipRect(iClipRect))
+			continue;
+
+		if (iPenSize == oneByOne)
+			{
+			if (iClipRect.Contains(point))
+				{
+				BG_ASSERT_DEBUG(point.iX >= deviceRect.iTl.iX, EBitgdiPanicOutOfBounds);
+				BG_ASSERT_DEBUG(point.iY >= deviceRect.iTl.iY, EBitgdiPanicOutOfBounds);
+				BG_ASSERT_DEBUG(point.iX <= deviceRect.iBr.iX, EBitgdiPanicOutOfBounds);
+				BG_ASSERT_DEBUG(point.iY <= deviceRect.iBr.iY, EBitgdiPanicOutOfBounds);
+
+				drawDevice->WriteRgb(point.iX,point.iY,iPenColor,iDrawMode);
+				}
+			}
+		else if (iPenSize.iWidth > 0 && iPenSize.iHeight > 0)
+			PenDrawClipped(point);
+
+		drawDevice->UpdateRegion(iClipRect);
+		}
+
+	iPenStyle = penStyle;
+	}
+
+
+/** Sets the shadow area.
+
+@param aRegion The region defining the shadow area. */
+EXPORT_C void CFbsBitGc::ShadowArea(const TRegion* aRegion)
+	{
+	ShadowFadeArea(aRegion,CFbsDrawDevice::EShadow);
+	}
+
+ 
+/** Sets the fade area.
+
+@param aRegion The region defining the fade area. */
+EXPORT_C void CFbsBitGc::FadeArea(const TRegion* aRegion)
+	{
+	ShadowFadeArea(aRegion,CFbsDrawDevice::EFade);
+	}
+
+void CFbsBitGc::ShadowFadeArea(const TRegion* aRegion,TInt8 aShadowMode)
+	{
+	if (!aRegion || aRegion->CheckError())
+		return;
+
+	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
+
+	CheckDevice();
+
+	TRect deviceRect;
+	drawDevice->GetDrawRect(deviceRect);
+
+	TInt8 shadowMode = iShadowMode;
+	iShadowMode = aShadowMode;
+
+	CGraphicsAccelerator* ga = GraphicsAccelerator();
+
+	SetupDevice();
+	iDevice->DrawingBegin();
+
+	const TInt limit = aRegion->Count();
+	TInt count;
+    //use Graphics accelerator if available
+	if(ga)
+		{
+		if(iShadowMode & CFbsDrawDevice::EFade)
+			{
+	        TInt gaOperationResult = KErrUnknown;
+            iDevice->DrawingEnd();
+
+			TGopFadeParams gopFadeParams;
+			gopFadeParams.iScale = iFadeWhiteMap-iFadeBlackMap+1;
+			gopFadeParams.iOffset = iFadeBlackMap;
+
+			for (count = 0; count < limit; count++)
+				{
+				iClipRect = (*aRegion)[count];
+				iClipRect.Move(iOrigin);
+				if(!iClipRect.Intersects(deviceRect))
+					continue;
+
+				iClipRect.Intersection(deviceRect);
+				AddRect(iClipRect);
+
+				gaOperationResult = ga->Operation(TGopFadeRect(iClipRect,gopFadeParams));
+				if(gaOperationResult != KErrNone)
+					break;
+				}
+			if(gaOperationResult == KErrNone)
+				goto finish;
+			iDevice->DrawingBegin();
+			}
+		}
+
+    //use graphics contex
+	for (count = 0; count < limit; count++)
+		{
+		iClipRect = (*aRegion)[count];
+		iClipRect.Move(iOrigin);
+		if(!iClipRect.Intersects(deviceRect))
+			continue;
+
+		iClipRect.Intersection(deviceRect);
+		AddRect(iClipRect);
+
+		drawDevice->ShadowArea(iClipRect);
+		drawDevice->UpdateRegion(iClipRect);
+		}
+
+	iDevice->DrawingEnd();
+
+finish:
+	iShadowMode = shadowMode;
+	}
+
+// if iBrushBitmap is an extended bitmap, PrepareRasterizerForExtendedBitmap() must have been called before this method
+void CFbsBitGc::ClipFillLine(TPoint aLeft,TPoint aRight)
+	{
+	if (iBrushStyle == ENullBrush || 
+		aLeft.iY < iClipRect.iTl.iY || aLeft.iY >= iClipRect.iBr.iY)
+		return;
+
+	aLeft.iX = Max(aLeft.iX,iClipRect.iTl.iX);
+	aRight.iX = Min(aRight.iX,iClipRect.iBr.iX-1);
+	if (aLeft.iX > aRight.iX)
+		return;
+
+	BG_ASSERT_DEBUG(iUserClipRect.Contains(aLeft),EBitgdiPanicOutOfBounds);
+
+	TInt xcoord = aLeft.iX;
+	TInt length = aRight.iX - aLeft.iX + 1;
+	TPoint origin(iOrigin + iBrushOrigin);
+
+	BG_ASSERT_DEBUG(aLeft.iX + length <= iUserClipRect.iBr.iX,EBitgdiPanicOutOfBounds);
+
+	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
+
+	switch(iBrushStyle)
+		{
+	case ESolidBrush:
+		drawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,iDrawMode);
+		return;
+	case EPatternedBrush:
+		{
+		CBitwiseBitmap* brushBitmap = iBrushBitmap.Address();
+		BG_ASSERT_ALWAYS(iBrushUsed,EBitgdiPanicInvalidBitmap);
+		BG_ASSERT_ALWAYS(brushBitmap != NULL,EBitgdiPanicInvalidBitmap);
+
+		TRect sourcerect(aLeft,TSize(length,1));
+		sourcerect.Move(-origin);
+		DoBitBlt(aLeft,brushBitmap,iBrushBitmap.DataAddress(),iBrushBitmap.DataStride(),sourcerect);
+		return;
+		}
+	case EHorizontalHatchBrush:
+		drawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,iDrawMode);
+		if (Abs((aLeft.iY - origin.iY) % 3) == 2)
+			drawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iPenColor,iDrawMode);
+		return;
+	case EVerticalHatchBrush:
+		drawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,iDrawMode);
+		while (Abs((xcoord - origin.iX) % 3) != 2)
+			xcoord++;
+		for (; xcoord < aLeft.iX + length; xcoord += 3)
+			drawDevice->WriteRgb(xcoord,aLeft.iY,iPenColor,iDrawMode);
+		return;
+	case ESquareCrossHatchBrush:
+		drawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,iDrawMode);
+		if (Abs((aLeft.iY - origin.iY) % 3) == 2)
+			drawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iPenColor,iDrawMode);
+		else
+			{
+			while (Abs((xcoord - origin.iX) % 3) != 2)
+				xcoord++;
+			for (; xcoord < aLeft.iX + length; xcoord += 3)
+				drawDevice->WriteRgb(xcoord,aLeft.iY,iPenColor,iDrawMode);
+			}
+		return;
+	case EForwardDiagonalHatchBrush:
+		{
+		drawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,iDrawMode);
+		TInt diff = (origin.iX + origin.iY - aLeft.iX - aLeft.iY) % 3;
+		if (diff < 0)
+			diff += 3;
+		xcoord += diff;
+		for (; xcoord < aLeft.iX + length; xcoord += 3)
+			drawDevice->WriteRgb(xcoord,aLeft.iY,iPenColor,iDrawMode);
+		}
+		return;
+	case ERearwardDiagonalHatchBrush:
+		{
+		drawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,iDrawMode);
+		TInt diff = (origin.iX - origin.iY - aLeft.iX + aLeft.iY) % 3;
+		if (diff < 0)
+			diff += 3;
+		xcoord += diff;
+		for (; xcoord < aLeft.iX + length; xcoord += 3)
+			drawDevice->WriteRgb(xcoord,aLeft.iY,iPenColor,iDrawMode);
+		}
+		return;
+	case EDiamondCrossHatchBrush:
+		{
+		drawDevice->WriteRgbMulti(aLeft.iX,aLeft.iY,length,1,iBrushColor,iDrawMode);
+		TInt sum = aLeft.iX + aLeft.iY - origin.iX - origin.iY;
+		for (; xcoord < aLeft.iX + length; xcoord++,sum++)
+			if ((sum & 1) == 0 && ((sum & 3) != 0 || ((xcoord-origin.iX) & 1) == 1))
+				drawDevice->WriteRgb(xcoord,aLeft.iY,iPenColor,iDrawMode);
+		}
+		return;
+	default:
+		return;
+		}
+	}
+
+void CFbsBitGc::PenAllocate()
+	{
+	iFbsBitGcExtraData->ResetPenArray();
+	if (iPenSize.iWidth == 1 && iPenSize.iHeight == 1)
+		return;
+
+	const TInt doublepenheight = iPenSize.iHeight << 1;
+
+	TInt* penArray = new TInt[doublepenheight];
+	if (!penArray)
+		return;
+
+	iFbsBitGcExtraData->SetPenArray(penArray);
+
+	if (iPenSize.iWidth == 1 || iPenSize.iWidth == 2 || iPenSize.iHeight == 1 || iPenSize.iHeight == 2)
+		{
+		TInt* bitGcPenArray = iFbsBitGcExtraData->PenArray();
+		for (TInt count = 0; count < iPenSize.iHeight; count += 2)
+			{
+			bitGcPenArray[doublepenheight - count - 2] = 0;
+			bitGcPenArray[doublepenheight - count - 1] = iPenSize.iWidth - 1;
+			bitGcPenArray[count] = 0;
+			bitGcPenArray[count + 1] = iPenSize.iWidth - 1;
+			}
+		}
+	else
+		{
+		TPoint tl,tr,bl,br;
+		TEllipse ellipse;
+		ellipse.Construct(TRect(iPenSize));
+		TInt* bitGcPenArray = iFbsBitGcExtraData->PenArray();
+		for (TInt count = 0; count < iPenSize.iHeight; count += 2)
+			{
+			//coverity[check_return]
+			//coverity[unchecked_value]
+			ellipse.NextStep(tl,tr,bl,br);
+			bitGcPenArray[doublepenheight - count - 2] = bl.iX;
+			bitGcPenArray[doublepenheight - count - 1] = br.iX;
+			bitGcPenArray[count] = tl.iX;
+			bitGcPenArray[count + 1] = tr.iX;
+			}
+		}
+	}
+
+void CFbsBitGc::PenDrawClipped(TPoint aPoint)
+	{
+	BG_ASSERT_DEBUG(iPenSize.iWidth > 0,EBitgdiPanicZeroLength);
+	BG_ASSERT_DEBUG(iPenSize.iHeight > 0,EBitgdiPanicZeroLength);
+
+	aPoint.iX -= ((iPenSize.iWidth - 1) >> 1);
+	aPoint.iY -= ((iPenSize.iHeight - 1) >> 1);
+
+	BG_ASSERT_DEBUG(iClipRect.iTl.iX >= iUserClipRect.iTl.iX,EBitgdiPanicOutOfBounds);
+	BG_ASSERT_DEBUG(iClipRect.iTl.iY >= iUserClipRect.iTl.iY,EBitgdiPanicOutOfBounds);
+	BG_ASSERT_DEBUG(iClipRect.iBr.iX <= iUserClipRect.iBr.iX,EBitgdiPanicOutOfBounds);
+	BG_ASSERT_DEBUG(iClipRect.iBr.iY <= iUserClipRect.iBr.iY,EBitgdiPanicOutOfBounds);
+
+	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
+
+	if (iPenSize.iWidth == 1 && iPenSize.iHeight == 1)
+		{
+		if (iPenStyle == CGraphicsContext::ESolidPen || (iDotMask & (1 << (iDotParam % iDotLength))))
+			if (iClipRect.Contains(aPoint))
+				drawDevice->WriteRgb(aPoint.iX,aPoint.iY,iPenColor,iDrawMode);
+		}
+	else if (iFbsBitGcExtraData->PenArray())
+		{
+		TInt ycoord = aPoint.iY;
+		const TInt maxdim = Max(iPenSize.iWidth,iPenSize.iHeight);
+		const TInt doublepenheight = iPenSize.iHeight << 1;
+
+		if (iPenStyle == CGraphicsContext::ESolidPen || (iDotMask & (1 << ((iDotParam / maxdim) % iDotLength))))
+			{
+			for (TInt ix = 0; ix < doublepenheight; ycoord++,ix += 2)
+				{
+				if (ycoord >= iClipRect.iTl.iY && ycoord < iClipRect.iBr.iY)
+					{
+					TInt left = aPoint.iX + iFbsBitGcExtraData->PenArray()[ix];
+					TInt right = aPoint.iX + iFbsBitGcExtraData->PenArray()[ix+1];
+					if (left < iClipRect.iTl.iX)
+						left = iClipRect.iTl.iX;
+					if (right >= iClipRect.iBr.iX)
+						right = iClipRect.iBr.iX - 1;
+					if (left <= right)
+						drawDevice->WriteRgbMulti(left,ycoord,right - left + 1,1,iPenColor,CGraphicsContext::EDrawModePEN);
+					}
+				}
+			}
+		}
+	else
+		{
+		TPoint tl,tr,bl,br;
+		TEllipse ellipse;
+		ellipse.Construct(TRect(aPoint,iPenSize));
+		while (!ellipse.NextStep(tl,tr,bl,br))
+			{
+			if (tl.iY >= iClipRect.iTl.iY && tl.iY < iClipRect.iBr.iY)
+				{
+				if (tl.iX < iClipRect.iTl.iX)
+					tl.iX = iClipRect.iTl.iX;
+				if (tr.iX >= iClipRect.iBr.iX)
+					tr.iX = iClipRect.iBr.iX-1;
+				if (tl.iX <= tr.iX)
+					drawDevice->WriteRgbMulti(tl.iX,tl.iY,tr.iX - tl.iX + 1,1,iPenColor,CGraphicsContext::EDrawModePEN);
+				}
+			if (bl.iY >= iClipRect.iTl.iY && bl.iY < iClipRect.iBr.iY)
+				{
+				if (bl.iX < iClipRect.iTl.iX)
+					bl.iX = iClipRect.iTl.iX;
+				if (br.iX >= iClipRect.iBr.iX)
+					br.iX = iClipRect.iBr.iX - 1;
+				if (bl.iX <= br.iX)
+					drawDevice->WriteRgbMulti(bl.iX,bl.iY,br.iX - bl.iX + 1,1,iPenColor,CGraphicsContext::EDrawModePEN);
+				}
+			}
+
+		if (tl.iY == bl.iY && tl.iY >= iClipRect.iTl.iY && tl.iY < iClipRect.iBr.iY)
+			{
+			if (tl.iX < iClipRect.iTl.iX)
+				tl.iX = iClipRect.iTl.iX;
+			if (tr.iX >= iClipRect.iBr.iX)
+				tr.iX = iClipRect.iBr.iX - 1;
+			if (tl.iX <= tr.iX)
+				drawDevice->WriteRgbMulti(tl.iX,tl.iY,tr.iX - tl.iX + 1,1,iPenColor,CGraphicsContext::EDrawModePEN);
+			}
+		}
+	}
+
+void CFbsBitGc::PenDrawDeferred(TPoint aPoint,TInt* aArray,TInt aFirstElement)
+	{
+	BG_ASSERT_DEBUG(iFbsBitGcExtraData->PenArray(),EBitgdiPanicZeroLength);
+	BG_ASSERT_DEBUG(iPenSize.iWidth > 0,EBitgdiPanicZeroLength);
+	BG_ASSERT_DEBUG(iPenSize.iHeight > 0,EBitgdiPanicZeroLength);
+	BG_ASSERT_DEBUG(iClipRect.iTl.iX >= iUserClipRect.iTl.iX,EBitgdiPanicOutOfBounds);
+	BG_ASSERT_DEBUG(iClipRect.iTl.iY >= iUserClipRect.iTl.iY,EBitgdiPanicOutOfBounds);
+	BG_ASSERT_DEBUG(iClipRect.iBr.iX <= iUserClipRect.iBr.iX,EBitgdiPanicOutOfBounds);
+	BG_ASSERT_DEBUG(iClipRect.iBr.iY <= iUserClipRect.iBr.iY,EBitgdiPanicOutOfBounds);
+
+	aPoint.iX -= ((iPenSize.iWidth - 1) >> 1);
+	const TInt doublepenheight = iPenSize.iHeight << 1;
+
+	for (TInt ix = 0; ix < doublepenheight; ix++,aFirstElement++)
+		{
+		if (aFirstElement == doublepenheight)
+			aFirstElement = 0;
+		TInt newval = aPoint.iX + iFbsBitGcExtraData->PenArray()[ix];
+		if (newval < aArray[aFirstElement])
+			aArray[aFirstElement] = newval;
+
+		ix++;
+		aFirstElement++;
+		newval = aPoint.iX + iFbsBitGcExtraData->PenArray()[ix];
+		if (newval > aArray[aFirstElement])
+			aArray[aFirstElement] = newval;
+		}
+	}
+
+//Default implementation of reserved virtual
+EXPORT_C void CFbsBitGc::Reserved_CGraphicsContext_2()
+	{
+	CBitmapContext::Reserved_CGraphicsContext_2();
+	}
+
+//Default implementation of reserved virtual
+EXPORT_C void CFbsBitGc::Reserved_CBitmapContext_1()
+	{
+	CBitmapContext::Reserved_CBitmapContext_1();
+	}
+
+//Default implementation of reserved virtual
+EXPORT_C void CFbsBitGc::Reserved_CBitmapContext_2()
+	{
+	CBitmapContext::Reserved_CBitmapContext_2();
+	}
+
+//Default implementation of reserved virtual
+EXPORT_C void CFbsBitGc::Reserved_CBitmapContext_3()
+	{
+	CBitmapContext::Reserved_CBitmapContext_3();
+	}
+
+//Default implementation of reserved virtual
+EXPORT_C void CFbsBitGc::Reserved_CFbsBitGc_1()
+	{
+	}
+
+//Default implementation of reserved virtual
+EXPORT_C void CFbsBitGc::Reserved_CFbsBitGc_2()
+	{
+	}
+
+//Default implementation of reserved virtual
+EXPORT_C void CFbsBitGc::Reserved_CFbsBitGc_3()
+	{
+	}
+
+//Default implementation of reserved virtual
+EXPORT_C void CFbsBitGc::Reserved_CFbsBitGc_4()
+	{
+	}
+
+//Default implementation of reserved virtual
+EXPORT_C void CFbsBitGc::Reserved_CFbsBitGc_5()
+	{
+	}