Path needed some love Phase I:

- Rewrite Path handle support and reordered path.c.
- Wine Sync/Port PATH_WidenPath and PATH_DoArcPart. Wine Path test results: 151 tests executed (0 marked as todo, 24 failures). 3 skipped.
- Found where the use of SelectObject in DC_InitDC, placed nulls into hbrush and hpen, I comment out and used StockObject and now default drawing works.
- Implemented AngleArc and most of Arc. This is very experimental and it does draw and does not crash.
- Cleaned up some files with extra <CR> at the end of lines.
- Fully tested: Taskmgr, FF 1.5, Abiword, drawing programs, and all.
- Note: Path drawing is majorly misaligned. Fill path will draw in one area and Stroke path will draw in another.
- Note: Trunk: Gdi wine DC test: dc.c:89 Failed to lock hDC, sometimes locking up the system. See bug 3333.

svn path=/trunk/; revision=34119
This commit is contained in:
James Tabor 2008-06-27 00:06:46 +00:00
parent 69f86788f8
commit 64a20b3ace
9 changed files with 2800 additions and 2249 deletions

View file

@ -9,11 +9,6 @@
// Get/SetBounds/Rect support. // Get/SetBounds/Rect support.
#define DCB_WINDOWMGR 0x8000 // Queries the Windows bounding rectangle instead of the application's #define DCB_WINDOWMGR 0x8000 // Queries the Windows bounding rectangle instead of the application's
/* DCPATH flPath */
#define DCPATH_ACTIVE 0x0001
#define DCPATH_SAVE 0x0002
#define DCPATH_CLOCKWISE 0x0004
// GDIDEVICE flags // GDIDEVICE flags
#define PDEV_DISPLAY 0x00000001 // Display device #define PDEV_DISPLAY 0x00000001 // Display device
#define PDEV_HARDWARE_POINTER 0x00000002 // Supports hardware cursor #define PDEV_HARDWARE_POINTER 0x00000002 // Supports hardware cursor
@ -34,22 +29,6 @@
/* Type definitions ***********************************************************/ /* Type definitions ***********************************************************/
typedef enum tagGdiPathState
{
PATH_Null,
PATH_Open,
PATH_Closed
} GdiPathState;
typedef struct tagGdiPath
{
GdiPathState state;
POINT *pPoints;
BYTE *pFlags;
int numEntriesUsed, numEntriesAllocated;
BOOL newStroke;
} GdiPath;
typedef struct _WIN_DC_INFO typedef struct _WIN_DC_INFO
{ {
HRGN hClipRgn; /* Clip region (may be 0) */ HRGN hClipRgn; /* Clip region (may be 0) */
@ -60,10 +39,6 @@ typedef struct _WIN_DC_INFO
HRGN hGCClipRgn; /* GC clip region (ClipRgn AND VisRgn) */ HRGN hGCClipRgn; /* GC clip region (ClipRgn AND VisRgn) */
HBITMAP hBitmap; HBITMAP hBitmap;
/* #if 0 */
GdiPath path;
/* #endif */
BYTE bitsPerPixel; BYTE bitsPerPixel;
} WIN_DC_INFO; } WIN_DC_INFO;

View file

