Author: jimtabor
Date: Thu Oct 20 12:02:15 2011
New Revision: 54210
URL:
http://svn.reactos.org/svn/reactos?rev=54210&view=rev
Log:
[Win32k]
- Fix path support, now all wine path tests pass.
- Need a PolyDraw test for non-path functions! The non-path code was synced ported, but
still failed 16 path tests, then path was moved out. Purged missing patches from the last
trunk freeze, tested with the program Area.
- Sync Information:
Evan Stade <estade(a)gmail.com> : Improved PolyDraw in path closed case. Added
PATH_PolyDraw.
Modified:
trunk/reactos/subsystems/win32/win32k/include/path.h
trunk/reactos/subsystems/win32/win32k/objects/line.c
trunk/reactos/subsystems/win32/win32k/objects/path.c
Modified: trunk/reactos/subsystems/win32/win32k/include/path.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/path.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/path.h [iso-8859-1] Thu Oct 20 12:02:15
2011
@@ -55,6 +55,7 @@
BOOL FASTCALL PATH_MoveTo (PDC dc);
BOOL FASTCALL PATH_PolyBezier (PDC dc, const POINT *pts, DWORD cbPoints);
BOOL FASTCALL PATH_PolyBezierTo (PDC dc, const POINT *pts, DWORD cbPoints);
+BOOL FASTCALL PATH_PolyDraw(PDC dc, const POINT *pts, const BYTE *types, DWORD
cbPoints);
BOOL FASTCALL PATH_Polygon (PDC dc, const POINT *pts, DWORD cbPoints);
BOOL FASTCALL PATH_Polyline (PDC dc, const POINT *pts, DWORD cbPoints);
BOOL FASTCALL PATH_PolylineTo (PDC dc, const POINT *pts, DWORD cbPoints);
Modified: trunk/reactos/subsystems/win32/win32k/objects/line.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ob…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/line.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/line.c [iso-8859-1] Thu Oct 20 12:02:15
2011
@@ -417,73 +417,110 @@
IN ULONG cCount)
{
PDC dc;
- PPATH pPath;
+ PDC_ATTR pdcattr;
+ POINT *line_pts = NULL, *line_pts_old, *bzr_pts = NULL, bzr[4];
+ INT i, num_pts, num_bzr_pts, space, space_old, size;
BOOL result = FALSE;
- POINT lastmove;
- unsigned int i;
- PDC_ATTR pdcattr;
dc = DC_LockDc(hdc);
if (!dc) return FALSE;
pdcattr = dc->pdcattr;
+ if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+ DC_vUpdateFillBrush(dc);
+
+ if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
+ DC_vUpdateLineBrush(dc);
+
+ if (!cCount)
+ {
+ DC_UnlockDc(dc);
+ return TRUE;
+ }
+
_SEH2_TRY
{
ProbeArrayForRead(lppt, sizeof(POINT), cCount, sizeof(LONG));
ProbeArrayForRead(lpbTypes, sizeof(BYTE), cCount, sizeof(BYTE));
- /* check for each bezierto if there are two more points */
+ if (PATH_IsPathOpen(dc->dclevel))
+ {
+ result = PATH_PolyDraw(dc, (const POINT *)lppt, (const BYTE *)lpbTypes,
cCount);
+ _SEH2_LEAVE;
+ }
+
+ /* check for valid point types */
+ for (i = 0; i < cCount; i++)
+ {
+ switch (lpbTypes[i])
+ {
+ case PT_MOVETO:
+ case PT_LINETO | PT_CLOSEFIGURE:
+ case PT_LINETO:
+ break;
+ case PT_BEZIERTO:
+ if((i + 2 < cCount) && (lpbTypes[i + 1] == PT_BEZIERTO)
&&
+ ((lpbTypes[i + 2] & ~PT_CLOSEFIGURE) == PT_BEZIERTO))
+ {
+ i += 2;
+ break;
+ }
+ default:
+ _SEH2_LEAVE;
+ }
+ }
+
+ space = cCount + 300;
+ line_pts = ExAllocatePoolWithTag(PagedPool, space * sizeof(POINT), TAG_SHAPE);
+ num_pts = 1;
+
+ line_pts[0].x = pdcattr->ptlCurrent.x;
+ line_pts[0].y = pdcattr->ptlCurrent.y;
+
for ( i = 0; i < cCount; i++ )
{
- if ( lpbTypes[i] != PT_MOVETO &&
- lpbTypes[i] & PT_BEZIERTO )
- {
- if ( cCount < i+3 ) _SEH2_LEAVE;
- else i += 2;
- }
- }
-
- /* if no moveto occurs, we will close the figure here */
- lastmove.x = pdcattr->ptlCurrent.x;
- lastmove.y = pdcattr->ptlCurrent.y;
-
- /* now let's draw */
- for ( i = 0; i < cCount; i++ )
- {
- if ( lpbTypes[i] == PT_MOVETO )
- {
- IntGdiMoveToEx( dc, lppt[i].x, lppt[i].y, NULL, FALSE );
- lastmove.x = pdcattr->ptlCurrent.x;
- lastmove.y = pdcattr->ptlCurrent.y;
- }
- else if ( lpbTypes[i] & PT_LINETO )
- IntGdiLineTo( dc, lppt[i].x, lppt[i].y );
- else if ( lpbTypes[i] & PT_BEZIERTO )
- {
- POINT pts[4];
- pts[0].x = pdcattr->ptlCurrent.x;
- pts[0].y = pdcattr->ptlCurrent.y;
- RtlCopyMemory(pts + 1, &lppt[i], sizeof(POINT) * 3);
- IntGdiPolyBezier(dc, pts, 4);
- i += 2;
- }
- else _SEH2_LEAVE;
-
- if ( lpbTypes[i] & PT_CLOSEFIGURE )
- {
- if ( PATH_IsPathOpen(dc->dclevel) )
- {
- pPath = PATH_LockPath( dc->dclevel.hPath );
- if (pPath)
- {
- IntGdiCloseFigure( pPath );
- PATH_UnlockPath( pPath );
- }
- }
- else IntGdiLineTo( dc, lastmove.x, lastmove.y );
- }
- }
-
+ switch (lpbTypes[i])
+ {
+ case PT_MOVETO:
+ if (num_pts >= 2) IntGdiPolyline( dc, line_pts, num_pts );
+ num_pts = 0;
+ line_pts[num_pts++] = lppt[i];
+ break;
+ case PT_LINETO:
+ case (PT_LINETO | PT_CLOSEFIGURE):
+ line_pts[num_pts++] = lppt[i];
+ break;
+ case PT_BEZIERTO:
+ bzr[0].x = line_pts[num_pts - 1].x;
+ bzr[0].y = line_pts[num_pts - 1].y;
+ RtlCopyMemory( &bzr[1], &lppt[i], 3 * sizeof(POINT) );
+
+ if ((bzr_pts = GDI_Bezier( bzr, 4, &num_bzr_pts )))
+ {
+ size = num_pts + (cCount - i) + num_bzr_pts;
+ if (space < size)
+ {
+ space_old = space;
+ space = size * 2;
+ line_pts_old = line_pts;
+ line_pts = ExAllocatePoolWithTag(PagedPool, space * sizeof(POINT),
TAG_SHAPE);
+ if (!line_pts) _SEH2_LEAVE;
+ RtlCopyMemory(line_pts, line_pts_old, space_old * sizeof(POINT));
+ ExFreePoolWithTag(line_pts_old, TAG_SHAPE);
+ }
+ RtlCopyMemory( &line_pts[num_pts], &bzr_pts[1], (num_bzr_pts -
1) * sizeof(POINT) );
+ num_pts += num_bzr_pts - 1;
+ ExFreePoolWithTag(bzr_pts, TAG_BEZIER);
+ }
+ i += 2;
+ break;
+ }
+ if (lpbTypes[i] & PT_CLOSEFIGURE) line_pts[num_pts++] = line_pts[0];
+ }
+
+ if (num_pts >= 2) IntGdiPolyline( dc, line_pts, num_pts );
+ IntGdiMoveToEx( dc, line_pts[num_pts - 1].x, line_pts[num_pts - 1].y, NULL, TRUE
);
+ ExFreePoolWithTag(line_pts, TAG_SHAPE);
result = TRUE;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
@@ -497,8 +534,8 @@
return result;
}
- /*
- * @unimplemented
+/*
+ * @implemented
*/
BOOL
APIENTRY
@@ -508,8 +545,32 @@
IN INT y,
OUT OPTIONAL LPPOINT pptOut)
{
- UNIMPLEMENTED;
- return FALSE;
+ PDC dc;
+ BOOL Ret;
+ POINT Point;
+
+ dc = DC_LockDc(hdc);
+ if (!dc) return FALSE;
+
+ Ret = IntGdiMoveToEx(dc, x, y, &Point, TRUE);
+
+ if (pptOut)
+ {
+ _SEH2_TRY
+ {
+ ProbeForWrite( pptOut, sizeof(POINT), 1);
+ RtlCopyMemory( pptOut, &Point, sizeof(POINT));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ Ret = FALSE;
+ }
+ _SEH2_END;
+ }
+ DC_UnlockDc(dc);
+
+ return Ret;
}
/* EOF */
Modified: trunk/reactos/subsystems/win32/win32k/objects/path.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ob…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/path.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/path.c [iso-8859-1] Thu Oct 20 12:02:15
2011
@@ -62,6 +62,18 @@
pPath->pFlags[pPath->numEntriesUsed-1]|=PT_CLOSEFIGURE;
pPath->newStroke=TRUE;
}
+}
+
+/* MSDN: This fails if the device coordinates exceed 27 bits, or if the converted
+ logical coordinates exceed 32 bits. */
+BOOL
+FASTCALL
+GdiPathDPtoLP(PDC pdc, PPOINT ppt, INT count)
+{
+ XFORMOBJ xo;
+
+ XFORMOBJ_vInit(&xo, &pdc->dclevel.mxDeviceToWorld);
+ return XFORMOBJ_bApplyXform(&xo, XF_LTOL, count, (PPOINTL)ppt, (PPOINTL)ppt);
}
/* PATH_FillPath
@@ -722,6 +734,103 @@
BOOL
FASTCALL
+PATH_PolyDraw(PDC dc, const POINT *pts, const BYTE *types, DWORD cbPoints)
+{
+ PPATH pPath;
+ POINT lastmove, orig_pos;
+ INT i;
+ PDC_ATTR pdcattr;
+ BOOL State = FALSE, Ret = FALSE;
+
+ pPath = PATH_LockPath( dc->dclevel.hPath );
+ if (!pPath) return FALSE;
+
+ if ( pPath->state != PATH_Open )
+ {
+ PATH_UnlockPath( pPath );
+ return FALSE;
+ }
+
+ pdcattr = dc->pdcattr;
+
+ lastmove.x = orig_pos.x = pdcattr->ptlCurrent.x;
+ lastmove.y = orig_pos.y = pdcattr->ptlCurrent.y;
+
+ for (i = pPath->numEntriesUsed - 1; i >= 0; i--)
+ {
+ if (pPath->pFlags[i] == PT_MOVETO)
+ {
+ lastmove.x = pPath->pPoints[i].x;
+ lastmove.y = pPath->pPoints[i].y;
+ if (!GdiPathDPtoLP(dc, &lastmove, 1))
+ {
+ PATH_UnlockPath( pPath );
+ return FALSE;
+ }
+ break;
+ }
+ }
+
+ for (i = 0; i < cbPoints; i++)
+ {
+ if (types[i] == PT_MOVETO)
+ {
+ pPath->newStroke = TRUE;
+ lastmove.x = pts[i].x;
+ lastmove.y = pts[i].y;
+ }
+ else if((types[i] & ~PT_CLOSEFIGURE) == PT_LINETO)
+ {
+ PATH_LineTo(dc, pts[i].x, pts[i].y);
+ }
+ else if(types[i] == PT_BEZIERTO)
+ {
+ if (!((i + 2 < cbPoints) && (types[i + 1] == PT_BEZIERTO)
+ && ((types[i + 2] & ~PT_CLOSEFIGURE) == PT_BEZIERTO)))
+ goto err;
+ PATH_PolyBezierTo(dc, &(pts[i]), 3);
+ i += 2;
+ }
+ else
+ goto err;
+
+ pdcattr->ptlCurrent.x = pts[i].x;
+ pdcattr->ptlCurrent.y = pts[i].y;
+ State = TRUE;
+
+ if (types[i] & PT_CLOSEFIGURE)
+ {
+ pPath->pFlags[pPath->numEntriesUsed-1] |= PT_CLOSEFIGURE;
+ pPath->newStroke = TRUE;
+ pdcattr->ptlCurrent.x = lastmove.x;
+ pdcattr->ptlCurrent.y = lastmove.y;
+ State = TRUE;
+ }
+ }
+ Ret = TRUE;
+ goto Exit;
+
+err:
+ if ((pdcattr->ptlCurrent.x != orig_pos.x) || (pdcattr->ptlCurrent.y !=
orig_pos.y))
+ {
+ pPath->newStroke = TRUE;
+ pdcattr->ptlCurrent.x = orig_pos.x;
+ pdcattr->ptlCurrent.y = orig_pos.y;
+ State = TRUE;
+ }
+Exit:
+ if (State) // State change?
+ {
+ pdcattr->ptfxCurrent = pdcattr->ptlCurrent;
+ CoordLPtoDP(dc, &pdcattr->ptfxCurrent); // Update fx
+ pdcattr->ulDirty_ &= ~(DIRTY_PTLCURRENT|DIRTY_PTFXCURRENT|DIRTY_STYLESTATE);
+ }
+ PATH_UnlockPath( pPath );
+ return Ret;
+}
+
+BOOL
+FASTCALL
PATH_Polyline ( PDC dc, const POINT *pts, DWORD cbPoints )
{
POINT pt;
@@ -1467,7 +1576,7 @@
FASTCALL
PATH_WidenPath(DC *dc)
{
- INT i, j, numStrokes, penWidth, penWidthIn, penWidthOut, size, penStyle;
+ INT i, j, numStrokes, numOldStrokes, penWidth, penWidthIn, penWidthOut, size,
penStyle;
BOOL ret = FALSE;
PPATH pPath, pNewPath, *pStrokes = NULL, *pOldStrokes, pUpPath, pDownPath;
EXTLOGPEN *elp;
@@ -1554,6 +1663,7 @@
{
pStrokes[numStrokes - 1]->state = PATH_Closed;
}
+ numOldStrokes = numStrokes;
numStrokes++;
j = 0;
if (numStrokes == 1)
@@ -1563,7 +1673,7 @@
pOldStrokes = pStrokes; // Save old pointer.
pStrokes = ExAllocatePoolWithTag(PagedPool, numStrokes *
sizeof(PPATH), TAG_PATH);
if (!pStrokes) return FALSE;
- RtlCopyMemory(pStrokes, pOldStrokes, numStrokes * sizeof(PPATH));
+ RtlCopyMemory(pStrokes, pOldStrokes, numOldStrokes * sizeof(PPATH));
ExFreePoolWithTag(pOldStrokes, TAG_PATH); // Free old pointer.
}
if (!pStrokes) return FALSE;
@@ -2392,7 +2502,11 @@
memcpy(Types, pPath->pFlags, sizeof(BYTE)*pPath->numEntriesUsed);
/* Convert the points to logical coordinates */
- IntDPtoLP(dc, Points, pPath->numEntriesUsed);
+ if (!GdiPathDPtoLP(dc, Points, pPath->numEntriesUsed))
+ {
+ EngSetLastError(ERROR_ARITHMETIC_OVERFLOW);
+ _SEH2_LEAVE;
+ }
ret = pPath->numEntriesUsed;
}