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
);
29 BOOL FASTCALL
IntDrawArc( PDC dc
, INT XLeft
, INT YLeft
, INT Width
, INT Height
, double StartArc
, double EndArc
, ARCTYPE arctype
, PGDIBRUSHOBJ PenBrushObj
);
46 RECTL RectBounds
, RectSEpts
;
47 PGDIBRUSHOBJ PenBrushObj
;
48 GDIBRUSHINST PenBrushInst
;
51 LONG PenWidth
, PenOrigWidth
;
52 double AngleStart
, AngleEnd
;
53 LONG RadiusX
, RadiusY
, CenterX
, CenterY
;
54 LONG SfCx
, SfCy
, EfCx
, EfCy
;
58 INT tmp
= Right
; Right
= Left
; Left
= tmp
;
62 INT tmp
= Bottom
; Bottom
= Top
; Top
= tmp
;
64 if ((Left
== Right
) ||
66 (((arctype
!= GdiTypeArc
) || (arctype
!= GdiTypeArcTo
)) &&
67 ((Right
- Left
== 1) ||
68 (Bottom
- Top
== 1))))
71 Dc_Attr
= dc
->pDc_Attr
;
72 if(!Dc_Attr
) Dc_Attr
= &dc
->Dc_Attr
;
74 PenBrushObj
= PENOBJ_LockPen(Dc_Attr
->hpen
);
75 if (NULL
== PenBrushObj
)
77 DPRINT1("Arc Fail 1\n");
78 SetLastWin32Error(ERROR_INTERNAL_ERROR
);
82 PenOrigWidth
= PenWidth
= PenBrushObj
->ptPenWidth
.x
;
83 if (PenBrushObj
->ulPenStyle
== PS_NULL
) PenWidth
= 0;
85 if (PenBrushObj
->ulPenStyle
== PS_INSIDEFRAME
)
87 if (2*PenWidth
> (Right
- Left
)) PenWidth
= (Right
-Left
+ 1)/2;
88 if (2*PenWidth
> (Bottom
- Top
)) PenWidth
= (Bottom
-Top
+ 1)/2;
90 Right
-= (PenWidth
- 1) / 2;
92 Bottom
-= (PenWidth
- 1) / 2;
95 if (!PenWidth
) PenWidth
= 1;
96 PenBrushObj
->ptPenWidth
.x
= PenWidth
;
98 RectBounds
.left
= Left
;
99 RectBounds
.right
= Right
;
100 RectBounds
.top
= Top
;
101 RectBounds
.bottom
= Bottom
;
103 RectSEpts
.left
= XRadialStart
;
104 RectSEpts
.top
= YRadialStart
;
105 RectSEpts
.right
= XRadialEnd
;
106 RectSEpts
.bottom
= YRadialEnd
;
108 IntLPtoDP(dc
, (LPPOINT
)&RectBounds
, 2);
109 IntLPtoDP(dc
, (LPPOINT
)&RectSEpts
, 2);
111 RectBounds
.left
+= dc
->ptlDCOrig
.x
;
112 RectBounds
.right
+= dc
->ptlDCOrig
.x
;
113 RectBounds
.top
+= dc
->ptlDCOrig
.y
;
114 RectBounds
.bottom
+= dc
->ptlDCOrig
.y
;
116 RectSEpts
.left
+= dc
->ptlDCOrig
.x
;
117 RectSEpts
.top
+= dc
->ptlDCOrig
.y
;
118 RectSEpts
.right
+= dc
->ptlDCOrig
.x
;
119 RectSEpts
.bottom
+= dc
->ptlDCOrig
.y
;
121 DPRINT("1: StartX: %d, StartY: %d, EndX: %d, EndY: %d\n",
122 RectSEpts
.left
,RectSEpts
.top
,RectSEpts
.right
,RectSEpts
.bottom
);
124 DPRINT("1: Left: %d, Top: %d, Right: %d, Bottom: %d\n",
125 RectBounds
.left
,RectBounds
.top
,RectBounds
.right
,RectBounds
.bottom
);
127 RadiusX
= max((RectBounds
.right
- RectBounds
.left
) / 2, 1);
128 RadiusY
= max((RectBounds
.bottom
- RectBounds
.top
) / 2, 1);
129 CenterX
= (RectBounds
.right
+ RectBounds
.left
) / 2;
130 CenterY
= (RectBounds
.bottom
+ RectBounds
.top
) / 2;
131 AngleEnd
= atan2((RectSEpts
.bottom
- CenterY
), RectSEpts
.right
- CenterX
)*(360.0/(M_PI
*2));
132 AngleStart
= atan2((RectSEpts
.top
- CenterY
), RectSEpts
.left
- CenterX
)*(360.0/(M_PI
*2));
134 SfCx
= (Rcos(AngleStart
) * RadiusX
);
135 SfCy
= (Rsin(AngleStart
) * RadiusY
);
136 EfCx
= (Rcos(AngleEnd
) * RadiusX
);
137 EfCy
= (Rsin(AngleEnd
) * RadiusY
);
139 if ((arctype
== GdiTypePie
) || (arctype
== GdiTypeChord
))
141 ret
= IntFillArc( dc
,
144 abs(RectBounds
.right
-RectBounds
.left
), // Width
145 abs(RectBounds
.bottom
-RectBounds
.top
), // Height
151 ret
= IntDrawArc( dc
,
154 abs(RectBounds
.right
-RectBounds
.left
), // Width
155 abs(RectBounds
.bottom
-RectBounds
.top
), // Height
161 BitmapObj
= BITMAPOBJ_LockBitmap(dc
->w
.hBitmap
);
162 if (NULL
== BitmapObj
)
164 DPRINT1("Arc Fail 2\n");
165 PENOBJ_UnlockPen(PenBrushObj
);
166 SetLastWin32Error(ERROR_INTERNAL_ERROR
);
170 IntGdiInitBrushInstance(&PenBrushInst
, PenBrushObj
, dc
->XlatePen
);
172 if (arctype
== GdiTypePie
)
174 PUTLINE(CenterX
, CenterY
, SfCx
+ CenterX
, SfCy
+ CenterY
, PenBrushInst
);
175 PUTLINE(EfCx
+ CenterX
, EfCy
+ CenterY
, CenterX
, CenterY
, PenBrushInst
);
177 if (arctype
== GdiTypeChord
)
178 PUTLINE(EfCx
+ CenterX
, EfCy
+ CenterY
, SfCx
+ CenterX
, SfCy
+ CenterY
, PenBrushInst
);
180 PenBrushObj
->ptPenWidth
.x
= PenOrigWidth
;
181 BITMAPOBJ_UnlockBitmap(BitmapObj
);
182 PENOBJ_UnlockPen(PenBrushObj
);
183 DPRINT("IntArc Exit.\n");
204 DPRINT("StartX: %d, StartY: %d, EndX: %d, EndY: %d\n",
205 XStartArc
,YStartArc
,XEndArc
,YEndArc
);
206 DPRINT("Left: %d, Top: %d, Right: %d, Bottom: %d\n",
207 LeftRect
,TopRect
,RightRect
,BottomRect
);
209 if ((LeftRect
== RightRect
) || (TopRect
== BottomRect
)) return TRUE
;
211 if (PATH_IsPathOpen(dc
->DcLevel
))
225 pDc_Attr
= dc
->pDc_Attr
;
226 if (!pDc_Attr
) pDc_Attr
= &dc
->Dc_Attr
;
228 if (pDc_Attr
->ulDirty_
& DC_BRUSH_DIRTY
)
229 IntGdiSelectBrush(dc
,pDc_Attr
->hbrush
);
231 if (pDc_Attr
->ulDirty_
& DC_PEN_DIRTY
)
232 IntGdiSelectPen(dc
,pDc_Attr
->hpen
);
234 if (arctype
== GdiTypeArcTo
)
236 if (dc
->DcLevel
.flPath
& DCPATH_CLOCKWISE
)
237 IntGdiLineTo(dc
, XEndArc
, YEndArc
);
239 IntGdiLineTo(dc
, XStartArc
, YStartArc
);
253 if (arctype
== GdiTypeArcTo
)
255 if (dc
->DcLevel
.flPath
& DCPATH_CLOCKWISE
)
256 IntGdiMoveToEx(dc
, XStartArc
, YStartArc
, NULL
);
258 IntGdiMoveToEx(dc
, XEndArc
, YEndArc
, NULL
);
265 IntGdiAngleArc( PDC pDC
,
272 INT x1
, y1
, x2
, y2
, arcdir
;
275 /* Calculate the end point */
276 x2
= x
+ (INT
)(cos(((eStartAngle
+eSweepAngle
)/360)*(M_PI
*2)) * dwRadius
);
277 y2
= y
- (INT
)(sin(((eStartAngle
+eSweepAngle
)/360)*(M_PI
*2)) * dwRadius
);
279 x1
= x
+ (INT
)(cos((eStartAngle
/360)*(M_PI
*2)) * dwRadius
);
280 y1
= y
- (INT
)(sin((eStartAngle
/360)*(M_PI
*2)) * dwRadius
);
282 arcdir
= pDC
->DcLevel
.flPath
& DCPATH_CLOCKWISE
;
283 if (eSweepAngle
>= 0)
284 pDC
->DcLevel
.flPath
&= ~DCPATH_CLOCKWISE
;
286 pDC
->DcLevel
.flPath
|= DCPATH_CLOCKWISE
;
288 result
= IntGdiArcInternal( GdiTypeArcTo
,
299 pDC
->DcLevel
.flPath
|= (arcdir
& DCPATH_CLOCKWISE
);
303 IntGdiMoveToEx(pDC
, x2
, y2
, NULL
); // Dont forget Path.
308 /* FUNCTIONS *****************************************************************/
317 IN DWORD dwStartAngle
,
318 IN DWORD dwSweepAngle
)
322 gxf_long worker
, worker1
;
324 pDC
= DC_LockDc (hDC
);
327 SetLastWin32Error(ERROR_INVALID_HANDLE
);
330 if (pDC
->DC_Type
== DC_TYPE_INFO
)
333 /* Yes, Windows really returns TRUE in this case */
336 worker
.l
= dwStartAngle
;
337 worker1
.l
= dwSweepAngle
;
338 Ret
= IntGdiAngleArc( pDC
, x
, y
, dwRadius
, worker
.f
, worker1
.f
);
360 dc
= DC_LockDc (hDC
);
363 SetLastWin32Error(ERROR_INVALID_HANDLE
);
366 if (dc
->DC_Type
== DC_TYPE_INFO
)
369 /* Yes, Windows really returns TRUE in this case */
373 Ret
= IntGdiArcInternal(