04c8c776e5a5512e9ba20b27d5582ab0a8c1d89b
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.
19 /* $Id: line.c,v 1.21 2003/08/20 07:45:02 gvg Exp $ */
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
,
460 NtGdiSetArcDirection(HDC hDC
,
464 INT nOldDirection
= 0; // default to FAILURE
466 dc
= DC_LockDc (hDC
);
469 if ( ArcDirection
== AD_COUNTERCLOCKWISE
|| ArcDirection
== AD_CLOCKWISE
)
471 nOldDirection
= dc
->w
.ArcDirection
;
472 dc
->w
.ArcDirection
= ArcDirection
;
476 return nOldDirection
;