7 * A couple of macros to fill a single pixel or a line
9 #define PUTPIXEL(x,y,BrushInst) \
10 ret = ret && IntEngLineTo(&psurf->SurfObj, \
12 &BrushInst.BrushObject, \
15 ROP2_TO_MIX(pdcattr->jROP2));
17 #define PUTLINE(x1,y1,x2,y2,BrushInst) \
18 ret = ret && IntEngLineTo(&psurf->SurfObj, \
20 &BrushInst.BrushObject, \
23 ROP2_TO_MIX(pdcattr->jROP2));
40 RECTL RectBounds
, RectSEpts
;
44 LONG PenWidth
, PenOrigWidth
;
45 double AngleStart
, AngleEnd
;
46 LONG CenterX
, CenterY
;
50 INT tmp
= Right
; Right
= Left
; Left
= tmp
;
54 INT tmp
= Bottom
; Bottom
= Top
; Top
= tmp
;
57 /* Check if the target rect is empty */
58 if ((Left
== Right
) || (Top
== Bottom
)) return TRUE
;
60 // FIXME: this needs to be verified
61 if ((arctype
== GdiTypeChord
) || (arctype
== GdiTypePie
))
63 if ((Right
- Left
== 1) || (Bottom
- Top
== 1))
68 pdcattr
= dc
->pdcattr
;
70 pbrPen
= PEN_ShareLockPen(pdcattr
->hpen
);
73 DPRINT1("Arc Fail 1\n");
74 EngSetLastError(ERROR_INTERNAL_ERROR
);
78 PenOrigWidth
= PenWidth
= pbrPen
->lWidth
;
79 if (pbrPen
->ulPenStyle
== PS_NULL
) PenWidth
= 0;
81 if (pbrPen
->ulPenStyle
== PS_INSIDEFRAME
)
83 if (2*PenWidth
> (Right
- Left
)) PenWidth
= (Right
-Left
+ 1)/2;
84 if (2*PenWidth
> (Bottom
- Top
)) PenWidth
= (Bottom
-Top
+ 1)/2;
86 Right
-= (PenWidth
- 1) / 2;
88 Bottom
-= (PenWidth
- 1) / 2;
91 if (!PenWidth
) PenWidth
= 1;
92 pbrPen
->lWidth
= PenWidth
;
94 RectBounds
.left
= Left
;
95 RectBounds
.right
= Right
;
97 RectBounds
.bottom
= Bottom
;
99 RectSEpts
.left
= XRadialStart
;
100 RectSEpts
.top
= YRadialStart
;
101 RectSEpts
.right
= XRadialEnd
;
102 RectSEpts
.bottom
= YRadialEnd
;
104 IntLPtoDP(dc
, (LPPOINT
)&RectBounds
, 2);
105 IntLPtoDP(dc
, (LPPOINT
)&RectSEpts
, 2);
107 RectBounds
.left
+= dc
->ptlDCOrig
.x
;
108 RectBounds
.right
+= dc
->ptlDCOrig
.x
;
109 RectBounds
.top
+= dc
->ptlDCOrig
.y
;
110 RectBounds
.bottom
+= dc
->ptlDCOrig
.y
;
112 RectSEpts
.left
+= dc
->ptlDCOrig
.x
;
113 RectSEpts
.top
+= dc
->ptlDCOrig
.y
;
114 RectSEpts
.right
+= dc
->ptlDCOrig
.x
;
115 RectSEpts
.bottom
+= dc
->ptlDCOrig
.y
;
117 DPRINT("1: StartX: %d, StartY: %d, EndX: %d, EndY: %d\n",
118 RectSEpts
.left
,RectSEpts
.top
,RectSEpts
.right
,RectSEpts
.bottom
);
120 DPRINT("1: Left: %d, Top: %d, Right: %d, Bottom: %d\n",
121 RectBounds
.left
,RectBounds
.top
,RectBounds
.right
,RectBounds
.bottom
);
123 CenterX
= (RectBounds
.right
+ RectBounds
.left
) / 2;
124 CenterY
= (RectBounds
.bottom
+ RectBounds
.top
) / 2;
125 AngleEnd
= atan2((RectSEpts
.bottom
- CenterY
), RectSEpts
.right
- CenterX
)*(360.0/(M_PI
*2));
126 AngleStart
= atan2((RectSEpts
.top
- CenterY
), RectSEpts
.left
- CenterX
)*(360.0/(M_PI
*2));
128 /* Edge Case: Check if the start segments overlaps(is equal) the end segment */
129 if (AngleEnd
== AngleStart
)
131 AngleStart
= AngleEnd
+ 360.0; // Arc(), ArcTo(), Pie() and Chord() are counterclockwise APIs.
134 if ((arctype
== GdiTypePie
) || (arctype
== GdiTypeChord
))
136 ret
= IntFillArc( dc
,
139 abs(RectBounds
.right
-RectBounds
.left
), // Width
140 abs(RectBounds
.bottom
-RectBounds
.top
), // Height
146 ret
= IntDrawArc( dc
,
149 abs(RectBounds
.right
-RectBounds
.left
), // Width
150 abs(RectBounds
.bottom
-RectBounds
.top
), // Height
156 psurf
= dc
->dclevel
.pSurface
;
159 DPRINT1("Arc Fail 2\n");
160 PEN_ShareUnlockPen(pbrPen
);
161 EngSetLastError(ERROR_INTERNAL_ERROR
);
165 if (arctype
== GdiTypePie
)
167 PUTLINE(CenterX
, CenterY
, RectSEpts
.left
, RectSEpts
.top
, dc
->eboLine
);
168 PUTLINE(RectSEpts
.right
, RectSEpts
.bottom
, CenterX
, CenterY
, dc
->eboLine
);
170 if (arctype
== GdiTypeChord
)
171 PUTLINE(RectSEpts
.right
, RectSEpts
.bottom
, RectSEpts
.left
, RectSEpts
.top
, dc
->eboLine
);
173 pbrPen
->lWidth
= PenOrigWidth
;
174 PEN_ShareUnlockPen(pbrPen
);
175 DPRINT("IntArc Exit.\n");
196 DPRINT("StartX: %d, StartY: %d, EndX: %d, EndY: %d\n",
197 XStartArc
,YStartArc
,XEndArc
,YEndArc
);
198 DPRINT("Left: %d, Top: %d, Right: %d, Bottom: %d\n",
199 LeftRect
,TopRect
,RightRect
,BottomRect
);
201 if ((LeftRect
== RightRect
) || (TopRect
== BottomRect
)) return TRUE
;
203 if (PATH_IsPathOpen(dc
->dclevel
))
217 //pdcattr = dc->pdcattr;
219 if (arctype
== GdiTypeArcTo
)
221 if (dc
->dclevel
.flPath
& DCPATH_CLOCKWISE
)
222 IntGdiLineTo(dc
, XEndArc
, YEndArc
);
224 IntGdiLineTo(dc
, XStartArc
, YStartArc
);
238 if (arctype
== GdiTypeArcTo
)
240 if (dc
->dclevel
.flPath
& DCPATH_CLOCKWISE
)
241 IntGdiMoveToEx(dc
, XStartArc
, YStartArc
, NULL
, TRUE
);
243 IntGdiMoveToEx(dc
, XEndArc
, YEndArc
, NULL
, TRUE
);
250 IntGdiAngleArc( PDC pDC
,
257 INT x1
, y1
, x2
, y2
, arcdir
;
260 /* Calculate the end point */
261 x2
= x
+ (INT
)(cos(((eStartAngle
+eSweepAngle
)/360)*(M_PI
*2)) * dwRadius
);
262 y2
= y
- (INT
)(sin(((eStartAngle
+eSweepAngle
)/360)*(M_PI
*2)) * dwRadius
);
264 x1
= x
+ (INT
)(cos((eStartAngle
/360)*(M_PI
*2)) * dwRadius
);
265 y1
= y
- (INT
)(sin((eStartAngle
/360)*(M_PI
*2)) * dwRadius
);
267 arcdir
= pDC
->dclevel
.flPath
& DCPATH_CLOCKWISE
;
268 if (eSweepAngle
>= 0)
269 pDC
->dclevel
.flPath
&= ~DCPATH_CLOCKWISE
;
271 pDC
->dclevel
.flPath
|= DCPATH_CLOCKWISE
;
273 result
= IntGdiArcInternal( GdiTypeArcTo
,
284 pDC
->dclevel
.flPath
|= (arcdir
& DCPATH_CLOCKWISE
);
288 IntGdiMoveToEx(pDC
, x2
, y2
, NULL
, TRUE
);
293 /* FUNCTIONS *****************************************************************/
302 IN DWORD dwStartAngle
,
303 IN DWORD dwSweepAngle
)
307 gxf_long worker
, worker1
;
308 KFLOATING_SAVE FloatSave
;
311 pDC
= DC_LockDc (hDC
);
314 EngSetLastError(ERROR_INVALID_HANDLE
);
317 if (pDC
->dctype
== DC_TYPE_INFO
)
320 /* Yes, Windows really returns TRUE in this case */
324 status
= KeSaveFloatingPointState(&FloatSave
);
325 if (!NT_SUCCESS(status
))
331 worker
.l
= dwStartAngle
;
332 worker1
.l
= dwSweepAngle
;
333 DC_vPrepareDCsForBlit(pDC
, NULL
, NULL
, NULL
);
334 if (pDC
->pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
335 DC_vUpdateFillBrush(pDC
);
336 if (pDC
->pdcattr
->ulDirty_
& (DIRTY_LINE
| DC_PEN_DIRTY
))
337 DC_vUpdateLineBrush(pDC
);
338 Ret
= IntGdiAngleArc( pDC
, x
, y
, dwRadius
, worker
.f
, worker1
.f
);
339 DC_vFinishBlit(pDC
, NULL
);
342 KeRestoreFloatingPointState(&FloatSave
);
363 KFLOATING_SAVE FloatSave
;
366 dc
= DC_LockDc (hDC
);
369 EngSetLastError(ERROR_INVALID_HANDLE
);
372 if (dc
->dctype
== DC_TYPE_INFO
)
375 /* Yes, Windows really returns TRUE in this case */
379 DC_vPrepareDCsForBlit(dc
, NULL
, NULL
, NULL
);
381 if (dc
->pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
382 DC_vUpdateFillBrush(dc
);
384 if (dc
->pdcattr
->ulDirty_
& (DIRTY_LINE
| DC_PEN_DIRTY
))
385 DC_vUpdateLineBrush(dc
);
387 status
= KeSaveFloatingPointState(&FloatSave
);
388 if (!NT_SUCCESS(status
))
394 Ret
= IntGdiArcInternal(
406 KeRestoreFloatingPointState(&FloatSave
);
407 DC_vFinishBlit(dc
, NULL
);