implemented NtGdiSelectClipPath and PATH_FillPath
authorChristoph von Wittich <christoph_vw@reactos.org>
Fri, 9 Dec 2005 18:06:19 +0000 (18:06 +0000)
committerChristoph von Wittich <christoph_vw@reactos.org>
Fri, 9 Dec 2005 18:06:19 +0000 (18:06 +0000)
svn path=/trunk/; revision=20012

reactos/include/win32k/cliprgn.h
reactos/subsys/win32k/include/path.h
reactos/subsys/win32k/objects/cliprgn.c
reactos/subsys/win32k/objects/path.c

index 6a0107e..e0bbe78 100644 (file)
@@ -4,6 +4,14 @@
 HRGN WINAPI SaveVisRgn(HDC hdc);
 INT WINAPI SelectVisRgn(HDC hdc, HRGN hrgn);
 
+int
+STDCALL
+IntGdiExtSelectClipRgn (
+        PDC     dc,
+        HRGN    hrgn, 
+        int     fnMode
+        );
+
 int
 STDCALL
 NtGdiExcludeClipRect (
index 2a77fef..9631b1f 100644 (file)
@@ -18,6 +18,6 @@ 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 (PDC dc, INT x1, INT y1, INT x2, INT y2, INT xradius, INT yradius);
-BOOL FASTCALL PATH_PathToRegion (const GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn);
+BOOL FASTCALL PATH_PathToRegion (GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn);
 
 #endif /* _WIN32K_PATH_H */
index 3e8c047..1c49d97 100644 (file)
@@ -99,20 +99,13 @@ NtGdiSelectVisRgn(HDC hdc, HRGN hrgn)
   return retval;
 }
 
-int STDCALL NtGdiExtSelectClipRgn(HDC  hDC,
-                          HRGN  hrgn,
-                          int  fnMode)
+
+int STDCALL IntGdiExtSelectClipRgn(PDC dc, 
+                                HRGN hrgn, 
+                                int fnMode)
 {
   int retval;
-  DC *dc;
-
-  if (!(dc = DC_LockDc(hDC)))
-  {
-       SetLastWin32Error(ERROR_INVALID_HANDLE);
-       return ERROR;
-  }
-
-//  dc->w.flags &= ~DC_DIRTY;
+  //  dc->w.flags &= ~DC_DIRTY;
 
   if (!hrgn)
   {
@@ -127,7 +120,6 @@ int STDCALL NtGdiExtSelectClipRgn(HDC  hDC,
     }
     else
     {
-      DC_UnlockDc(dc);
       SetLastWin32Error(ERROR_INVALID_PARAMETER);
       return ERROR;
     }
@@ -158,8 +150,26 @@ int STDCALL NtGdiExtSelectClipRgn(HDC  hDC,
   }
 
   retval = CLIPPING_UpdateGCRegion(dc);
-  DC_UnlockDc(dc);
+  return retval;
+}
+
+
+int STDCALL NtGdiExtSelectClipRgn(HDC  hDC,
+                          HRGN  hrgn,
+                          int  fnMode)
+{
+  int retval;
+  DC *dc;
+
+  if (!(dc = DC_LockDc(hDC)))
+  {
+       SetLastWin32Error(ERROR_INVALID_HANDLE);
+       return ERROR;
+  }
 
+  retval = IntGdiExtSelectClipRgn ( dc, hrgn, fnMode );
+
+  DC_UnlockDc(dc);
   return retval;
 }
 
@@ -427,13 +437,6 @@ BOOL STDCALL NtGdiRectVisible(HDC  hDC,
    return Result;
 }
 
-BOOL STDCALL NtGdiSelectClipPath(HDC  hDC,
-                         int  Mode)
-{
-  UNIMPLEMENTED;
-  return FALSE;
-}
-
 INT STDCALL
 NtGdiSelectClipRgn(HDC hDC, HRGN hRgn)
 {
index 7ba7208..472b007 100644 (file)
@@ -35,7 +35,7 @@ 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(const GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn);
+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);
 
@@ -235,7 +235,37 @@ NtGdiWidenPath(HDC  hDC)
    return FALSE;
 }
 
