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/obj... ============================================================================== --- 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 */