Alexandre Julliard : gdi32: Maintain a region inside gdi32 to keep track of the total visible region.

Alexandre Julliard julliard at winehq.org
Tue Dec 6 15:46:18 CST 2011


Module: wine
Branch: master
Commit: 5a1a6e935a8a42c63712e9a41f6b779ce13426d1
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=5a1a6e935a8a42c63712e9a41f6b779ce13426d1

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Dec  6 13:08:19 2011 +0100

gdi32: Maintain a region inside gdi32 to keep track of the total visible region.

---

 dlls/gdi32/clipping.c    |   52 +++++++++++++--------------------------------
 dlls/gdi32/dc.c          |    3 ++
 dlls/gdi32/gdi_private.h |   15 +++++++++---
 3 files changed, 29 insertions(+), 41 deletions(-)

diff --git a/dlls/gdi32/clipping.c b/dlls/gdi32/clipping.c
index 53ad56b..b4d77d3 100644
--- a/dlls/gdi32/clipping.c
+++ b/dlls/gdi32/clipping.c
@@ -53,27 +53,6 @@ static inline RECT get_clip_rect( DC * dc, int left, int top, int right, int bot
 }
 
 /***********************************************************************
- *           get_clip_box
- *
- * Get the clipping rectangle in device coordinates.
- */
-static int get_clip_box( DC *dc, RECT *rect )
-{
-    int ret = ERROR;
-    HRGN rgn, clip = get_clip_region( dc );
-
-    if (!clip) return GetRgnBox( dc->hVisRgn, rect );
-
-    if ((rgn = CreateRectRgn( 0, 0, 0, 0 )))
-    {
-        CombineRgn( rgn, dc->hVisRgn, clip, RGN_AND );
-        ret = GetRgnBox( rgn, rect );
-        DeleteObject( rgn );
-    }
-    return ret;
-}
-
-/***********************************************************************
  *           clip_visrect
  *
  * Clip a rectangle to the DC visible rect.
@@ -82,7 +61,7 @@ BOOL clip_visrect( DC *dc, RECT *dst, const RECT *src )
 {
     RECT clip;
 
-    if (!get_clip_box( dc, &clip ))
+    if (!GetRgnBox( get_dc_region(dc), &clip ))
     {
         *dst = *src;
         return !is_rect_empty( dst );
@@ -105,13 +84,22 @@ void CLIPPING_UpdateGCRegion( DC * dc )
     {
         if (!dc->hMetaClipRgn) dc->hMetaClipRgn = CreateRectRgn( 0, 0, 0, 0 );
         CombineRgn( dc->hMetaClipRgn, dc->hClipRgn, dc->hMetaRgn, RGN_AND );
-        clip_rgn = dc->hMetaClipRgn;
     }
     else  /* only one is set, no need for an intersection */
     {
         if (dc->hMetaClipRgn) DeleteObject( dc->hMetaClipRgn );
         dc->hMetaClipRgn = 0;
-        clip_rgn = dc->hMetaRgn ? dc->hMetaRgn : dc->hClipRgn;
+    }
+    clip_rgn = get_clip_region( dc );
+    if (clip_rgn || dc->hVisRgn)
+    {
+        if (!dc->region) dc->region = CreateRectRgn( 0, 0, 0, 0 );
+        CombineRgn( dc->region, dc->hVisRgn, clip_rgn, clip_rgn ? RGN_AND : RGN_COPY );
+    }
+    else
+    {
+        if (dc->region) DeleteObject( dc->region );
+        dc->region = 0;
     }
     physdev->funcs->pSetDeviceClipping( physdev, dc->hVisRgn, clip_rgn );
 }
@@ -365,7 +353,6 @@ BOOL WINAPI PtVisible( HDC hdc, INT x, INT y )
 {
     POINT pt;
     BOOL ret;
-    HRGN clip;
     DC *dc = get_dc_ptr( hdc );
 
     TRACE("%p %d,%d\n", hdc, x, y );
@@ -375,8 +362,7 @@ BOOL WINAPI PtVisible( HDC hdc, INT x, INT y )
     pt.y = y;
     LPtoDP( hdc, &pt, 1 );
     update_dc( dc );
-    ret = PtInRegion( dc->hVisRgn, pt.x, pt.y );
-    if (ret && (clip = get_clip_region(dc))) ret = PtInRegion( clip, pt.x, pt.y );
+    ret = PtInRegion( get_dc_region(dc), pt.x, pt.y );
     release_dc_ptr( dc );
     return ret;
 }
