diff -r 000000000000 -r bde4ae8d615e os/graphics/graphicsdeviceinterface/bitgdi/sbit/ELLIPSE.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/graphics/graphicsdeviceinterface/bitgdi/sbit/ELLIPSE.CPP Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,405 @@ +// 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 "BITPANIC.H" +#include +#include + +/* + * TEllipse + */ + + /** + Initialises the values of the ellipse so that it conforms to a rectangle entered as a parameter. + @param aRect the rectangle within which the ellipse is drawn + */ +EXPORT_C void TEllipse::Construct(const TRect& aRect) + { + TInt width=aRect.Width(); + TInt height=aRect.Height(); + iA=(width-1)>>1; + iB=(height-1)>>1; + iXAdj=(width+1)&1; + iYAdj=(height+1)&1; + iOffset=aRect.iTl; + iX=0; + iY=iB; + iASquared=iA*iA; + iBSquared=iB*iB; + iASquBSqu=iASquared*iBSquared; + iD1=iBSquared-iASquared*iB+(iASquared>>1); + if(width<=0 || height<=0) + iStatus=EComplete; + else if(width<=2 || height<=2) + iStatus=ELine; + else if(iA+iXAdj==0 || iB+iYAdj==0) + iStatus=EComplete; + else + iStatus=EInitialised; + } + +/** +Does the next stage in producing an ellipse by taking four points (the corners of +the rectangle the ellipse should fill) as parameters. Updates TEllipse status +accordingly and calls Output(aTopLeft,aTopRight,aBottomLeft,aBottomRight). +@param aTopLeft Top left corner of rectangle +@param aTopRight Top right corner of rectangle +@param aBottomLeft Bottom left corner of rectangle +@param aBottomRight Bottom right corner of rectangle +@return TBool ETrue if step completed successfully. +*/ +EXPORT_C TBool TEllipse::SingleStep(TPoint& aTopLeft,TPoint& aTopRight, + TPoint& aBottomLeft,TPoint& aBottomRight) + { + TBool ret=EFalse; + if(iStatus==EFirstSector) + { + if(iD1<0) + iD1+=iBSquared*((iX<<1)+3); + else if(iY>0) + { + iD1+=iBSquared*((iX<<1)+3)+iASquared*(2-(iY<<1)); + iY--; + } + iX++; + ret=Output(aTopLeft,aTopRight,aBottomLeft,aBottomRight); + if(iStatus==EComplete && iXiA+iXAdj) ret=ETrue; + else + { + iStatus=ELine; + ret=EFalse; + } + } + return(ret); + } + if(iStatus==EInitialised) + { + iStatus=EFirstSector; + return(Output(aTopLeft,aTopRight,aBottomLeft,aBottomRight)); + } + Output(aTopLeft,aTopRight,aBottomLeft,aBottomRight); + return(ETrue); + } + +/** +Sets the absolute points that define the ellipse as calculated using its iOffset +from the origin and using the half width and half height of the rectangle iA and iB. +@param aTopLeft The absolute (x,y) position for the top left point. +@param aTopRight The absolute (x,y) position for the top right point. +@param aBottomLeft The absolute (x,y) position for the bottom left point. +@param aBottomRight The absolute (x,y) position for the bottom right point. +@return TBool ETrue if a valid rectangle is produced, else EFalse. Also sets +iStatus to EComplete. +*/ +EXPORT_C TBool TEllipse::Output(TPoint& aTopLeft,TPoint& aTopRight, + TPoint& aBottomLeft,TPoint& aBottomRight) + { + TInt lx=iA-iX+iOffset.iX; + TInt ty=iB-iY+iOffset.iY; + TInt rx=iA+iX+iXAdj+iOffset.iX; + TInt by=iB+iY+iYAdj+iOffset.iY; + aTopLeft.SetXY(lx,ty); + aTopRight.SetXY(rx,ty); + aBottomLeft.SetXY(lx,by); + aBottomRight.SetXY(rx,by); + if(iY<=0) + { + iStatus=EComplete; + if(iYAdj==0 || ty>by) + return(ETrue); + } + return(EFalse); + } + +/** +By analysing the current state of the ellipse the process is taken to the next appropriate step. +If iStatus = EInitialised only one step will be taken, if the ellipse is already semi constructed then +it will be taken to completion. Takes in four point parameters that defines the rectangle in order to pass to +SingleStep(aTopLeft,aTopRight,aBottomLeft,aBottomRight). +@param aTopLeft Top left corner of rectangle +@param aTopRight Top right corner of rectangle +@param aBottomLeft Bottom left corner of rectangle +@param aBottomRight Bottom right corner of rectangle +@return TBool ETrue if a valid rectangle is produced, else EFalse. +*/ +EXPORT_C TBool TEllipse::NextStep(TPoint& aTopLeft,TPoint& aTopRight, + TPoint& aBottomLeft,TPoint& aBottomRight) + { + if(iStatus==EInitialised) + return(SingleStep(aTopLeft,aTopRight,aBottomLeft,aBottomRight)); + TInt prevlev=iY; + TBool ret; + do + ret=SingleStep(aTopLeft,aTopRight,aBottomLeft,aBottomRight); + while(prevlev==iY && ret==EFalse); + return(ret); + } + +/** +Constructs an ellipse from the rectangle which it is given and assesses the +points position with regard to the ellipse and where they intersect. +@param aRect The rectangle within which the ellipse is drawn. +@param aPoint A point to compare with the ellipse to determine if intersection occurs. +@return TPoint The point is set to the corner which the intersection is nearest to. +*/ +EXPORT_C TPoint TEllipse::Intersection(const TRect& aRect,const TPoint& aPoint) + { + Construct(aRect); //constructs the rect (an elipse object) + TPoint centre=aRect.Center(); //centre of ellipse + TPoint ptcpy(aPoint); + ptcpy-=iOffset; //ptcpy = aPoint - iOffset - TPoint(iA,iB) //radius from centre of ellipse + ptcpy-=TPoint(iA,iB); + TPoint pt[4],opt[4]; + TInt mpt[4],ompt[4]; + TInt count=0; + for(;count<4;count++) + ompt[count]=KMaxTInt; //fills ompt 1->4 with KMaxTInt + while(SingleStep(pt[0],pt[1],pt[2],pt[3])==EFalse) //creates a complete ellipse with pts as rect + for(count=0;count<4;count++) + { + mpt[count]=Abs((pt[count].iY-iOffset.iY-iB)*(ptcpy.iX)-(ptcpy.iY)*(pt[count].iX-iOffset.iX-iA)); + if(mpt[count]CGraphicsContext::DrawEllipse(). The function +behaviour is the same as documented in that class. +*/ +EXPORT_C void CFbsBitGc::DrawEllipse(const TRect& aRect) + { + if(CheckDevice(aRect)) return; + TRect rcpy(aRect); + rcpy.Move(iOrigin); + iDevice->TruncateRect(rcpy); + TRect clippedRect(rcpy); + clippedRect.Grow((iPenSize.iWidth>>1)+1,(iPenSize.iHeight>>1)+1); + if(UserClipRect(clippedRect)) return; + SetupDevice(); + iDevice->DrawingBegin(&iBrushBitmap); + CFbsRasterizer* brushRasterizer = PrepareRasterizerForExtendedBitmap(iBrushBitmap); + if(iBrushStyle!=ENullBrush) + EllipseFill(rcpy); + if(iPenStyle!=ENullPen) + { + if(iPenSize.iWidth>1 && iPenSize.iHeight>1) + EllipseOutlineWide(rcpy); + else + if(iPenSize.iWidth==1 || iPenSize.iHeight==1) + EllipseOutline(rcpy); + } + if (brushRasterizer) + { + brushRasterizer->EndBitmap(iBrushBitmap.SerialNumber()); + } + iDevice->DrawingEnd(&iBrushBitmap); + } + +void CFbsBitGc::EllipseOutline(const TRect& aRect) + { + CFbsDrawDevice* drawDevice = iDevice->iDrawDevice; + TPoint tl,tr,bl,br; + AddRect(aRect); +#if defined(_DEBUG) + TRect deviceDestRect; + drawDevice->GetDrawRect(deviceDestRect); +#endif + for(TInt count=0;countCount();count++) + { + iClipRect=(*iDefaultRegionPtr)[count]; + if(!iClipRect.Intersects(aRect)) + continue; + iClipRect.Intersection(aRect); + if(UserClipRect(iClipRect)) continue; + BG_ASSERT_DEBUG(iClipRect.iTl.iX >= deviceDestRect.iTl.iX, EBitgdiPanicOutOfBounds); + BG_ASSERT_DEBUG(iClipRect.iTl.iY >= deviceDestRect.iTl.iY, EBitgdiPanicOutOfBounds); + BG_ASSERT_DEBUG(iClipRect.iBr.iX <= deviceDestRect.iBr.iX, EBitgdiPanicOutOfBounds); + BG_ASSERT_DEBUG(iClipRect.iBr.iY <= deviceDestRect.iBr.iY, EBitgdiPanicOutOfBounds); + TEllipse ellipse; + ellipse.Construct(aRect); + TInt pattern=0; + while(!ellipse.SingleStep(tl,tr,bl,br)) + { + if(iPenStyle==CGraphicsContext::ESolidPen || (iDotMask&(1<<(pattern%iDotLength)))) + { + if(tl.iY>=iClipRect.iTl.iY && tl.iY=iClipRect.iTl.iX && tl.iXWriteRgb(tl.iX,tl.iY,iPenColor,iDrawMode); + if(tr.iX>=iClipRect.iTl.iX && tr.iXWriteRgb(tr.iX,tr.iY,iPenColor,iDrawMode); + } + if(bl.iY>=iClipRect.iTl.iY && bl.iY=iClipRect.iTl.iX && bl.iXWriteRgb(bl.iX,bl.iY,iPenColor,iDrawMode); + if(br.iX>=iClipRect.iTl.iX && br.iXWriteRgb(br.iX,br.iY,iPenColor,iDrawMode); + } + } + pattern++; + } + if(tl.iY==bl.iY && tl.iY>=iClipRect.iTl.iY && tl.iY=iClipRect.iTl.iX && tl.iXWriteRgb(tl.iX,tl.iY,iPenColor,iDrawMode); + if(tr.iX>=iClipRect.iTl.iX && tr.iXWriteRgb(tr.iX,tr.iY,iPenColor,iDrawMode); + } + drawDevice->UpdateRegion(iClipRect); + } + } + +void CFbsBitGc::EllipseOutlineWide(const TRect& aRect) + { + TRect rcpy(aRect); + TPoint tl,tr,bl,br; + TInt halfpenwidth=(iPenSize.iWidth+1)>>1; + TInt halfpenheight=(iPenSize.iHeight+1)>>1; + rcpy.Grow(halfpenwidth,halfpenheight); + AddRect(rcpy); + TInt dp=iDotParam; + for(TInt count=0;countCount();count++) + { + iClipRect=(*iDefaultRegionPtr)[count]; + if(!iClipRect.Intersects(rcpy)) + continue; + iClipRect.Intersection(rcpy); + if(UserClipRect(iClipRect)) continue; + TEllipse ellipse; + ellipse.Construct(aRect); + iDotParam=Max(iPenSize.iWidth>>1,iPenSize.iHeight>>1); + while(!ellipse.SingleStep(tl,tr,bl,br)) + { + PenDrawClipped(tl); + PenDrawClipped(tr); + PenDrawClipped(bl); + PenDrawClipped(br); + iDotParam+=iDotDirection; + } + if(tl.iY==bl.iY) + { + PenDrawClipped(tl); + PenDrawClipped(tr); + } + iDevice->iDrawDevice->UpdateRegion(iClipRect); + } + iDotParam=dp; + } + +// if iBrushBitmap is an extended bitmap, PrepareRasterizerForExtendedBitmap() must have been called before this method +void CFbsBitGc::EllipseFill(const TRect& aRect) + { + TRect rcpy(aRect); + if(iPenSize.iWidth==0 || iPenSize.iHeight==0) + rcpy.Grow(1,1); + AddRect(aRect); + TPoint tl,tr,bl,br; + for(TInt count=0;countCount();count++) + { + iClipRect=(*iDefaultRegionPtr)[count]; + if(!iClipRect.Intersects(rcpy)) + continue; + iClipRect.Intersection(rcpy); + if(UserClipRect(iClipRect)) continue; + TEllipse ellipse; + ellipse.Construct(rcpy); + while(!ellipse.NextStep(tl,tr,bl,br)) + { + tl.iX++; + tr.iX--; + bl.iX++; + br.iX--; + ClipFillLine(tl,tr); + ClipFillLine(bl,br); + } + if(tl.iY==bl.iY) + { + tl.iX++; + tr.iX--; + ClipFillLine(tl,tr); + } + iDevice->iDrawDevice->UpdateRegion(iClipRect); + } + } +