From 0afa832f3739ba2363491883e546bfd6f5bc378a Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 25 Mar 2005 20:52:53 +0000 Subject: [PATCH] Maintain the stack of saved vis regions in the DC structure instead of storing it directly in the region objects. --- dlls/gdi/clipping.c | 60 ++++++++++++++---------------------------- dlls/gdi/dc.c | 9 +++++++ dlls/gdi/gdi_private.h | 8 ++++++ 3 files changed, 37 insertions(+), 40 deletions(-) diff --git a/dlls/gdi/clipping.c b/dlls/gdi/clipping.c index 3570f91d1a5..0b98b467661 100644 --- a/dlls/gdi/clipping.c +++ b/dlls/gdi/clipping.c @@ -434,39 +434,25 @@ INT WINAPI GetClipRgn( HDC hdc, HRGN hRgn ) */ HRGN16 WINAPI SaveVisRgn16( HDC16 hdc16 ) { - HRGN copy; - GDIOBJHDR *obj, *copyObj; + struct saved_visrgn *saved; HDC hdc = HDC_32( hdc16 ); DC *dc = DC_GetDCUpdate( hdc ); if (!dc) return 0; TRACE("%p\n", hdc ); - if (!(obj = GDI_GetObjPtr( dc->hVisRgn, REGION_MAGIC ))) - { - GDI_ReleaseObj( hdc ); - return 0; - } - if (!(copy = CreateRectRgn( 0, 0, 0, 0 ))) - { - GDI_ReleaseObj( dc->hVisRgn ); - GDI_ReleaseObj( hdc ); - return 0; - } - CombineRgn( copy, dc->hVisRgn, 0, RGN_COPY ); - if (!(copyObj = GDI_GetObjPtr( copy, REGION_MAGIC ))) - { - DeleteObject( copy ); - GDI_ReleaseObj( dc->hVisRgn ); - GDI_ReleaseObj( hdc ); - return 0; - } - copyObj->hNext = obj->hNext; - obj->hNext = HRGN_16(copy); - GDI_ReleaseObj( copy ); - GDI_ReleaseObj( dc->hVisRgn ); + if (!(saved = HeapAlloc( GetProcessHeap(), 0, sizeof(*saved) ))) goto error; + if (!(saved->hrgn = CreateRectRgn( 0, 0, 0, 0 ))) goto error; + CombineRgn( saved->hrgn, dc->hVisRgn, 0, RGN_COPY ); + saved->next = dc->saved_visrgn; + dc->saved_visrgn = saved; GDI_ReleaseObj( hdc ); - return HRGN_16(copy); + return HRGN_16(saved->hrgn); + +error: + GDI_ReleaseObj( hdc ); + HeapFree( GetProcessHeap(), 0, saved ); + return 0; } @@ -475,8 +461,7 @@ HRGN16 WINAPI SaveVisRgn16( HDC16 hdc16 ) */ INT16 WINAPI RestoreVisRgn16( HDC16 hdc16 ) { - HRGN saved; - GDIOBJHDR *obj, *savedObj; + struct saved_visrgn *saved; HDC hdc = HDC_32( hdc16 ); DC *dc = DC_GetDCPtr( hdc ); INT16 ret = ERROR; @@ -485,19 +470,14 @@ INT16 WINAPI RestoreVisRgn16( HDC16 hdc16 ) TRACE("%p\n", hdc ); - if (!(obj = GDI_GetObjPtr( dc->hVisRgn, REGION_MAGIC ))) goto done; - saved = HRGN_32(obj->hNext); + if (!(saved = dc->saved_visrgn)) goto done; - if ((savedObj = GDI_GetObjPtr( saved, REGION_MAGIC ))) - { - ret = CombineRgn( dc->hVisRgn, saved, 0, RGN_COPY ); - obj->hNext = savedObj->hNext; - GDI_ReleaseObj( saved ); - DeleteObject( saved ); - dc->flags &= ~DC_DIRTY; - CLIPPING_UpdateGCRegion( dc ); - } - GDI_ReleaseObj( dc->hVisRgn ); + ret = CombineRgn( dc->hVisRgn, saved->hrgn, 0, RGN_COPY ); + dc->saved_visrgn = saved->next; + DeleteObject( saved->hrgn ); + HeapFree( GetProcessHeap(), 0, saved ); + dc->flags &= ~DC_DIRTY; + CLIPPING_UpdateGCRegion( dc ); done: GDI_ReleaseObj( hdc ); return ret; diff --git a/dlls/gdi/dc.c b/dlls/gdi/dc.c index f5a95c5340f..723bacd4baf 100644 --- a/dlls/gdi/dc.c +++ b/dlls/gdi/dc.c @@ -121,6 +121,7 @@ DC *DC_AllocDC( const DC_FUNCTIONS *funcs, WORD magic ) dc->BoundsRect.top = 0; dc->BoundsRect.right = 0; dc->BoundsRect.bottom = 0; + dc->saved_visrgn = NULL; PATH_InitGdiPath(&dc->path); return dc; } @@ -340,6 +341,7 @@ HDC WINAPI GetDCState( HDC hdc ) newdc->pAbortProc = NULL; newdc->hookThunk = NULL; newdc->hookProc = 0; + newdc->saved_visrgn = NULL; /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */ @@ -788,6 +790,13 @@ BOOL WINAPI DeleteDC( HDC hdc ) dc->physDev = NULL; } + while (dc->saved_visrgn) + { + struct saved_visrgn *next = dc->saved_visrgn->next; + DeleteObject( dc->saved_visrgn->hrgn ); + HeapFree( GetProcessHeap(), 0, dc->saved_visrgn ); + dc->saved_visrgn = next; + } if (dc->hClipRgn) DeleteObject( dc->hClipRgn ); if (dc->hVisRgn) DeleteObject( dc->hVisRgn ); PATH_DestroyGdiPath(&dc->path); diff --git a/dlls/gdi/gdi_private.h b/dlls/gdi/gdi_private.h index 560f4af4695..ddd1d1626c9 100644 --- a/dlls/gdi/gdi_private.h +++ b/dlls/gdi/gdi_private.h @@ -196,6 +196,12 @@ typedef struct tagGdiPath typedef struct tagGdiFont *GdiFont; +struct saved_visrgn +{ + struct saved_visrgn *next; + HRGN hrgn; +}; + typedef struct tagDC { GDIOBJHDR header; @@ -259,6 +265,8 @@ typedef struct tagDC XFORM xformVport2World; /* Inverse of the above transformation */ BOOL vport2WorldValid; /* Is xformVport2World valid? */ RECT BoundsRect; /* Current bounding rect */ + + struct saved_visrgn *saved_visrgn; } DC; /* DC flags */