[WIN32K] Fix drawing the Start and End Segments with Pie(). Brought to you by Barrett...
[reactos.git] / reactos / win32ss / gdi / ntgdi / arc.c
index b332a90..c24628c 100644 (file)
@@ -8,7 +8,7 @@
  */
 #define PUTPIXEL(x,y,BrushInst)        \
   ret = ret && IntEngLineTo(&psurf->SurfObj, \
-       dc->rosdc.CombinedClip,                         \
+       &dc->co.ClipObj,                         \
        &BrushInst.BrushObject,                   \
        x, y, (x)+1, y,                           \
        &RectBounds,                              \
 
 #define PUTLINE(x1,y1,x2,y2,BrushInst) \
   ret = ret && IntEngLineTo(&psurf->SurfObj, \
-       dc->rosdc.CombinedClip,                         \
+       &dc->co.ClipObj,                         \
        &BrushInst.BrushObject,                   \
        x1, y1, x2, y2,                           \
        &RectBounds,                              \
        ROP2_TO_MIX(pdcattr->jROP2));
 
-#define Rsin(d) ((d) == 0.0 ? 0.0 : ((d) == 90.0 ? 1.0 : sin(d*M_PI/180.0)))
-#define Rcos(d) ((d) == 0.0 ? 1.0 : ((d) == 90.0 ? 0.0 : cos(d*M_PI/180.0)))
-
 static
 BOOL
 FASTCALL
@@ -46,8 +43,7 @@ IntArc( DC *dc,
     BOOL ret = TRUE;
     LONG PenWidth, PenOrigWidth;
     double AngleStart, AngleEnd;
-    LONG RadiusX, RadiusY, CenterX, CenterY;
-    LONG SfCx, SfCy, EfCx, EfCy;
+    LONG CenterX, CenterY;
 
     if (Right < Left)
     {
@@ -79,7 +75,7 @@ IntArc( DC *dc,
         return FALSE;
     }
 
-    PenOrigWidth = PenWidth = pbrPen->ptPenWidth.x;
+    PenOrigWidth = PenWidth = pbrPen->lWidth;
     if (pbrPen->ulPenStyle == PS_NULL) PenWidth = 0;
 
     if (pbrPen->ulPenStyle == PS_INSIDEFRAME)
@@ -93,7 +89,7 @@ IntArc( DC *dc,
     }
 
     if (!PenWidth) PenWidth = 1;
-    pbrPen->ptPenWidth.x = PenWidth;
+    pbrPen->lWidth = PenWidth;
 
     RectBounds.left   = Left;
     RectBounds.right  = Right;
@@ -124,8 +120,6 @@ IntArc( DC *dc,
     DPRINT("1: Left: %d, Top: %d, Right: %d, Bottom: %d\n",
                RectBounds.left,RectBounds.top,RectBounds.right,RectBounds.bottom);
 
-    RadiusX = max((RectBounds.right - RectBounds.left) / 2, 1);
-    RadiusY = max((RectBounds.bottom - RectBounds.top) / 2, 1);
     CenterX = (RectBounds.right + RectBounds.left) / 2;
     CenterY = (RectBounds.bottom + RectBounds.top) / 2;
     AngleEnd   = atan2((RectSEpts.bottom - CenterY), RectSEpts.right - CenterX)*(360.0/(M_PI*2));
@@ -137,11 +131,6 @@ IntArc( DC *dc,
         AngleStart = AngleEnd + 360.0; // Arc(), ArcTo(), Pie() and Chord() are counterclockwise APIs.
     }
 
-    SfCx = (LONG)(Rcos(AngleStart) * RadiusX);
-    SfCy = (LONG)(Rsin(AngleStart) * RadiusY);
-    EfCx = (LONG)(Rcos(AngleEnd) * RadiusX);
-    EfCy = (LONG)(Rsin(AngleEnd) * RadiusY);
-
     if ((arctype == GdiTypePie) || (arctype == GdiTypeChord))
     {
         ret = IntFillArc( dc,
@@ -175,13 +164,13 @@ IntArc( DC *dc,
 
     if (arctype == GdiTypePie)
     {
-       PUTLINE(CenterX, CenterY, SfCx + CenterX, SfCy + CenterY, dc->eboLine);
-       PUTLINE(EfCx + CenterX, EfCy + CenterY, CenterX, CenterY, dc->eboLine);
+        PUTLINE(CenterX, CenterY, RectSEpts.left, RectSEpts.top, dc->eboLine);
+        PUTLINE(RectSEpts.right, RectSEpts.bottom, CenterX, CenterY, dc->eboLine);
     }
     if (arctype == GdiTypeChord)
-        PUTLINE(EfCx + CenterX, EfCy + CenterY, SfCx + CenterX, SfCy + CenterY, dc->eboLine);
+        PUTLINE(RectSEpts.right, RectSEpts.bottom, RectSEpts.left, RectSEpts.top, dc->eboLine);
 
-    pbrPen->ptPenWidth.x = PenOrigWidth;
+    pbrPen->lWidth = PenOrigWidth;
     PEN_ShareUnlockPen(pbrPen);
     DPRINT("IntArc Exit.\n");
     return ret;
@@ -316,6 +305,8 @@ NtGdiAngleArc(
   DC *pDC;
   BOOL Ret = FALSE;
   gxf_long worker, worker1;
+  KFLOATING_SAVE FloatSave;
+  NTSTATUS status;
 
   pDC = DC_LockDc (hDC);
   if(!pDC)
@@ -329,10 +320,17 @@ NtGdiAngleArc(
     /* Yes, Windows really returns TRUE in this case */
     return TRUE;
   }
+
+  status = KeSaveFloatingPointState(&FloatSave);
+  if (!NT_SUCCESS(status))
+  {
+      DC_UnlockDc( pDC );
+      return FALSE;
+  }
+
   worker.l  = dwStartAngle;
   worker1.l = dwSweepAngle;
-  DC_vPrepareDCsForBlit(pDC, pDC->rosdc.CombinedClip->rclBounds,
-                           NULL, pDC->rosdc.CombinedClip->rclBounds);
+  DC_vPrepareDCsForBlit(pDC, NULL, NULL, NULL);
   if (pDC->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
     DC_vUpdateFillBrush(pDC);
   if (pDC->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
@@ -340,6 +338,9 @@ NtGdiAngleArc(
   Ret = IntGdiAngleArc( pDC, x, y, dwRadius, worker.f, worker1.f);
   DC_vFinishBlit(pDC, NULL);
   DC_UnlockDc( pDC );
+
+  KeRestoreFloatingPointState(&FloatSave);
+
   return Ret;
 }
 
@@ -359,6 +360,8 @@ NtGdiArcInternal(
 {
   DC *dc;
   BOOL Ret;
+  KFLOATING_SAVE FloatSave;
+  NTSTATUS status;
 
   dc = DC_LockDc (hDC);
   if(!dc)
@@ -373,8 +376,7 @@ NtGdiArcInternal(
     return TRUE;
   }
 
-  DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds,
-                            NULL, dc->rosdc.CombinedClip->rclBounds);
+  DC_vPrepareDCsForBlit(dc, NULL, NULL, NULL);
 
   if (dc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
     DC_vUpdateFillBrush(dc);
@@ -382,6 +384,13 @@ NtGdiArcInternal(
   if (dc->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
     DC_vUpdateLineBrush(dc);
 
+  status = KeSaveFloatingPointState(&FloatSave);
+  if (!NT_SUCCESS(status))
+  {
+      DC_UnlockDc( dc );
+      return FALSE;
+  }
+
   Ret = IntGdiArcInternal(
                   arctype,
                   dc,
@@ -394,6 +403,7 @@ NtGdiArcInternal(
                   XEndArc,
                   YEndArc);
 
+  KeRestoreFloatingPointState(&FloatSave);
   DC_vFinishBlit(dc, NULL);
   DC_UnlockDc( dc );
   return Ret;