diff -r 000000000000 -r 5d03bc08d59c graphicsdeviceinterface/bitgdi/sbit/GRAPHICS.CPP --- /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 +#include +#include +#include +#include "BITPANIC.H" +#include +#include +#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() + { + }