+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 )
+   SetLastWin32Error(ERROR_CAN_NOT_COMPLETE);
+   return FALSE;
+ /* Construct a region from the path */
+ else if( PATH_PathToRegion( pPath, dc->w.polyFillMode, &hrgnPath ) )
+ {
+   success = IntGdiExtSelectClipRgn( dc, hrgnPath, Mode ) != ERROR;
+   NtGdiDeleteObject( hrgnPath );
+
+   /* Empty the path */
+   if( success )
+     PATH_EmptyPath( pPath );
+   /* FIXME: Should this function delete the path even if it failed? */
+ }
+
+ DC_UnlockDc ( dc );
+ return success;
+}
 
 /***********************************************************************
  * Exported functions
@@ -243,19 +273,76 @@ NtGdiWidenPath(HDC  hDC)
 
 
 /* PATH_FillPath
- * unimplemented
+ * 
  * 
  */
 BOOL
 FASTCALL 
 PATH_FillPath( PDC dc, GdiPath *pPath )
 {
+  INT   mapMode, graphicsMode;
+  SIZE  ptViewportExt, ptWindowExt;
+  POINT ptViewportOrg, ptWindowOrg;
+  XFORM xform;
+  HRGN  hrgn;
+
   if( pPath->state != PATH_Closed )
   {
+    SetLastWin32Error(ERROR_CAN_NOT_COMPLETE);
     return FALSE;
   }
     
-  UNIMPLEMENTED;
+  if( PATH_PathToRegion( pPath, dc->w.polyFillMode, &hrgn ))
+  {
+    /* Since PaintRgn interprets the region as being in logical coordinates
+     * but the points we store for the path are already in device
+     * coordinates, we have to set the mapping mode to MM_TEXT temporarily.
+     * Using SaveDC to save information about the mapping mode / world
+     * transform would be easier but would require more overhead, especially
+     * now that SaveDC saves the current path.
+     */
+
+    /* Save the information about the old mapping mode */
+    mapMode = NtGdiGetMapMode( dc->hSelf );
+    NtGdiGetViewportExtEx( dc->hSelf, &ptViewportExt );
+    NtGdiGetViewportOrgEx( dc->hSelf, &ptViewportOrg );
+    NtGdiGetWindowExtEx( dc->hSelf, &ptWindowExt );
+    NtGdiGetWindowOrgEx( dc->hSelf, &ptWindowOrg );
+
+    /* Save world transform
+     * NB: The Windows documentation on world transforms would lead one to
+     * believe that this has to be done only in GM_ADVANCED; however, my
+     * tests show that resetting the graphics mode to GM_COMPATIBLE does
+     * not reset the world transform.
+     */
+    NtGdiGetWorldTransform( dc->hSelf, &xform );
+
+    /* Set MM_TEXT */
+    NtGdiSetMapMode( dc->hSelf, MM_TEXT );
+    NtGdiSetViewportOrgEx( dc->hSelf, 0, 0, NULL );
+    NtGdiSetWindowOrgEx( dc->hSelf, 0, 0, NULL );
+    graphicsMode = NtGdiGetGraphicsMode( dc->hSelf );
+    NtGdiSetGraphicsMode( dc->hSelf, GM_ADVANCED );
+    NtGdiModifyWorldTransform( dc->hSelf, &xform, MWT_IDENTITY );
+    NtGdiSetGraphicsMode( dc->hSelf, graphicsMode );
+
+    /* Paint the region */
+    NtGdiPaintRgn( dc->hSelf, hrgn );
+    NtGdiDeleteObject( hrgn );
+    /* Restore the old mapping mode */
+    NtGdiSetMapMode( dc->hSelf, mapMode );
+    NtGdiSetViewportExtEx( dc->hSelf, ptViewportExt.cx, ptViewportExt.cy, NULL );
+    NtGdiSetViewportOrgEx( dc->hSelf, ptViewportOrg.x, ptViewportOrg.y, NULL );
+    NtGdiSetWindowExtEx( dc->hSelf, ptWindowExt.cx, ptWindowExt.cy, NULL );
+    NtGdiSetWindowOrgEx( dc->hSelf, ptWindowOrg.x, ptWindowOrg.y, NULL );
+
+    /* Go to GM_ADVANCED temporarily to restore the world transform */
+    graphicsMode = NtGdiGetGraphicsMode( dc->hSelf );
+    NtGdiSetGraphicsMode( dc->hSelf, GM_ADVANCED );
+    NtGdiSetWorldTransform( dc->hSelf, &xform );
+    NtGdiSetGraphicsMode( dc->hSelf, graphicsMode );
+    return TRUE;
+  }
   return FALSE;
 }
 
@@ -924,15 +1011,11 @@ PATH_FlattenPath(GdiPath *pPath)
  * error occurs, SetLastError is called with the appropriate value and
  * FALSE is returned.
  */
-#if 0
-// FIXME - don't reenable this function until you deal with the
-// const pPath being given to PATH_FlattenPath() - which is
-// expecting a non-const*. Since this function isn't being called
-// at the moment, I'm commenting it out until the issue needs to
-// be addressed.
+
+
 BOOL
 FASTCALL
-PATH_PathToRegion ( const GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn )
+PATH_PathToRegion ( GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn )
 {
   int    numStrokes, iStroke, i;
   INT  *pNumPointsInStroke;
@@ -990,7 +1073,6 @@ PATH_PathToRegion ( const GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn )
   *pHrgn=hrgn;
   return TRUE;
 }
-#endif
 
 /* PATH_EmptyPath
  *