update for HEAD-2003021201
[reactos.git] / subsys / win32k / objects / line.c
1 // Some code from the WINE project source (www.winehq.com)
2
3 #undef WIN32_LEAN_AND_MEAN
4 #include <windows.h>
5 #include <ddk/ntddk.h>
6 #include <win32k/dc.h>
7 #include <win32k/line.h>
8 #include <win32k/path.h>
9 #include <win32k/pen.h>
10 #include <win32k/region.h>
11
12 // #define NDEBUG
13 #include <win32k/debug1.h>
14
15 BOOL
16 STDCALL
17 W32kAngleArc(HDC  hDC,
18                    int  X,
19                    int  Y,
20                    DWORD  Radius,
21                    FLOAT  StartAngle,
22                    FLOAT  SweepAngle)
23 {
24   UNIMPLEMENTED;
25 }
26
27 BOOL
28 STDCALL
29 W32kArc(HDC  hDC,
30               int  LeftRect,
31               int  TopRect,
32               int  RightRect,
33               int  BottomRect,
34               int  XStartArc,
35               int  YStartArc,
36               int  XEndArc,
37               int  YEndArc)
38 {
39   DC *dc = DC_HandleToPtr(hDC);
40   if(!dc) return FALSE;
41
42   if(PATH_IsPathOpen(dc->w.path))
43     return PATH_Arc(hDC, LeftRect, TopRect, RightRect, BottomRect,
44                     XStartArc, YStartArc, XEndArc, YEndArc);
45
46   DC_ReleasePtr( hDC );
47 //   EngArc(dc, LeftRect, TopRect, RightRect, BottomRect, UNIMPLEMENTED
48 //          XStartArc, YStartArc, XEndArc, YEndArc);
49 }
50
51 BOOL
52 STDCALL
53 W32kArcTo(HDC  hDC,
54                 int  LeftRect,
55                 int  TopRect,
56                 int  RightRect,
57                 int  BottomRect,
58                 int  XRadial1,
59                 int  YRadial1,
60                 int  XRadial2,
61                 int  YRadial2)
62 {
63   BOOL result;
64   DC *dc = DC_HandleToPtr(hDC);
65   if(!dc) return FALSE;
66
67   // Line from current position to starting point of arc
68   W32kLineTo(hDC, XRadial1, YRadial1);
69
70   // Then the arc is drawn.
71   result = W32kArc(hDC, LeftRect, TopRect, RightRect, BottomRect,
72                    XRadial1, YRadial1, XRadial2, YRadial2);
73
74   // If no error occured, the current position is moved to the ending point of the arc.
75   if(result)
76   {
77     W32kMoveToEx(hDC, XRadial2, YRadial2, NULL);
78   }
79   DC_ReleasePtr( hDC );
80   return result;
81 }
82
83 INT
84 STDCALL
85 W32kGetArcDirection(HDC  hDC)
86 {
87   PDC dc;
88   int ret;
89
90   dc = DC_HandleToPtr (hDC);
91   if (!dc)
92   {
93     return 0;
94   }
95
96   ret = dc->w.ArcDirection;
97   DC_ReleasePtr( hDC );
98   return ret;
99 }
100
101 BOOL
102 STDCALL
103 W32kLineTo(HDC  hDC,
104                  int  XEnd,
105                  int  YEnd)
106 {
107   DC            *dc = DC_HandleToPtr(hDC);
108   SURFOBJ       *SurfObj = (SURFOBJ*)AccessUserObject(dc->Surface);
109   BOOL ret;
110   PPENOBJ   pen;
111   PROSRGNDATA  reg;
112
113   if(!dc) return FALSE;
114
115   if(PATH_IsPathOpen(dc->w.path)) {
116     ret = PATH_LineTo(hDC, XEnd, YEnd);
117   } else {
118         pen = (PPENOBJ) GDIOBJ_LockObj(dc->w.hPen, GO_PEN_MAGIC);
119         reg = (PROSRGNDATA)GDIOBJ_LockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC);
120
121         ASSERT( pen );
122         // not yet implemented ASSERT( reg );
123
124     /* Draw the line according to the DC origin */
125     ret = EngLineTo(SurfObj,
126                     NULL, // ClipObj
127                     PenToBrushObj(dc, pen),
128                     dc->w.DCOrgX + dc->w.CursPosX, dc->w.DCOrgY + dc->w.CursPosY,
129                     dc->w.DCOrgX + XEnd,           dc->w.DCOrgY + YEnd,
130                     reg, // Bounding rectangle
131                     dc->w.ROPmode); // MIX
132
133         GDIOBJ_UnlockObj( dc->w.hGCClipRgn, GO_REGION_MAGIC );
134         GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC);
135   }
136   if(ret) {
137     dc->w.CursPosX = XEnd;
138     dc->w.CursPosY = YEnd;
139   }
140   DC_ReleasePtr( hDC );
141   return ret;
142 }
143
144 BOOL
145 STDCALL
146 W32kMoveToEx(HDC  hDC,
147                    int  X,
148                    int  Y,
149                    LPPOINT  Point)
150 {
151   DC *dc = DC_HandleToPtr( hDC );
152
153   if(!dc) return FALSE;
154
155   if(Point) {
156     Point->x = dc->w.CursPosX;
157     Point->y = dc->w.CursPosY;
158   }
159   dc->w.CursPosX = X;
160   dc->w.CursPosY = Y;
161
162   if(PATH_IsPathOpen(dc->w.path)){
163         DC_ReleasePtr( hDC );
164     return PATH_MoveTo(hDC);
165   }
166   DC_ReleasePtr( hDC );
167   return FALSE;
168 }
169
170 BOOL
171 STDCALL
172 W32kPolyBezier(HDC  hDC,
173                      CONST LPPOINT  pt,
174                      DWORD  Count)
175 {
176   DC *dc = DC_HandleToPtr(hDC);
177   if(!dc) return FALSE;
178
179   if(PATH_IsPathOpen(dc->w.path)){
180         DC_ReleasePtr( hDC );
181     return PATH_PolyBezier(hDC, pt, Count);
182   }
183
184   /* We'll convert it into line segments and draw them using Polyline */
185   {
186     POINT *Pts;
187     INT nOut;
188     BOOL ret;
189
190     Pts = GDI_Bezier(pt, Count, &nOut);
191     if(!Pts) return FALSE;
192     DbgPrint("Pts = %p, no = %d\n", Pts, nOut);
193     ret = W32kPolyline(dc->hSelf, Pts, nOut);
194     ExFreePool(Pts);
195         DC_ReleasePtr( hDC );
196     return ret;
197   }
198 }
199
200 BOOL
201 STDCALL
202 W32kPolyBezierTo(HDC  hDC,
203                        CONST LPPOINT  pt,
204                        DWORD  Count)
205 {
206   DC *dc = DC_HandleToPtr(hDC);
207   BOOL ret;
208
209   if(!dc) return FALSE;
210
211   if(PATH_IsPathOpen(dc->w.path))
212     ret = PATH_PolyBezierTo(hDC, pt, Count);
213   else { /* We'll do it using PolyBezier */
214     POINT *npt;
215     npt = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1));
216     if(!npt) return FALSE;
217     npt[0].x = dc->w.CursPosX;
218     npt[0].y = dc->w.CursPosY;
219     memcpy(npt + 1, pt, sizeof(POINT) * Count);
220     ret = W32kPolyBezier(dc->hSelf, npt, Count+1);
221     ExFreePool(npt);
222   }
223   if(ret) {
224     dc->w.CursPosX = pt[Count-1].x;
225     dc->w.CursPosY = pt[Count-1].y;
226   }
227   DC_ReleasePtr( hDC );
228   return ret;
229 }
230
231 BOOL
232 STDCALL
233 W32kPolyDraw(HDC  hDC,
234                    CONST LPPOINT  pt,
235                    CONST LPBYTE  Types,
236                    int  Count)
237 {
238   UNIMPLEMENTED;
239 }
240
241 BOOL
242 STDCALL
243 W32kPolyline(HDC  hDC,
244                    CONST LPPOINT  pt,
245                    int  Count)
246 {
247    UNIMPLEMENTED;
248 }
249
250 BOOL
251 STDCALL
252 W32kPolylineTo(HDC  hDC,
253                      CONST LPPOINT  pt,
254                      DWORD  Count)
255 {
256   DC *dc = DC_HandleToPtr(hDC);
257   BOOL ret;
258
259   if(!dc) return FALSE;
260
261   if(PATH_IsPathOpen(dc->w.path))
262   {
263     ret = PATH_PolylineTo(hDC, pt, Count);
264   }
265   else { /* do it using Polyline */
266     POINT *pts = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1));
267     if(!pts) return FALSE;
268
269     pts[0].x = dc->w.CursPosX;
270     pts[0].y = dc->w.CursPosY;
271     memcpy( pts + 1, pt, sizeof(POINT) * Count);
272     ret = W32kPolyline(hDC, pts, Count + 1);
273     ExFreePool(pts);
274   }
275   if(ret) {
276     dc->w.CursPosX = pt[Count-1].x;
277     dc->w.CursPosY = pt[Count-1].y;
278   }
279   DC_ReleasePtr( hDC );
280   return ret;
281 }
282
283 BOOL
284 STDCALL
285 W32kPolyPolyline(HDC  hDC,
286                        CONST LPPOINT  pt,
287                        CONST LPDWORD  PolyPoints,
288                        DWORD  Count)
289 {
290    UNIMPLEMENTED;
291 }
292
293 int
294 STDCALL
295 W32kSetArcDirection(HDC  hDC,
296                          int  ArcDirection)
297 {
298   PDC  dc;
299   INT  nOldDirection;
300
301   dc = DC_HandleToPtr (hDC);
302   if (!dc)
303   {
304     return 0;
305   }
306   if (ArcDirection != AD_COUNTERCLOCKWISE && ArcDirection != AD_CLOCKWISE)
307   {
308 //    SetLastError(ERROR_INVALID_PARAMETER);
309         DC_ReleasePtr( hDC );
310     return 0;
311   }
312
313   nOldDirection = dc->w.ArcDirection;
314   dc->w.ArcDirection = ArcDirection;
315   DC_ReleasePtr( hDC );
316   return nOldDirection;
317 }