branch update for HEAD-2003050101
[reactos.git] / subsys / win32k / eng / lineto.c
index ce09b70..a4d2f09 100644 (file)
@@ -1,13 +1,16 @@
 #include <ddk/winddi.h>
+#include <include/inteng.h>
+#include <include/dib.h>
 #include "objects.h"
 #include "../dib/dib.h"
+#include "misc.h"
 
 #include <include/mouse.h>
 #include <include/object.h>
 #include <include/surface.h>
 
 BOOL STDCALL
-EngLineTo(SURFOBJ *Surface,
+EngLineTo(SURFOBJ *DestObj,
          CLIPOBJ *Clip,
          BRUSHOBJ *Brush,
          LONG x1,
@@ -17,125 +20,194 @@ EngLineTo(SURFOBJ *Surface,
          RECTL *RectBounds,
          MIX mix)
 {
-  BOOLEAN ret;
-  SURFGDI *SurfGDI;
-  LONG x, y, d, deltax, deltay, i, length, xchange, ychange, error, hx, vy;
-
-  // These functions are assigned if we're working with a DIB
-  // The assigned functions depend on the bitsPerPixel of the DIB
-  PFN_DIB_PutPixel DIB_PutPixel;
-  PFN_DIB_HLine    DIB_HLine;
-  PFN_DIB_VLine    DIB_VLine;
-
-  SurfGDI = (SURFGDI*)AccessInternalObjectFromUserObject(Surface);
-
-  MouseSafetyOnDrawStart(Surface, SurfGDI, x1, y1, x2, y2);
-
-  if(Surface->iType!=STYPE_BITMAP)
-  {
-    // Call the driver's DrvLineTo
-    ret = SurfGDI->LineTo(Surface, Clip, Brush, x1, y1, x2, y2, RectBounds, mix);
-    MouseSafetyOnDrawEnd(Surface, SurfGDI);
-    return ret;
-  }
-
-  // Assign DIB functions according to bytes per pixel
-  switch(BitsPerFormat(Surface->iBitmapFormat))
-  {
-    case 1:
-      DIB_PutPixel = (PFN_DIB_PutPixel)DIB_1BPP_PutPixel;
-      DIB_HLine    = (PFN_DIB_HLine)DIB_1BPP_HLine;
-      DIB_VLine    = (PFN_DIB_VLine)DIB_1BPP_VLine;
-      break;
-
-    case 4:
-      DIB_PutPixel = (PFN_DIB_PutPixel)DIB_4BPP_PutPixel;
-      DIB_HLine    = (PFN_DIB_HLine)DIB_4BPP_HLine;
-      DIB_VLine    = (PFN_DIB_VLine)DIB_4BPP_VLine;
-      break;
+  LONG x, y, deltax, deltay, i, xchange, ychange, error, hx, vy;
+  ULONG Pixel = Brush->iSolidColor;
+  SURFOBJ *OutputObj;
+  SURFGDI *OutputGDI;
+  RECTL DestRect;
+  POINTL Translate;
+  INTENG_ENTER_LEAVE EnterLeave;
+
+  DestRect.left = x1;
+  if (x1 != x2)
+    {
+    DestRect.right = x2;
+    }
+  else
+    {
+    DestRect.right = x2 + 1;
+    }
+  DestRect.top = y1;
+  if (y1 != y2)
+    {
+    DestRect.bottom = y2;
+    }
+  else
+    {
+    DestRect.bottom = y2 + 1;
+    }
 
-    case 24:
-      DIB_PutPixel = (PFN_DIB_PutPixel)DIB_24BPP_PutPixel;
-      DIB_HLine    = (PFN_DIB_HLine)DIB_24BPP_HLine;
-      DIB_VLine    = (PFN_DIB_VLine)DIB_24BPP_VLine;
-      break;
+  if (! IntEngEnter(&EnterLeave, DestObj, &DestRect, FALSE, &Translate, &OutputObj))
+    {
+    return FALSE;
+    }
 
-    default:
-      DbgPrint("EngLineTo: unsupported DIB format %u (bitsPerPixel:%u)\n", Surface->iBitmapFormat,
-               BitsPerFormat(Surface->iBitmapFormat));
+  x1 += Translate.x;
+  x2 += Translate.x;
+  y1 += Translate.y;
+  y2 += Translate.y;
 
-      MouseSafetyOnDrawEnd(Surface, SurfGDI);
-      return FALSE;
-  }
+  OutputGDI = AccessInternalObjectFromUserObject(OutputObj);
 
   // FIXME: Implement clipping
-  x=x1;
-  y=y1;
-  deltax=x2-x1;
-  deltay=y2-y1;
+  x = x1;
+  y = y1;
+  deltax = x2 - x1;
+  deltay = y2 - y1;
 
-  if(deltax<0)
-  {
-    xchange=-1;
-    deltax=-deltax;
+  if (deltax < 0)
+    {
+    xchange = -1;
+    deltax = - deltax;
     hx = x2;
-  } else
-  {
-    xchange=1;
+    x--;
+    }
+  else
+    {
+    xchange = 1;
     hx = x1;
-  }
+    }
 
-  if(deltay<0)
-  {
-    ychange=-1;
-    deltay=-deltay;
+  if (deltay < 0)
+    {
+    ychange = -1;
+    deltay = - deltay;
     vy = y2;
-  } else
-  {
-    ychange=1;
+    y--;
+    }
+  else
+    {
+    ychange = 1;
     vy = y1;
-  }
-
-  if(y1==y2) { DIB_HLine(Surface, hx, hx + deltax, y1, Brush->iSolidColor); MouseSafetyOnDrawEnd(Surface, SurfGDI); return TRUE; }
-  if(x1==x2) { DIB_VLine(Surface, x1, vy, vy + deltay, Brush->iSolidColor); MouseSafetyOnDrawEnd(Surface, SurfGDI); return TRUE; }
-
-  error=0;
-  i=0;
+    }
 
-  if(deltax<deltay)
-  {
-    length=deltay+1;
-    while(i<length)
+  if (y1 == y2)
+    {
+    OutputGDI->DIB_HLine(OutputObj, hx, hx + deltax, y1, Pixel);
+    }
+  else if (x1 == x2)
+    {
+    OutputGDI->DIB_VLine(OutputObj, x1, vy, vy + deltay, Pixel);
+    }
+  else
     {
-      DIB_PutPixel(Surface, x, y, Brush->iSolidColor);
-      y=y+ychange;
-      error=error+deltax;
+    error = 0;
 
-      if(error>deltay)
+    if (deltax < deltay)
       {
-        x=x+xchange;
-        error=error-deltay;
+      for (i = 0; i < deltay; i++)
+        {
+        OutputGDI->DIB_PutPixel(OutputObj, x, y, Pixel);
+        y = y + ychange;
+        error = error + deltax;
+
+        if (deltay <= error)
+          {
+          x = x + xchange;
+          error = error - deltay;
+          }
+        }
       }
-      i=i+1;
-    }
-  } else
-  {
-    length=deltax+1;
-    while(i<length)
-    {
-      DIB_PutPixel(Surface, x, y, Brush->iSolidColor);
-      x=x+xchange;
-      error=error+deltay;
-      if(error>deltax)
+     else
       {
-        y=y+ychange;
-        error=error-deltax;
+      for (i = 0; i < deltax; i++)
+        {
+        OutputGDI->DIB_PutPixel(OutputObj, x, y, Pixel);
+        x = x + xchange;
+        error = error + deltay;
+        if (deltax <= error)
+          {
+          y = y + ychange;
+          error = error - deltax;
+          }
+        }
       }
-      i=i+1;
     }
+
+  return IntEngLeave(&EnterLeave);
+}
+
+BOOL STDCALL
+IntEngLineTo(SURFOBJ *DestSurf,
+            CLIPOBJ *Clip,
+            BRUSHOBJ *Brush,
+            LONG x1,
+            LONG y1,
+            LONG x2,
+            LONG y2,
+            RECTL *RectBounds,
+            MIX mix)
+{
+  BOOLEAN ret;
+  SURFGDI *SurfGDI;
+
+  /* No success yet */
+  ret = FALSE;
+  SurfGDI = (SURFGDI*)AccessInternalObjectFromUserObject(DestSurf);
+
+  MouseSafetyOnDrawStart(DestSurf, SurfGDI, x1, y1, x2, y2);
+
+  if (NULL != SurfGDI->LineTo) {
+    /* Call the driver's DrvLineTo */
+    ret = SurfGDI->LineTo(DestSurf, Clip, Brush, x1, y1, x2, y2, RectBounds, mix);
+  }
+
+#if 0
+  if (! ret && NULL != SurfGDI->StrokePath) {
+    /* FIXME: Emulate LineTo using drivers DrvStrokePath and set ret on success */
+  }
+#endif
+
+  if (! ret) {
+    ret = EngLineTo(DestSurf, Clip, Brush, x1, y1, x2, y2, RectBounds, mix);
   }
 
-  MouseSafetyOnDrawEnd(Surface, SurfGDI);
+  MouseSafetyOnDrawEnd(DestSurf, SurfGDI);
+
+  return ret;
+}
+
+BOOL STDCALL
+IntEngPolyline(SURFOBJ *DestSurf,
+              CLIPOBJ *Clip,
+              BRUSHOBJ *Brush,
+              CONST LPPOINT  pt,
+               LONG dCount,
+              MIX mix)
+{
+  LONG i;
+  RECTL rect;
+  BOOL ret = FALSE;
+
+  //Draw the Polyline with a call to IntEngLineTo for each segment.
+  for (i=1; i<dCount; i++)
+  {
+    rect.left = MIN(pt[i-1].x, pt[i].x);
+    rect.top = MIN(pt[i-1].y, pt[i].y);
+    rect.right = MAX(pt[i-1].x, pt[i].x);
+    rect.bottom = MAX(pt[i-1].y, pt[i].y);
+    ret = IntEngLineTo(DestSurf,
+                      Clip,
+                      Brush,
+                      pt[i-1].x,
+                      pt[i-1].y,
+                      pt[i].x,
+                      pt[i].y,
+                      &rect,
+                      mix);
+    if (!ret)
+      break;
+  }
 
-  return TRUE;
+  return ret;
 }