Author: tretiakov
Date: Sun Sep 24 21:02:29 2006
New Revision: 24256
URL:
http://svn.reactos.org/svn/reactos?rev=24256&view=rev
Log:
- Implement NtGdiStrokePath and NtGdiStrokeAndFillPath (based on wine)
- Get rid of PATH_GetPathFromDc()
Modified:
trunk/reactos/subsystems/win32/win32k/objects/path.c
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 (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/path.c Sun Sep 24 21:02:29 2006
@@ -33,12 +33,11 @@
BOOL FASTCALL PATH_DoArcPart (GdiPath *pPath, FLOAT_POINT corners[], double angleStart,
double angleEnd, BOOL addMoveTo);
BOOL FASTCALL PATH_FillPath( PDC dc, GdiPath *pPath );
BOOL FASTCALL PATH_FlattenPath (GdiPath *pPath);
-VOID FASTCALL PATH_GetPathFromDC (PDC dc, GdiPath **ppPath);
VOID FASTCALL PATH_NormalizePoint (FLOAT_POINT corners[], const FLOAT_POINT *pPoint,
double *pX, double *pY);
BOOL FASTCALL PATH_PathToRegion (GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn);
BOOL FASTCALL PATH_ReserveEntries (GdiPath *pPath, INT numEntries);
VOID FASTCALL PATH_ScaleNormalizedPoint (FLOAT_POINT corners[], double x, double y, POINT
*pPoint);
-
+BOOL FASTCALL PATH_StrokePath(DC *dc, GdiPath *pPath);
INT FASTCALL
IntGdiGetArcDirection(DC *dc);
@@ -51,16 +50,12 @@
STDCALL
NtGdiAbortPath(HDC hDC)
{
- GdiPath *pPath;
BOOL ret = TRUE;
PDC dc = DC_LockDc ( hDC );
if( !dc ) return FALSE;
- /* Get pointer to path */
- PATH_GetPathFromDC ( dc, &pPath );
-
- PATH_EmptyPath( pPath );
+ PATH_EmptyPath(&dc->w.path);
DC_UnlockDc ( dc );
return ret;
@@ -70,24 +65,20 @@
STDCALL
NtGdiBeginPath( HDC hDC )
{
- GdiPath *pPath;
BOOL ret = TRUE;
PDC dc = DC_LockDc ( hDC );
if( !dc ) return FALSE;
-
- /* Get pointer to path */
- PATH_GetPathFromDC ( dc, &pPath );
/* If path is already open, do nothing */
- if ( pPath->state != PATH_Open )
+ if ( dc->w.path.state != PATH_Open )
{
/* Make sure that path is empty */
- PATH_EmptyPath( pPath );
+ PATH_EmptyPath( &dc->w.path );
/* Initialize variables for new path */
- pPath->newStroke = TRUE;
- pPath->state = PATH_Open;
+ dc->w.path.newStroke = TRUE;
+ dc->w.path.state = PATH_Open;
}
DC_UnlockDc ( dc );
@@ -142,22 +133,18 @@
STDCALL
NtGdiEndPath(HDC hDC)
{
- GdiPath *pPath;
BOOL ret = TRUE;
PDC dc = DC_LockDc ( hDC );
if ( !dc ) return FALSE;
- /* Get pointer to path */
- PATH_GetPathFromDC ( dc, &pPath );
-
/* Check that path is currently being constructed */
- if( pPath->state != PATH_Open )
+ if( dc->w.path.state != PATH_Open )
{
ret = FALSE;
}
/* Set flag to indicate that path is finished */
- else pPath->state = PATH_Closed;
+ else dc->w.path.state = PATH_Closed;
DC_UnlockDc ( dc );
return ret;
@@ -167,21 +154,17 @@
STDCALL
NtGdiFillPath(HDC hDC)
{
- GdiPath *pPath;
BOOL ret = TRUE;
PDC dc = DC_LockDc ( hDC );
if ( !dc ) return FALSE;
-
- /* Get pointer to path */
- PATH_GetPathFromDC ( dc, &pPath );
- ret = PATH_FillPath( dc, pPath );
+ ret = PATH_FillPath( dc, &dc->w.path );
if( ret )
{
/* FIXME: Should the path be emptied even if conversion
failed? */
- PATH_EmptyPath( pPath );
+ PATH_EmptyPath( &dc->w.path );
}
DC_UnlockDc ( dc );
@@ -323,18 +306,39 @@
BOOL
STDCALL
-NtGdiStrokeAndFillPath(HDC hDC)
-{
- UNIMPLEMENTED;
- return FALSE;
+NtGdiStrokeAndFillPath(HDC hDC)
+{
+ DC *pDc;
+ BOOL bRet = FALSE;
+
+ DPRINT("Enter %s\n", __FUNCTION__);
+
+ if(!(pDc = DC_LockDc(hDC))) return FALSE;
+
+ bRet = PATH_FillPath(pDc, &pDc->w.path);
+ if(bRet) bRet = PATH_StrokePath(pDc, &pDc->w.path);
+ if(bRet) PATH_EmptyPath(&pDc->w.path);
+
+ DC_UnlockDc(pDc);
+ return bRet;
}
BOOL
STDCALL
-NtGdiStrokePath(HDC hDC)
-{
- UNIMPLEMENTED;
- return FALSE;
+NtGdiStrokePath(HDC hDC)
+{
+ DC *pDc;
+ BOOL bRet = FALSE;
+
+ DPRINT("Enter %s\n", __FUNCTION__);
+
+ if(!(pDc = DC_LockDc(hDC))) return FALSE;
+
+ bRet = PATH_StrokePath(pDc, &pDc->w.path);
+ PATH_EmptyPath(&pDc->w.path);
+
+ DC_UnlockDc(pDc);
+ return bRet;
}
BOOL
@@ -348,30 +352,27 @@
BOOL STDCALL NtGdiSelectClipPath(HDC hDC,
int Mode)
{
- GdiPath *pPath;
HRGN hrgnPath;
BOOL success = FALSE;
PDC dc = DC_LockDc ( hDC );
if( !dc ) return FALSE;
- PATH_GetPathFromDC ( dc, &pPath );
-
/* Check that path is closed */
- if( pPath->state != PATH_Closed )
+ if( dc->w.path.state != PATH_Closed )
{
SetLastWin32Error(ERROR_CAN_NOT_COMPLETE);
return FALSE;
}
/* Construct a region from the path */
- else if( PATH_PathToRegion( pPath, dc->w.polyFillMode, &hrgnPath ) )
+ else if( PATH_PathToRegion( &dc->w.path, dc->w.polyFillMode, &hrgnPath )
)
{
success = IntGdiExtSelectClipRgn( dc, hrgnPath, Mode ) != ERROR;
NtGdiDeleteObject( hrgnPath );
/* Empty the path */
if( success )
- PATH_EmptyPath( pPath );
+ PATH_EmptyPath( &dc->w.path);
/* FIXME: Should this function delete the path even if it failed? */
}
@@ -532,18 +533,14 @@
FASTCALL
PATH_MoveTo ( PDC dc )
{
- GdiPath *pPath;
-
- /* Get pointer to path */
- PATH_GetPathFromDC ( dc, &pPath );
/* Check that path is open */
- if ( pPath->state != PATH_Open )
+ if ( dc->w.path.state != PATH_Open )
/* FIXME: Do we have to call SetLastError? */
return FALSE;
/* Start a new stroke */
- pPath->newStroke = TRUE;
+ dc->w.path.newStroke = TRUE;
return TRUE;
}
@@ -559,14 +556,10 @@
FASTCALL
PATH_LineTo ( PDC dc, INT x, INT y )
{
- GdiPath *pPath;
POINT point, pointCurPos;
- /* Get pointer to path */
- PATH_GetPathFromDC ( dc, &pPath );
-
/* Check that path is open */
- if ( pPath->state != PATH_Open )
+ if ( dc->w.path.state != PATH_Open )
return FALSE;
/* Convert point to device coordinates */
@@ -575,17 +568,17 @@
CoordLPtoDP ( dc, &point );
/* Add a PT_MOVETO if necessary */
- if ( pPath->newStroke )
- {
- pPath->newStroke = FALSE;
+ if ( dc->w.path.newStroke )
+ {
+ dc->w.path.newStroke = FALSE;
IntGetCurrentPositionEx ( dc, &pointCurPos );
CoordLPtoDP ( dc, &pointCurPos );
- if ( !PATH_AddEntry(pPath, &pointCurPos, PT_MOVETO) )
+ if ( !PATH_AddEntry(&dc->w.path, &pointCurPos, PT_MOVETO) )
return FALSE;
}
/* Add a PT_LINETO entry */
- return PATH_AddEntry(pPath, &point, PT_LINETO);
+ return PATH_AddEntry(&dc->w.path, &point, PT_LINETO);
}
/* PATH_Rectangle
@@ -597,15 +590,11 @@
FASTCALL
PATH_Rectangle ( PDC dc, INT x1, INT y1, INT x2, INT y2 )
{
- GdiPath *pPath;
POINT corners[2], pointTemp;
INT temp;
- /* Get pointer to path */
- PATH_GetPathFromDC ( dc, &pPath );
-
/* Check that path is open */
- if ( pPath->state != PATH_Open )
+ if ( dc->w.path.state != PATH_Open )
return FALSE;
/* Convert points to device coordinates */
@@ -642,15 +631,15 @@
/* Add four points to the path */
pointTemp.x=corners[1].x;
pointTemp.y=corners[0].y;
- if ( !PATH_AddEntry(pPath, &pointTemp, PT_MOVETO) )
- return FALSE;
- if ( !PATH_AddEntry(pPath, corners, PT_LINETO) )
+ if ( !PATH_AddEntry(&dc->w.path, &pointTemp, PT_MOVETO) )
+ return FALSE;
+ if ( !PATH_AddEntry(&dc->w.path, corners, PT_LINETO) )
return FALSE;
pointTemp.x=corners[0].x;
pointTemp.y=corners[1].y;
- if ( !PATH_AddEntry(pPath, &pointTemp, PT_LINETO) )
- return FALSE;
- if ( !PATH_AddEntry(pPath, corners+1, PT_LINETO) )
+ if ( !PATH_AddEntry(&dc->w.path, &pointTemp, PT_LINETO) )
+ return FALSE;
+ if ( !PATH_AddEntry(&dc->w.path, corners+1, PT_LINETO) )
return FALSE;
/* Close the rectangle figure */
@@ -693,7 +682,6 @@
PATH_Arc ( PDC dc, INT x1, INT y1, INT x2, INT y2,
INT xStart, INT yStart, INT xEnd, INT yEnd)
{
- GdiPath *pPath;
double angleStart, angleEnd, angleStartQuadrant, angleEndQuadrant=0.0;
/* Initialize angleEndQuadrant to silence gcc's warning */
double x, y;
@@ -709,11 +697,8 @@
clockwise = ( IntGdiGetArcDirection(dc) == AD_CLOCKWISE );
- /* Get pointer to path */
- PATH_GetPathFromDC ( dc, &pPath );
-
/* Check that path is open */
- if ( pPath->state != PATH_Open )
+ if ( dc->w.path.state != PATH_Open )
return FALSE;
/* FIXME: Do we have to close the current figure? */
@@ -817,7 +802,7 @@
}
/* Add the Bezier spline to the path */
- PATH_DoArcPart ( pPath, corners, angleStartQuadrant, angleEndQuadrant, start );
+ PATH_DoArcPart ( &dc->w.path, corners, angleStartQuadrant, angleEndQuadrant,
start );
start = FALSE;
} while(!end);
@@ -828,7 +813,6 @@
FASTCALL
PATH_PolyBezierTo ( PDC dc, const POINT *pts, DWORD cbPoints )
{
- GdiPath *pPath;
POINT pt;
ULONG i;
@@ -836,19 +820,17 @@
ASSERT ( pts );
ASSERT ( cbPoints );
- PATH_GetPathFromDC ( dc, &pPath );
-
/* Check that path is open */
- if ( pPath->state != PATH_Open )
+ if ( dc->w.path.state != PATH_Open )
return FALSE;
/* Add a PT_MOVETO if necessary */
- if ( pPath->newStroke )
- {
- pPath->newStroke=FALSE;
+ if ( dc->w.path.newStroke )
+ {
+ dc->w.path.newStroke=FALSE;
IntGetCurrentPositionEx ( dc, &pt );
CoordLPtoDP ( dc, &pt );
- if ( !PATH_AddEntry(pPath, &pt, PT_MOVETO) )
+ if ( !PATH_AddEntry(&dc->w.path, &pt, PT_MOVETO) )
return FALSE;
}
@@ -856,7 +838,7 @@
{
pt = pts[i];
CoordLPtoDP ( dc, &pt );
- PATH_AddEntry(pPath, &pt, PT_BEZIERTO);
+ PATH_AddEntry(&dc->w.path, &pt, PT_BEZIERTO);
}
return TRUE;
}
@@ -865,7 +847,6 @@
FASTCALL
PATH_PolyBezier ( PDC dc, const POINT *pts, DWORD cbPoints )
{
- GdiPath *pPath;
POINT pt;
ULONG i;
@@ -873,17 +854,15 @@
ASSERT ( pts );
ASSERT ( cbPoints );
- PATH_GetPathFromDC ( dc, &pPath );
-
/* Check that path is open */
- if ( pPath->state != PATH_Open )
+ if ( dc->w.path.state != PATH_Open )
return FALSE;
for ( i = 0; i < cbPoints; i++ )
{
pt = pts[i];
CoordLPtoDP ( dc, &pt );
- PATH_AddEntry ( pPath, &pt, (i == 0) ? PT_MOVETO : PT_BEZIERTO );
+ PATH_AddEntry ( &dc->w.path, &pt, (i == 0) ? PT_MOVETO : PT_BEZIERTO );
}
return TRUE;
@@ -893,7 +872,6 @@
FASTCALL
PATH_Polyline ( PDC dc, const POINT *pts, DWORD cbPoints )
{
- GdiPath *pPath;
POINT pt;
ULONG i;
@@ -901,17 +879,15 @@
ASSERT ( pts );
ASSERT ( cbPoints );
- PATH_GetPathFromDC ( dc, &pPath );
-
/* Check that path is open */
- if ( pPath->state != PATH_Open )
+ if ( dc->w.path.state != PATH_Open )
return FALSE;
for ( i = 0; i < cbPoints; i++ )
{
pt = pts[i];
CoordLPtoDP ( dc, &pt );
- PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO : PT_LINETO);
+ PATH_AddEntry(&dc->w.path, &pt, (i == 0) ? PT_MOVETO : PT_LINETO);
}
return TRUE;
}
@@ -920,7 +896,6 @@
FASTCALL
PATH_PolylineTo ( PDC dc, const POINT *pts, DWORD cbPoints )
{
- GdiPath *pPath;
POINT pt;
ULONG i;
@@ -928,19 +903,17 @@
ASSERT ( pts );
ASSERT ( cbPoints );
- PATH_GetPathFromDC ( dc, &pPath );
-
/* Check that path is open */
- if ( pPath->state != PATH_Open )
+ if ( dc->w.path.state != PATH_Open )
return FALSE;
/* Add a PT_MOVETO if necessary */
- if ( pPath->newStroke )
- {
- pPath->newStroke = FALSE;
+ if ( dc->w.path.newStroke )
+ {
+ dc->w.path.newStroke = FALSE;
IntGetCurrentPositionEx ( dc, &pt );
CoordLPtoDP ( dc, &pt );
- if ( !PATH_AddEntry(pPath, &pt, PT_MOVETO) )
+ if ( !PATH_AddEntry(&dc->w.path, &pt, PT_MOVETO) )
return FALSE;
}
@@ -948,7 +921,7 @@
{
pt = pts[i];
CoordLPtoDP ( dc, &pt );
- PATH_AddEntry(pPath, &pt, PT_LINETO);
+ PATH_AddEntry(&dc->w.path, &pt, PT_LINETO);
}
return TRUE;
@@ -959,24 +932,21 @@
FASTCALL
PATH_Polygon ( PDC dc, const POINT *pts, DWORD cbPoints )
{
- GdiPath *pPath;
POINT pt;
ULONG i;
ASSERT ( dc );
ASSERT ( pts );
- PATH_GetPathFromDC ( dc, &pPath );
-
/* Check that path is open */
- if ( pPath->state != PATH_Open )
+ if ( dc->w.path.state != PATH_Open )
return FALSE;
for(i = 0; i < cbPoints; i++)
{
pt = pts[i];
CoordLPtoDP ( dc, &pt );
- PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO :
+ PATH_AddEntry(&dc->w.path, &pt, (i == 0) ? PT_MOVETO :
((i == cbPoints-1) ? PT_LINETO | PT_CLOSEFIGURE :
PT_LINETO));
}
@@ -987,7 +957,6 @@
FASTCALL
PATH_PolyPolygon ( PDC dc, const POINT* pts, const INT* counts, UINT polygons )
{
- GdiPath *pPath;
POINT pt, startpt;
ULONG poly, point, i;
@@ -996,10 +965,8 @@
ASSERT ( counts );
ASSERT ( polygons );
- PATH_GetPathFromDC ( dc, &pPath );
-
/* Check that path is open */
- if ( pPath->state != PATH_Open );
+ if ( dc->w.path.state != PATH_Open );
return FALSE;
for(i = 0, poly = 0; poly < polygons; poly++)
@@ -1009,10 +976,10 @@
pt = pts[i];
CoordLPtoDP ( dc, &pt );
if(point == 0) startpt = pt;
- PATH_AddEntry(pPath, &pt, (point == 0) ? PT_MOVETO : PT_LINETO);
+ PATH_AddEntry(&dc->w.path, &pt, (point == 0) ? PT_MOVETO :
PT_LINETO);
}
/* win98 adds an extra line to close the figure for some reason */
- PATH_AddEntry(pPath, &startpt, PT_LINETO | PT_CLOSEFIGURE);
+ PATH_AddEntry(&dc->w.path, &startpt, PT_LINETO | PT_CLOSEFIGURE);
}
return TRUE;
}
@@ -1021,7 +988,6 @@
FASTCALL
PATH_PolyPolyline ( PDC dc, const POINT* pts, const DWORD* counts, DWORD polylines )
{
- GdiPath *pPath;
POINT pt;
ULONG poly, point, i;
@@ -1030,10 +996,8 @@
ASSERT ( counts );
ASSERT ( polylines );
- PATH_GetPathFromDC ( dc, &pPath );
-
/* Check that path is open */
- if ( pPath->state != PATH_Open )
+ if ( dc->w.path.state != PATH_Open )
return FALSE;
for(i = 0, poly = 0; poly < polylines; poly++)
@@ -1042,7 +1006,7 @@
{
pt = pts[i];
CoordLPtoDP ( dc, &pt );
- PATH_AddEntry(pPath, &pt, (point == 0) ? PT_MOVETO : PT_LINETO);
+ PATH_AddEntry(&dc->w.path, &pt, (point == 0) ? PT_MOVETO : PT_LINETO);
}
}
return TRUE;
@@ -1085,7 +1049,7 @@
GdiPath newPath;
INT srcpt;
- memset(&newPath, 0, sizeof(newPath));
+ RtlZeroMemory(&newPath, sizeof(newPath));
newPath.state = PATH_Open;
for(srcpt = 0; srcpt < pPath->numEntriesUsed; srcpt++) {
switch(pPath->pFlags[srcpt] & ~PT_CLOSEFIGURE) {
@@ -1287,20 +1251,6 @@
}
return TRUE;
-}
-
-/* PATH_GetPathFromDC
- *
- * Retrieves a pointer to the GdiPath structure contained in an HDC and
- * places it in *ppPath. TRUE is returned if successful, FALSE otherwise.
- */
-VOID
-FASTCALL
-PATH_GetPathFromDC ( PDC dc, GdiPath **ppPath )
-{
- ASSERT ( dc );
- ASSERT ( ppPath );
- *ppPath = &dc->w.path;
}
/* PATH_DoArcPart
@@ -1401,4 +1351,176 @@
*pX=(double)(pPoint->x-corners[0].x)/(double)(corners[1].x-corners[0].x) * 2.0 -
1.0;
*pY=(double)(pPoint->y-corners[0].y)/(double)(corners[1].y-corners[0].y) * 2.0 -
1.0;
}
+
+
+BOOL FASTCALL PATH_StrokePath(DC *dc, GdiPath *pPath)
+{
+ BOOL ret = FALSE;
+ INT i=0;
+ INT nLinePts, nAlloc;
+ POINT *pLinePts = NULL;
+ POINT ptViewportOrg, ptWindowOrg;
+ SIZE szViewportExt, szWindowExt;
+ DWORD mapMode, graphicsMode;
+ XFORM xform;
+
+ DPRINT("Enter %s\n", __FUNCTION__);
+
+ if(pPath->state != PATH_Closed)
+ return FALSE;
+
+ /* Save the mapping mode info */
+ mapMode=dc->w.MapMode;
+ IntGetViewportExtEx(dc, &szViewportExt);
+ IntGetViewportOrgEx(dc, &ptViewportOrg);
+ IntGetWindowExtEx(dc, &szWindowExt);
+ IntGetWindowOrgEx(dc, &ptWindowOrg);
+ xform = dc->w.xformWorld2Wnd;
+
+ /* Set MM_TEXT */
+ dc->w.MapMode = MM_TEXT;
+ dc->vportOrgX = 0;
+ dc->vportOrgY = 0;
+ dc->wndOrgX = 0;
+ dc->wndOrgY = 0;
+ graphicsMode = dc->w.GraphicsMode;
+ dc->w.GraphicsMode = GM_ADVANCED;
+ IntGdiModifyWorldTransform(dc, &xform, MWT_IDENTITY);
+ dc->w.GraphicsMode = graphicsMode;
+
+ /* Allocate enough memory for the worst case without beziers (one PT_MOVETO
+ * and the rest PT_LINETO with PT_CLOSEFIGURE at the end) plus some buffer
+ * space in case we get one to keep the number of reallocations small. */
+ nAlloc = pPath->numEntriesUsed + 1 + 300;
+ pLinePts = ExAllocatePoolWithTag(PagedPool, nAlloc * sizeof(POINT), TAG_PATH);
+ if(!pLinePts)
+ {
+ DPRINT1("Can't allocate pool!\n");
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ goto end;
+ }
+ nLinePts = 0;
+
+ for(i = 0; i < pPath->numEntriesUsed; i++)
+ {
+ if((i == 0 || (pPath->pFlags[i-1] & PT_CLOSEFIGURE))
+ && (pPath->pFlags[i] != PT_MOVETO))
+ {
+ DPRINT1("Expected PT_MOVETO %s, got path flag %d\n",
+ i == 0 ? "as first point" : "after PT_CLOSEFIGURE",
+ (INT)pPath->pFlags[i]);
+ goto end;
+ }
+
+ switch(pPath->pFlags[i])
+ {
+ case PT_MOVETO:
+ DPRINT("Got PT_MOVETO (%ld, %ld)\n",
+ pPath->pPoints[i].x, pPath->pPoints[i].y);
+ if(nLinePts >= 2) IntGdiPolyline(dc, pLinePts, nLinePts);
+ nLinePts = 0;
+ pLinePts[nLinePts++] = pPath->pPoints[i];
+ break;
+ case PT_LINETO:
+ case (PT_LINETO | PT_CLOSEFIGURE):
+ DPRINT("Got PT_LINETO (%ld, %ld)\n",
+ pPath->pPoints[i].x, pPath->pPoints[i].y);
+ pLinePts[nLinePts++] = pPath->pPoints[i];
+ break;
+ case PT_BEZIERTO:
+ DPRINT("Got PT_BEZIERTO\n");
+ if(pPath->pFlags[i+1] != PT_BEZIERTO ||
+ (pPath->pFlags[i+2] & ~PT_CLOSEFIGURE) != PT_BEZIERTO)
+ {
+ DPRINT1("Path didn't contain 3 successive
PT_BEZIERTOs\n");
+ ret = FALSE;
+ goto end;
+ }
+ else
+ {
+ INT nBzrPts, nMinAlloc;
+ POINT *pBzrPts = GDI_Bezier(&pPath->pPoints[i-1], 4,
&nBzrPts);
+ /* Make sure we have allocated enough memory for the lines of
+ * this bezier and the rest of the path, assuming we won't get
+ * another one (since we won't reallocate again then). */
+ nMinAlloc = nLinePts + (pPath->numEntriesUsed - i) + nBzrPts;
+ if(nAlloc < nMinAlloc)
+ {
+ // Reallocate memory
+
+ POINT *Realloc = NULL;
+ nAlloc = nMinAlloc * 2;
+
+ Realloc = ExAllocatePoolWithTag(PagedPool,
+ nAlloc * sizeof(POINT),
+ TAG_PATH);
+
+ if(!Realloc)
+ {
+ DPRINT1("Can't allocate pool!\n");
+ goto end;
+ }
+
+ RtlCopyMemory(Realloc, pLinePts, nLinePts*sizeof(POINT));
+ ExFreePool(pLinePts);
+ pLinePts = Realloc;
+ }
+ RtlCopyMemory(&pLinePts[nLinePts], &pBzrPts[1], (nBzrPts - 1) *
sizeof(POINT));
+ nLinePts += nBzrPts - 1;
+ ExFreePool(pBzrPts);
+ i += 2;
+ }
+ break;
+ default:
+ DPRINT1("Got path flag %d (not supported)\n",
(INT)pPath->pFlags[i]);
+ goto end;
+ }
+
+ if(pPath->pFlags[i] & PT_CLOSEFIGURE)
+ {
+ pLinePts[nLinePts++] = pLinePts[0];
+ }
+ }//for
+
+ if(nLinePts >= 2)
+ IntGdiPolyline(dc, pLinePts, nLinePts);
+
+ ret = TRUE;
+
+end:
+ if(pLinePts)ExFreePool(pLinePts);
+
+ /* Restore the old mapping mode */
+ dc->w.MapMode = mapMode;
+ dc->wndExtX = szWindowExt.cx;
+ dc->wndExtY = szWindowExt.cy;
+ dc->wndOrgX = ptWindowOrg.x;
+ dc->wndOrgY = ptWindowOrg.y;
+
+ dc->vportExtX = szViewportExt.cx;
+ dc->vportExtY = szViewportExt.cy;
+ dc->vportOrgX = ptViewportOrg.x;
+ dc->vportOrgY = ptViewportOrg.y;
+
+ /* Restore the world transform */
+ dc->w.xformWorld2Wnd = xform;
+
+ /* If we've moved the current point then get its new position
+ which will be in device (MM_TEXT) co-ords, convert it to
+ logical co-ords and re-set it. This basically updates
+ dc->CurPosX|Y so that their values are in the correct mapping
+ mode.
+ */
+ if(i > 0)
+ {
+ POINT pt;
+ IntGetCurrentPositionEx(dc, &pt);
+ IntDPtoLP(dc, &pt, 1);
+ IntGdiMoveToEx(dc, pt.x, pt.y, NULL);
+ }
+
+ DPRINT("Leave %s, ret=%d\n", __FUNCTION__, ret);
+ return ret;
+}
+
/* EOF */