7 * a couple macros to fill a single pixel or a line
9 #define PUTPIXEL(x,y,BrushInst) \
10 ret = ret && IntEngLineTo(&BitmapObj->SurfObj, \
12 &BrushInst.BrushObject, \
15 ROP2_TO_MIX(Dc_Attr->jROP2));
17 #define PUTLINE(x1,y1,x2,y2,BrushInst) \
18 ret = ret && IntEngLineTo(&BitmapObj->SurfObj, \
20 &BrushInst.BrushObject, \
23 ROP2_TO_MIX(Dc_Attr->jROP2));
25 #define Rsin(d) ((d) == 0.0 ? 0.0 : ((d) == 90.0 ? 1.0 : sin(d*M_PI/180.0)))
26 #define Rcos(d) ((d) == 0.0 ? 1.0 : ((d) == 90.0 ? 0.0 : cos(d*M_PI/180.0)))
28 BOOL FASTCALL
IntFillArc( PDC dc
, INT XLeft
, INT YLeft
, INT Width
, INT Height
, double StartArc
, double EndArc
, ARCTYPE arctype
);
46 PGDIBRUSHOBJ PenBrushObj
;
47 GDIBRUSHINST PenBrushInst
;
50 LONG PenWidth
, PenOrigWidth
;
51 double AngleStart
, AngleEnd
;
52 LONG RadiusX
, RadiusY
, CenterX
, CenterY
;
53 LONG SfCx
, SfCy
, EfCx
, EfCy
;
63 0|___________________|
68 INT tmp
= Right
; Right
= Left
; Left
= tmp
;
72 INT tmp
= Bottom
; Bottom
= Top
; Top
= tmp
;
74 if ((Left
== Right
) ||
76 (((arctype
!= GdiTypeArc
) || (arctype
!= GdiTypeArcTo
)) &&
77 ((Right
- Left
== 1) ||
78 (Bottom
- Top
== 1))))
81 if (dc
->DcLevel
.flPath
& DCPATH_CLOCKWISE
)
86 XRadialStart
= XRadialEnd
;
87 YRadialStart
= YRadialEnd
;
92 Dc_Attr
= dc
->pDc_Attr
;
93 if(!Dc_Attr
) Dc_Attr
= &dc
->Dc_Attr
;
95 PenBrushObj
= PENOBJ_LockPen(Dc_Attr
->hpen
);
96 if (NULL
== PenBrushObj
)
98 DPRINT1("Arc Fail 1\n");
99 SetLastWin32Error(ERROR_INTERNAL_ERROR
);
103 PenOrigWidth
= PenWidth
= PenBrushObj
->ptPenWidth
.x
;
104 if (PenBrushObj
->ulPenStyle
== PS_NULL
) PenWidth
= 0;
106 if (PenBrushObj
->ulPenStyle
== PS_INSIDEFRAME
)
108 if (2*PenWidth
> (Right
- Left
)) PenWidth
= (Right
-Left
+ 1)/2;
109 if (2*PenWidth
> (Bottom
- Top
)) PenWidth
= (Bottom
-Top
+ 1)/2;
110 Left
+= PenWidth
/ 2;
111 Right
-= (PenWidth
- 1) / 2;
113 Bottom
-= (PenWidth
- 1) / 2;
116 if (!PenWidth
) PenWidth
= 1;
117 PenBrushObj
->ptPenWidth
.x
= PenWidth
;
119 Left
+= dc
->ptlDCOrig
.x
;
120 Right
+= dc
->ptlDCOrig
.x
;
121 Top
+= dc
->ptlDCOrig
.y
;
122 Bottom
+= dc
->ptlDCOrig
.y
;
124 XRadialStart
+= dc
->ptlDCOrig
.x
;
125 YRadialStart
+= dc
->ptlDCOrig
.y
;
126 XRadialEnd
+= dc
->ptlDCOrig
.x
;
127 YRadialEnd
+= dc
->ptlDCOrig
.y
;
129 DPRINT1("1: StartX: %d, StartY: %d, EndX: %d, EndY: %d\n",
130 XRadialStart
,YRadialStart
,XRadialEnd
,YRadialEnd
);
132 RectBounds
.left
= Left
;
133 RectBounds
.right
= Right
;
134 RectBounds
.top
= Top
;
135 RectBounds
.bottom
= Bottom
;
137 IntLPtoDP(dc
, (LPPOINT
)&RectBounds
, 2);
139 DPRINT1("1: Left: %d, Top: %d, Right: %d, Bottom: %d\n",
140 RectBounds
.left
,RectBounds
.top
,RectBounds
.right
,RectBounds
.bottom
);
142 RadiusX
= max((RectBounds
.right
- RectBounds
.left
) / 2, 1);
143 RadiusY
= max((RectBounds
.bottom
- RectBounds
.top
) / 2, 1);
144 CenterX
= (RectBounds
.right
+ RectBounds
.left
) / 2;
145 CenterY
= (RectBounds
.bottom
+ RectBounds
.top
) / 2;
146 AngleEnd
= atan2((YRadialEnd
- CenterY
), XRadialEnd
- CenterX
)*(360.0/(M_PI
*2));
147 AngleStart
= atan2((YRadialStart
- CenterY
), XRadialStart
- CenterX
)*(360.0/(M_PI
*2));
149 SfCx
= (Rcos(AngleStart
) * RadiusX
);
150 SfCy
= (Rsin(AngleStart
) * RadiusY
);
151 EfCx
= (Rcos(AngleEnd
) * RadiusX
);
152 EfCy
= (Rsin(AngleEnd
) * RadiusY
);
154 if ((arctype
== GdiTypePie
) || (arctype
== GdiTypeChord
))
156 ret
= IntFillArc( dc
,
159 abs(RectBounds
.right
-RectBounds
.left
), // Width
160 abs(RectBounds
.bottom
-RectBounds
.top
), // Height
166 BitmapObj
= BITMAPOBJ_LockBitmap(dc
->w
.hBitmap
);
167 if (NULL
== BitmapObj
)
169 DPRINT1("Arc Fail 2\n");
170 PENOBJ_UnlockPen(PenBrushObj
);
171 SetLastWin32Error(ERROR_INTERNAL_ERROR
);
175 IntGdiInitBrushInstance(&PenBrushInst
, PenBrushObj
, dc
->XlatePen
);
177 if (arctype
== GdiTypePie
)
179 PUTLINE(CenterX
, CenterY
, SfCx
+ CenterX
, SfCy
+ CenterY
, PenBrushInst
);
182 double AngS
= AngleStart
, AngT
= AngleEnd
,
183 Factor
= fabs(RadiusX
) < 25 ? 1.0 : (25/fabs(RadiusX
));
184 int x
,y
, ox
= 0, oy
= 0;
187 if (dc
->DcLevel
.flPath
& DCPATH_CLOCKWISE
)
190 for (; AngS
< AngT
; AngS
+= Factor
)
192 x
= (RadiusX
* Rcos(AngS
));
193 y
= (RadiusY
* Rsin(AngS
));
195 DPRINT("Arc CW -> %d, X: %d Y: %d\n",(INT
)AngS
,x
,y
);
198 PUTPIXEL(x
+ CenterX
, y
+ CenterY
, PenBrushInst
);
204 PUTLINE(ox
+ CenterX
, oy
+ CenterY
, x
+ CenterX
, y
+ CenterY
, PenBrushInst
);
211 DPRINT1("Arc CCW\n");
212 for (; AngT
< AngS
; AngS
-= Factor
)
214 x
= (RadiusX
* Rcos(AngS
));
215 y
= (RadiusY
* Rsin(AngS
));
217 DPRINT("Arc CCW -> %d, X: %d Y: %d\n",(INT
)AngS
,x
,y
);
220 PUTPIXEL(x
+ CenterX
, y
+ CenterY
, PenBrushInst
);
226 PUTLINE(ox
+ CenterX
, oy
+ CenterY
, x
+ CenterX
, y
+ CenterY
, PenBrushInst
);
232 if (arctype
== GdiTypePie
)
233 PUTLINE(EfCx
+ CenterX
, EfCy
+ CenterY
, CenterX
, CenterY
, PenBrushInst
);
234 if (arctype
== GdiTypeChord
)
235 PUTLINE(EfCx
+ CenterX
, EfCy
+ CenterY
, SfCx
+ CenterX
, SfCy
+ CenterY
, PenBrushInst
);
237 PenBrushObj
->ptPenWidth
.x
= PenOrigWidth
;
238 BITMAPOBJ_UnlockBitmap(BitmapObj
);
239 PENOBJ_UnlockPen(PenBrushObj
);
240 DPRINT1("IntArc Exit.\n");
261 DPRINT1("StartX: %d, StartY: %d, EndX: %d, EndY: %d\n",
262 XStartArc
,YStartArc
,XEndArc
,YEndArc
);
263 DPRINT1("Left: %d, Top: %d, Right: %d, Bottom: %d\n",
264 LeftRect
,TopRect
,RightRect
,BottomRect
);
266 if (PATH_IsPathOpen(dc
->DcLevel
))
280 if (arctype
== GdiTypeArcTo
)
282 if (dc
->DcLevel
.flPath
& DCPATH_CLOCKWISE
)
283 IntGdiLineTo(dc
, XEndArc
, YEndArc
);
285 IntGdiLineTo(dc
, XStartArc
, YStartArc
);
288 IntGdiSetRect(&rc
, LeftRect
, TopRect
, RightRect
, BottomRect
);
289 IntGdiSetRect(&rc1
, XStartArc
, YStartArc
, XEndArc
, YEndArc
);
291 // IntLPtoDP(dc, (LPPOINT)&rc, 2);
292 // IntLPtoDP(dc, (LPPOINT)&rc1, 2);
306 if (arctype
== GdiTypeArcTo
)
308 if (dc
->DcLevel
.flPath
& DCPATH_CLOCKWISE
)
309 IntGdiMoveToEx(dc
, XStartArc
, YStartArc
, NULL
);
311 IntGdiMoveToEx(dc
, XEndArc
, YEndArc
, NULL
);
318 IntGdiAngleArc( PDC pDC
,
325 INT x1
, y1
, x2
, y2
, arcdir
;
328 /* Calculate the end point */
329 x2
= x
+ (INT
)(cos(((eStartAngle
+eSweepAngle
)/360)*(M_PI
*2)) * dwRadius
);
330 y2
= y
- (INT
)(sin(((eStartAngle
+eSweepAngle
)/360)*(M_PI
*2)) * dwRadius
);
332 x1
= x
+ (INT
)(cos((eStartAngle
/360)*(M_PI
*2)) * dwRadius
);
333 y1
= y
- (INT
)(sin((eStartAngle
/360)*(M_PI
*2)) * dwRadius
);
335 arcdir
= pDC
->DcLevel
.flPath
& DCPATH_CLOCKWISE
;
336 if (eSweepAngle
>= 0)
337 pDC
->DcLevel
.flPath
&= ~DCPATH_CLOCKWISE
;
339 pDC
->DcLevel
.flPath
|= DCPATH_CLOCKWISE
;
341 result
= IntGdiArcInternal( GdiTypeArcTo
,
352 pDC
->DcLevel
.flPath
|= (arcdir
& DCPATH_CLOCKWISE
);
356 IntGdiMoveToEx(pDC
, x2
, y2
, NULL
); // Dont forget Path.
361 /* FUNCTIONS *****************************************************************/
370 IN DWORD dwStartAngle
,
371 IN DWORD dwSweepAngle
)
375 gxf_long worker
, worker1
;
377 pDC
= DC_LockDc (hDC
);
380 SetLastWin32Error(ERROR_INVALID_HANDLE
);
383 if (pDC
->DC_Type
== DC_TYPE_INFO
)
386 /* Yes, Windows really returns TRUE in this case */
389 worker
.l
= dwStartAngle
;
390 worker1
.l
= dwSweepAngle
;
391 Ret
= IntGdiAngleArc( pDC
, x
, y
, dwRadius
, worker
.f
, worker1
.f
);
413 dc
= DC_LockDc (hDC
);
416 SetLastWin32Error(ERROR_INVALID_HANDLE
);
419 if (dc
->DC_Type
== DC_TYPE_INFO
)
422 /* Yes, Windows really returns TRUE in this case */
426 Ret
= IntGdiArcInternal(