2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 // Some code from the WINE project source (www.winehq.com)
23 #undef WIN32_LEAN_AND_MEAN
25 #include <internal/safe.h>
26 #include <ddk/ntddk.h>
27 #include <win32k/dc.h>
28 #include <win32k/line.h>
29 #include <win32k/path.h>
30 #include <win32k/pen.h>
31 #include <win32k/region.h>
32 #include <include/error.h>
33 #include <include/inteng.h>
34 #include <include/object.h>
35 #include <include/path.h>
38 #include <win32k/debug1.h>
43 NtGdiAngleArc(HDC hDC,
65 DC *dc = DC_LockDc(hDC);
68 if(PATH_IsPathOpen(dc->w.path))
71 return PATH_Arc(hDC, LeftRect, TopRect, RightRect, BottomRect,
72 XStartArc, YStartArc, XEndArc, YEndArc);
76 // EngArc(dc, LeftRect, TopRect, RightRect, BottomRect, UNIMPLEMENTED
77 // XStartArc, YStartArc, XEndArc, YEndArc);
98 // Line from current position to starting point of arc
99 if ( !NtGdiLineTo(hDC, XRadial1, YRadial1) )
102 //dc = DC_LockDc(hDC);
104 //if(!dc) return FALSE;
106 // Then the arc is drawn.
107 result = NtGdiArc(hDC, LeftRect, TopRect, RightRect, BottomRect,
108 XRadial1, YRadial1, XRadial2, YRadial2);
110 //DC_UnlockDc( hDC );
112 // If no error occured, the current position is moved to the ending point of the arc.
114 NtGdiMoveToEx(hDC, XRadial2, YRadial2, NULL);
121 IntGetArcDirection ( PDC dc )
124 return dc->w.ArcDirection;
129 NtGdiGetArcDirection(HDC hDC)
131 PDC dc = DC_LockDc (hDC);
132 int ret = 0; // default to failure
136 ret = IntGetArcDirection ( dc );
149 DC *dc = DC_LockDc(hDC);
152 BRUSHOBJ PenBrushObj;
157 SetLastWin32Error(ERROR_INVALID_HANDLE);
161 SurfObj = (SURFOBJ*)AccessUserObject ( (ULONG)dc->Surface );
163 if (PATH_IsPathOpen(dc->w.path))
166 Ret = PATH_LineTo(hDC, XEnd, YEnd);
169 // FIXME - PATH_LineTo should maybe do this...
171 dc->w.CursPosX = XEnd;
172 dc->w.CursPosY = YEnd;
179 if (dc->w.CursPosX <= XEnd)
181 Bounds.left = dc->w.CursPosX;
187 Bounds.right = dc->w.CursPosX;
189 Bounds.left += dc->w.DCOrgX;
190 Bounds.right += dc->w.DCOrgX;
191 if (dc->w.CursPosY <= YEnd)
193 Bounds.top = dc->w.CursPosY;
194 Bounds.bottom = YEnd;
199 Bounds.bottom = dc->w.CursPosY;
201 Bounds.top += dc->w.DCOrgY;
202 Bounds.bottom += dc->w.DCOrgY;
204 /* make BRUSHOBJ from current pen. */
205 HPenToBrushObj ( &PenBrushObj, dc->w.hPen );
207 Ret = IntEngLineTo(SurfObj,
210 dc->w.DCOrgX + dc->w.CursPosX, dc->w.DCOrgY + dc->w.CursPosY,
211 dc->w.DCOrgX + XEnd, dc->w.DCOrgY + YEnd,
218 dc->w.CursPosX = XEnd;
219 dc->w.CursPosY = YEnd;
228 NtGdiMoveToEx(HDC hDC,
233 DC *dc = DC_LockDc( hDC );
236 if ( !dc ) return FALSE;
240 Point->x = dc->w.CursPosX;
241 Point->y = dc->w.CursPosY;
246 PathIsOpen = PATH_IsPathOpen(dc->w.path);
251 return PATH_MoveTo ( hDC );
258 NtGdiPolyBezier(HDC hDC,
262 DC *dc = DC_LockDc(hDC);
263 BOOL ret = FALSE; // default to FAILURE
265 if ( !dc ) return FALSE;
267 if ( PATH_IsPathOpen(dc->w.path) )
270 return PATH_PolyBezier ( hDC, pt, Count );
273 /* We'll convert it into line segments and draw them using Polyline */
278 Pts = GDI_Bezier ( pt, Count, &nOut );
281 DbgPrint("Pts = %p, no = %d\n", Pts, nOut);
282 ret = NtGdiPolyline(dc->hSelf, Pts, nOut);
292 NtGdiPolyBezierTo(HDC hDC,
296 DC *dc = DC_LockDc(hDC);
297 BOOL ret = FALSE; // default to failure
299 if ( !dc ) return ret;
301 if ( PATH_IsPathOpen(dc->w.path) )
302 ret = PATH_PolyBezierTo ( hDC, pt, Count );
303 else /* We'll do it using PolyBezier */
306 npt = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1));
309 npt[0].x = dc->w.CursPosX;
310 npt[0].y = dc->w.CursPosY;
311 memcpy(npt + 1, pt, sizeof(POINT) * Count);
312 ret = NtGdiPolyBezier(dc->hSelf, npt, Count+1);
318 dc->w.CursPosX = pt[Count-1].x;
319 dc->w.CursPosY = pt[Count-1].y;
327 NtGdiPolyDraw(HDC hDC,
341 SURFOBJ *SurfObj = NULL;
342 BOOL ret = FALSE; // default to failure
345 BRUSHOBJ PenBrushObj;
348 SurfObj = (SURFOBJ*)AccessUserObject((ULONG)dc->Surface);
351 if ( PATH_IsPathOpen ( dc->w.path ) )
352 return PATH_Polyline ( dc, pt, Count );
354 reg = RGNDATA_LockRgn(dc->w.hGCClipRgn);
356 //FIXME: Do somthing with reg...
358 //Allocate "Count" bytes of memory to hold a safe copy of pt
359 pts = (POINT*)ExAllocatePool ( NonPagedPool, sizeof(POINT)*Count );
362 // safely copy pt to local version
363 if ( STATUS_SUCCESS == MmCopyFromCaller(pts, pt, sizeof(POINT)*Count) )
365 //offset the array of point by the dc->w.DCOrg
366 for ( i = 0; i < Count; i++ )
368 pts[i].x += dc->w.DCOrgX;
369 pts[i].y += dc->w.DCOrgY;
372 /* make BRUSHOBJ from current pen. */
373 HPenToBrushObj ( &PenBrushObj, dc->w.hPen );
375 //get IntEngPolyline to do the drawing.
376 ret = IntEngPolyline(SurfObj,
388 RGNDATA_UnlockRgn(dc->w.hGCClipRgn);
395 NtGdiPolyline(HDC hDC,
399 DC *dc = DC_LockDc(hDC);
400 BOOL ret = FALSE; // default to failure
404 ret = IntPolyline ( dc, pt, Count );
414 NtGdiPolylineTo(HDC hDC,
418 DC *dc = DC_LockDc(hDC);
419 BOOL ret = FALSE; // default to failure
421 if ( !dc ) return ret;
423 if(PATH_IsPathOpen(dc->w.path))
425 ret = PATH_PolylineTo(hDC, pt, Count);
427 else /* do it using Polyline */
429 POINT *pts = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1));
432 pts[0].x = dc->w.CursPosX;
433 pts[0].y = dc->w.CursPosY;
434 memcpy( pts + 1, pt, sizeof(POINT) * Count);
435 ret = NtGdiPolyline(hDC, pts, Count + 1);
441 dc->w.CursPosX = pt[Count-1].x;
442 dc->w.CursPosY = pt[Count-1].y;
450 NtGdiPolyPolyline(HDC hDC,
452 CONST LPDWORD PolyPoints,
455 DC *dc = DC_LockDc(hDC);
459 BOOL ret = FALSE; // default to failure
464 for (i=0;i<Count;i++)
466 ret = IntPolyline ( dc, pts, *pc );
482 NtGdiSetArcDirection(HDC hDC,
486 INT nOldDirection = 0; // default to FAILURE
488 dc = DC_LockDc (hDC);
491 if ( ArcDirection == AD_COUNTERCLOCKWISE || ArcDirection == AD_CLOCKWISE )
493 nOldDirection = dc->w.ArcDirection;
494 dc->w.ArcDirection = ArcDirection;
498 return nOldDirection;