From 5a1a6e935a8a42c63712e9a41f6b779ce13426d1 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 6 Dec 2011 13:08:19 +0100 Subject: [PATCH] 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 53ad56bd2f3..b4d77d30bbc 100644 --- a/dlls/gdi32/clipping.c +++ b/dlls/gdi32/clipping.c @@ -52,27 +52,6 @@ static inline RECT get_clip_rect( DC * dc, int left, int top, int right, int bot return rect; } -/*********************************************************************** - * 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 * @@ -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 b357cee2bd6..77897e979bf 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 c01c2f5ec3f..f499de008bc 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;