@ -1,6 +1,22 @@
#ifndef _WIN32K_PATH_H #ifndef _WIN32K_PATH_H
#define _WIN32K_PATH_H #define _WIN32K_PATH_H
/* DCPATH flPath */
#define DCPATH_ACTIVE 0x0001
#define DCPATH_SAVE 0x0002
#define DCPATH_CLOCKWISE 0x0004
// ReactOS only
#define DCPATH_SAVESTATE 0x80000000
typedef HGDIOBJ HPATH, *PHPATH;
typedef enum tagGdiPathState
{
PATH_Null,
PATH_Open,
PATH_Closed
} GdiPathState;
typedef struct _PATH typedef struct _PATH
{ {
BASEOBJECT BaseObject; BASEOBJECT BaseObject;
@ -26,19 +42,19 @@ typedef struct _EPATHOBJ
#define PATH_AllocPath() ((PPATH) GDIOBJ_AllocObj(GDIObjType_PATH_TYPE)) #define PATH_AllocPath() ((PPATH) GDIOBJ_AllocObj(GDIObjType_PATH_TYPE))
#define PATH_AllocPathWithHandle() ((PPATH) GDIOBJ_AllocObjWithHandle (GDI_OBJECT_TYPE_PATH)) #define PATH_AllocPathWithHandle() ((PPATH) GDIOBJ_AllocObjWithHandle (GDI_OBJECT_TYPE_PATH))
#define PATH_FreePath(pPath) GDIOBJ_FreeObj((POBJ)pPath, GDIObjType_PATH_TYPE) #define PATH_FreePath(pPath) GDIOBJ_FreeObj((POBJ)pPath, GDIObjType_PATH_TYPE)
#define PATH_FreePathByHandle(hPath) GDIOBJ_FreeObjbyHandle((HGDIOBJ)hPath, GDI_OBJECT_TYPE_PATH) #define PATH_FreeExtPathByHandle(hPath) GDIOBJ_FreeObjByHandle((HGDIOBJ) hPath, GDI_OBJECT_TYPE_PATH)
#define PATH_LockPath(hPath) ((PROSRGNDATA)GDIOBJ_LockObj((HGDIOBJ)hPath, GDI_OBJECT_TYPE_PATH)) #define PATH_LockPath(hPath) ((PPATH)GDIOBJ_ShareLockObj((HGDIOBJ)hPath, GDI_OBJECT_TYPE_PATH))
#define PATH_UnlockPath(pPath) GDIOBJ_UnlockObjByPtr((POBJ)pPath) #define PATH_UnlockPath(pPath) GDIOBJ_ShareUnlockObjByPtr((POBJ)pPath)
#define PATH_IsPathOpen(path) ((path).state==PATH_Open) #define PATH_IsPathOpen(DcLevel) ( ((DcLevel).hPath) && ((DcLevel).flPath & DCPATH_ACTIVE) )
BOOL FASTCALL PATH_Arc (PDC dc, INT x1, INT y1, INT x2, INT y2, INT xStart, INT yStart, INT xEnd, INT yEnd, INT lines); BOOL FASTCALL PATH_Arc (PDC dc, INT x1, INT y1, INT x2, INT y2, INT xStart, INT yStart, INT xEnd, INT yEnd, INT lines);
BOOL FASTCALL PATH_AssignGdiPath (GdiPath *pPathDest, const GdiPath *pPathSrc); BOOL FASTCALL PATH_AssignGdiPath (PPATH pPathDest, const PPATH pPathSrc);
VOID FASTCALL PATH_DestroyGdiPath (GdiPath *pPath); VOID FASTCALL PATH_DestroyGdiPath (PPATH pPath);
BOOL FASTCALL PATH_Ellipse (PDC dc, INT x1, INT y1, INT x2, INT y2); BOOL FASTCALL PATH_Ellipse (PDC dc, INT x1, INT y1, INT x2, INT y2);
VOID FASTCALL PATH_EmptyPath (GdiPath *pPath); VOID FASTCALL PATH_EmptyPath (PPATH pPath);
VOID FASTCALL PATH_InitGdiPath (GdiPath *pPath); VOID FASTCALL PATH_InitGdiPath (PPATH pPath);
BOOL FASTCALL PATH_LineTo (PDC dc, INT x, INT y); BOOL FASTCALL PATH_LineTo (PDC dc, INT x, INT y);
BOOL FASTCALL PATH_MoveTo (PDC dc); BOOL FASTCALL PATH_MoveTo (PDC dc);
BOOL FASTCALL PATH_PolyBezier (PDC dc, const POINT *pts, DWORD cbPoints); BOOL FASTCALL PATH_PolyBezier (PDC dc, const POINT *pts, DWORD cbPoints);
@ -50,8 +66,9 @@ BOOL FASTCALL PATH_PolyPolygon ( PDC dc, const POINT* pts, const INT* counts, UI
BOOL FASTCALL PATH_PolyPolyline( PDC dc, const POINT* pts, const DWORD* counts, DWORD polylines); BOOL FASTCALL PATH_PolyPolyline( PDC dc, const POINT* pts, const DWORD* counts, DWORD polylines);
BOOL FASTCALL PATH_Rectangle (PDC dc, INT x1, INT y1, INT x2, INT y2); BOOL FASTCALL PATH_Rectangle (PDC dc, INT x1, INT y1, INT x2, INT y2);
BOOL FASTCALL PATH_RoundRect(DC *dc, INT x1, INT y1, INT x2, INT y2, INT ell_width, INT ell_height); BOOL FASTCALL PATH_RoundRect(DC *dc, INT x1, INT y1, INT x2, INT y2, INT ell_width, INT ell_height);
BOOL FASTCALL PATH_PathToRegion (GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn); BOOL FASTCALL PATH_PathToRegion (PPATH pPath, INT nPolyFillMode, HRGN *pHrgn);
VOID FASTCALL IntGdiCloseFigure(PDC pDc); VOID FASTCALL IntGdiCloseFigure(PPATH pPath);
BOOL FASTCALL PATH_Delete(HPATH hPath);
#endif /* _WIN32K_PATH_H */ #endif /* _WIN32K_PATH_H */

View file

@ -1,471 +1,323 @@
#include <w32k.h>
#define NDEBUG
#include <debug.h>
typedef struct tagSHAPEPOINT
{
int X;
int Y;
int Type;
} SHAPEPOINT, *PSHAPEPOINT;
#define SHAPEPOINT_TYPE_CIRCLE 'C' #include <w32k.h>
#define SHAPEPOINT_TYPE_LINE_RIGHT 'R' /* Fill at right side of line */
#define SHAPEPOINT_TYPE_LINE_LEFT 'L' /* Fill at left side of line */
#define SETPOINT(x, y, type) \ #define NDEBUG
ShapePoints[*PointCount].X = (x); \ #include <debug.h>
ShapePoints[*PointCount].Y = (y); \
ShapePoints[*PointCount].Type = (type); \
(*PointCount)++
#define SETCIRCLEPOINT(x, y) \ /*
SETPOINT(x, y, SHAPEPOINT_TYPE_CIRCLE) * a couple macros to fill a single pixel or a line
*/
#ifdef TODO #define PUTPIXEL(x,y,BrushInst) \
STATIC VOID ret = ret && IntEngLineTo(&BitmapObj->SurfObj, \
FASTCALL dc->CombinedClip, \
CirclePoints(UINT *PointCount, PSHAPEPOINT ShapePoints, int Left, int Top, &BrushInst.BrushObject, \
int Right, int Bottom) x, y, (x)+1, y, \
{ &RectBounds, \
int X, X18, X27, X36, X45; ROP2_TO_MIX(Dc_Attr->jROP2));
int Y, Y14, Y23, Y58, Y67;
int d, Radius;
BOOL Even;
Even = (0 == (Right - Left) % 2); #define PUTLINE(x1,y1,x2,y2,BrushInst) \
Right--; ret = ret && IntEngLineTo(&BitmapObj->SurfObj, \
Bottom--; dc->CombinedClip, \
Radius = (Right - Left) >> 1; &BrushInst.BrushObject, \
x1, y1, x2, y2, \
&RectBounds, \
ROP2_TO_MIX(Dc_Attr->jROP2));
if (Even) #define Rsin(d) ((d) == 0.0 ? 0.0 : ((d) == 90.0 ? 1.0 : sin(d*M_PI/180.0)))
{ #define Rcos(d) ((d) == 0.0 ? 1.0 : ((d) == 90.0 ? 0.0 : cos(d*M_PI/180.0)))
X = 0;
Y = Radius;
d = 2 - Radius;
X18 = Right;
X27 = ((Left + Right) >> 1) + 1;
X36 = (Left + Right) >> 1;
X45 = Left;
Y14 = Top + Radius;
Y23 = Top;
Y58 = Top + Radius + 1;
Y67 = Top + (Right - Left);
ShapePoints[*PointCount].X = X27;
SETCIRCLEPOINT(X27, Y23);
SETCIRCLEPOINT(X36, Y23);
SETCIRCLEPOINT(X18, Y14);
SETCIRCLEPOINT(X45, Y14);
SETCIRCLEPOINT(X18, Y58);
SETCIRCLEPOINT(X45, Y58);
SETCIRCLEPOINT(X27, Y67);
SETCIRCLEPOINT(X36, Y67);
}
else
{
X = 0;
Y = Radius;
d = 1 - Radius;
X18 = Right;
X27 = (Left + Right) >> 1;
X36 = (Left + Right) >> 1;
X45 = Left;
Y14 = Top + Radius;
Y23 = Top;
Y58 = Top + Radius;
Y67 = Top + (Right - Left);
SETCIRCLEPOINT(X27, Y23);
SETCIRCLEPOINT(X45, Y14);
SETCIRCLEPOINT(X18, Y58);
SETCIRCLEPOINT(X27, Y67);
}
while (X < Y) static
{
if (d < 0)
{
d += (X << 1) + (Even ? 4 : 3);
X27++;
X36--;
Y14--;
Y58++;
}
else
{
d += ((X - Y) << 1) + 5;
Y--;
Y23++;
Y67--;
X18--;
X45++;
X27++;
X36--;
Y14--;
Y58++;
}
X++;
SETCIRCLEPOINT(X27, Y23);
SETCIRCLEPOINT(X36, Y23);
SETCIRCLEPOINT(X18, Y14);
SETCIRCLEPOINT(X45, Y14);
SETCIRCLEPOINT(X18, Y58);
SETCIRCLEPOINT(X45, Y58);
SETCIRCLEPOINT(X27, Y67);
SETCIRCLEPOINT(X36, Y67);
}
}
STATIC VOID
LinePoints(UINT *PointCount, PSHAPEPOINT ShapePoints, int Left, int Top,
int Right, int Bottom, int XTo, int YTo, BOOL Start)
{
LONG x, y, deltax, deltay, i, xchange, ychange, error;
int Type;
x = (Right + Left) >> 1;
y = (Bottom + Top) >> 1;
deltax = XTo - x;
deltay = YTo - y;
if (deltax < 0)
{
xchange = -1;
deltax = - deltax;
x--;
}
else
{
xchange = 1;
}
if (deltay < 0)
{
ychange = -1;
deltay = - deltay;
y--;
Type = (Start ? SHAPEPOINT_TYPE_LINE_LEFT : SHAPEPOINT_TYPE_LINE_RIGHT);
}
else
{
ychange = 1;
Type = (Start ? SHAPEPOINT_TYPE_LINE_RIGHT : SHAPEPOINT_TYPE_LINE_LEFT);
}
if (y == YTo)
{
for (i = x; i <= XTo; i++)
{
SETPOINT(i, y, Type);
}
}
else if (x == XTo)
{
for (i = y; i <= YTo; i++)
{
SETPOINT(x, i, Type);
}
}
else
{
error = 0;
if (deltax < deltay)
{
for (i = 0; i < deltay; i++)
{
SETPOINT(x, y, Type);
y = y + ychange;
error = error + deltax;
if (deltay <= error)
{
x = x + xchange;
error = error - deltay;
}
}
}
else
{
for (i = 0; i < deltax; i++)
{
SETPOINT(x, y, Type);
x = x + xchange;
error = error + deltay;
if (deltax <= error)
{
y = y + ychange;
error = error - deltax;
}
}
}
}
}
STATIC int
CDECL
CompareShapePoints(const void *pv1, const void *pv2)
{
if (((const PSHAPEPOINT) pv1)->Y < ((const PSHAPEPOINT) pv2)->Y)
{
return -1;
}
else if (((const PSHAPEPOINT) pv2)->Y < ((const PSHAPEPOINT) pv1)->Y)
{
return +1;
}
else if (((const PSHAPEPOINT) pv1)->X < ((const PSHAPEPOINT) pv2)->X)
{
return -1;
}
else if (((const PSHAPEPOINT) pv2)->X < ((const PSHAPEPOINT) pv1)->X)
{
return +1;
}
else
{
return 0;
}
}
#endif
BOOL BOOL
STDCALL FASTCALL
NtGdiPie(HDC hDC, IntArc( DC *dc,
int Left, int Left,
int Top, int Top,
int Right, int Right,
int Bottom, int Bottom,
int XRadialStart, int XRadialStart,
int YRadialStart, int YRadialStart,
int XRadialEnd, int XRadialEnd,
int YRadialEnd) int YRadialEnd,
ARCTYPE arctype)
{ {
#ifdef TODO PDC_ATTR Dc_Attr;
PDC dc;
PDC_ATTR;
RECTL RectBounds; RECTL RectBounds;
SURFOBJ *SurfObj; PGDIBRUSHOBJ PenBrushObj, FillBrushObj;
BRUSHOBJ PenBrushObj; GDIBRUSHINST FillBrushInst, PenBrushInst;
PBRUSHOBJ FillBrushObj; BITMAPOBJ *BitmapObj;
PSHAPEPOINT ShapePoints;
UINT Point, PointCount;
BOOL ret = TRUE; BOOL ret = TRUE;
int Y, CircleStart, CircleEnd, LineStart, LineEnd; double AngleStart, AngleEnd;
BOOL FullFill; LONG RadiusX, RadiusY, CenterX, CenterY;
LONG SfCx, SfCy, EfCx, EfCy;
if (Right <= Left || Bottom <= Top) /* top
___________________
+| |
| |
| |
left | | right
| |
| |
0|___________________|
0 bottom +
*/
if (Right <= Left || Top <= Bottom)
{ {
DPRINT1("Arc Fail 1\n");
SetLastWin32Error(ERROR_INVALID_PARAMETER); SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
/*
if (Right - Left != Bottom - Top) if (Right - Left != Bottom - Top)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
} }
*/
dc = DC_LockDc ( hDC );
if (NULL == dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
if (dc->DC_Type == DC_TYPE_INFO)
{
DC_UnlockDc(dc);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
Dc_Attr = dc->pDc_Attr; Dc_Attr = dc->pDc_Attr;
if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr; if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
FillBrushObj = BRUSHOBJ_LockBrush(Dc_Attr->hbrush); FillBrushObj = BRUSHOBJ_LockBrush(Dc_Attr->hbrush);
if (NULL == FillBrushObj) if (NULL == FillBrushObj)
{ {
DC_UnlockDc(dc); DPRINT1("Arc Fail 2\n");
SetLastWin32Error(ERROR_INTERNAL_ERROR); SetLastWin32Error(ERROR_INTERNAL_ERROR);
return FALSE; return FALSE;
} }
Left += dc->ptlDCOrig.x; PenBrushObj = PENOBJ_LockPen(Dc_Attr->hpen);
Right += dc->ptlDCOrig.x; if (NULL == PenBrushObj)
Top += dc->ptlDCOrig.y;
Bottom += dc->ptlDCOrig.y;
XRadialStart += dc->ptlDCOrig.x;
YRadialStart += dc->ptlDCOrig.y;
XRadialEnd += dc->ptlDCOrig.x;
YRadialEnd += dc->ptlDCOrig.y;
RectBounds.left = Left;
RectBounds.right = Right;
RectBounds.top = Top;
RectBounds.bottom = Bottom;
SurfObj = (SURFOBJ*) AccessUserObject((ULONG)dc->Surface);
HPenToBrushObj(&PenBrushObj, Dc_Attr->hpen);
/* Number of points for the circle is 4 * sqrt(2) * Radius, start
and end line have at most Radius points, so allocate at least
that much */
ShapePoints = ExAllocatePoolWithTag(PagedPool, 8 * (Right - Left + 1) / 2 * sizeof(SHAPEPOINT), TAG_SHAPE);
if (NULL == ShapePoints)
{ {
DPRINT1("Arc Fail 3\n");
BRUSHOBJ_UnlockBrush(FillBrushObj); BRUSHOBJ_UnlockBrush(FillBrushObj);
DC_UnlockDc(dc); SetLastWin32Error(ERROR_INTERNAL_ERROR);
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return FALSE; return FALSE;
} }
BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
if (NULL == BitmapObj)
{
DPRINT1("Arc Fail 4\n");
BRUSHOBJ_UnlockBrush(FillBrushObj);
PENOBJ_UnlockPen(PenBrushObj);
SetLastWin32Error(ERROR_INTERNAL_ERROR);
return FALSE;
}
IntGdiInitBrushInstance(&FillBrushInst, FillBrushObj, dc->XlateBrush);
IntGdiInitBrushInstance(&PenBrushInst, PenBrushObj, dc->XlatePen);
Left += dc->ptlDCOrig.x;
Right += dc->ptlDCOrig.x;
Top += dc->ptlDCOrig.y;
Bottom += dc->ptlDCOrig.y;
XRadialStart += dc->ptlDCOrig.x;
YRadialStart += dc->ptlDCOrig.y;
XRadialEnd += dc->ptlDCOrig.x;
YRadialEnd += dc->ptlDCOrig.y;
DPRINT1("1: StartX: %d, StartY: %d, EndX: %d, EndY: %d\n",
XRadialStart,YRadialStart,XRadialEnd,YRadialEnd);
RectBounds.left = Left;
RectBounds.right = Right;
RectBounds.top = Top;
RectBounds.bottom = Bottom;
DPRINT1("1: Left: %d, Top: %d, Right: %d, Bottom: %d\n",
RectBounds.left,RectBounds.top,RectBounds.right,RectBounds.bottom);
if (Left == Right) if (Left == Right)
{ {
PUTPIXEL(Left, Top, &PenBrushObj); DPRINT1("Arc Good Exit\n");
PUTPIXEL(Left, Top, PenBrushInst);
BITMAPOBJ_UnlockBitmap(BitmapObj);
BRUSHOBJ_UnlockBrush(FillBrushObj); BRUSHOBJ_UnlockBrush(FillBrushObj);
DC_UnlockDc(dc); PENOBJ_UnlockPen(PenBrushObj);
return ret; return ret;
} }
RadiusX = (RectBounds.right - RectBounds.left)/2;
RadiusY = (RectBounds.bottom - RectBounds.top)/2;
CenterX = RectBounds.left + RadiusX;
CenterY = RectBounds.top + RadiusY;
PointCount = 0; AngleEnd = atan2(-(YRadialEnd - CenterY), XRadialEnd - CenterX)* (180.0 / M_PI);
CirclePoints(&PointCount, ShapePoints, Left, Top, Right, Bottom); AngleStart = atan2(-(YRadialStart - CenterY), XRadialStart - CenterX)* (180.0 / M_PI);
LinePoints(&PointCount, ShapePoints, Left, Top, Right, Bottom,
XRadialStart, YRadialStart, TRUE);
LinePoints(&PointCount, ShapePoints, Left, Top, Right, Bottom,
XRadialEnd, YRadialEnd, FALSE);
ASSERT(PointCount <= 8 * (Right - Left + 1) / 2);
EngSort((PBYTE) ShapePoints, sizeof(SHAPEPOINT), PointCount, CompareShapePoints);
FullFill = TRUE; SfCx = (Rcos(AngleStart) * RadiusX);
Point = 0; SfCy = (Rsin(AngleStart) * RadiusY);
while (Point < PointCount)
EfCx = (Rcos(AngleEnd) * RadiusX);
EfCy = (Rsin(AngleEnd) * RadiusY);
{ {
Y = ShapePoints[Point].Y; FLOAT AngS = AngleStart, Factor = 1;
int x,y, ox = 0, oy = 0;
/* Skip any line pixels before circle */ if (arctype == GdiTypePie)
while (Point < PointCount && ShapePoints[Point].Y == Y {
&& SHAPEPOINT_TYPE_CIRCLE != ShapePoints[Point].Type) PUTLINE(SfCx + CenterX, SfCy + CenterY, CenterX, CenterY, PenBrushInst);
{ }
Point++;
}
/* Handle left side of circle */ for(; AngS < AngleEnd; AngS += Factor)
if (Point < PointCount && ShapePoints[Point].Y == Y) {
{ x = (Rcos(AngS) * RadiusX);
CircleStart = ShapePoints[Point].X; y = (Rsin(AngS) * RadiusY);
Point++;
while (Point < PointCount && ShapePoints[Point].Y == Y if (arctype == GdiTypePie)
&& ShapePoints[Point].X == ShapePoints[Point - 1].X + 1 PUTLINE((x + CenterX) - 1, (y + CenterY) - 1, CenterX, CenterY, FillBrushInst);
&& SHAPEPOINT_TYPE_CIRCLE == ShapePoints[Point].Type)
{
Point++;
}
CircleEnd = ShapePoints[Point - 1].X;
PUTLINE(CircleStart, Y, CircleEnd + 1, Y, &PenBrushObj); PUTPIXEL (x + CenterX, y + CenterY, PenBrushInst);
} ox = x;
oy = y;
}
/* Handle line(s) (max 2) inside the circle */ if (arctype == GdiTypePie)
while (Point < PointCount && ShapePoints[Point].Y == Y PUTLINE(EfCx + CenterX, EfCy + CenterY, CenterX, CenterY, PenBrushInst);
&& SHAPEPOINT_TYPE_CIRCLE != ShapePoints[Point].Type)
{
LineStart = ShapePoints[Point].X;
Point++;
while (Point < PointCount && ShapePoints[Point].Y == Y
&& ShapePoints[Point].X == ShapePoints[Point - 1].X + 1
&& ShapePoints[Point].Type == ShapePoints[Point - 1].Type)
{
Point++;
}
LineEnd = ShapePoints[Point - 1].X;
PUTLINE(LineStart, Y, LineEnd + 1, Y, &PenBrushObj);
}
/* Handle right side of circle */
while (Point < PointCount && ShapePoints[Point].Y == Y
&& SHAPEPOINT_TYPE_CIRCLE == ShapePoints[Point].Type)
{
CircleStart = ShapePoints[Point].X;
Point++;
while (Point < PointCount && ShapePoints[Point].Y == Y
&& ShapePoints[Point].X == ShapePoints[Point - 1].X + 1
&& SHAPEPOINT_TYPE_CIRCLE == ShapePoints[Point].Type)
{
Point++;
}
CircleEnd = ShapePoints[Point - 1].X;
PUTLINE(CircleStart, Y, CircleEnd + 1, Y, &PenBrushObj);
}
/* Skip any line pixels after circle */
while (Point < PointCount && ShapePoints[Point].Y == Y)
{
Point++;
}
} }
BITMAPOBJ_UnlockBitmap(BitmapObj);
ExFreePool(ShapePoints);
BRUSHOBJ_UnlockBrush(FillBrushObj); BRUSHOBJ_UnlockBrush(FillBrushObj);
DC_UnlockDc(dc); PENOBJ_UnlockPen(PenBrushObj);
DPRINT1("IntArc Exit.\n");
return ret; return ret;
#else
return TRUE;
#endif
} }
static BOOL FASTCALL BOOL FASTCALL
IntArc( DC *dc, int LeftRect, int TopRect, int RightRect, int BottomRect, IntGdiArcInternal(
int XStartArc, int YStartArc, int XEndArc, int YEndArc, ARCTYPE arctype) ARCTYPE arctype,
{ DC *dc,
return TRUE; int LeftRect,
} int TopRect,
int RightRect,
BOOL FASTCALL int BottomRect,
IntGdiArcInternal( int XStartArc,
ARCTYPE arctype, int YStartArc,
DC *dc, int XEndArc,
int LeftRect, int YEndArc)
int TopRect, {
int RightRect, BOOL Ret;
int BottomRect, RECT rc, rc1;
int XStartArc, double AngleStart, AngleEnd;
int YStartArc, LONG RadiusX, RadiusY, CenterX, CenterY, Width, Height;
int XEndArc, LONG SfCx, SfCy, EfCx = 0, EfCy = 0;
int YEndArc)
{ DPRINT1("StartX: %d, StartY: %d, EndX: %d, EndY: %d\n",
INT rx, ry; XStartArc,YStartArc,XEndArc,YEndArc);
RECT rc, rc1; DPRINT1("Left: %d, Top: %d, Right: %d, Bottom: %d\n",
LeftRect,TopRect,RightRect,BottomRect);
if(PATH_IsPathOpen(dc->w.path))
{ if (PATH_IsPathOpen(dc->DcLevel))
INT type = arctype; {
if (arctype == GdiTypeArcTo) type = GdiTypeArc; return PATH_Arc( dc,
return PATH_Arc(dc, LeftRect, TopRect, RightRect, BottomRect, LeftRect,
XStartArc, YStartArc, XEndArc, YEndArc, type); TopRect,
} RightRect,
BottomRect,
IntGdiSetRect(&rc, LeftRect, TopRect, RightRect, BottomRect); XStartArc,
IntGdiSetRect(&rc1, XStartArc, YStartArc, XEndArc, YEndArc); YStartArc,
XEndArc,
rx = (rc.right - rc.left)/2 - 1; YEndArc,
ry = (rc.bottom - rc.top)/2 -1; arctype);
rc.left += rx; }
rc.top += ry;
if (arctype == GdiTypeArcTo)
return IntArc( dc, rc.left, rc.top, rx, ry, {
rc1.left, rc1.top, rc1.right, rc1.bottom, arctype); Width = fabs(RightRect - LeftRect);
} Height = fabs(BottomRect - TopRect);
RadiusX = Width/2;
RadiusY = Height/2;
CenterX = RightRect > LeftRect ? LeftRect + RadiusX : RightRect + RadiusX;
CenterY = BottomRect > TopRect ? TopRect + RadiusY : BottomRect + RadiusY;
AngleStart = atan2((YStartArc - CenterY)/Height, (XStartArc - CenterX)/Width);
AngleEnd = atan2((YEndArc - CenterY)/Height, (XEndArc - CenterX)/Width);
EfCx = GDI_ROUND(CenterX+cos(AngleEnd) * RadiusX);
EfCy = GDI_ROUND(CenterY+sin(AngleEnd) * RadiusY);
SfCx = GDI_ROUND(CenterX+cos(AngleStart) * RadiusX);
SfCy = GDI_ROUND(CenterY+sin(AngleStart) * RadiusY);
IntGdiLineTo(dc, SfCx, SfCy);
}
IntGdiSetRect(&rc, LeftRect, TopRect, RightRect, BottomRect);
IntGdiSetRect(&rc1, XStartArc, YStartArc, XEndArc, YEndArc);
// IntLPtoDP(dc, (LPPOINT)&rc, 2);
// IntLPtoDP(dc, (LPPOINT)&rc1, 2);
Ret = IntArc( dc,
rc.left,
rc.top,
rc.right,
rc.bottom,
rc1.left,
rc1.top,
rc1.right,
rc1.bottom,
arctype);
if (arctype == GdiTypeArcTo)
{
dc->ptlDCOrig.x = EfCx;
dc->ptlDCOrig.y = EfCy;
}
return Ret;
}
BOOL
FASTCALL
IntGdiAngleArc( PDC pDC,
INT x,
INT y,
DWORD dwRadius,
FLOAT eStartAngle,
FLOAT eSweepAngle)
{
INT x1, y1, x2, y2, arcdir;
BOOL result;
/* Calculate the end point */
x2 = x + (INT)(cos(((eStartAngle+eSweepAngle)/360)*(M_PI*2)) * dwRadius);
y2 = y - (INT)(sin(((eStartAngle+eSweepAngle)/360)*(M_PI*2)) * dwRadius);
x1 = x + (INT)(cos((eStartAngle/360)*(M_PI*2)) * dwRadius);
y1 = y - (INT)(sin((eStartAngle/360)*(M_PI*2)) * dwRadius);
arcdir = pDC->DcLevel.flPath & DCPATH_CLOCKWISE;
if (eSweepAngle >= 0)
pDC->DcLevel.flPath &= ~DCPATH_CLOCKWISE;
else
pDC->DcLevel.flPath |= DCPATH_CLOCKWISE;
result = IntGdiArcInternal( GdiTypeArcTo,
pDC,
x-dwRadius,
y+dwRadius,
x+dwRadius,
y-dwRadius,
x1,
y1,
x2,
y2 );
pDC->DcLevel.flPath |= (arcdir & DCPATH_CLOCKWISE);
if (result)
{
POINT point;
point.x=x2;
point.y=y2;
// CoordLPtoDP ( pDC, &point );
pDC->ptlDCOrig.x = point.x;
pDC->ptlDCOrig.y = point.y;
}
return result;
}
/* FUNCTIONS *****************************************************************/
BOOL BOOL
APIENTRY APIENTRY
NtGdiAngleArc( NtGdiAngleArc(
@ -476,89 +328,72 @@ NtGdiAngleArc(
IN DWORD dwStartAngle, IN DWORD dwStartAngle,
IN DWORD dwSweepAngle) IN DWORD dwSweepAngle)
{ {
DC *dc; DC *pDC;
BOOL Ret = FALSE; BOOL Ret = FALSE;
gxf_long worker, worker1; gxf_long worker, worker1;
dc = DC_LockDc (hDC); pDC = DC_LockDc (hDC);
if(!dc) if(!pDC)
{ {
SetLastWin32Error(ERROR_INVALID_HANDLE); SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
if (dc->DC_Type == DC_TYPE_INFO) if (pDC->DC_Type == DC_TYPE_INFO)
{ {
DC_UnlockDc(dc); DC_UnlockDc(pDC);
/* Yes, Windows really returns TRUE in this case */ /* Yes, Windows really returns TRUE in this case */
return TRUE; return TRUE;
} }
worker.l = dwStartAngle; worker.l = dwStartAngle;
worker1.l = dwSweepAngle; worker1.l = dwSweepAngle;
Ret = IntGdiAngleArc( pDC, x, y, dwRadius, worker.f, worker1.f);
DC_UnlockDc( dc ); DC_UnlockDc( pDC );
return Ret; return Ret;
} }
BOOL BOOL
STDCALL STDCALL
NtGdiArcInternal( NtGdiArcInternal(
ARCTYPE arctype, ARCTYPE arctype,
HDC hDC, HDC hDC,
int LeftRect, int LeftRect,
int TopRect, int TopRect,
int RightRect, int RightRect,
int BottomRect, int BottomRect,
int XStartArc, int XStartArc,
int YStartArc, int YStartArc,
int XEndArc, int XEndArc,
int YEndArc) int YEndArc)
{ {
DC *dc; DC *dc;
BOOL Ret; BOOL Ret;
dc = DC_LockDc (hDC); dc = DC_LockDc (hDC);
if(!dc) if(!dc)
{ {
SetLastWin32Error(ERROR_INVALID_HANDLE); SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
if (dc->DC_Type == DC_TYPE_INFO) if (dc->DC_Type == DC_TYPE_INFO)
{ {
DC_UnlockDc(dc); DC_UnlockDc(dc);
/* Yes, Windows really returns TRUE in this case */ /* Yes, Windows really returns TRUE in this case */
return TRUE; return TRUE;
} }
if (arctype == GdiTypeArcTo) Ret = IntGdiArcInternal(
{ arctype,
// Line from current position to starting point of arc dc,
if ( !IntGdiLineTo(dc, XStartArc, YStartArc) ) LeftRect,
{ TopRect,
DC_UnlockDc(dc); RightRect,
return FALSE; BottomRect,
} XStartArc,
} YStartArc,
XEndArc,
Ret = IntGdiArcInternal( YEndArc);
arctype,
dc, DC_UnlockDc( dc );
LeftRect, return Ret;
TopRect, }
RightRect,
BottomRect,
XStartArc,
YStartArc,
XEndArc,
YEndArc);
if (arctype == GdiTypeArcTo)
{
// If no error occured, the current position is moved to the ending point of the arc.
if(Ret)
IntGdiMoveToEx(dc, XEndArc, YEndArc, NULL);
}
DC_UnlockDc( dc );
return Ret;
}

File diff suppressed because it is too large Load diff

View file

@ -1026,7 +1026,7 @@ IntGdiDeleteDC(HDC hDC, BOOL Force)
} }
/* Free GDI resources allocated to this DC */ /* Free GDI resources allocated to this DC */
if (!(DCToDelete->DcLevel.flPath & DCPATH_SAVE)) if (!(DCToDelete->DcLevel.flPath & DCPATH_SAVESTATE))
{ {
/* /*
NtGdiSelectPen (DCHandle, STOCK_BLACK_PEN); NtGdiSelectPen (DCHandle, STOCK_BLACK_PEN);
@ -1054,7 +1054,7 @@ IntGdiDeleteDC(HDC hDC, BOOL Force)
{ {
NtGdiDeleteObject (DCToDelete->w.hGCClipRgn); NtGdiDeleteObject (DCToDelete->w.hGCClipRgn);
} }
PATH_DestroyGdiPath (&DCToDelete->w.path); PATH_Delete(DCToDelete->DcLevel.hPath);
DC_UnlockDc( DCToDelete ); DC_UnlockDc( DCToDelete );
DC_FreeDC ( hDC ); DC_FreeDC ( hDC );
@ -1326,7 +1326,7 @@ IntGdiCopyToSaveState(PDC dc, PDC newdc)
nDc_Attr = newdc->pDc_Attr; nDc_Attr = newdc->pDc_Attr;
if(!nDc_Attr) nDc_Attr = &newdc->Dc_Attr; if(!nDc_Attr) nDc_Attr = &newdc->Dc_Attr;
newdc->DcLevel.flPath = dc->DcLevel.flPath | DCPATH_SAVE; newdc->DcLevel.flPath = dc->DcLevel.flPath | DCPATH_SAVESTATE;
nDc_Attr->dwLayout = Dc_Attr->dwLayout; nDc_Attr->dwLayout = Dc_Attr->dwLayout;
nDc_Attr->hpen = Dc_Attr->hpen; nDc_Attr->hpen = Dc_Attr->hpen;
nDc_Attr->hbrush = Dc_Attr->hbrush; nDc_Attr->hbrush = Dc_Attr->hbrush;
@ -1372,7 +1372,7 @@ IntGdiCopyToSaveState(PDC dc, PDC newdc)
newdc->DC_Type = dc->DC_Type; newdc->DC_Type = dc->DC_Type;
#if 0 #if 0
PATH_InitGdiPath( &newdc->w.path ); PATH_InitGdiPath( &newdc->DcLevel.hPath );
#endif #endif
/* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */ /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
@ -1397,7 +1397,7 @@ IntGdiCopyFromSaveState(PDC dc, PDC dcs, HDC hDC)
sDc_Attr = dcs->pDc_Attr; sDc_Attr = dcs->pDc_Attr;
if(!sDc_Attr) sDc_Attr = &dcs->Dc_Attr; if(!sDc_Attr) sDc_Attr = &dcs->Dc_Attr;
dc->DcLevel.flPath = dcs->DcLevel.flPath & ~DCPATH_SAVE; dc->DcLevel.flPath = dcs->DcLevel.flPath & ~DCPATH_SAVESTATE;
Dc_Attr->dwLayout = sDc_Attr->dwLayout; Dc_Attr->dwLayout = sDc_Attr->dwLayout;
Dc_Attr->jROP2 = sDc_Attr->jROP2; Dc_Attr->jROP2 = sDc_Attr->jROP2;
@ -1528,7 +1528,7 @@ IntGdiSetDCState ( HDC hDC, HDC hDCSave )
dcs = DC_LockDc ( hDCSave ); dcs = DC_LockDc ( hDCSave );
if ( dcs ) if ( dcs )
{ {
if ( dcs->DcLevel.flPath & DCPATH_SAVE ) if ( dcs->DcLevel.flPath & DCPATH_SAVESTATE )
{ {
IntGdiCopyFromSaveState( dc, dcs, dc->DcLevel.hdcSave); IntGdiCopyFromSaveState( dc, dcs, dc->DcLevel.hdcSave);
} }
@ -1824,17 +1824,19 @@ NtGdiRestoreDC(HDC hDC, INT SaveLevel)
IntGdiSetDCState(hDC, hdcs); IntGdiSetDCState(hDC, hdcs);
if (!PATH_AssignGdiPath( &dc->w.path, &dcs->w.path ))
{
/* FIXME: This might not be quite right, since we're
* returning FALSE but still destroying the saved DC state */
success = FALSE;
}
dc = DC_LockDc(hDC); dc = DC_LockDc(hDC);
if(!dc) if(!dc)
{ {
return FALSE; return FALSE;
} }
// Restore Path by removing it, if the Save flag is set.
// BeginPath will takecare of the rest.
if ( dc->DcLevel.hPath && dc->DcLevel.flPath & DCPATH_SAVE)
{
PATH_Delete(dc->DcLevel.hPath);
dc->DcLevel.hPath = 0;
dc->DcLevel.flPath &= ~DCPATH_SAVE;
}
} }
else else
{ {
@ -1875,20 +1877,11 @@ NtGdiSaveDC(HDC hDC)
return 0; return 0;
} }
#if 0 /*
/* Copy path. The reason why path saving / restoring is in SaveDC/ * Copy path.
* RestoreDC and not in GetDCState/SetDCState is that the ...DCState */
* functions are only in Win16 (which doesn't have paths) and that dcs->DcLevel.hPath = dc->DcLevel.hPath;
* SetDCState doesn't allow us to signal an error (which can happen if (dcs->DcLevel.hPath) dcs->DcLevel.flPath |= DCPATH_SAVE;
* when copying paths).
*/
if (!PATH_AssignGdiPath (&dcs->w.path, &dc->w.path))
{
NtGdiDeleteObjectApp (hdcs);
return 0;
}
#endif
DC_SetNextDC (dcs, DC_GetNextDC (dc)); DC_SetNextDC (dcs, DC_GetNextDC (dc));
DC_SetNextDC (dc, hdcs); DC_SetNextDC (dc, hdcs);
@ -2511,6 +2504,10 @@ DC_AllocDC(PUNICODE_STRING Driver)
Dc_Attr->ulBrushClr = RGB( 255, 255, 255 ); // Do this way too. Dc_Attr->ulBrushClr = RGB( 255, 255, 255 ); // Do this way too.
Dc_Attr->crBrushClr = RGB( 255, 255, 255 ); Dc_Attr->crBrushClr = RGB( 255, 255, 255 );
//// This fixes the default brush and pen settings. See DC_InitDC.
Dc_Attr->hbrush = NtGdiGetStockObject( WHITE_BRUSH );
Dc_Attr->hpen = NtGdiGetStockObject( BLACK_PEN );
////
Dc_Attr->hlfntNew = NtGdiGetStockObject(SYSTEM_FONT); Dc_Attr->hlfntNew = NtGdiGetStockObject(SYSTEM_FONT);
TextIntRealizeFont(Dc_Attr->hlfntNew); TextIntRealizeFont(Dc_Attr->hlfntNew);
@ -2536,8 +2533,10 @@ DC_InitDC(HDC DCHandle)
{ {
// NtGdiRealizeDefaultPalette(DCHandle); // NtGdiRealizeDefaultPalette(DCHandle);
NtGdiSelectBrush(DCHandle, NtGdiGetStockObject( WHITE_BRUSH )); //// Removed for now.. See above brush and pen.
NtGdiSelectPen(DCHandle, NtGdiGetStockObject( BLACK_PEN )); // NtGdiSelectBrush(DCHandle, NtGdiGetStockObject( WHITE_BRUSH ));
// NtGdiSelectPen(DCHandle, NtGdiGetStockObject( BLACK_PEN ));
////
//NtGdiSelectFont(DCHandle, hFont); //NtGdiSelectFont(DCHandle, hFont);
/* /*
@ -2729,6 +2728,10 @@ DC_SetOwnership(HDC hDC, PEPROCESS Owner)
{ {
if(!GDIOBJ_SetOwnership(pDC->w.hGCClipRgn, Owner)) return FALSE; if(!GDIOBJ_SetOwnership(pDC->w.hGCClipRgn, Owner)) return FALSE;
} }
if (pDC->DcLevel.hPath)
{
if(!GDIOBJ_SetOwnership(pDC->DcLevel.hPath, Owner)) return FALSE;
}
DC_UnlockDc(pDC); DC_UnlockDc(pDC);
} }
return TRUE; return TRUE;

View file

@ -77,7 +77,7 @@ IntGdiPolygon(PDC dc,
UnsafePoints[CurrentPoint].y += dc->ptlDCOrig.y; UnsafePoints[CurrentPoint].y += dc->ptlDCOrig.y;
} }
if (PATH_IsPathOpen(dc->w.path)) if (PATH_IsPathOpen(dc->DcLevel))
ret = PATH_Polygon(dc, UnsafePoints, Count ); ret = PATH_Polygon(dc, UnsafePoints, Count );
else else
{ {
@ -632,7 +632,7 @@ IntRectangle(PDC dc,
Dc_Attr = dc->pDc_Attr; Dc_Attr = dc->pDc_Attr;
if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr; if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
if ( PATH_IsPathOpen(dc->w.path) ) if ( PATH_IsPathOpen(dc->DcLevel) )
{ {
ret = PATH_Rectangle ( dc, LeftRect, TopRect, RightRect, BottomRect ); ret = PATH_Rectangle ( dc, LeftRect, TopRect, RightRect, BottomRect );
} }
@ -789,7 +789,7 @@ IntRoundRect(
ASSERT ( dc ); // caller's responsibility to set this up ASSERT ( dc ); // caller's responsibility to set this up
if ( PATH_IsPathOpen(dc->w.path) ) if ( PATH_IsPathOpen(dc->DcLevel) )
return PATH_RoundRect ( dc, left, top, right, bottom, return PATH_RoundRect ( dc, left, top, right, bottom,
xCurveDiameter, yCurveDiameter ); xCurveDiameter, yCurveDiameter );
Dc_Attr = dc->pDc_Attr; Dc_Attr = dc->pDc_Attr;

View file

@ -55,7 +55,7 @@ IntGdiMoveToEx(DC *dc,
CoordLPtoDP(dc, &Dc_Attr->ptfxCurrent); // Update fx CoordLPtoDP(dc, &Dc_Attr->ptfxCurrent); // Update fx
Dc_Attr->ulDirty_ &= ~(DIRTY_PTLCURRENT|DIRTY_PTFXCURRENT|DIRTY_STYLESTATE); Dc_Attr->ulDirty_ &= ~(DIRTY_PTLCURRENT|DIRTY_PTFXCURRENT|DIRTY_STYLESTATE);
PathIsOpen = PATH_IsPathOpen(dc->w.path); PathIsOpen = PATH_IsPathOpen(dc->DcLevel);
if ( PathIsOpen ) if ( PathIsOpen )
return PATH_MoveTo ( dc ); return PATH_MoveTo ( dc );
@ -99,9 +99,10 @@ IntGdiLineTo(DC *dc,
if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr; if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
if (PATH_IsPathOpen(dc->w.path)) if (PATH_IsPathOpen(dc->DcLevel))
{ {
Ret = PATH_LineTo(dc, XEnd, YEnd); Ret = PATH_LineTo(dc, XEnd, YEnd);
#if 0
if (Ret) if (Ret)
{ {
// FIXME - PATH_LineTo should maybe do this... // FIXME - PATH_LineTo should maybe do this...
@ -111,6 +112,7 @@ IntGdiLineTo(DC *dc,
CoordLPtoDP(dc, &Dc_Attr->ptfxCurrent); // Update fx CoordLPtoDP(dc, &Dc_Attr->ptfxCurrent); // Update fx
Dc_Attr->ulDirty_ &= ~(DIRTY_PTLCURRENT|DIRTY_PTFXCURRENT|DIRTY_STYLESTATE); Dc_Attr->ulDirty_ &= ~(DIRTY_PTLCURRENT|DIRTY_PTFXCURRENT|DIRTY_STYLESTATE);
} }
#endif
return Ret; return Ret;
} }
else else
@ -184,7 +186,7 @@ IntGdiPolyBezier(DC *dc,
{ {
BOOL ret = FALSE; // default to FAILURE BOOL ret = FALSE; // default to FAILURE
if ( PATH_IsPathOpen(dc->w.path) ) if ( PATH_IsPathOpen(dc->DcLevel) )
{ {
return PATH_PolyBezier ( dc, pt, Count ); return PATH_PolyBezier ( dc, pt, Count );
} }
@ -214,7 +216,7 @@ IntGdiPolyBezierTo(DC *dc,
PDC_ATTR Dc_Attr = dc->pDc_Attr; PDC_ATTR Dc_Attr = dc->pDc_Attr;
if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr; if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
if ( PATH_IsPathOpen(dc->w.path) ) if ( PATH_IsPathOpen(dc->DcLevel) )
ret = PATH_PolyBezierTo ( dc, pt, Count ); ret = PATH_PolyBezierTo ( dc, pt, Count );
else /* We'll do it using PolyBezier */ else /* We'll do it using PolyBezier */
{ {
@ -257,7 +259,7 @@ IntGdiPolyline(DC *dc,
PDC_ATTR Dc_Attr = dc->pDc_Attr; PDC_ATTR Dc_Attr = dc->pDc_Attr;
if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr; if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
if (PATH_IsPathOpen(dc->w.path)) if (PATH_IsPathOpen(dc->DcLevel))
return PATH_Polyline(dc, pt, Count); return PATH_Polyline(dc, pt, Count);
/* Get BRUSHOBJ from current pen. */ /* Get BRUSHOBJ from current pen. */
@ -316,7 +318,7 @@ IntGdiPolylineTo(DC *dc,
PDC_ATTR Dc_Attr = dc->pDc_Attr; PDC_ATTR Dc_Attr = dc->pDc_Attr;
if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr; if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
if (PATH_IsPathOpen(dc->w.path)) if (PATH_IsPathOpen(dc->DcLevel))
{ {
ret = PATH_PolylineTo(dc, pt, Count); ret = PATH_PolylineTo(dc, pt, Count);
} }
@ -412,6 +414,7 @@ NtGdiPolyDraw(
IN ULONG cCount) IN ULONG cCount)
{ {
PDC dc; PDC dc;
PPATH pPath;
BOOL result = FALSE; BOOL result = FALSE;
POINT lastmove; POINT lastmove;
unsigned int i; unsigned int i;
@ -466,9 +469,14 @@ NtGdiPolyDraw(
if ( lpbTypes[i] & PT_CLOSEFIGURE ) if ( lpbTypes[i] & PT_CLOSEFIGURE )
{ {
if ( PATH_IsPathOpen(dc->w.path) ) if ( PATH_IsPathOpen(dc->DcLevel) )
{ {
IntGdiCloseFigure( dc ); pPath = PATH_LockPath( dc->DcLevel.hPath );
if (pPath)
{
IntGdiCloseFigure( pPath );
PATH_UnlockPath( pPath );
}
} }
else IntGdiLineTo( dc, lastmove.x, lastmove.y ); else IntGdiLineTo( dc, lastmove.x, lastmove.y );
} }

File diff suppressed because it is too large Load diff

View file

@ -3648,7 +3648,7 @@ REGION_CreateETandAET(
} }
HRGN FASTCALL HRGN FASTCALL
IntCreatePolyPolgonRgn( IntCreatePolyPolygonRgn(
POINT *Pts, POINT *Pts,
INT *Count, INT *Count,
INT nbpolygons, INT nbpolygons,
@ -3972,7 +3972,7 @@ GdiCreatePolyPolygonRgn(
} }
/* now we're ready to calculate the region safely */ /* now we're ready to calculate the region safely */
hRgn = IntCreatePolyPolgonRgn(Safept, SafePolyCounts, Count, PolyFillMode); hRgn = IntCreatePolyPolygonRgn(Safept, SafePolyCounts, Count, PolyFillMode);
ExFreePool(Safept); ExFreePool(Safept);
ExFreePool(SafePolyCounts); ExFreePool(SafePolyCounts);