|
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". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include <bitstd.h> |
|
17 #include <bitdev.h> |
|
18 #include "BITPANIC.H" |
|
19 #include <bitdraw.h> |
|
20 #include <graphics/fbsrasterizer.h> |
|
21 |
|
22 // TPieArc |
|
23 |
|
24 class TArc : public TEllipse |
|
25 { |
|
26 public: |
|
27 void Construct(const TRect& aRect,const TPoint& aStart,const TPoint& aEnd); |
|
28 TBool SingleStep(TPoint& aTl,TBool& aDoTl,TPoint& aTr,TBool& aDoTr,TPoint& aBl,TBool& aDoBl,TPoint& aBr,TBool& aDoBr); |
|
29 void Step(TPoint& aTl,TBool& aDoTl,TPoint& aTr,TBool& aDoTr,TPoint& aBl,TBool& aDoBl,TPoint& aBr,TBool& aDoBr); |
|
30 public: |
|
31 TPoint iStart; |
|
32 TPoint iEnd; |
|
33 private: |
|
34 TBool iTlquad; |
|
35 TBool iTrquad; |
|
36 TBool iBlquad; |
|
37 TBool iBrquad; |
|
38 TBool iStartquadenabled; |
|
39 TBool iEndquadenabled; |
|
40 TBool iStartquaddone; |
|
41 TBool iEndquaddone; |
|
42 TInt iStartquad; |
|
43 TInt iEndquad; |
|
44 TBool iSlice; |
|
45 }; |
|
46 |
|
47 void TArc::Construct(const TRect& aRect,const TPoint& aStart,const TPoint& aEnd) |
|
48 { |
|
49 iStart=Intersection(aRect,aStart); |
|
50 iEnd=Intersection(aRect,aEnd); |
|
51 TEllipse::Construct(aRect); |
|
52 iTlquad=EFalse; |
|
53 iTrquad=EFalse; |
|
54 iBlquad=EFalse; |
|
55 iBrquad=EFalse; |
|
56 iStartquadenabled=EFalse; |
|
57 iEndquadenabled=EFalse; |
|
58 iSlice=EFalse; |
|
59 iStartquad=0; |
|
60 iEndquad=0; |
|
61 TPoint center=aRect.Center(); |
|
62 if (iStart.iX>=center.iX) iStartquad=1; |
|
63 if (iStart.iY>=center.iY) iStartquad+=2; |
|
64 if (iEnd.iX>=center.iX) iEndquad=1; |
|
65 if (iEnd.iY>=center.iY) iEndquad+=2; |
|
66 if (iStartquad!=iEndquad) |
|
67 { |
|
68 if (iStartquad==0 && iEndquad==1) |
|
69 { |
|
70 iBlquad=ETrue; |
|
71 iBrquad=ETrue; |
|
72 } |
|
73 else if (iStartquad==0 && iEndquad==3) |
|
74 iBlquad=ETrue; |
|
75 else if (iStartquad==1 && iEndquad==2) |
|
76 iTlquad=ETrue; |
|
77 else if (iStartquad==1 && iEndquad==3) |
|
78 { |
|
79 iTlquad=ETrue; |
|
80 iBlquad=ETrue; |
|
81 } |
|
82 else if (iStartquad==2 && iEndquad==0) |
|
83 { |
|
84 iTrquad=ETrue; |
|
85 iBrquad=ETrue; |
|
86 } |
|
87 else if (iStartquad==2 && iEndquad==1) |
|
88 iBrquad=ETrue; |
|
89 else if (iStartquad==3 && iEndquad==0) |
|
90 iTrquad=ETrue; |
|
91 else if (iStartquad==3 && iEndquad==2) |
|
92 { |
|
93 iTlquad=ETrue; |
|
94 iTrquad=ETrue; |
|
95 } |
|
96 } |
|
97 else if (iStart==iEnd) |
|
98 { |
|
99 iTlquad=ETrue; |
|
100 iTrquad=ETrue; |
|
101 iBlquad=ETrue; |
|
102 iBrquad=ETrue; |
|
103 } |
|
104 else |
|
105 { |
|
106 iSlice=ETrue; |
|
107 if (iStartquad==0 && (iStart.iX<iEnd.iX || iStart.iY>iEnd.iY)) |
|
108 { |
|
109 iTrquad=ETrue; |
|
110 iBlquad=ETrue; |
|
111 iBrquad=ETrue; |
|
112 iSlice=EFalse; |
|
113 } |
|
114 else if (iStartquad==1 && (iStart.iX<iEnd.iX || iStart.iY<iEnd.iY)) |
|
115 { |
|
116 iTlquad=ETrue; |
|
117 iBlquad=ETrue; |
|
118 iBrquad=ETrue; |
|
119 iSlice=EFalse; |
|
120 } |
|
121 else if (iStartquad==2 && (iStart.iX>iEnd.iX || iStart.iY>iEnd.iY)) |
|
122 { |
|
123 iTlquad=ETrue; |
|
124 iTrquad=ETrue; |
|
125 iBrquad=ETrue; |
|
126 iSlice=EFalse; |
|
127 } |
|
128 else if (iStartquad==3 && (iStart.iX>iEnd.iX || iStart.iY<iEnd.iY)) |
|
129 { |
|
130 iTlquad=ETrue; |
|
131 iTrquad=ETrue; |
|
132 iBlquad=ETrue; |
|
133 iSlice=EFalse; |
|
134 } |
|
135 } |
|
136 if (iStartquad==1 || iStartquad==2) |
|
137 iStartquadenabled=ETrue; |
|
138 if (iEndquad==0 || iEndquad==3) |
|
139 iEndquadenabled=ETrue; |
|
140 iStartquaddone=EFalse; |
|
141 iEndquaddone=EFalse; |
|
142 } |
|
143 |
|
144 TBool TArc::SingleStep(TPoint& aTopLeft,TBool& aDoTl,TPoint& aTopRight, |
|
145 TBool& aDoTr,TPoint& aBottomLeft,TBool& aDoBl, |
|
146 TPoint& aBottomRight,TBool& aDoBr) |
|
147 { |
|
148 TBool finished=TEllipse::SingleStep(aTopLeft,aTopRight,aBottomLeft,aBottomRight); |
|
149 Step(aTopLeft,aDoTl,aTopRight,aDoTr,aBottomLeft,aDoBl,aBottomRight,aDoBr); |
|
150 |
|
151 return finished; |
|
152 } |
|
153 |
|
154 void TArc::Step(TPoint& aTopLeft,TBool& aDoTl,TPoint& aTopRight,TBool& aDoTr, |
|
155 TPoint& aBottomLeft,TBool& aDoBl,TPoint& aBottomRight,TBool& aDoBr) |
|
156 { |
|
157 aDoTl=iTlquad; |
|
158 aDoTr=iTrquad; |
|
159 aDoBl=iBlquad; |
|
160 aDoBr=iBrquad; |
|
161 if (!iStartquaddone) |
|
162 { |
|
163 if (!iStartquadenabled) |
|
164 { |
|
165 if (iStartquad==0 && aTopLeft.iX<=iStart.iX && aTopLeft.iY>=iStart.iY) |
|
166 { |
|
167 iStartquadenabled=ETrue; |
|
168 iStartquaddone=ETrue; |
|
169 } |
|
170 if (iStartquad==3 && aBottomRight.iX>=iStart.iX && aBottomRight.iY<=iStart.iY) |
|
171 { |
|
172 iStartquadenabled=ETrue; |
|
173 iStartquaddone=ETrue; |
|
174 } |
|
175 } |
|
176 else |
|
177 { |
|
178 if (iStartquad==1 && (aTopRight.iX>iStart.iX || aTopRight.iY>iStart.iY)) |
|
179 { |
|
180 iStartquadenabled=EFalse; |
|
181 iStartquaddone=ETrue; |
|
182 } |
|
183 if (iStartquad==2 && (aBottomLeft.iX<iStart.iX || aBottomLeft.iY<iStart.iY)) |
|
184 { |
|
185 iStartquadenabled=EFalse; |
|
186 iStartquaddone=ETrue; |
|
187 } |
|
188 } |
|
189 } |
|
190 if (!iEndquaddone) |
|
191 { |
|
192 if (iEndquadenabled) |
|
193 { |
|
194 if (iEndquad==0 && (aTopLeft.iX<iEnd.iX || aTopLeft.iY>iEnd.iY)) |
|
195 { |
|
196 iEndquadenabled=EFalse; |
|
197 iEndquaddone=ETrue; |
|
198 } |
|
199 if (iEndquad==3 && (aBottomRight.iX>iEnd.iX || aBottomRight.iY<iEnd.iY)) |
|
200 { |
|
201 iEndquadenabled=EFalse; |
|
202 iEndquaddone=ETrue; |
|
203 } |
|
204 } |
|
205 else |
|
206 { |
|
207 if (iEndquad==1 && aTopRight.iX>=iEnd.iX && aTopRight.iY>=iEnd.iY) |
|
208 { |
|
209 iEndquadenabled=ETrue; |
|
210 iEndquaddone=ETrue; |
|
211 } |
|
212 if (iEndquad==2 && aBottomLeft.iX<=iEnd.iX && aBottomLeft.iY<=iEnd.iY) |
|
213 { |
|
214 iEndquadenabled=ETrue; |
|
215 iEndquaddone=ETrue; |
|
216 } |
|
217 } |
|
218 } |
|
219 if (iStartquad!=iEndquad) |
|
220 { |
|
221 if (iStartquadenabled) |
|
222 { |
|
223 if (iStartquad==0) aDoTl=ETrue; |
|
224 else if (iStartquad==1) aDoTr=ETrue; |
|
225 else if (iStartquad==2) aDoBl=ETrue; |
|
226 else if (iStartquad==3) aDoBr=ETrue; |
|
227 } |
|
228 if (iEndquadenabled) |
|
229 { |
|
230 if (iEndquad==0) aDoTl=ETrue; |
|
231 else if (iEndquad==1) aDoTr=ETrue; |
|
232 else if (iEndquad==2) aDoBl=ETrue; |
|
233 else if (iEndquad==3) aDoBr=ETrue; |
|
234 } |
|
235 } |
|
236 else |
|
237 { |
|
238 if (iSlice) |
|
239 { |
|
240 if (iStartquadenabled && iEndquadenabled) |
|
241 { |
|
242 if (iStartquad==0) aDoTl=ETrue; |
|
243 else if (iStartquad==1) aDoTr=ETrue; |
|
244 else if (iStartquad==2) aDoBl=ETrue; |
|
245 else if (iStartquad==3) aDoBr=ETrue; |
|
246 } |
|
247 } |
|
248 else |
|
249 { |
|
250 if (iStartquadenabled || iEndquadenabled) |
|
251 { |
|
252 if (iStartquad==0) aDoTl=ETrue; |
|
253 else if (iStartquad==1) aDoTr=ETrue; |
|
254 else if (iStartquad==2) aDoBl=ETrue; |
|
255 else if (iStartquad==3) aDoBr=ETrue; |
|
256 } |
|
257 } |
|
258 } |
|
259 if (aTopLeft.iX==aTopRight.iX) |
|
260 { |
|
261 if (aDoTl && aDoTr) aDoTr=EFalse; |
|
262 if (aDoBl && aDoBr) aDoBr=EFalse; |
|
263 } |
|
264 } |
|
265 |
|
266 // |
|
267 // Pie and Arc drawing functions |
|
268 // |
|
269 |
|
270 /** |
|
271 Draws an arc. |
|
272 |
|
273 The function provides a concrete implementation of the pure virtual |
|
274 function <code>CGraphicsContext::DrawArc()</code>. The function |
|
275 behaviour is the same as documented in that class. |
|
276 */ |
|
277 EXPORT_C void CFbsBitGc::DrawArc(const TRect& aRect,const TPoint& aStartradius, |
|
278 const TPoint& aEndradius) |
|
279 { |
|
280 if (!iPenStyle || !iPenSize.iWidth || !iPenSize.iHeight || aRect.IsEmpty() || CheckDevice(aRect)) |
|
281 return; |
|
282 |
|
283 TRect rcpy(aRect); |
|
284 rcpy.Move(iOrigin); |
|
285 iDevice->TruncateRect(rcpy); |
|
286 TRect arcBoundingRect(rcpy); |
|
287 arcBoundingRect.Grow((iPenSize.iWidth>>1)+1,(iPenSize.iHeight>>1)+1); |
|
288 if (!arcBoundingRect.Intersects(iUserClipRect)) |
|
289 return; |
|
290 |
|
291 SetupDevice(); |
|
292 iDevice->DrawingBegin(); |
|
293 PieArcOutline(rcpy,aStartradius+iOrigin,aEndradius+iOrigin,EFalse); |
|
294 iDevice->DrawingEnd(); |
|
295 } |
|
296 |
|
297 /** |
|
298 Draws and fills a pie slice. |
|
299 |
|
300 The function provides a concrete implementation of the pure virtual |
|
301 function <code>CGraphicsContext::DrawPie()</code>. The function |
|
302 behaviour is the same as documented in that class. |
|
303 */ |
|
304 EXPORT_C void CFbsBitGc::DrawPie(const TRect& aRect,const TPoint& aStartradius, |
|
305 const TPoint& aEndradius) |
|
306 { |
|
307 if (CheckDevice(aRect)) |
|
308 return; |
|
309 |
|
310 TRect rcpy(aRect); |
|
311 rcpy.Move(iOrigin); |
|
312 iDevice->TruncateRect(rcpy); |
|
313 TRect pieBoundingRect(rcpy); |
|
314 pieBoundingRect.Grow((iPenSize.iWidth>>1)+1,(iPenSize.iHeight>>1)+1); |
|
315 if (!pieBoundingRect.Intersects(iUserClipRect)) |
|
316 return; |
|
317 |
|
318 TPoint startIntersect = aStartradius + iOrigin, endIntersect = aEndradius + iOrigin; |
|
319 TInt startQuadrant, endQuadrant; |
|
320 TBool quadrants[5]; |
|
321 const TBool isEllipse = AnalyseEllipse( |
|
322 rcpy, startIntersect, endIntersect, startQuadrant, endQuadrant, quadrants); |
|
323 |
|
324 SetupDevice(); |
|
325 iDevice->DrawingBegin(&iBrushBitmap); |
|
326 CFbsRasterizer* brushRasterizer = PrepareRasterizerForExtendedBitmap(iBrushBitmap); |
|
327 if (iBrushStyle!=ENullBrush) |
|
328 { |
|
329 if (isEllipse) |
|
330 EllipseFill(rcpy); |
|
331 else |
|
332 PieFill(rcpy, startIntersect, endIntersect, startQuadrant, endQuadrant, quadrants); |
|
333 } |
|
334 if (iPenStyle!=ENullPen && iPenSize.iWidth>0 && iPenSize.iHeight>0) |
|
335 PieArcOutline(rcpy,aStartradius+iOrigin,aEndradius+iOrigin,ETrue); |
|
336 if (brushRasterizer) |
|
337 { |
|
338 brushRasterizer->EndBitmap(iBrushBitmap.SerialNumber()); |
|
339 } |
|
340 iDevice->DrawingEnd(&iBrushBitmap); |
|
341 } |
|
342 |
|
343 /** |
|
344 Determine the pie constructed within the given rectangle. |
|
345 @internalTechnology |
|
346 @param rc Input - The bounding rectangle. |
|
347 @param srad Input/Output - The intersection point from the geometric centre |
|
348 of the ellipse to the given start point |
|
349 @param erad Input/Output - The intersection point from the geometric centre |
|
350 of the ellipse to the given end point |
|
351 @param startq Output - The start quadrant |
|
352 @param endq Output - The end quadrant |
|
353 @param quads Output - Quadrants |
|
354 @pre Input params rc, srad, erad are to be given. |
|
355 @post Output params srad, erad, startq, endq, quads will be populated. |
|
356 @return ETrue if the pie is an ellipse, otherwise EFalse. |
|
357 */ |
|
358 TBool CFbsBitGc::AnalyseEllipse(const TRect& rc,TPoint& srad,TPoint& erad, |
|
359 TInt& startq,TInt& endq,TBool* quads) |
|
360 { |
|
361 startq=0; |
|
362 endq=0; |
|
363 const TPoint center = rc.Center(); |
|
364 TEllipse ellipse; |
|
365 srad=ellipse.Intersection(rc,srad); |
|
366 erad=ellipse.Intersection(rc,erad); |
|
367 if (srad==erad) |
|
368 { |
|
369 quads[0]=EFalse; |
|
370 quads[1]=ETrue; |
|
371 quads[2]=ETrue; |
|
372 quads[3]=ETrue; |
|
373 quads[4]=ETrue; |
|
374 return ETrue; |
|
375 } |
|
376 const TInt startx = srad.iX - center.iX, starty = srad.iY - center.iY; |
|
377 const TInt endx = erad.iX - center.iX, endy = erad.iY - center.iY; |
|
378 if (startx>=0) startq=1; |
|
379 if (starty>=0) startq+=2; |
|
380 if (endx>=0) endq=1; |
|
381 if (endy>=0) endq+=2; |
|
382 quads[1]=EFalse,quads[2]=EFalse,quads[3]=EFalse,quads[4]=EFalse; // complete quadrants to draw |
|
383 quads[0]=EFalse; // ellipse is a sliver completely within a quadrant |
|
384 if (startq==endq) |
|
385 { |
|
386 if (startq==0 && (startx<endx || starty>endy)) |
|
387 { |
|
388 quads[2]=ETrue; |
|
389 quads[3]=ETrue; |
|
390 quads[4]=ETrue; |
|
391 } |
|
392 else if (startq==1 && (startx<endx || starty<endy)) |
|
393 { |
|
394 quads[1]=ETrue; |
|
395 quads[3]=ETrue; |
|
396 quads[4]=ETrue; |
|
397 } |
|
398 else if (startq==2 && (startx>endx || starty>endy)) |
|
399 { |
|
400 quads[1]=ETrue; |
|
401 quads[2]=ETrue; |
|
402 quads[4]=ETrue; |
|
403 } |
|
404 else if (startq==3 && (startx>endx || starty<endy)) |
|
405 { |
|
406 quads[1]=ETrue; |
|
407 quads[2]=ETrue; |
|
408 quads[3]=ETrue; |
|
409 } |
|
410 else quads[0]=ETrue; // "slice" |
|
411 } |
|
412 else |
|
413 { |
|
414 if (startq==0 && endq==1) |
|
415 { |
|
416 quads[3]=ETrue; |
|
417 quads[4]=ETrue; |
|
418 } |
|
419 else if (startq==0 && endq==3) |
|
420 quads[3]=ETrue; |
|
421 else if (startq==1 && endq==2) |
|
422 quads[1]=ETrue; |
|
423 else if (startq==1 && endq==3) |
|
424 { |
|
425 quads[1]=ETrue; |
|
426 quads[3]=ETrue; |
|
427 } |
|
428 else if (startq==2 && endq==0) |
|
429 { |
|
430 quads[2]=ETrue; |
|
431 quads[4]=ETrue; |
|
432 } |
|
433 else if (startq==2 && endq==1) |
|
434 quads[4]=ETrue; |
|
435 else if (startq==3 && endq==0) |
|
436 quads[2]=ETrue; |
|
437 else if (startq==3 && endq==2) |
|
438 { |
|
439 quads[1]=ETrue; |
|
440 quads[2]=ETrue; |
|
441 } |
|
442 } |
|
443 return EFalse; |
|
444 } |
|
445 |
|
446 void CFbsBitGc::PieArcOutline(const TRect& ellrect,const TPoint& startradius, |
|
447 const TPoint& endradius,TBool pie) |
|
448 { |
|
449 // arc runs counterclockwise, from startradius-center/ellipse intersect to endradius-center/ellipse intersect |
|
450 TInt dotparam=iDotParam; |
|
451 TRect rcpy(ellrect); |
|
452 TPoint pt[4]; |
|
453 TInt halfpenwidth=iPenSize.iWidth>>1; |
|
454 TInt halfpenheight=iPenSize.iHeight>>1; |
|
455 TInt otherhalfwidth=(iPenSize.iWidth+1)>>1; |
|
456 TInt otherhalfheight=(iPenSize.iHeight+1)>>1; |
|
457 rcpy.iTl.iX-=halfpenwidth; |
|
458 rcpy.iTl.iY-=halfpenheight; |
|
459 rcpy.iBr.iX+=otherhalfwidth; |
|
460 rcpy.iBr.iY+=otherhalfheight; |
|
461 AddRect(rcpy); |
|
462 for(TInt count=0;count<iDefaultRegionPtr->Count();count++) |
|
463 { |
|
464 iClipRect=(*iDefaultRegionPtr)[count]; |
|
465 if (!iClipRect.Intersects(rcpy)) |
|
466 continue; |
|
467 iClipRect.Intersection(rcpy); |
|
468 if (UserClipRect(iClipRect)) continue; |
|
469 TArc arc; |
|
470 arc.Construct(ellrect,startradius,endradius); |
|
471 iDotParam=Max(iPenSize.iWidth>>1,iPenSize.iHeight>>1); |
|
472 TBool dotl,dotr,dobl,dobr; |
|
473 while(!arc.SingleStep(pt[0],dotl,pt[1],dotr,pt[2],dobl,pt[3],dobr)) |
|
474 { |
|
475 if (dotl) PenDrawClipped(pt[0]); |
|
476 if (dotr) PenDrawClipped(pt[1]); |
|
477 if (dobl) PenDrawClipped(pt[2]); |
|
478 if (dobr) PenDrawClipped(pt[3]); |
|
479 iDotParam+=iDotDirection; |
|
480 } |
|
481 if (pt[0].iY==pt[2].iY) |
|
482 { |
|
483 if (dotl) PenDrawClipped(pt[0]); |
|
484 if (dotr) PenDrawClipped(pt[1]); |
|
485 } |
|
486 if (pie) |
|
487 { |
|
488 TPoint temp; |
|
489 const TPoint center = ellrect.Center(); |
|
490 TLinearDDA line; |
|
491 line.Construct(arc.iStart,center); |
|
492 line.SingleStep(temp); |
|
493 while(!line.SingleStep(temp)) |
|
494 { |
|
495 PenDrawClipped(temp); |
|
496 iDotParam+=iDotDirection; |
|
497 } |
|
498 line.Construct(arc.iEnd,center); |
|
499 line.SingleStep(temp); |
|
500 while(!line.SingleStep(temp)) |
|
501 { |
|
502 PenDrawClipped(temp); |
|
503 iDotParam+=iDotDirection; |
|
504 } |
|
505 PenDrawClipped(center); |
|
506 } |
|
507 iDevice->iDrawDevice->UpdateRegion(iClipRect); |
|
508 } |
|
509 iDotParam=dotparam; |
|
510 } |
|
511 |
|
512 // if iBrushBitmap is an extended bitmap, PrepareRasterizerForExtendedBitmap() must have been called before this method |
|
513 void CFbsBitGc::PieFill(const TRect& ellrect, const TPoint& aStartIntersect, const TPoint& aEndIntersect, |
|
514 TInt aStartQuadrant, TInt aEndQuadrant, const TBool* aQuadrants) |
|
515 { |
|
516 // arc runs counterclockwise, from startradius-center/ellipse intersect to endradius-center/ellipse intersect |
|
517 AddRect(ellrect); |
|
518 const TInt limit = iDefaultRegionPtr->Count(); |
|
519 for(TInt count=0;count<limit;count++) |
|
520 { |
|
521 iClipRect=(*iDefaultRegionPtr)[count]; |
|
522 if (!iClipRect.Intersects(ellrect)) |
|
523 continue; |
|
524 iClipRect.Intersection(ellrect); |
|
525 if (UserClipRect(iClipRect)) continue; |
|
526 if (!aQuadrants[0]) |
|
527 PieShell(ellrect, aStartIntersect, aEndIntersect, aQuadrants, aStartQuadrant, aEndQuadrant); |
|
528 else |
|
529 PieSliver(ellrect, aStartIntersect, aEndIntersect, aStartQuadrant); |
|
530 iDevice->iDrawDevice->UpdateRegion(iClipRect); |
|
531 } |
|
532 } |
|
533 |
|
534 // if iBrushBitmap is an extended bitmap, PrepareRasterizerForExtendedBitmap() must have been called before this method |
|
535 void CFbsBitGc::PieShell(const TRect& ellrect,const TPoint& startradius, |
|
536 const TPoint& endradius, const TBool* quads, TInt startquad, TInt endquad) |
|
537 { |
|
538 TEllipse ellipse; |
|
539 ellipse.Construct(ellrect); |
|
540 TInt c=ellrect.Center().iX; |
|
541 TPoint pt[4]; |
|
542 TPoint tl,tr,bl,br; |
|
543 TBool donestart=EFalse,doneend=EFalse; |
|
544 TBool todostart=EFalse,todoend=EFalse; |
|
545 while(!ellipse.NextStep(pt[0],pt[1],pt[2],pt[3])) |
|
546 { |
|
547 if (pt[startquad].iY==startradius.iY) |
|
548 todostart=ETrue; |
|
549 if (pt[endquad].iY==endradius.iY) |
|
550 todoend=ETrue; |
|
551 pt[0].iX++; |
|
552 pt[1].iX--; |
|
553 pt[2].iX++; |
|
554 pt[3].iX--; |
|
555 tl.iY=pt[0].iY; |
|
556 tr.iY=pt[1].iY; |
|
557 bl.iY=pt[2].iY; |
|
558 br.iY=pt[3].iY; |
|
559 if (quads[1] || (endquad==0 && !doneend)) // tl quadrant, half top end chord |
|
560 tl.iX=pt[0].iX; |
|
561 else tl.iX=c+1; |
|
562 if (quads[2] || (startquad==1 && !donestart)) // tr quadrant, half top start chord |
|
563 tr.iX=pt[1].iX; |
|
564 else tr.iX=c; |
|
565 if (quads[3] || (startquad==2 && !donestart)) // bl quadrant, half top start chord |
|
566 bl.iX=pt[2].iX; |
|
567 else bl.iX=c+1; |
|
568 if (quads[4] || (endquad==3 && !doneend)) // br quadrant, half top end chord |
|
569 br.iX=pt[3].iX; |
|
570 else br.iX=c; |
|
571 ClipFillLine(tl,tr); |
|
572 ClipFillLine(bl,br); |
|
573 // do partial quadrants |
|
574 if (todostart) |
|
575 { |
|
576 if (startquad==0) |
|
577 { |
|
578 tl.iX=pt[0].iX; |
|
579 tr.iX=startradius.iX; |
|
580 ClipFillLine(tl,tr); |
|
581 } |
|
582 else if (startquad==3) |
|
583 { |
|
584 bl.iX=startradius.iX; |
|
585 br.iX=pt[3].iX; |
|
586 ClipFillLine(bl,br); |
|
587 } |
|
588 } |
|
589 if (todoend) |
|
590 { |
|
591 if (endquad==2) |
|
592 { |
|
593 bl.iX=pt[2].iX; |
|
594 br.iX=endradius.iX; |
|
595 ClipFillLine(bl,br); |
|
596 } |
|
597 else if (endquad==1) |
|
598 { |
|
599 tl.iX=endradius.iX; |
|
600 tr.iX=pt[1].iX; |
|
601 ClipFillLine(tl,tr); |
|
602 } |
|
603 } |
|
604 donestart=todostart; |
|
605 doneend=todoend; |
|
606 } |
|
607 tl.iX=c+1; |
|
608 tr.iX=c; |
|
609 if (pt[0].iY==pt[2].iY) // congruent mid lines |
|
610 { |
|
611 if (pt[startquad].iY==startradius.iY) |
|
612 todostart=ETrue; |
|
613 if (pt[endquad].iY==endradius.iY) |
|
614 todoend=ETrue; |
|
615 pt[0].iX++; |
|
616 pt[1].iX--; |
|
617 tl.iY=pt[0].iY; |
|
618 tr.iY=tl.iY; |
|
619 TBool leftflag=EFalse,rightflag=EFalse; |
|
620 if (quads[1] || (endquad==0 && !doneend) || |
|
621 quads[3] || (startquad==2 && !donestart) || |
|
622 (todostart && startquad==0) || (todoend && endquad==2)) |
|
623 leftflag=ETrue; |
|
624 if (quads[2] || (startquad==1 && !donestart) || |
|
625 quads[4] || (endquad==3 && !doneend) || |
|
626 (todostart && startquad==3) || (todoend && endquad==1)) |
|
627 rightflag=ETrue; |
|
628 if (leftflag) tl.iX=pt[0].iX; |
|
629 if (rightflag) tr.iX=pt[1].iX; |
|
630 ClipFillLine(tl,tr); |
|
631 } |
|
632 else |
|
633 { |
|
634 tl.iY=ellrect.Center().iY; |
|
635 tr.iY=tl.iY; |
|
636 if (startquad==3) tr.iX=startradius.iX-1; |
|
637 if (endquad==2) tl.iX=endradius.iX+1; |
|
638 ClipFillLine(tl,tr); |
|
639 } |
|
640 PieTriangles(startquad==1 || startquad==2,startradius,ellrect.Center()); |
|
641 PieTriangles(endquad==0 || endquad==3,endradius,ellrect.Center()); |
|
642 } |
|
643 |
|
644 // if iBrushBitmap is an extended bitmap, PrepareRasterizerForExtendedBitmap() must have been called before this method |
|
645 void CFbsBitGc::PieTriangles(TBool aInside,const TPoint& aStart,const TPoint& aEnd) |
|
646 { |
|
647 TInt x=aInside?aEnd.iX:aStart.iX; |
|
648 if (aStart.iX>aEnd.iX) |
|
649 { |
|
650 if (aInside) |
|
651 x++; |
|
652 else |
|
653 x--; |
|
654 } |
|
655 else |
|
656 if (!aInside) |
|
657 x++; |
|
658 TLinearDDA line; |
|
659 TPoint pt,left,right; |
|
660 line.Construct(aStart,aEnd); |
|
661 line.NextStep(pt); |
|
662 while(!line.NextStep(pt)) |
|
663 { |
|
664 if (pt.iY==aEnd.iY) break; |
|
665 left.iX=Min(pt.iX,x); |
|
666 right.iX=Max(pt.iX,x); |
|
667 left.iY=right.iY=pt.iY; |
|
668 ClipFillLine(left,right); |
|
669 } |
|
670 } |
|
671 |
|
672 // if iBrushBitmap is an extended bitmap, PrepareRasterizerForExtendedBitmap() must have been called before this method |
|
673 void CFbsBitGc::PieSliver(const TRect& ellrect,const TPoint& startradius, |
|
674 const TPoint& endradius,TInt quad) |
|
675 { |
|
676 TPoint center=ellrect.Center(),left,right; |
|
677 TPoint nearinter(startradius),farinter(endradius); |
|
678 if (Abs(nearinter.iY-center.iY)>Abs(farinter.iY-center.iY)) |
|
679 { |
|
680 nearinter=endradius; |
|
681 farinter=startradius; |
|
682 } |
|
683 TBool ellipseComplete = EFalse; |
|
684 TPoint pt[4]; |
|
685 TEllipse ellipse; |
|
686 ellipse.Construct(ellrect); |
|
687 TLinearDDA mainline; |
|
688 mainline.Construct(farinter,center); |
|
689 ellipseComplete = ellipse.SingleStep(pt[0],pt[1],pt[2],pt[3]); |
|
690 mainline.SingleStep(right); |
|
691 do { |
|
692 while(!ellipseComplete && pt[quad].iY!=right.iY) |
|
693 ellipseComplete = ellipse.NextStep(pt[0],pt[1],pt[2],pt[3]); |
|
694 left=pt[quad]; |
|
695 while(!ellipseComplete && pt[quad].iY==right.iY) |
|
696 { |
|
697 left=pt[quad]; |
|
698 ellipseComplete = ellipse.NextStep(pt[0],pt[1],pt[2],pt[3]); |
|
699 } |
|
700 if (right.iY==nearinter.iY || (ellipseComplete && (pt[0].iY != pt[2].iY))) |
|
701 break; |
|
702 if (left.iX>right.iX) |
|
703 { |
|
704 TInt temp=left.iX; |
|
705 left.iX=right.iX; |
|
706 right.iX=temp; |
|
707 } |
|
708 if(right==farinter && left.iX<=right.iX) |
|
709 { |
|
710 continue; |
|
711 } |
|
712 left.iX++; |
|
713 right.iX--; |
|
714 if (left.iX<=right.iX) |
|
715 ClipFillLine(left,right); |
|
716 } |
|
717 while(!mainline.NextStep(right)); |
|
718 TPoint temppt; |
|
719 TLinearDDA line; |
|
720 line.Construct(nearinter,center); |
|
721 TBool linestat=EFalse; |
|
722 do |
|
723 linestat=line.SingleStep(temppt); |
|
724 while(temppt.iY!=right.iY && !linestat); |
|
725 do { |
|
726 do { |
|
727 left=temppt; |
|
728 linestat=line.SingleStep(temppt); |
|
729 } |
|
730 while(temppt.iY==right.iY && !linestat); |
|
731 if (ellipseComplete) |
|
732 break; |
|
733 if (left.iX>right.iX) |
|
734 { |
|
735 TInt temp=left.iX; |
|
736 left.iX=right.iX; |
|
737 right.iX=temp; |
|
738 } |
|
739 if(right==farinter && left.iX<=right.iX) |
|
740 { |
|
741 continue; |
|
742 } |
|
743 left.iX++; |
|
744 right.iX--; |
|
745 if (left.iX<=right.iX) |
|
746 ClipFillLine(left,right); |
|
747 } |
|
748 while(!mainline.NextStep(right)); |
|
749 } |
|
750 |