@@ -389,7 +375,6 @@ BOOL WINAPI RectVisible( HDC hdc, const RECT* rect )
 {
     RECT tmpRect;
     BOOL ret;
-    HRGN clip;
     DC *dc = get_dc_ptr( hdc );
     if (!dc) return FALSE;
     TRACE("%p %s\n", hdc, wine_dbgstr_rect( rect ));
@@ -398,14 +383,7 @@ BOOL WINAPI RectVisible( HDC hdc, const RECT* rect )
     LPtoDP( hdc, (POINT *)&tmpRect, 2 );
 
     update_dc( dc );
-    if ((clip = get_clip_region(dc)))
-    {
-        HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
-        CombineRgn( hrgn, dc->hVisRgn, clip, RGN_AND );
-        ret = RectInRegion( hrgn, &tmpRect );
-        DeleteObject( hrgn );
-    }
-    else ret = RectInRegion( dc->hVisRgn, &tmpRect );
+    ret = RectInRegion( get_dc_region(dc), &tmpRect );
     release_dc_ptr( dc );
     return ret;
 }
@@ -421,7 +399,7 @@ INT WINAPI GetClipBox( HDC hdc, LPRECT rect )
     if (!dc) return ERROR;
 
     update_dc( dc );
-    ret = get_clip_box( dc, rect );
+    ret = GetRgnBox( get_dc_region(dc), rect );
     if (dc->layout & LAYOUT_RTL)
     {
         int tmp = rect->left;
diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c
index b357cee..77897e9 100644
--- a/dlls/gdi32/dc.c
+++ b/dlls/gdi32/dc.c
@@ -103,6 +103,7 @@ DC *alloc_dc_ptr( WORD magic )
     dc->hMetaRgn            = 0;
     dc->hMetaClipRgn        = 0;
     dc->hVisRgn             = 0;
+    dc->region              = 0;
     dc->hPen                = GDI_inc_ref_count( GetStockObject( BLACK_PEN ));
     dc->hBrush              = GDI_inc_ref_count( GetStockObject( WHITE_BRUSH ));
     dc->hFont               = GDI_inc_ref_count( GetStockObject( SYSTEM_FONT ));
@@ -174,6 +175,7 @@ static void free_dc_state( DC *dc )
     if (dc->hMetaRgn) DeleteObject( dc->hMetaRgn );
     if (dc->hMetaClipRgn) DeleteObject( dc->hMetaClipRgn );
     if (dc->hVisRgn) DeleteObject( dc->hVisRgn );
+    if (dc->region) DeleteObject( dc->region );
     if (dc->path) free_gdi_path( dc->path );
     HeapFree( GetProcessHeap(), 0, dc );
 }
@@ -418,6 +420,7 @@ INT nulldrv_SaveDC( PHYSDEV dev )
 
     /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
 
+    newdc->region       = 0;
     newdc->hVisRgn      = 0;
     newdc->hClipRgn     = 0;
     newdc->hMetaRgn     = 0;
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index c01c2f5..f499de0 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -104,10 +104,11 @@ typedef struct tagDC
 
     int           flags;
     DWORD         layout;
-    HRGN          hClipRgn;      /* Clip region (may be 0) */
-    HRGN          hMetaRgn;      /* Meta region (may be 0) */
-    HRGN          hMetaClipRgn;  /* Intersection of meta and clip regions (may be 0) */
-    HRGN          hVisRgn;       /* Visible region (must never be 0) */
+    HRGN          hClipRgn;      /* Clip region */
+    HRGN          hMetaRgn;      /* Meta region */
+    HRGN          hMetaClipRgn;  /* Intersection of meta and clip regions */
+    HRGN          hVisRgn;       /* Visible region */
+    HRGN          region;        /* Total DC region (intersection of clip and visible) */
     HPEN          hPen;
     HBRUSH        hBrush;
     HFONT         hFont;
@@ -223,6 +224,12 @@ static inline HRGN get_clip_region( DC * dc )
     return dc->hClipRgn;
 }
 
+/* Return the total DC region (if any) */
+static inline HRGN get_dc_region( DC *dc )
+{
+    return dc->region;
+}
+
 /* dc.c */
 extern DC *alloc_dc_ptr( WORD magic ) DECLSPEC_HIDDEN;
 extern void free_dc_ptr( DC *dc ) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list