os/graphics/graphicsdeviceinterface/directgdiadaptation/swsrc/swdirectgdiellipse.cpp
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 #include "directgdiadapter.h"
17 #include "swdirectgdiellipse.h"
18 #include "swdirectgdiengine.h"
25 Initialises the values of the ellipse so that it conforms to a rectangle entered as a parameter.
26 @param aRect the rectangle within which the ellipse is drawn
28 void TSwDirectGdiEllipse::Construct(const TRect& aRect)
30 TInt width = aRect.Width();
31 TInt height = aRect.Height();
34 iXAdj = (width+1) & 1;
35 iYAdj = (height+1) & 1;
41 iASquBSqu = iASquared * iBSquared;
42 iD1 = iBSquared - iASquared * iB + (iASquared>>1);
43 if (width<=0 || height<=0)
47 else if (width<=2 || height<=2)
53 iStatus = EInitialised;
58 Does the next stage in producing an ellipse by taking four points (the corners of
59 the rectangle the ellipse should fill) as parameters. Updates TSwDirectGdiEllipse status
60 accordingly and calls Output(aTopLeft,aTopRight,aBottomLeft,aBottomRight).
62 @param aTopLeft Top left corner of rectangle.
63 @param aTopRight Top right corner of rectangle.
64 @param aBottomLeft Bottom left corner of rectangle.
65 @param aBottomRight Bottom right corner of rectangle.
66 @return TBool ETrue if step completed successfully.
68 TBool TSwDirectGdiEllipse::SingleStep(TPoint& aTopLeft, TPoint& aTopRight,
69 TPoint& aBottomLeft, TPoint& aBottomRight)
72 if (iStatus == EFirstSector)
76 iD1 += iBSquared * ((iX<<1)+3);
80 iD1 += iBSquared * ((iX<<1)+3) + iASquared * (2-(iY<<1));
84 ret = Output(aTopLeft,aTopRight,aBottomLeft,aBottomRight);
85 if (iStatus == EComplete && iX<iA)
87 iStatus = EFirstSector;
90 if (iASquared*iY<=iBSquared*(iX+1) && ret==EFalse)
92 iStatus = ESecondSector;
93 iD2 =- iASquBSqu + iBSquared * iX * iX + iASquared * (iY-1) * (iY-1);
97 if (iStatus == ESecondSector)
101 iD2 += iBSquared * ((iX<<1)+2) + iASquared * (3-(iY<<1));
106 iD2 += iASquared * (3-(iY<<1));
109 return Output(aTopLeft, aTopRight, aBottomLeft, aBottomRight);
111 if (iStatus == ELine)
113 ret = Output(aTopLeft, aTopRight, aBottomLeft, aBottomRight);
133 if (iStatus == EInitialised)
135 iStatus = EFirstSector;
136 return Output(aTopLeft, aTopRight, aBottomLeft, aBottomRight);
138 Output(aTopLeft, aTopRight, aBottomLeft, aBottomRight);
143 Sets the absolute points that define the ellipse as calculated using its iOffset
144 from the origin and using the half width and half height of the rectangle iA and iB.
146 @param aTopLeft The absolute (x,y) position for the top left point.
147 @param aTopRight The absolute (x,y) position for the top right point.
148 @param aBottomLeft The absolute (x,y) position for the bottom left point.
149 @param aBottomRight The absolute (x,y) position for the bottom right point.
150 @return ETrue if a valid rectangle is produced, else EFalse. Also sets
151 iStatus to EComplete.
153 TBool TSwDirectGdiEllipse::Output(TPoint& aTopLeft, TPoint& aTopRight,
154 TPoint& aBottomLeft, TPoint& aBottomRight)
156 TInt lx = iA-iX+iOffset.iX;
157 TInt ty = iB-iY+iOffset.iY;
158 TInt rx = iA+iX+iXAdj+iOffset.iX;
159 TInt by = iB+iY+iYAdj+iOffset.iY;
160 aTopLeft.SetXY(lx,ty);
161 aTopRight.SetXY(rx,ty);
162 aBottomLeft.SetXY(lx,by);
163 aBottomRight.SetXY(rx,by);
167 if (iYAdj==0 || ty>by)
174 By analysing the current state of the ellipse the process is taken to the next appropriate step.
175 If iStatus = EInitialised only one step will be taken, if the ellipse is already semi constructed then
176 it will be taken to completion. Takes in four point parameters that define the rectangle in order to pass to
177 SingleStep(aTopLeft,aTopRight,aBottomLeft,aBottomRight).
179 @param aTopLeft Top-left corner of rectangle.
180 @param aTopRight Top-right corner of rectangle.
181 @param aBottomLeft Bottom-left corner of rectangle.
182 @param aBottomRight Bottom-right corner of rectangle.
183 @return ETrue if a valid rectangle is produced, else EFalse.
185 TBool TSwDirectGdiEllipse::NextStep(TPoint& aTopLeft, TPoint& aTopRight,
186 TPoint& aBottomLeft, TPoint& aBottomRight)
188 if(iStatus == EInitialised)
190 return(SingleStep(aTopLeft,aTopRight,aBottomLeft,aBottomRight));
196 ret = SingleStep(aTopLeft,aTopRight,aBottomLeft,aBottomRight);
198 while (prevlev==iY && ret==EFalse);
203 Constructs an ellipse from the rectangle that has been added. Assesses the position of
204 the points and the places where they intersect the ellipse.
206 @param aRect The rectangle within which the ellipse is drawn.
207 @param aPoint A point to compare with the ellipse to determine if intersection occurs.
208 @return TPoint The point is set to the corner which the intersection is nearest to.
210 TPoint TSwDirectGdiEllipse::Intersection(const TRect& aRect, const TPoint& aPoint)
212 Construct(aRect); //constructs the rect (an elipse object)
213 TPoint centre = aRect.Center(); //centre of ellipse
214 TPoint ptcpy(aPoint);
215 ptcpy -= iOffset; //ptcpy = aPoint - iOffset - TPoint(iA,iB) //radius from centre of ellipse
216 ptcpy -= TPoint(iA,iB);
217 TPoint pt[4], opt[4];
218 TInt mpt[4], ompt[4];
220 for( ; count < 4; count++)
222 ompt[count]=KMaxTInt; //fills ompt 1->4 with KMaxTInt
224 while (SingleStep(pt[0], pt[1], pt[2], pt[3]) == EFalse) //creates a complete ellipse with pts as rect
226 for (count = 0; count < 4; count++)
228 mpt[count] = Abs((pt[count].iY-iOffset.iY-iB)*(ptcpy.iX)-(ptcpy.iY)*(pt[count].iX-iOffset.iX-iA));
229 if (mpt[count] < ompt[count]) //use the larger number set.
231 ompt[count] = mpt[count];
232 opt[count] = pt[count];
236 if (pt[0].iY == pt[2].iY) //if it is horizontal
238 for (count = 0; count < 4; count++)
240 mpt[count] = Abs((pt[count].iY-iOffset.iY-iB)*(ptcpy.iX)-(ptcpy.iY)*(pt[count].iX-iOffset.iX-iA));
241 if (mpt[count] < ompt[count]) //use the larger number set.
243 ompt[count] = mpt[count];
244 opt[count] = pt[count];
248 if (ptcpy.iX<0 && ptcpy.iY<0) //if point is further left and higher than centre of rect
252 if (ptcpy.iY < 0) //if point is higher than centre of rect
256 if (ptcpy.iX < 0) //if point is further left than centre of rect
260 if (aPoint.iX<centre.iX && aPoint.iY<centre.iY) //if point is further left and higher than centre of rect
264 if (aPoint.iY < centre.iY) //if point is higher than centre of rect
268 if (aPoint.iX < centre.iX) //if point is further left than centre of rect
272 return(opt[3]); //else
280 @see MDirectGdiEngine::DrawEllipse()
282 void CSwDirectGdiEngine::DrawEllipse(const TRect& aRect)
287 iBrushBitmap.BeginDataAccess();
288 if(iBrushStyle!=DirectGdi::ENullBrush)
291 if(iPenStyle!=DirectGdi::ENullPen)
293 if(iPenSize.iWidth>1 && iPenSize.iHeight>1)
295 EllipseOutlineWide(rcpy);
297 else if(iPenSize.iWidth==1 || iPenSize.iHeight==1)
299 EllipseOutline(rcpy);
302 iBrushBitmap.EndDataAccess(ETrue);
306 Draws an ellipse inside the given rectangle. Current pen settings apply.
307 @param aRect The rectangle in which to draw the ellipse.
309 void CSwDirectGdiEngine::EllipseOutline(const TRect& aRect)
313 TRect deviceDestRect;
314 iDrawDevice->GetDrawRect(deviceDestRect);
316 TRect clipRect(0,0,0,0);
317 const CGraphicsContext::TDrawMode drawMode = GcDrawMode(iDrawMode);
318 for(TInt count=0;count<iDefaultRegionPtr->Count();count++)
320 clipRect=(*iDefaultRegionPtr)[count];
321 if(!clipRect.Intersects(aRect))
323 clipRect.Intersection(aRect);
324 GRAPHICS_ASSERT_DEBUG(clipRect.iTl.iX >= deviceDestRect.iTl.iX, EDirectGdiPanicOutOfBounds);
325 GRAPHICS_ASSERT_DEBUG(clipRect.iTl.iY >= deviceDestRect.iTl.iY, EDirectGdiPanicOutOfBounds);
326 GRAPHICS_ASSERT_DEBUG(clipRect.iBr.iX <= deviceDestRect.iBr.iX, EDirectGdiPanicOutOfBounds);
327 GRAPHICS_ASSERT_DEBUG(clipRect.iBr.iY <= deviceDestRect.iBr.iY, EDirectGdiPanicOutOfBounds);
328 TSwDirectGdiEllipse ellipse;
329 ellipse.Construct(aRect);
331 while(!ellipse.SingleStep(tl,tr,bl,br))
333 if(iPenStyle==DirectGdi::ESolidPen || (iDotMask&(1<<(pattern%iDotLength))))
335 if(tl.iY>=clipRect.iTl.iY && tl.iY<clipRect.iBr.iY)
337 if(tl.iX>=clipRect.iTl.iX && tl.iX<clipRect.iBr.iX)
338 iDrawDevice->WriteRgb(tl.iX,tl.iY,iPenColor,drawMode);
339 if(tr.iX>=clipRect.iTl.iX && tr.iX<clipRect.iBr.iX && tl.iX!=tr.iX)
340 iDrawDevice->WriteRgb(tr.iX,tr.iY,iPenColor,drawMode);
342 if(bl.iY>=clipRect.iTl.iY && bl.iY<clipRect.iBr.iY)
344 if(bl.iX>=clipRect.iTl.iX && bl.iX<clipRect.iBr.iX)
345 iDrawDevice->WriteRgb(bl.iX,bl.iY,iPenColor,drawMode);
346 if(br.iX>=clipRect.iTl.iX && br.iX<clipRect.iBr.iX && bl.iX!=br.iX)
347 iDrawDevice->WriteRgb(br.iX,br.iY,iPenColor,drawMode);
352 if(tl.iY==bl.iY && tl.iY>=clipRect.iTl.iY && tl.iY<clipRect.iBr.iY)
354 if(tl.iX>=clipRect.iTl.iX && tl.iX<clipRect.iBr.iX)
355 iDrawDevice->WriteRgb(tl.iX,tl.iY,iPenColor,drawMode);
356 if(tr.iX>=clipRect.iTl.iX && tr.iX<clipRect.iBr.iX && tl.iX!=tr.iX)
357 iDrawDevice->WriteRgb(tr.iX,tr.iY,iPenColor,drawMode);
359 iDrawDevice->UpdateRegion(clipRect);
364 Draws an ellipse inside the given rectangle. Current pen settings apply.
365 @param aRect The rectangle in which to draw the ellipse.
367 void CSwDirectGdiEngine::EllipseOutlineWide(const TRect& aRect)
371 TInt halfpenwidth=(iPenSize.iWidth+1)>>1;
372 TInt halfpenheight=(iPenSize.iHeight+1)>>1;
373 rcpy.Grow(halfpenwidth, halfpenheight);
375 TRect clipRect(0,0,0,0);
376 for(TInt count=0;count<iDefaultRegionPtr->Count();count++)
378 clipRect=(*iDefaultRegionPtr)[count];
379 if(!clipRect.Intersects(rcpy))
381 clipRect.Intersection(rcpy);
382 TSwDirectGdiEllipse ellipse;
383 ellipse.Construct(aRect);
384 iDotParam=Max(iPenSize.iWidth>>1,iPenSize.iHeight>>1);
385 while(!ellipse.SingleStep(tl,tr,bl,br))
387 PenDrawClipped(tl, clipRect);
388 PenDrawClipped(tr, clipRect);
389 PenDrawClipped(bl, clipRect);
390 PenDrawClipped(br, clipRect);
391 iDotParam+=iDotDirection;
395 PenDrawClipped(tl, clipRect);
396 PenDrawClipped(tr, clipRect);
398 iDrawDevice->UpdateRegion(clipRect);
404 Fills an ellipse inside the given rectangle. Current brush settings apply.
405 @param aRect The rectangle in which to draw the ellipse.
407 void CSwDirectGdiEngine::EllipseFill(const TRect& aRect)
410 if(iPenSize.iWidth==0 || iPenSize.iHeight==0)
415 TRect clipRect(0,0,0,0);
416 for(TInt count=0;count<iDefaultRegionPtr->Count();count++)
418 clipRect=(*iDefaultRegionPtr)[count];
419 if(!clipRect.Intersects(rcpy))
421 clipRect.Intersection(rcpy);
422 TSwDirectGdiEllipse ellipse;
423 ellipse.Construct(rcpy);
424 while(!ellipse.NextStep(tl,tr,bl,br))
430 ClipFillLine(tl,tr, clipRect);
431 ClipFillLine(bl,br, clipRect);
437 ClipFillLine(tl,tr, clipRect);
439 iDrawDevice->UpdateRegion(clipRect);