xref: /reactos/win32ss/gdi/ntgdi/arc.c (revision c2c66aff)
1*c2c66affSColin Finck #include <win32k.h>
2*c2c66affSColin Finck 
3*c2c66affSColin Finck #define NDEBUG
4*c2c66affSColin Finck #include <debug.h>
5*c2c66affSColin Finck 
6*c2c66affSColin Finck /*
7*c2c66affSColin Finck  * A couple of macros to fill a single pixel or a line
8*c2c66affSColin Finck  */
9*c2c66affSColin Finck #define PUTPIXEL(x,y,BrushInst)        \
10*c2c66affSColin Finck   ret = ret && IntEngLineTo(&psurf->SurfObj, \
11*c2c66affSColin Finck        (CLIPOBJ *)&dc->co,                       \
12*c2c66affSColin Finck        &BrushInst.BrushObject,                   \
13*c2c66affSColin Finck        x, y, (x)+1, y,                           \
14*c2c66affSColin Finck        &RectBounds,                              \
15*c2c66affSColin Finck        ROP2_TO_MIX(pdcattr->jROP2));
16*c2c66affSColin Finck 
17*c2c66affSColin Finck #define PUTLINE(x1,y1,x2,y2,BrushInst) \
18*c2c66affSColin Finck   ret = ret && IntEngLineTo(&psurf->SurfObj, \
19*c2c66affSColin Finck        (CLIPOBJ *)&dc->co,                       \
20*c2c66affSColin Finck        &BrushInst.BrushObject,                   \
21*c2c66affSColin Finck        x1, y1, x2, y2,                           \
22*c2c66affSColin Finck        &RectBounds,                              \
23*c2c66affSColin Finck        ROP2_TO_MIX(pdcattr->jROP2));
24*c2c66affSColin Finck 
25*c2c66affSColin Finck static
26*c2c66affSColin Finck BOOL
27*c2c66affSColin Finck FASTCALL
IntArc(DC * dc,int Left,int Top,int Right,int Bottom,int XRadialStart,int YRadialStart,int XRadialEnd,int YRadialEnd,ARCTYPE arctype)28*c2c66affSColin Finck IntArc( DC *dc,
29*c2c66affSColin Finck         int  Left,
30*c2c66affSColin Finck         int  Top,
31*c2c66affSColin Finck         int  Right,
32*c2c66affSColin Finck         int  Bottom,
33*c2c66affSColin Finck         int  XRadialStart,
34*c2c66affSColin Finck         int  YRadialStart,
35*c2c66affSColin Finck         int  XRadialEnd,
36*c2c66affSColin Finck         int  YRadialEnd,
37*c2c66affSColin Finck         ARCTYPE arctype)
38*c2c66affSColin Finck {
39*c2c66affSColin Finck     PDC_ATTR pdcattr;
40*c2c66affSColin Finck     RECTL RectBounds, RectSEpts;
41*c2c66affSColin Finck     PBRUSH pbrPen;
42*c2c66affSColin Finck     SURFACE *psurf;
43*c2c66affSColin Finck     BOOL ret = TRUE;
44*c2c66affSColin Finck     LONG PenWidth, PenOrigWidth;
45*c2c66affSColin Finck     double AngleStart, AngleEnd;
46*c2c66affSColin Finck     LONG CenterX, CenterY;
47*c2c66affSColin Finck 
48*c2c66affSColin Finck     if (Right < Left)
49*c2c66affSColin Finck     {
50*c2c66affSColin Finck        INT tmp = Right; Right = Left; Left = tmp;
51*c2c66affSColin Finck     }
52*c2c66affSColin Finck     if (Bottom < Top)
53*c2c66affSColin Finck     {
54*c2c66affSColin Finck        INT tmp = Bottom; Bottom = Top; Top = tmp;
55*c2c66affSColin Finck     }
56*c2c66affSColin Finck 
57*c2c66affSColin Finck     /* Check if the target rect is empty */
58*c2c66affSColin Finck     if ((Left == Right) || (Top == Bottom)) return TRUE;
59*c2c66affSColin Finck 
60*c2c66affSColin Finck     // FIXME: this needs to be verified
61*c2c66affSColin Finck     if ((arctype == GdiTypeChord ) || (arctype == GdiTypePie))
62*c2c66affSColin Finck     {
63*c2c66affSColin Finck         if ((Right - Left == 1) || (Bottom - Top == 1))
64*c2c66affSColin Finck            return TRUE;
65*c2c66affSColin Finck     }
66*c2c66affSColin Finck 
67*c2c66affSColin Finck 
68*c2c66affSColin Finck     pdcattr = dc->pdcattr;
69*c2c66affSColin Finck 
70*c2c66affSColin Finck     pbrPen = PEN_ShareLockPen(pdcattr->hpen);
71*c2c66affSColin Finck     if (!pbrPen)
72*c2c66affSColin Finck     {
73*c2c66affSColin Finck         DPRINT1("Arc Fail 1\n");
74*c2c66affSColin Finck         EngSetLastError(ERROR_INTERNAL_ERROR);
75*c2c66affSColin Finck         return FALSE;
76*c2c66affSColin Finck     }
77*c2c66affSColin Finck 
78*c2c66affSColin Finck     PenOrigWidth = PenWidth = pbrPen->lWidth;
79*c2c66affSColin Finck     if (pbrPen->ulPenStyle == PS_NULL) PenWidth = 0;
80*c2c66affSColin Finck 
81*c2c66affSColin Finck     if (pbrPen->ulPenStyle == PS_INSIDEFRAME)
82*c2c66affSColin Finck     {
83*c2c66affSColin Finck        if (2*PenWidth > (Right - Left)) PenWidth = (Right -Left + 1)/2;
84*c2c66affSColin Finck        if (2*PenWidth > (Bottom - Top)) PenWidth = (Bottom -Top + 1)/2;
85*c2c66affSColin Finck        Left   += PenWidth / 2;
86*c2c66affSColin Finck        Right  -= (PenWidth - 1) / 2;
87*c2c66affSColin Finck        Top    += PenWidth / 2;
88*c2c66affSColin Finck        Bottom -= (PenWidth - 1) / 2;
89*c2c66affSColin Finck     }
90*c2c66affSColin Finck 
91*c2c66affSColin Finck     if (!PenWidth) PenWidth = 1;
92*c2c66affSColin Finck     pbrPen->lWidth = PenWidth;
93*c2c66affSColin Finck 
94*c2c66affSColin Finck     RectBounds.left   = Left;
95*c2c66affSColin Finck     RectBounds.right  = Right;
96*c2c66affSColin Finck     RectBounds.top    = Top;
97*c2c66affSColin Finck     RectBounds.bottom = Bottom;
98*c2c66affSColin Finck 
99*c2c66affSColin Finck     RectSEpts.left   = XRadialStart;
100*c2c66affSColin Finck     RectSEpts.top    = YRadialStart;
101*c2c66affSColin Finck     RectSEpts.right  = XRadialEnd;
102*c2c66affSColin Finck     RectSEpts.bottom = YRadialEnd;
103*c2c66affSColin Finck 
104*c2c66affSColin Finck     IntLPtoDP(dc, (LPPOINT)&RectBounds, 2);
105*c2c66affSColin Finck     IntLPtoDP(dc, (LPPOINT)&RectSEpts, 2);
106*c2c66affSColin Finck 
107*c2c66affSColin Finck     RectBounds.left   += dc->ptlDCOrig.x;
108*c2c66affSColin Finck     RectBounds.right  += dc->ptlDCOrig.x;
109*c2c66affSColin Finck     RectBounds.top    += dc->ptlDCOrig.y;
110*c2c66affSColin Finck     RectBounds.bottom += dc->ptlDCOrig.y;
111*c2c66affSColin Finck 
112*c2c66affSColin Finck     RectSEpts.left    += dc->ptlDCOrig.x;
113*c2c66affSColin Finck     RectSEpts.top     += dc->ptlDCOrig.y;
114*c2c66affSColin Finck     RectSEpts.right   += dc->ptlDCOrig.x;
115*c2c66affSColin Finck     RectSEpts.bottom  += dc->ptlDCOrig.y;
116*c2c66affSColin Finck 
117*c2c66affSColin Finck     DPRINT("1: StartX: %d, StartY: %d, EndX: %d, EndY: %d\n",
118*c2c66affSColin Finck                RectSEpts.left,RectSEpts.top,RectSEpts.right,RectSEpts.bottom);
119*c2c66affSColin Finck 
120*c2c66affSColin Finck     DPRINT("1: Left: %d, Top: %d, Right: %d, Bottom: %d\n",
121*c2c66affSColin Finck                RectBounds.left,RectBounds.top,RectBounds.right,RectBounds.bottom);
122*c2c66affSColin Finck 
123*c2c66affSColin Finck     CenterX = (RectBounds.right + RectBounds.left) / 2;
124*c2c66affSColin Finck     CenterY = (RectBounds.bottom + RectBounds.top) / 2;
125*c2c66affSColin Finck     AngleEnd   = atan2((RectSEpts.bottom - CenterY), RectSEpts.right - CenterX)*(360.0/(M_PI*2));
126*c2c66affSColin Finck     AngleStart = atan2((RectSEpts.top - CenterY), RectSEpts.left - CenterX)*(360.0/(M_PI*2));
127*c2c66affSColin Finck 
128*c2c66affSColin Finck     /* Edge Case: Check if the start segments overlaps(is equal) the end segment */
129*c2c66affSColin Finck     if (AngleEnd == AngleStart)
130*c2c66affSColin Finck     {
131*c2c66affSColin Finck         AngleStart = AngleEnd + 360.0; // Arc(), ArcTo(), Pie() and Chord() are counterclockwise APIs.
132*c2c66affSColin Finck     }
133*c2c66affSColin Finck 
134*c2c66affSColin Finck     if ((arctype == GdiTypePie) || (arctype == GdiTypeChord))
135*c2c66affSColin Finck     {
136*c2c66affSColin Finck         ret = IntFillArc( dc,
137*c2c66affSColin Finck               RectBounds.left,
138*c2c66affSColin Finck               RectBounds.top,
139*c2c66affSColin Finck               abs(RectBounds.right-RectBounds.left), // Width
140*c2c66affSColin Finck               abs(RectBounds.bottom-RectBounds.top), // Height
141*c2c66affSColin Finck               AngleStart,
142*c2c66affSColin Finck               AngleEnd,
143*c2c66affSColin Finck               arctype);
144*c2c66affSColin Finck     }
145*c2c66affSColin Finck 
146*c2c66affSColin Finck     if(ret)
147*c2c66affSColin Finck     {
148*c2c66affSColin Finck         ret = IntDrawArc( dc,
149*c2c66affSColin Finck                   RectBounds.left,
150*c2c66affSColin Finck                   RectBounds.top,
151*c2c66affSColin Finck                   abs(RectBounds.right-RectBounds.left), // Width
152*c2c66affSColin Finck                   abs(RectBounds.bottom-RectBounds.top), // Height
153*c2c66affSColin Finck                   AngleStart,
154*c2c66affSColin Finck                   AngleEnd,
155*c2c66affSColin Finck                   arctype,
156*c2c66affSColin Finck                   pbrPen);
157*c2c66affSColin Finck     }
158*c2c66affSColin Finck 
159*c2c66affSColin Finck     psurf = dc->dclevel.pSurface;
160*c2c66affSColin Finck     if (NULL == psurf)
161*c2c66affSColin Finck     {
162*c2c66affSColin Finck         DPRINT1("Arc Fail 2\n");
163*c2c66affSColin Finck         PEN_ShareUnlockPen(pbrPen);
164*c2c66affSColin Finck         EngSetLastError(ERROR_INTERNAL_ERROR);
165*c2c66affSColin Finck         return FALSE;
166*c2c66affSColin Finck     }
167*c2c66affSColin Finck 
168*c2c66affSColin Finck     if (arctype == GdiTypePie)
169*c2c66affSColin Finck     {
170*c2c66affSColin Finck         PUTLINE(CenterX, CenterY, RectSEpts.left, RectSEpts.top, dc->eboLine);
171*c2c66affSColin Finck         PUTLINE(RectSEpts.right, RectSEpts.bottom, CenterX, CenterY, dc->eboLine);
172*c2c66affSColin Finck     }
173*c2c66affSColin Finck     if (arctype == GdiTypeChord)
174*c2c66affSColin Finck         PUTLINE(RectSEpts.right, RectSEpts.bottom, RectSEpts.left, RectSEpts.top, dc->eboLine);
175*c2c66affSColin Finck 
176*c2c66affSColin Finck     pbrPen->lWidth = PenOrigWidth;
177*c2c66affSColin Finck     PEN_ShareUnlockPen(pbrPen);
178*c2c66affSColin Finck     DPRINT("IntArc Exit.\n");
179*c2c66affSColin Finck     return ret;
180*c2c66affSColin Finck }
181*c2c66affSColin Finck 
182*c2c66affSColin Finck 
183*c2c66affSColin Finck BOOL FASTCALL
IntGdiArcInternal(ARCTYPE arctype,DC * dc,int LeftRect,int TopRect,int RightRect,int BottomRect,int XStartArc,int YStartArc,int XEndArc,int YEndArc)184*c2c66affSColin Finck IntGdiArcInternal(
185*c2c66affSColin Finck           ARCTYPE arctype,
186*c2c66affSColin Finck           DC  *dc,
187*c2c66affSColin Finck           int LeftRect,
188*c2c66affSColin Finck           int TopRect,
189*c2c66affSColin Finck           int RightRect,
190*c2c66affSColin Finck           int BottomRect,
191*c2c66affSColin Finck           int XStartArc,
192*c2c66affSColin Finck           int YStartArc,
193*c2c66affSColin Finck           int XEndArc,
194*c2c66affSColin Finck           int YEndArc)
195*c2c66affSColin Finck {
196*c2c66affSColin Finck   BOOL Ret;
197*c2c66affSColin Finck   //PDC_ATTR pdcattr;
198*c2c66affSColin Finck 
199*c2c66affSColin Finck   DPRINT("StartX: %d, StartY: %d, EndX: %d, EndY: %d\n",
200*c2c66affSColin Finck            XStartArc,YStartArc,XEndArc,YEndArc);
201*c2c66affSColin Finck   DPRINT("Left: %d, Top: %d, Right: %d, Bottom: %d\n",
202*c2c66affSColin Finck            LeftRect,TopRect,RightRect,BottomRect);
203*c2c66affSColin Finck 
204*c2c66affSColin Finck   if ((LeftRect == RightRect) || (TopRect == BottomRect)) return TRUE;
205*c2c66affSColin Finck 
206*c2c66affSColin Finck   if (PATH_IsPathOpen(dc->dclevel))
207*c2c66affSColin Finck   {
208*c2c66affSColin Finck      return PATH_Arc( dc,
209*c2c66affSColin Finck                 LeftRect,
210*c2c66affSColin Finck                  TopRect,
211*c2c66affSColin Finck                RightRect,
212*c2c66affSColin Finck               BottomRect,
213*c2c66affSColin Finck                XStartArc,
214*c2c66affSColin Finck                YStartArc,
215*c2c66affSColin Finck                  XEndArc,
216*c2c66affSColin Finck                  YEndArc,
217*c2c66affSColin Finck                        0,
218*c2c66affSColin Finck                  arctype);
219*c2c66affSColin Finck   }
220*c2c66affSColin Finck 
221*c2c66affSColin Finck   //pdcattr = dc->pdcattr;
222*c2c66affSColin Finck 
223*c2c66affSColin Finck   if (arctype == GdiTypeArcTo)
224*c2c66affSColin Finck   {
225*c2c66affSColin Finck     if (dc->dclevel.flPath & DCPATH_CLOCKWISE)
226*c2c66affSColin Finck        IntGdiLineTo(dc, XEndArc, YEndArc);
227*c2c66affSColin Finck     else
228*c2c66affSColin Finck        IntGdiLineTo(dc, XStartArc, YStartArc);
229*c2c66affSColin Finck   }
230*c2c66affSColin Finck 
231*c2c66affSColin Finck   Ret = IntArc( dc,
232*c2c66affSColin Finck           LeftRect,
233*c2c66affSColin Finck            TopRect,
234*c2c66affSColin Finck          RightRect,
235*c2c66affSColin Finck         BottomRect,
236*c2c66affSColin Finck          XStartArc,
237*c2c66affSColin Finck          YStartArc,
238*c2c66affSColin Finck            XEndArc,
239*c2c66affSColin Finck            YEndArc,
240*c2c66affSColin Finck            arctype);
241*c2c66affSColin Finck 
242*c2c66affSColin Finck   if (arctype == GdiTypeArcTo)
243*c2c66affSColin Finck   {
244*c2c66affSColin Finck      if (dc->dclevel.flPath & DCPATH_CLOCKWISE)
245*c2c66affSColin Finck        IntGdiMoveToEx(dc, XStartArc, YStartArc, NULL);
246*c2c66affSColin Finck      else
247*c2c66affSColin Finck        IntGdiMoveToEx(dc, XEndArc, YEndArc, NULL);
248*c2c66affSColin Finck   }
249*c2c66affSColin Finck   return Ret;
250*c2c66affSColin Finck }
251*c2c66affSColin Finck 
252*c2c66affSColin Finck BOOL
253*c2c66affSColin Finck FASTCALL
IntGdiAngleArc(PDC pDC,INT x,INT y,DWORD dwRadius,FLOAT eStartAngle,FLOAT eSweepAngle)254*c2c66affSColin Finck IntGdiAngleArc( PDC pDC,
255*c2c66affSColin Finck                   INT x,
256*c2c66affSColin Finck                   INT y,
257*c2c66affSColin Finck          DWORD dwRadius,
258*c2c66affSColin Finck       FLOAT eStartAngle,
259*c2c66affSColin Finck       FLOAT eSweepAngle)
260*c2c66affSColin Finck {
261*c2c66affSColin Finck   INT  x1, y1, x2, y2, arcdir;
262*c2c66affSColin Finck   BOOL result;
263*c2c66affSColin Finck 
264*c2c66affSColin Finck   /* Calculate the end point */
265*c2c66affSColin Finck   x2 = x + (INT)(cos(((eStartAngle+eSweepAngle)/360)*(M_PI*2)) * dwRadius);
266*c2c66affSColin Finck   y2 = y - (INT)(sin(((eStartAngle+eSweepAngle)/360)*(M_PI*2)) * dwRadius);
267*c2c66affSColin Finck 
268*c2c66affSColin Finck   x1 = x + (INT)(cos((eStartAngle/360)*(M_PI*2)) * dwRadius);
269*c2c66affSColin Finck   y1 = y - (INT)(sin((eStartAngle/360)*(M_PI*2)) * dwRadius);
270*c2c66affSColin Finck 
271*c2c66affSColin Finck   arcdir = pDC->dclevel.flPath & DCPATH_CLOCKWISE;
272*c2c66affSColin Finck   if (eSweepAngle >= 0)
273*c2c66affSColin Finck      pDC->dclevel.flPath &= ~DCPATH_CLOCKWISE;
274*c2c66affSColin Finck   else
275*c2c66affSColin Finck      pDC->dclevel.flPath |= DCPATH_CLOCKWISE;
276*c2c66affSColin Finck 
277*c2c66affSColin Finck   result = IntGdiArcInternal( GdiTypeArcTo,
278*c2c66affSColin Finck                                        pDC,
279*c2c66affSColin Finck                                 x-dwRadius,
280*c2c66affSColin Finck                                 y-dwRadius,
281*c2c66affSColin Finck                                 x+dwRadius,
282*c2c66affSColin Finck                                 y+dwRadius,
283*c2c66affSColin Finck                                         x1,
284*c2c66affSColin Finck                                         y1,
285*c2c66affSColin Finck                                         x2,
286*c2c66affSColin Finck                                         y2 );
287*c2c66affSColin Finck 
288*c2c66affSColin Finck   pDC->dclevel.flPath |= (arcdir & DCPATH_CLOCKWISE);
289*c2c66affSColin Finck 
290*c2c66affSColin Finck   if (result)
291*c2c66affSColin Finck   {
292*c2c66affSColin Finck      IntGdiMoveToEx(pDC, x2, y2, NULL);
293*c2c66affSColin Finck   }
294*c2c66affSColin Finck   return result;
295*c2c66affSColin Finck }
296*c2c66affSColin Finck 
297*c2c66affSColin Finck /* FUNCTIONS *****************************************************************/
298*c2c66affSColin Finck 
299*c2c66affSColin Finck BOOL
300*c2c66affSColin Finck APIENTRY
NtGdiAngleArc(IN HDC hDC,IN INT x,IN INT y,IN DWORD dwRadius,IN DWORD dwStartAngle,IN DWORD dwSweepAngle)301*c2c66affSColin Finck NtGdiAngleArc(
302*c2c66affSColin Finck     IN HDC hDC,
303*c2c66affSColin Finck     IN INT x,
304*c2c66affSColin Finck     IN INT y,
305*c2c66affSColin Finck     IN DWORD dwRadius,
306*c2c66affSColin Finck     IN DWORD dwStartAngle,
307*c2c66affSColin Finck     IN DWORD dwSweepAngle)
308*c2c66affSColin Finck {
309*c2c66affSColin Finck   DC *pDC;
310*c2c66affSColin Finck   BOOL Ret = FALSE;
311*c2c66affSColin Finck   gxf_long worker, worker1;
312*c2c66affSColin Finck   KFLOATING_SAVE FloatSave;
313*c2c66affSColin Finck   NTSTATUS status;
314*c2c66affSColin Finck 
315*c2c66affSColin Finck   pDC = DC_LockDc (hDC);
316*c2c66affSColin Finck   if(!pDC)
317*c2c66affSColin Finck   {
318*c2c66affSColin Finck     EngSetLastError(ERROR_INVALID_HANDLE);
319*c2c66affSColin Finck     return FALSE;
320*c2c66affSColin Finck   }
321*c2c66affSColin Finck 
322*c2c66affSColin Finck   status = KeSaveFloatingPointState(&FloatSave);
323*c2c66affSColin Finck   if (!NT_SUCCESS(status))
324*c2c66affSColin Finck   {
325*c2c66affSColin Finck       DC_UnlockDc( pDC );
326*c2c66affSColin Finck       return FALSE;
327*c2c66affSColin Finck   }
328*c2c66affSColin Finck 
329*c2c66affSColin Finck   worker.l  = dwStartAngle;
330*c2c66affSColin Finck   worker1.l = dwSweepAngle;
331*c2c66affSColin Finck   DC_vPrepareDCsForBlit(pDC, NULL, NULL, NULL);
332*c2c66affSColin Finck   if (pDC->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
333*c2c66affSColin Finck     DC_vUpdateFillBrush(pDC);
334*c2c66affSColin Finck   if (pDC->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
335*c2c66affSColin Finck     DC_vUpdateLineBrush(pDC);
336*c2c66affSColin Finck   Ret = IntGdiAngleArc( pDC, x, y, dwRadius, worker.f, worker1.f);
337*c2c66affSColin Finck   DC_vFinishBlit(pDC, NULL);
338*c2c66affSColin Finck   DC_UnlockDc( pDC );
339*c2c66affSColin Finck 
340*c2c66affSColin Finck   KeRestoreFloatingPointState(&FloatSave);
341*c2c66affSColin Finck 
342*c2c66affSColin Finck   return Ret;
343*c2c66affSColin Finck }
344*c2c66affSColin Finck 
345*c2c66affSColin Finck BOOL
346*c2c66affSColin Finck APIENTRY
NtGdiArcInternal(ARCTYPE arctype,HDC hDC,int LeftRect,int TopRect,int RightRect,int BottomRect,int XStartArc,int YStartArc,int XEndArc,int YEndArc)347*c2c66affSColin Finck NtGdiArcInternal(
348*c2c66affSColin Finck         ARCTYPE arctype,
349*c2c66affSColin Finck         HDC  hDC,
350*c2c66affSColin Finck         int  LeftRect,
351*c2c66affSColin Finck         int  TopRect,
352*c2c66affSColin Finck         int  RightRect,
353*c2c66affSColin Finck         int  BottomRect,
354*c2c66affSColin Finck         int  XStartArc,
355*c2c66affSColin Finck         int  YStartArc,
356*c2c66affSColin Finck         int  XEndArc,
357*c2c66affSColin Finck         int  YEndArc)
358*c2c66affSColin Finck {
359*c2c66affSColin Finck   DC *dc;
360*c2c66affSColin Finck   BOOL Ret;
361*c2c66affSColin Finck   KFLOATING_SAVE FloatSave;
362*c2c66affSColin Finck   NTSTATUS status;
363*c2c66affSColin Finck 
364*c2c66affSColin Finck   dc = DC_LockDc (hDC);
365*c2c66affSColin Finck   if(!dc)
366*c2c66affSColin Finck   {
367*c2c66affSColin Finck     EngSetLastError(ERROR_INVALID_HANDLE);
368*c2c66affSColin Finck     return FALSE;
369*c2c66affSColin Finck   }
370*c2c66affSColin Finck   if (arctype > GdiTypePie)
371*c2c66affSColin Finck   {
372*c2c66affSColin Finck     DC_UnlockDc(dc);
373*c2c66affSColin Finck     EngSetLastError(ERROR_INVALID_PARAMETER);
374*c2c66affSColin Finck     return FALSE;
375*c2c66affSColin Finck   }
376*c2c66affSColin Finck 
377*c2c66affSColin Finck   DC_vPrepareDCsForBlit(dc, NULL, NULL, NULL);
378*c2c66affSColin Finck 
379*c2c66affSColin Finck   if (dc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
380*c2c66affSColin Finck     DC_vUpdateFillBrush(dc);
381*c2c66affSColin Finck 
382*c2c66affSColin Finck   if (dc->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
383*c2c66affSColin Finck     DC_vUpdateLineBrush(dc);
384*c2c66affSColin Finck 
385*c2c66affSColin Finck   status = KeSaveFloatingPointState(&FloatSave);
386*c2c66affSColin Finck   if (!NT_SUCCESS(status))
387*c2c66affSColin Finck   {
388*c2c66affSColin Finck       DC_UnlockDc( dc );
389*c2c66affSColin Finck       return FALSE;
390*c2c66affSColin Finck   }
391*c2c66affSColin Finck 
392*c2c66affSColin Finck   Ret = IntGdiArcInternal(
393*c2c66affSColin Finck                   arctype,
394*c2c66affSColin Finck                   dc,
395*c2c66affSColin Finck                   LeftRect,
396*c2c66affSColin Finck                   TopRect,
397*c2c66affSColin Finck                   RightRect,
398*c2c66affSColin Finck                   BottomRect,
399*c2c66affSColin Finck                   XStartArc,
400*c2c66affSColin Finck                   YStartArc,
401*c2c66affSColin Finck                   XEndArc,
402*c2c66affSColin Finck                   YEndArc);
403*c2c66affSColin Finck 
404*c2c66affSColin Finck   KeRestoreFloatingPointState(&FloatSave);
405*c2c66affSColin Finck   DC_vFinishBlit(dc, NULL);
406*c2c66affSColin Finck   DC_UnlockDc( dc );
407*c2c66affSColin Finck   return Ret;
408*c2c66affSColin Finck }
409*c2c66affSColin Finck 
410