update for HEAD-2003050101
[reactos.git] / subsys / win32k / eng / lineto.c
1 #include <ddk/winddi.h>
2 #include <include/inteng.h>
3 #include <include/dib.h>
4 #include "objects.h"
5 #include "../dib/dib.h"
6 #include "misc.h"
7
8 #include <include/mouse.h>
9 #include <include/object.h>
10 #include <include/surface.h>
11
12 BOOL STDCALL
13 EngLineTo(SURFOBJ *DestObj,
14           CLIPOBJ *Clip,
15           BRUSHOBJ *Brush,
16           LONG x1,
17           LONG y1,
18           LONG x2,
19           LONG y2,
20           RECTL *RectBounds,
21           MIX mix)
22 {
23   LONG x, y, deltax, deltay, i, xchange, ychange, error, hx, vy;
24   ULONG Pixel = Brush->iSolidColor;
25   SURFOBJ *OutputObj;
26   SURFGDI *OutputGDI;
27   RECTL DestRect;
28   POINTL Translate;
29   INTENG_ENTER_LEAVE EnterLeave;
30
31   DestRect.left = x1;
32   if (x1 != x2)
33     {
34     DestRect.right = x2;
35     }
36   else
37     {
38     DestRect.right = x2 + 1;
39     }
40   DestRect.top = y1;
41   if (y1 != y2)
42     {
43     DestRect.bottom = y2;
44     }
45   else
46     {
47     DestRect.bottom = y2 + 1;
48     }
49
50   if (! IntEngEnter(&EnterLeave, DestObj, &DestRect, FALSE, &Translate, &OutputObj))
51     {
52     return FALSE;
53     }
54
55   x1 += Translate.x;
56   x2 += Translate.x;
57   y1 += Translate.y;
58   y2 += Translate.y;
59
60   OutputGDI = AccessInternalObjectFromUserObject(OutputObj);
61
62   // FIXME: Implement clipping
63   x = x1;
64   y = y1;
65   deltax = x2 - x1;
66   deltay = y2 - y1;
67
68   if (deltax < 0)
69     {
70     xchange = -1;
71     deltax = - deltax;
72     hx = x2;
73     x--;
74     }
75   else
76     {
77     xchange = 1;
78     hx = x1;
79     }
80
81   if (deltay < 0)
82     {
83     ychange = -1;
84     deltay = - deltay;
85     vy = y2;
86     y--;
87     }
88   else
89     {
90     ychange = 1;
91     vy = y1;
92     }
93
94   if (y1 == y2)
95     {
96     OutputGDI->DIB_HLine(OutputObj, hx, hx + deltax, y1, Pixel);
97     }
98   else if (x1 == x2)
99     {
100     OutputGDI->DIB_VLine(OutputObj, x1, vy, vy + deltay, Pixel);
101     }
102   else
103     {
104     error = 0;
105
106     if (deltax < deltay)
107       {
108       for (i = 0; i < deltay; i++)
109         {
110         OutputGDI->DIB_PutPixel(OutputObj, x, y, Pixel);
111         y = y + ychange;
112         error = error + deltax;
113
114         if (deltay <= error)
115           {
116           x = x + xchange;
117           error = error - deltay;
118           }
119         }
120       }
121      else
122       {
123       for (i = 0; i < deltax; i++)
124         {
125         OutputGDI->DIB_PutPixel(OutputObj, x, y, Pixel);
126         x = x + xchange;
127         error = error + deltay;
128         if (deltax <= error)
129           {
130           y = y + ychange;
131           error = error - deltax;
132           }
133         }
134       }
135     }
136
137   return IntEngLeave(&EnterLeave);
138 }
139
140 BOOL STDCALL
141 IntEngLineTo(SURFOBJ *DestSurf,
142              CLIPOBJ *Clip,
143              BRUSHOBJ *Brush,
144              LONG x1,
145              LONG y1,
146              LONG x2,
147              LONG y2,
148              RECTL *RectBounds,
149              MIX mix)
150 {
151   BOOLEAN ret;
152   SURFGDI *SurfGDI;
153
154   /* No success yet */
155   ret = FALSE;
156   SurfGDI = (SURFGDI*)AccessInternalObjectFromUserObject(DestSurf);
157
158   MouseSafetyOnDrawStart(DestSurf, SurfGDI, x1, y1, x2, y2);
159
160   if (NULL != SurfGDI->LineTo) {
161     /* Call the driver's DrvLineTo */
162     ret = SurfGDI->LineTo(DestSurf, Clip, Brush, x1, y1, x2, y2, RectBounds, mix);
163   }
164
165 #if 0
166   if (! ret && NULL != SurfGDI->StrokePath) {
167     /* FIXME: Emulate LineTo using drivers DrvStrokePath and set ret on success */
168   }
169 #endif
170
171   if (! ret) {
172     ret = EngLineTo(DestSurf, Clip, Brush, x1, y1, x2, y2, RectBounds, mix);
173   }
174
175   MouseSafetyOnDrawEnd(DestSurf, SurfGDI);
176
177   return ret;
178 }
179
180 BOOL STDCALL
181 IntEngPolyline(SURFOBJ *DestSurf,
182                CLIPOBJ *Clip,
183                BRUSHOBJ *Brush,
184                CONST LPPOINT  pt,
185                LONG dCount,
186                MIX mix)
187 {
188   LONG i;
189   RECTL rect;
190   BOOL ret = FALSE;
191
192   //Draw the Polyline with a call to IntEngLineTo for each segment.
193   for (i=1; i<dCount; i++)
194   {
195     rect.left = MIN(pt[i-1].x, pt[i].x);
196     rect.top = MIN(pt[i-1].y, pt[i].y);
197     rect.right = MAX(pt[i-1].x, pt[i].x);
198     rect.bottom = MAX(pt[i-1].y, pt[i].y);
199     ret = IntEngLineTo(DestSurf,
200                        Clip,
201                        Brush,
202                        pt[i-1].x,
203                        pt[i-1].y,
204                        pt[i].x,
205                        pt[i].y,
206                        &rect,
207                        mix);
208     if (!ret)
209       break;
210   }
211
212   return ret;
213 }