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.
#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
#define PDEV_DISPLAY 0x00000001 // Display device
#define PDEV_HARDWARE_POINTER 0x00000002 // Supports hardware cursor
@ -34,22 +29,6 @@
/* 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
{
HRGN hClipRgn; /* Clip region (may be 0) */
@ -60,10 +39,6 @@ typedef struct _WIN_DC_INFO
HRGN hGCClipRgn; /* GC clip region (ClipRgn AND VisRgn) */
HBITMAP hBitmap;
/* #if 0 */
GdiPath path;
/* #endif */
BYTE bitsPerPixel;
} WIN_DC_INFO;

View file

@ -1,6 +1,22 @@
#ifndef _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
{
BASEOBJECT BaseObject;
@ -26,19 +42,19 @@ typedef struct _EPATHOBJ
#define PATH_AllocPath() ((PPATH) GDIOBJ_AllocObj(GDIObjType_PATH_TYPE))
#define PATH_AllocPathWithHandle() ((PPATH) GDIOBJ_AllocObjWithHandle (GDI_OBJECT_TYPE_PATH))
#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_LockPath(hPath) ((PROSRGNDATA)GDIOBJ_LockObj((HGDIOBJ)hPath, GDI_OBJECT_TYPE_PATH))
#define PATH_UnlockPath(pPath) GDIOBJ_UnlockObjByPtr((POBJ)pPath)
#define PATH_FreeExtPathByHandle(hPath) GDIOBJ_FreeObjByHandle((HGDIOBJ) hPath, GDI_OBJECT_TYPE_PATH)
#define PATH_LockPath(hPath) ((PPATH)GDIOBJ_ShareLockObj((HGDIOBJ)hPath, GDI_OBJECT_TYPE_PATH))
#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_AssignGdiPath (GdiPath *pPathDest, const GdiPath *pPathSrc);
VOID FASTCALL PATH_DestroyGdiPath (GdiPath *pPath);
BOOL FASTCALL PATH_AssignGdiPath (PPATH pPathDest, const PPATH pPathSrc);
VOID FASTCALL PATH_DestroyGdiPath (PPATH pPath);
BOOL FASTCALL PATH_Ellipse (PDC dc, INT x1, INT y1, INT x2, INT y2);
VOID FASTCALL PATH_EmptyPath (GdiPath *pPath);
VOID FASTCALL PATH_InitGdiPath (GdiPath *pPath);
VOID FASTCALL PATH_EmptyPath (PPATH pPath);
VOID FASTCALL PATH_InitGdiPath (PPATH pPath);
BOOL FASTCALL PATH_LineTo (PDC dc, INT x, INT y);
BOOL FASTCALL PATH_MoveTo (PDC dc);
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_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_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 */

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'
#define SHAPEPOINT_TYPE_LINE_RIGHT 'R' /* Fill at right side of line */
#define SHAPEPOINT_TYPE_LINE_LEFT 'L' /* Fill at left side of line */
#include <w32k.h>
#define SETPOINT(x, y, type) \
ShapePoints[*PointCount].X = (x); \
ShapePoints[*PointCount].Y = (y); \
ShapePoints[*PointCount].Type = (type); \
(*PointCount)++
#define NDEBUG
#include <debug.h>
#define SETCIRCLEPOINT(x, y) \
SETPOINT(x, y, SHAPEPOINT_TYPE_CIRCLE)
#ifdef TODO
STATIC VOID
FASTCALL
CirclePoints(UINT *PointCount, PSHAPEPOINT ShapePoints, int Left, int Top,
int Right, int Bottom)
{
int X, X18, X27, X36, X45;
int Y, Y14, Y23, Y58, Y67;
int d, Radius;
BOOL Even;
/*
* a couple macros to fill a single pixel or a line
*/
#define PUTPIXEL(x,y,BrushInst) \
ret = ret && IntEngLineTo(&BitmapObj->SurfObj, \
dc->CombinedClip, \
&BrushInst.BrushObject, \
x, y, (x)+1, y, \
&RectBounds, \
ROP2_TO_MIX(Dc_Attr->jROP2));
Even = (0 == (Right - Left) % 2);
Right--;
Bottom--;
Radius = (Right - Left) >> 1;
#define PUTLINE(x1,y1,x2,y2,BrushInst) \
ret = ret && IntEngLineTo(&BitmapObj->SurfObj, \
dc->CombinedClip, \
&BrushInst.BrushObject, \
x1, y1, x2, y2, \
&RectBounds, \
ROP2_TO_MIX(Dc_Attr->jROP2));
if (Even)
{
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);
}
#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)))
while (X < Y)
{
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
static
BOOL
STDCALL
NtGdiPie(HDC hDC,
int Left,
int Top,
int Right,
int Bottom,
int XRadialStart,
int YRadialStart,
int XRadialEnd,
int YRadialEnd)
FASTCALL
IntArc( DC *dc,
int Left,
int Top,
int Right,
int Bottom,
int XRadialStart,
int YRadialStart,
int XRadialEnd,
int YRadialEnd,
ARCTYPE arctype)
{
#ifdef TODO
PDC dc;
PDC_ATTR;
PDC_ATTR Dc_Attr;
RECTL RectBounds;
SURFOBJ *SurfObj;
BRUSHOBJ PenBrushObj;
PBRUSHOBJ FillBrushObj;
PSHAPEPOINT ShapePoints;
UINT Point, PointCount;
PGDIBRUSHOBJ PenBrushObj, FillBrushObj;
GDIBRUSHINST FillBrushInst, PenBrushInst;
BITMAPOBJ *BitmapObj;
BOOL ret = TRUE;
int Y, CircleStart, CircleEnd, LineStart, LineEnd;
BOOL FullFill;
double AngleStart, AngleEnd;
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);
return FALSE;
}
/*
if (Right - Left != Bottom - Top)
{
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;
if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
FillBrushObj = BRUSHOBJ_LockBrush(Dc_Attr->hbrush);
if (NULL == FillBrushObj)
{
DC_UnlockDc(dc);
DPRINT1("Arc Fail 2\n");
SetLastWin32Error(ERROR_INTERNAL_ERROR);
return FALSE;
}
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;
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)
PenBrushObj = PENOBJ_LockPen(Dc_Attr->hpen);
if (NULL == PenBrushObj)
{
DPRINT1("Arc Fail 3\n");
BRUSHOBJ_UnlockBrush(FillBrushObj);
DC_UnlockDc(dc);
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
SetLastWin32Error(ERROR_INTERNAL_ERROR);
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)
{
PUTPIXEL(Left, Top, &PenBrushObj);
DPRINT1("Arc Good Exit\n");
PUTPIXEL(Left, Top, PenBrushInst);
BITMAPOBJ_UnlockBitmap(BitmapObj);
BRUSHOBJ_UnlockBrush(FillBrushObj);
DC_UnlockDc(dc);
PENOBJ_UnlockPen(PenBrushObj);
return ret;
}
RadiusX = (RectBounds.right - RectBounds.left)/2;
RadiusY = (RectBounds.bottom - RectBounds.top)/2;
CenterX = RectBounds.left + RadiusX;
CenterY = RectBounds.top + RadiusY;
PointCount = 0;
CirclePoints(&PointCount, ShapePoints, Left, Top, Right, Bottom);
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);
AngleEnd = atan2(-(YRadialEnd - CenterY), XRadialEnd - CenterX)* (180.0 / M_PI);
AngleStart = atan2(-(YRadialStart - CenterY), XRadialStart - CenterX)* (180.0 / M_PI);
FullFill = TRUE;
Point = 0;
while (Point < PointCount)
SfCx = (Rcos(AngleStart) * RadiusX);
SfCy = (Rsin(AngleStart) * RadiusY);
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 */
while (Point < PointCount && ShapePoints[Point].Y == Y
&& SHAPEPOINT_TYPE_CIRCLE != ShapePoints[Point].Type)
{
Point++;
}
if (arctype == GdiTypePie)
{
PUTLINE(SfCx + CenterX, SfCy + CenterY, CenterX, CenterY, PenBrushInst);
}
/* Handle left side of circle */
if (Point < PointCount && ShapePoints[Point].Y == Y)
{
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;
for(; AngS < AngleEnd; AngS += Factor)
{
x = (Rcos(AngS) * RadiusX);
y = (Rsin(AngS) * RadiusY);
if (arctype == GdiTypePie)
PUTLINE((x + CenterX) - 1, (y + CenterY) - 1, CenterX, CenterY, FillBrushInst);
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 */
while (Point < PointCount && ShapePoints[Point].Y == Y
&& 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;
if (arctype == GdiTypePie)
PUTLINE(EfCx + CenterX, EfCy + CenterY, CenterX, CenterY, PenBrushInst);
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++;
}
}
ExFreePool(ShapePoints);
BITMAPOBJ_UnlockBitmap(BitmapObj);
BRUSHOBJ_UnlockBrush(FillBrushObj);
DC_UnlockDc(dc);
PENOBJ_UnlockPen(PenBrushObj);
DPRINT1("IntArc Exit.\n");
return ret;
#else
return TRUE;
#endif
}
static BOOL FASTCALL
IntArc( DC *dc, int LeftRect, int TopRect, int RightRect, int BottomRect,
int XStartArc, int YStartArc, int XEndArc, int YEndArc, ARCTYPE arctype)
{
return TRUE;
}
BOOL FASTCALL
IntGdiArcInternal(
ARCTYPE arctype,
DC *dc,
int LeftRect,
int TopRect,
int RightRect,
int BottomRect,
int XStartArc,
int YStartArc,
int XEndArc,
int YEndArc)
{
INT rx, ry;
RECT rc, rc1;
if(PATH_IsPathOpen(dc->w.path))
{
INT type = arctype;
if (arctype == GdiTypeArcTo) type = GdiTypeArc;
return PATH_Arc(dc, LeftRect, TopRect, RightRect, BottomRect,
XStartArc, YStartArc, XEndArc, YEndArc, type);
}
IntGdiSetRect(&rc, LeftRect, TopRect, RightRect, BottomRect);
IntGdiSetRect(&rc1, XStartArc, YStartArc, XEndArc, YEndArc);
rx = (rc.right - rc.left)/2 - 1;
ry = (rc.bottom - rc.top)/2 -1;
rc.left += rx;
rc.top += ry;
return IntArc( dc, rc.left, rc.top, rx, ry,
rc1.left, rc1.top, rc1.right, rc1.bottom, arctype);
}
BOOL FASTCALL
IntGdiArcInternal(
ARCTYPE arctype,
DC *dc,
int LeftRect,
int TopRect,
int RightRect,
int BottomRect,
int XStartArc,
int YStartArc,
int XEndArc,
int YEndArc)
{
BOOL Ret;
RECT rc, rc1;
double AngleStart, AngleEnd;
LONG RadiusX, RadiusY, CenterX, CenterY, Width, Height;
LONG SfCx, SfCy, EfCx = 0, EfCy = 0;
DPRINT1("StartX: %d, StartY: %d, EndX: %d, EndY: %d\n",
XStartArc,YStartArc,XEndArc,YEndArc);
DPRINT1("Left: %d, Top: %d, Right: %d, Bottom: %d\n",
LeftRect,TopRect,RightRect,BottomRect);
if (PATH_IsPathOpen(dc->DcLevel))
{
return PATH_Arc( dc,
LeftRect,
TopRect,
RightRect,
BottomRect,
XStartArc,
YStartArc,
XEndArc,
YEndArc,
arctype);
}
if (arctype == GdiTypeArcTo)
{
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
APIENTRY
NtGdiAngleArc(
@ -476,89 +328,72 @@ NtGdiAngleArc(
IN DWORD dwStartAngle,
IN DWORD dwSweepAngle)
{
DC *dc;
BOOL Ret = FALSE;
gxf_long worker, worker1;
dc = DC_LockDc (hDC);
if(!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;
}
worker.l = dwStartAngle;
worker1.l = dwSweepAngle;
DC_UnlockDc( dc );
return Ret;
DC *pDC;
BOOL Ret = FALSE;
gxf_long worker, worker1;
pDC = DC_LockDc (hDC);
if(!pDC)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pDC->DC_Type == DC_TYPE_INFO)
{
DC_UnlockDc(pDC);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
worker.l = dwStartAngle;
worker1.l = dwSweepAngle;
Ret = IntGdiAngleArc( pDC, x, y, dwRadius, worker.f, worker1.f);
DC_UnlockDc( pDC );
return Ret;
}
BOOL
STDCALL
NtGdiArcInternal(
ARCTYPE arctype,
HDC hDC,
int LeftRect,
int TopRect,
int RightRect,
int BottomRect,
int XStartArc,
int YStartArc,
int XEndArc,
int YEndArc)
{
DC *dc;
BOOL Ret;
dc = DC_LockDc (hDC);
if(!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;
}
if (arctype == GdiTypeArcTo)
{
// Line from current position to starting point of arc
if ( !IntGdiLineTo(dc, XStartArc, YStartArc) )
{
DC_UnlockDc(dc);
return FALSE;
}
}
Ret = IntGdiArcInternal(
arctype,
dc,
LeftRect,
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;
}
BOOL
STDCALL
NtGdiArcInternal(
ARCTYPE arctype,
HDC hDC,
int LeftRect,
int TopRect,
int RightRect,
int BottomRect,
int XStartArc,
int YStartArc,
int XEndArc,
int YEndArc)
{
DC *dc;
BOOL Ret;
dc = DC_LockDc (hDC);
if(!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;
}
Ret = IntGdiArcInternal(
arctype,
dc,
LeftRect,
TopRect,
RightRect,
BottomRect,
XStartArc,
YStartArc,
XEndArc,
YEndArc);
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 */
if (!(DCToDelete->DcLevel.flPath & DCPATH_SAVE))
if (!(DCToDelete->DcLevel.flPath & DCPATH_SAVESTATE))
{
/*
NtGdiSelectPen (DCHandle, STOCK_BLACK_PEN);
@ -1054,7 +1054,7 @@ IntGdiDeleteDC(HDC hDC, BOOL Force)
{
NtGdiDeleteObject (DCToDelete->w.hGCClipRgn);
}
PATH_DestroyGdiPath (&DCToDelete->w.path);
PATH_Delete(DCToDelete->DcLevel.hPath);
DC_UnlockDc( DCToDelete );
DC_FreeDC ( hDC );
@ -1326,7 +1326,7 @@ IntGdiCopyToSaveState(PDC dc, PDC newdc)
nDc_Attr = newdc->pDc_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->hpen = Dc_Attr->hpen;
nDc_Attr->hbrush = Dc_Attr->hbrush;
@ -1372,7 +1372,7 @@ IntGdiCopyToSaveState(PDC dc, PDC newdc)
newdc->DC_Type = dc->DC_Type;
#if 0
PATH_InitGdiPath( &newdc->w.path );
PATH_InitGdiPath( &newdc->DcLevel.hPath );
#endif
/* 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;
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->jROP2 = sDc_Attr->jROP2;
@ -1528,7 +1528,7 @@ IntGdiSetDCState ( HDC hDC, HDC hDCSave )
dcs = DC_LockDc ( hDCSave );
if ( dcs )
{
if ( dcs->DcLevel.flPath & DCPATH_SAVE )
if ( dcs->DcLevel.flPath & DCPATH_SAVESTATE )
{
IntGdiCopyFromSaveState( dc, dcs, dc->DcLevel.hdcSave);
}
@ -1824,17 +1824,19 @@ NtGdiRestoreDC(HDC hDC, INT SaveLevel)
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);
if(!dc)
{
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
{
@ -1875,20 +1877,11 @@ NtGdiSaveDC(HDC hDC)
return 0;
}
#if 0
/* Copy path. The reason why path saving / restoring is in SaveDC/
* RestoreDC and not in GetDCState/SetDCState is that the ...DCState
* functions are only in Win16 (which doesn't have paths) and that
* SetDCState doesn't allow us to signal an error (which can happen
* when copying paths).
*/
if (!PATH_AssignGdiPath (&dcs->w.path, &dc->w.path))
{
NtGdiDeleteObjectApp (hdcs);
return 0;
}
#endif
/*
* Copy path.
*/
dcs->DcLevel.hPath = dc->DcLevel.hPath;
if (dcs->DcLevel.hPath) dcs->DcLevel.flPath |= DCPATH_SAVE;
DC_SetNextDC (dcs, DC_GetNextDC (dc));
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->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);
TextIntRealizeFont(Dc_Attr->hlfntNew);
@ -2536,8 +2533,10 @@ DC_InitDC(HDC DCHandle)
{
// NtGdiRealizeDefaultPalette(DCHandle);
NtGdiSelectBrush(DCHandle, NtGdiGetStockObject( WHITE_BRUSH ));
NtGdiSelectPen(DCHandle, NtGdiGetStockObject( BLACK_PEN ));
//// Removed for now.. See above brush and pen.
// NtGdiSelectBrush(DCHandle, NtGdiGetStockObject( WHITE_BRUSH ));
// NtGdiSelectPen(DCHandle, NtGdiGetStockObject( BLACK_PEN ));
////
//NtGdiSelectFont(DCHandle, hFont);
/*
@ -2729,6 +2728,10 @@ DC_SetOwnership(HDC hDC, PEPROCESS Owner)
{
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);
}
return TRUE;

View file

@ -77,7 +77,7 @@ IntGdiPolygon(PDC dc,
UnsafePoints[CurrentPoint].y += dc->ptlDCOrig.y;
}
if (PATH_IsPathOpen(dc->w.path))
if (PATH_IsPathOpen(dc->DcLevel))
ret = PATH_Polygon(dc, UnsafePoints, Count );
else
{
@ -632,7 +632,7 @@ IntRectangle(PDC dc,
Dc_Attr = dc->pDc_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 );
}
@ -789,7 +789,7 @@ IntRoundRect(
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,
xCurveDiameter, yCurveDiameter );
Dc_Attr = dc->pDc_Attr;

View file

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

File diff suppressed because it is too large Load diff

View file

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