Update contrib.
1 // Copyright (c) 1997-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.
20 #include <graphics/fbsrasterizer.h>
27 Initialises the values of the ellipse so that it conforms to a rectangle entered as a parameter.
28 @param aRect the rectangle within which the ellipse is drawn
30 EXPORT_C void TEllipse::Construct(const TRect& aRect)
32 TInt width=aRect.Width();
33 TInt height=aRect.Height();
43 iASquBSqu=iASquared*iBSquared;
44 iD1=iBSquared-iASquared*iB+(iASquared>>1);
45 if(width<=0 || height<=0)
47 else if(width<=2 || height<=2)
49 else if(iA+iXAdj==0 || iB+iYAdj==0)
56 Does the next stage in producing an ellipse by taking four points (the corners of
57 the rectangle the ellipse should fill) as parameters. Updates TEllipse status
58 accordingly and calls <code>Output(aTopLeft,aTopRight,aBottomLeft,aBottomRight)</code>.
59 @param aTopLeft Top left corner of rectangle
60 @param aTopRight Top right corner of rectangle
61 @param aBottomLeft Bottom left corner of rectangle
62 @param aBottomRight Bottom right corner of rectangle
63 @return TBool ETrue if step completed successfully.
65 EXPORT_C TBool TEllipse::SingleStep(TPoint& aTopLeft,TPoint& aTopRight,
66 TPoint& aBottomLeft,TPoint& aBottomRight)
69 if(iStatus==EFirstSector)
72 iD1+=iBSquared*((iX<<1)+3);
75 iD1+=iBSquared*((iX<<1)+3)+iASquared*(2-(iY<<1));
79 ret=Output(aTopLeft,aTopRight,aBottomLeft,aBottomRight);
80 if(iStatus==EComplete && iX<iA)
85 if(iASquared*iY<=iBSquared*(iX+1) && ret==EFalse)
87 iStatus=ESecondSector;
88 iD2=-iASquBSqu+iBSquared*iX*iX+iASquared*(iY-1)*(iY-1);
92 if(iStatus==ESecondSector)
96 iD2+=iBSquared*((iX<<1)+2)+iASquared*(3-(iY<<1));
100 iD2+=iASquared*(3-(iY<<1));
102 return(Output(aTopLeft,aTopRight,aBottomLeft,aBottomRight));
106 ret=Output(aTopLeft,aTopRight,aBottomLeft,aBottomRight);
112 if(iX>iA+iXAdj) ret=ETrue;
121 if(iStatus==EInitialised)
123 iStatus=EFirstSector;
124 return(Output(aTopLeft,aTopRight,aBottomLeft,aBottomRight));
126 Output(aTopLeft,aTopRight,aBottomLeft,aBottomRight);
131 Sets the absolute points that define the ellipse as calculated using its iOffset
132 from the origin and using the half width and half height of the rectangle iA and iB.
133 @param aTopLeft The absolute (x,y) position for the top left point.
134 @param aTopRight The absolute (x,y) position for the top right point.
135 @param aBottomLeft The absolute (x,y) position for the bottom left point.
136 @param aBottomRight The absolute (x,y) position for the bottom right point.
137 @return TBool ETrue if a valid rectangle is produced, else EFalse. Also sets
138 iStatus to EComplete.
140 EXPORT_C TBool TEllipse::Output(TPoint& aTopLeft,TPoint& aTopRight,
141 TPoint& aBottomLeft,TPoint& aBottomRight)
143 TInt lx=iA-iX+iOffset.iX;
144 TInt ty=iB-iY+iOffset.iY;
145 TInt rx=iA+iX+iXAdj+iOffset.iX;
146 TInt by=iB+iY+iYAdj+iOffset.iY;
147 aTopLeft.SetXY(lx,ty);
148 aTopRight.SetXY(rx,ty);
149 aBottomLeft.SetXY(lx,by);
150 aBottomRight.SetXY(rx,by);
154 if(iYAdj==0 || ty>by)
161 By analysing the current state of the ellipse the process is taken to the next appropriate step.
162 If iStatus = EInitialised only one step will be taken, if the ellipse is already semi constructed then
163 it will be taken to completion. Takes in four point parameters that defines the rectangle in order to pass to
164 SingleStep(aTopLeft,aTopRight,aBottomLeft,aBottomRight).
165 @param aTopLeft Top left corner of rectangle
166 @param aTopRight Top right corner of rectangle
167 @param aBottomLeft Bottom left corner of rectangle
168 @param aBottomRight Bottom right corner of rectangle
169 @return TBool ETrue if a valid rectangle is produced, else EFalse.
171 EXPORT_C TBool TEllipse::NextStep(TPoint& aTopLeft,TPoint& aTopRight,
172 TPoint& aBottomLeft,TPoint& aBottomRight)
174 if(iStatus==EInitialised)
175 return(SingleStep(aTopLeft,aTopRight,aBottomLeft,aBottomRight));
179 ret=SingleStep(aTopLeft,aTopRight,aBottomLeft,aBottomRight);
180 while(prevlev==iY && ret==EFalse);
185 Constructs an ellipse from the rectangle which it is given and assesses the
186 points position with regard to the ellipse and where they intersect.
187 @param aRect The rectangle within which the ellipse is drawn.
188 @param aPoint A point to compare with the ellipse to determine if intersection occurs.
189 @return TPoint The point is set to the corner which the intersection is nearest to.
191 EXPORT_C TPoint TEllipse::Intersection(const TRect& aRect,const TPoint& aPoint)
193 Construct(aRect); //constructs the rect (an elipse object)
194 TPoint centre=aRect.Center(); //centre of ellipse
195 TPoint ptcpy(aPoint);
196 ptcpy-=iOffset; //ptcpy = aPoint - iOffset - TPoint(iA,iB) //radius from centre of ellipse
197 ptcpy-=TPoint(iA,iB);
201 for(;count<4;count++)
202 ompt[count]=KMaxTInt; //fills ompt 1->4 with KMaxTInt
203 while(SingleStep(pt[0],pt[1],pt[2],pt[3])==EFalse) //creates a complete ellipse with pts as rect
204 for(count=0;count<4;count++)
206 mpt[count]=Abs((pt[count].iY-iOffset.iY-iB)*(ptcpy.iX)-(ptcpy.iY)*(pt[count].iX-iOffset.iX-iA));
207 if(mpt[count]<ompt[count]) //use the larger number set.
209 ompt[count]=mpt[count];
210 opt[count]=pt[count];
213 if(pt[0].iY==pt[2].iY) //if it is horizontal
214 for(count=0;count<4;count++)
216 mpt[count]=Abs((pt[count].iY-iOffset.iY-iB)*(ptcpy.iX)-(ptcpy.iY)*(pt[count].iX-iOffset.iX-iA));
217 if(mpt[count]<ompt[count]) //use the larger number set.
219 ompt[count]=mpt[count];
220 opt[count]=pt[count];
223 if(ptcpy.iX<0 && ptcpy.iY<0) //if point is further left and higher than centre of rect
225 if(ptcpy.iY<0) //if point is higher than centre of rect
227 if(ptcpy.iX<0) //if point is further left than centre of rect
229 if(aPoint.iX<centre.iX && aPoint.iY<centre.iY) //if point is further left and higher than centre of rect
231 if(aPoint.iY<centre.iY) //if point is higher than centre of rect
233 if(aPoint.iX<centre.iX) //if point is further left than centre of rect
235 return(opt[3]); //else
243 Draws and fills an ellipse.
245 The function provides a concrete implementation of the pure virtual
246 function <code>CGraphicsContext::DrawEllipse()</code>. The function
247 behaviour is the same as documented in that class.
249 EXPORT_C void CFbsBitGc::DrawEllipse(const TRect& aRect)
251 if(CheckDevice(aRect)) return;
254 iDevice->TruncateRect(rcpy);
255 TRect clippedRect(rcpy);
256 clippedRect.Grow((iPenSize.iWidth>>1)+1,(iPenSize.iHeight>>1)+1);
257 if(UserClipRect(clippedRect)) return;
259 iDevice->DrawingBegin(&iBrushBitmap);
260 CFbsRasterizer* brushRasterizer = PrepareRasterizerForExtendedBitmap(iBrushBitmap);
261 if(iBrushStyle!=ENullBrush)
263 if(iPenStyle!=ENullPen)
265 if(iPenSize.iWidth>1 && iPenSize.iHeight>1)
266 EllipseOutlineWide(rcpy);
268 if(iPenSize.iWidth==1 || iPenSize.iHeight==1)
269 EllipseOutline(rcpy);
273 brushRasterizer->EndBitmap(iBrushBitmap.SerialNumber());
275 iDevice->DrawingEnd(&iBrushBitmap);
278 void CFbsBitGc::EllipseOutline(const TRect& aRect)
280 CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
284 TRect deviceDestRect;
285 drawDevice->GetDrawRect(deviceDestRect);
287 for(TInt count=0;count<iDefaultRegionPtr->Count();count++)
289 iClipRect=(*iDefaultRegionPtr)[count];
290 if(!iClipRect.Intersects(aRect))
292 iClipRect.Intersection(aRect);
293 if(UserClipRect(iClipRect)) continue;
294 BG_ASSERT_DEBUG(iClipRect.iTl.iX >= deviceDestRect.iTl.iX, EBitgdiPanicOutOfBounds);
295 BG_ASSERT_DEBUG(iClipRect.iTl.iY >= deviceDestRect.iTl.iY, EBitgdiPanicOutOfBounds);
296 BG_ASSERT_DEBUG(iClipRect.iBr.iX <= deviceDestRect.iBr.iX, EBitgdiPanicOutOfBounds);
297 BG_ASSERT_DEBUG(iClipRect.iBr.iY <= deviceDestRect.iBr.iY, EBitgdiPanicOutOfBounds);
299 ellipse.Construct(aRect);
301 while(!ellipse.SingleStep(tl,tr,bl,br))
303 if(iPenStyle==CGraphicsContext::ESolidPen || (iDotMask&(1<<(pattern%iDotLength))))
305 if(tl.iY>=iClipRect.iTl.iY && tl.iY<iClipRect.iBr.iY)
307 if(tl.iX>=iClipRect.iTl.iX && tl.iX<iClipRect.iBr.iX)
308 drawDevice->WriteRgb(tl.iX,tl.iY,iPenColor,iDrawMode);
309 if(tr.iX>=iClipRect.iTl.iX && tr.iX<iClipRect.iBr.iX && tl.iX!=tr.iX)
310 drawDevice->WriteRgb(tr.iX,tr.iY,iPenColor,iDrawMode);
312 if(bl.iY>=iClipRect.iTl.iY && bl.iY<iClipRect.iBr.iY)
314 if(bl.iX>=iClipRect.iTl.iX && bl.iX<iClipRect.iBr.iX)
315 drawDevice->WriteRgb(bl.iX,bl.iY,iPenColor,iDrawMode);
316 if(br.iX>=iClipRect.iTl.iX && br.iX<iClipRect.iBr.iX && bl.iX!=br.iX)
317 drawDevice->WriteRgb(br.iX,br.iY,iPenColor,iDrawMode);
322 if(tl.iY==bl.iY && tl.iY>=iClipRect.iTl.iY && tl.iY<iClipRect.iBr.iY)
324 if(tl.iX>=iClipRect.iTl.iX && tl.iX<iClipRect.iBr.iX)
325 drawDevice->WriteRgb(tl.iX,tl.iY,iPenColor,iDrawMode);
326 if(tr.iX>=iClipRect.iTl.iX && tr.iX<iClipRect.iBr.iX && tl.iX!=tr.iX)
327 drawDevice->WriteRgb(tr.iX,tr.iY,iPenColor,iDrawMode);
329 drawDevice->UpdateRegion(iClipRect);
333 void CFbsBitGc::EllipseOutlineWide(const TRect& aRect)
337 TInt halfpenwidth=(iPenSize.iWidth+1)>>1;
338 TInt halfpenheight=(iPenSize.iHeight+1)>>1;
339 rcpy.Grow(halfpenwidth,halfpenheight);
342 for(TInt count=0;count<iDefaultRegionPtr->Count();count++)
344 iClipRect=(*iDefaultRegionPtr)[count];
345 if(!iClipRect.Intersects(rcpy))
347 iClipRect.Intersection(rcpy);
348 if(UserClipRect(iClipRect)) continue;
350 ellipse.Construct(aRect);
351 iDotParam=Max(iPenSize.iWidth>>1,iPenSize.iHeight>>1);
352 while(!ellipse.SingleStep(tl,tr,bl,br))
358 iDotParam+=iDotDirection;
365 iDevice->iDrawDevice->UpdateRegion(iClipRect);
370 // if iBrushBitmap is an extended bitmap, PrepareRasterizerForExtendedBitmap() must have been called before this method
371 void CFbsBitGc::EllipseFill(const TRect& aRect)
374 if(iPenSize.iWidth==0 || iPenSize.iHeight==0)
378 for(TInt count=0;count<iDefaultRegionPtr->Count();count++)
380 iClipRect=(*iDefaultRegionPtr)[count];
381 if(!iClipRect.Intersects(rcpy))
383 iClipRect.Intersection(rcpy);
384 if(UserClipRect(iClipRect)) continue;
386 ellipse.Construct(rcpy);
387 while(!ellipse.NextStep(tl,tr,bl,br))
402 iDevice->iDrawDevice->UpdateRegion(iClipRect);