update for HEAD-2002110401
[reactos.git] / subsys / win32k / eng / lineto.c
1 #include <ddk/winddi.h>
2 #include "objects.h"
3 #include "../dib/dib.h"
4
5 #include <include/mouse.h>
6 #include <include/object.h>
7 #include <include/surface.h>
8
9 BOOL STDCALL
10 EngLineTo(SURFOBJ *Surface,
11           CLIPOBJ *Clip,
12           BRUSHOBJ *Brush,
13           LONG x1,
14           LONG y1,
15           LONG x2,
16           LONG y2,
17           RECTL *RectBounds,
18           MIX mix)
19 {
20   BOOLEAN ret;
21   SURFGDI *SurfGDI;
22   LONG x, y, d, deltax, deltay, i, length, xchange, ychange, error, hx, vy;
23
24   // These functions are assigned if we're working with a DIB
25   // The assigned functions depend on the bitsPerPixel of the DIB
26   PFN_DIB_PutPixel DIB_PutPixel;
27   PFN_DIB_HLine    DIB_HLine;
28   PFN_DIB_VLine    DIB_VLine;
29
30   SurfGDI = (SURFGDI*)AccessInternalObjectFromUserObject(Surface);
31
32   MouseSafetyOnDrawStart(Surface, SurfGDI, x1, y1, x2, y2);
33
34   if(Surface->iType!=STYPE_BITMAP)
35   {
36     // Call the driver's DrvLineTo
37     ret = SurfGDI->LineTo(Surface, Clip, Brush, x1, y1, x2, y2, RectBounds, mix);
38     MouseSafetyOnDrawEnd(Surface, SurfGDI);
39     return ret;
40   }
41
42   // Assign DIB functions according to bytes per pixel
43   switch(BitsPerFormat(Surface->iBitmapFormat))
44   {
45     case 1:
46       DIB_PutPixel = (PFN_DIB_PutPixel)DIB_1BPP_PutPixel;
47       DIB_HLine    = (PFN_DIB_HLine)DIB_1BPP_HLine;
48       DIB_VLine    = (PFN_DIB_VLine)DIB_1BPP_VLine;
49       break;
50
51     case 4:
52       DIB_PutPixel = (PFN_DIB_PutPixel)DIB_4BPP_PutPixel;
53       DIB_HLine    = (PFN_DIB_HLine)DIB_4BPP_HLine;
54       DIB_VLine    = (PFN_DIB_VLine)DIB_4BPP_VLine;
55       break;
56
57     case 24:
58       DIB_PutPixel = (PFN_DIB_PutPixel)DIB_24BPP_PutPixel;
59       DIB_HLine    = (PFN_DIB_HLine)DIB_24BPP_HLine;
60       DIB_VLine    = (PFN_DIB_VLine)DIB_24BPP_VLine;
61       break;
62
63     default:
64       DbgPrint("EngLineTo: unsupported DIB format %u (bitsPerPixel:%u)\n", Surface->iBitmapFormat,
65                BitsPerFormat(Surface->iBitmapFormat));
66
67       MouseSafetyOnDrawEnd(Surface, SurfGDI);
68       return FALSE;
69   }
70
71   // FIXME: Implement clipping
72   x=x1;
73   y=y1;
74   deltax=x2-x1;
75   deltay=y2-y1;
76
77   if(deltax<0)
78   {
79     xchange=-1;
80     deltax=-deltax;
81     hx = x2;
82   } else
83   {
84     xchange=1;
85     hx = x1;
86   }
87
88   if(deltay<0)
89   {
90     ychange=-1;
91     deltay=-deltay;
92     vy = y2;
93   } else
94   {
95     ychange=1;
96     vy = y1;
97   }
98
99   if(y1==y2) { DIB_HLine(Surface, hx, hx + deltax, y1, Brush->iSolidColor); MouseSafetyOnDrawEnd(Surface, SurfGDI); return TRUE; }
100   if(x1==x2) { DIB_VLine(Surface, x1, vy, vy + deltay, Brush->iSolidColor); MouseSafetyOnDrawEnd(Surface, SurfGDI); return TRUE; }
101
102   error=0;
103   i=0;
104
105   if(deltax<deltay)
106   {
107     length=deltay+1;
108     while(i<length)
109     {
110       DIB_PutPixel(Surface, x, y, Brush->iSolidColor);
111       y=y+ychange;
112       error=error+deltax;
113
114       if(error>deltay)
115       {
116         x=x+xchange;
117         error=error-deltay;
118       }
119       i=i+1;
120     }
121   } else
122   {
123     length=deltax+1;
124     while(i<length)
125     {
126       DIB_PutPixel(Surface, x, y, Brush->iSolidColor);
127       x=x+xchange;
128       error=error+deltay;
129       if(error>deltax)
130       {
131         y=y+ychange;
132         error=error-deltax;
133       }
134       i=i+1;
135     }
136   }
137
138   MouseSafetyOnDrawEnd(Surface, SurfGDI);
139
140   return TRUE;
141 }