Commit ee9b4265 authored by Alexandre Julliard's avatar Alexandre Julliard

Added support for the DC meta region.

parent df52b726
...@@ -33,12 +33,27 @@ WINE_DEFAULT_DEBUG_CHANNEL(clipping); ...@@ -33,12 +33,27 @@ WINE_DEFAULT_DEBUG_CHANNEL(clipping);
/*********************************************************************** /***********************************************************************
* get_clip_region
*
* Return the total clip region (if any).
*/
static inline HRGN get_clip_region( DC * dc )
{
if (dc->hMetaClipRgn) return dc->hMetaClipRgn;
if (dc->hMetaRgn) return dc->hMetaRgn;
return dc->hClipRgn;
}
/***********************************************************************
* CLIPPING_UpdateGCRegion * CLIPPING_UpdateGCRegion
* *
* Update the GC clip region when the ClipRgn or VisRgn have changed. * Update the GC clip region when the ClipRgn or VisRgn have changed.
*/ */
void CLIPPING_UpdateGCRegion( DC * dc ) void CLIPPING_UpdateGCRegion( DC * dc )
{ {
HRGN clip_rgn;
if (!dc->hVisRgn) if (!dc->hVisRgn)
{ {
ERR("hVisRgn is zero. Please report this.\n" ); ERR("hVisRgn is zero. Please report this.\n" );
...@@ -47,12 +62,26 @@ void CLIPPING_UpdateGCRegion( DC * dc ) ...@@ -47,12 +62,26 @@ void CLIPPING_UpdateGCRegion( DC * dc )
if (dc->flags & DC_DIRTY) ERR( "DC is dirty. Please report this.\n" ); if (dc->flags & DC_DIRTY) ERR( "DC is dirty. Please report this.\n" );
/* update the intersection of meta and clip regions */
if (dc->hMetaRgn && dc->hClipRgn)
{
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;
}
if (dc->funcs->pSetDeviceClipping) if (dc->funcs->pSetDeviceClipping)
dc->funcs->pSetDeviceClipping( dc->physDev, dc->hVisRgn, dc->hClipRgn ); dc->funcs->pSetDeviceClipping( dc->physDev, dc->hVisRgn, clip_rgn );
} }
/*********************************************************************** /***********************************************************************
* create_default_clip_rgn * create_default_clip_region
* *
* Create a default clipping region when none already exists. * Create a default clipping region when none already exists.
*/ */
...@@ -346,6 +375,7 @@ BOOL WINAPI PtVisible( HDC hdc, INT x, INT y ) ...@@ -346,6 +375,7 @@ BOOL WINAPI PtVisible( HDC hdc, INT x, INT y )
{ {
POINT pt; POINT pt;
BOOL ret; BOOL ret;
HRGN clip;
DC *dc = DC_GetDCUpdate( hdc ); DC *dc = DC_GetDCUpdate( hdc );
TRACE("%p %d,%d\n", hdc, x, y ); TRACE("%p %d,%d\n", hdc, x, y );
...@@ -355,7 +385,7 @@ BOOL WINAPI PtVisible( HDC hdc, INT x, INT y ) ...@@ -355,7 +385,7 @@ BOOL WINAPI PtVisible( HDC hdc, INT x, INT y )
pt.y = y; pt.y = y;
LPtoDP( hdc, &pt, 1 ); LPtoDP( hdc, &pt, 1 );
ret = PtInRegion( dc->hVisRgn, pt.x, pt.y ); ret = PtInRegion( dc->hVisRgn, pt.x, pt.y );
if (ret && dc->hClipRgn) ret = PtInRegion( dc->hClipRgn, pt.x, pt.y ); if (ret && (clip = get_clip_region(dc))) ret = PtInRegion( clip, pt.x, pt.y );
GDI_ReleaseObj( hdc ); GDI_ReleaseObj( hdc );
return ret; return ret;
} }
...@@ -368,6 +398,7 @@ BOOL WINAPI RectVisible( HDC hdc, const RECT* rect ) ...@@ -368,6 +398,7 @@ BOOL WINAPI RectVisible( HDC hdc, const RECT* rect )
{ {
RECT tmpRect; RECT tmpRect;
BOOL ret; BOOL ret;
HRGN clip;
DC *dc = DC_GetDCUpdate( hdc ); DC *dc = DC_GetDCUpdate( hdc );
if (!dc) return FALSE; if (!dc) return FALSE;
TRACE("%p %ld,%ldx%ld,%ld\n", hdc, rect->left, rect->top, rect->right, rect->bottom ); TRACE("%p %ld,%ldx%ld,%ld\n", hdc, rect->left, rect->top, rect->right, rect->bottom );
...@@ -375,10 +406,10 @@ BOOL WINAPI RectVisible( HDC hdc, const RECT* rect ) ...@@ -375,10 +406,10 @@ BOOL WINAPI RectVisible( HDC hdc, const RECT* rect )
tmpRect = *rect; tmpRect = *rect;
LPtoDP( hdc, (POINT *)&tmpRect, 2 ); LPtoDP( hdc, (POINT *)&tmpRect, 2 );
if (dc->hClipRgn) if ((clip = get_clip_region(dc)))
{ {
HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 ); HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
CombineRgn( hrgn, dc->hVisRgn, dc->hClipRgn, RGN_AND ); CombineRgn( hrgn, dc->hVisRgn, clip, RGN_AND );
ret = RectInRegion( hrgn, &tmpRect ); ret = RectInRegion( hrgn, &tmpRect );
DeleteObject( hrgn ); DeleteObject( hrgn );
} }
...@@ -394,12 +425,13 @@ BOOL WINAPI RectVisible( HDC hdc, const RECT* rect ) ...@@ -394,12 +425,13 @@ BOOL WINAPI RectVisible( HDC hdc, const RECT* rect )
INT WINAPI GetClipBox( HDC hdc, LPRECT rect ) INT WINAPI GetClipBox( HDC hdc, LPRECT rect )
{ {
INT ret; INT ret;
HRGN clip;
DC *dc = DC_GetDCUpdate( hdc ); DC *dc = DC_GetDCUpdate( hdc );
if (!dc) return ERROR; if (!dc) return ERROR;
if (dc->hClipRgn) if ((clip = get_clip_region(dc)))
{ {
HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 ); HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
CombineRgn( hrgn, dc->hVisRgn, dc->hClipRgn, RGN_AND ); CombineRgn( hrgn, dc->hVisRgn, clip, RGN_AND );
ret = GetRgnBox( hrgn, rect ); ret = GetRgnBox( hrgn, rect );
DeleteObject( hrgn ); DeleteObject( hrgn );
} }
...@@ -429,6 +461,25 @@ INT WINAPI GetClipRgn( HDC hdc, HRGN hRgn ) ...@@ -429,6 +461,25 @@ INT WINAPI GetClipRgn( HDC hdc, HRGN hRgn )
return ret; return ret;
} }
/***********************************************************************
* GetMetaRgn (GDI32.@)
*/
INT WINAPI GetMetaRgn( HDC hdc, HRGN hRgn )
{
INT ret = 0;
DC * dc = DC_GetDCPtr( hdc );
if (dc)
{
if (dc->hMetaRgn && CombineRgn( hRgn, dc->hMetaRgn, 0, RGN_COPY ) != ERROR)
ret = 1;
GDI_ReleaseObj( hdc );
}
return ret;
}
/*********************************************************************** /***********************************************************************
* SaveVisRgn (GDI.129) * SaveVisRgn (GDI.129)
*/ */
...@@ -500,59 +551,74 @@ INT16 WINAPI RestoreVisRgn16( HDC16 hdc16 ) ...@@ -500,59 +551,74 @@ INT16 WINAPI RestoreVisRgn16( HDC16 hdc16 )
*/ */
INT WINAPI GetRandomRgn(HDC hDC, HRGN hRgn, INT iCode) INT WINAPI GetRandomRgn(HDC hDC, HRGN hRgn, INT iCode)
{ {
HRGN rgn;
DC *dc = DC_GetDCPtr( hDC );
if (!dc) return -1;
switch (iCode) switch (iCode)
{ {
case 1:
rgn = dc->hClipRgn;
break;
case 2:
rgn = dc->hMetaRgn;
break;
case 3:
rgn = dc->hMetaClipRgn;
break;
case SYSRGN: /* == 4 */ case SYSRGN: /* == 4 */
{ rgn = dc->hVisRgn;
DC *dc = DC_GetDCPtr (hDC); break;
if (!dc) return -1;
CombineRgn (hRgn, dc->hVisRgn, 0, RGN_COPY);
GDI_ReleaseObj( hDC );
/*
* On Windows NT/2000,
* the region returned is in screen coordinates.
* On Windows 95/98,
* the region returned is in window coordinates
*/
if (!(GetVersion() & 0x80000000))
{
POINT org;
GetDCOrgEx(hDC, &org);
OffsetRgn(hRgn, org.x, org.y);
}
return 1;
}
case 1: /* clip region */
return GetClipRgn (hDC, hRgn);
default: default:
WARN("Unknown iCode %d\n", iCode); WARN("Unknown code %d\n", iCode);
GDI_ReleaseObj( hDC );
return -1; return -1;
} }
if (rgn) CombineRgn( hRgn, rgn, 0, RGN_COPY );
GDI_ReleaseObj( hDC );
return -1; /* On Windows NT/2000, the region returned is in screen coordinates */
if (!(GetVersion() & 0x80000000))
{
POINT org;
GetDCOrgEx( hDC, &org );
OffsetRgn( hRgn, org.x, org.y );
}
return (rgn != 0);
} }
/*********************************************************************** /***********************************************************************
* GetMetaRgn (GDI32.@) * SetMetaRgn (GDI32.@)
*/ */
INT WINAPI GetMetaRgn( HDC hdc, HRGN hRgn ) INT WINAPI SetMetaRgn( HDC hdc )
{ {
FIXME( "stub\n" ); INT ret;
RECT dummy;
DC *dc = DC_GetDCPtr( hdc );
return 0; if (!dc) return ERROR;
}
if (dc->hMetaClipRgn)
{
/* the intersection becomes the new meta region */
DeleteObject( dc->hMetaRgn );
DeleteObject( dc->hClipRgn );
dc->hMetaRgn = dc->hMetaClipRgn;
dc->hClipRgn = 0;
dc->hMetaClipRgn = 0;
}
else if (dc->hClipRgn)
{
dc->hMetaRgn = dc->hClipRgn;
dc->hClipRgn = 0;
}
/* else nothing to do */
/*********************************************************************** /* Note: no need to call CLIPPING_UpdateGCRegion, the overall clip region hasn't changed */
* SetMetaRgn (GDI32.@)
*/
INT WINAPI SetMetaRgn( HDC hdc )
{
FIXME( "stub\n" );
return ERROR; ret = GetRgnBox( dc->hMetaRgn, &dummy );
GDI_ReleaseObj( hdc );
return ret;
} }
...@@ -80,6 +80,8 @@ DC *DC_AllocDC( const DC_FUNCTIONS *funcs, WORD magic ) ...@@ -80,6 +80,8 @@ DC *DC_AllocDC( const DC_FUNCTIONS *funcs, WORD magic )
dc->flags = 0; dc->flags = 0;
dc->layout = 0; dc->layout = 0;
dc->hClipRgn = 0; dc->hClipRgn = 0;
dc->hMetaRgn = 0;
dc->hMetaClipRgn = 0;
dc->hVisRgn = 0; dc->hVisRgn = 0;
dc->hPen = GetStockObject( BLACK_PEN ); dc->hPen = GetStockObject( BLACK_PEN );
dc->hBrush = GetStockObject( WHITE_BRUSH ); dc->hBrush = GetStockObject( WHITE_BRUSH );
...@@ -347,14 +349,21 @@ HDC WINAPI GetDCState( HDC hdc ) ...@@ -347,14 +349,21 @@ HDC WINAPI GetDCState( HDC hdc )
/* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */ /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
newdc->hVisRgn = 0; newdc->hVisRgn = 0;
newdc->hClipRgn = 0;
newdc->hMetaRgn = 0;
newdc->hMetaClipRgn = 0;
if (dc->hClipRgn) if (dc->hClipRgn)
{ {
newdc->hClipRgn = CreateRectRgn( 0, 0, 0, 0 ); newdc->hClipRgn = CreateRectRgn( 0, 0, 0, 0 );
CombineRgn( newdc->hClipRgn, dc->hClipRgn, 0, RGN_COPY ); CombineRgn( newdc->hClipRgn, dc->hClipRgn, 0, RGN_COPY );
} }
else if (dc->hMetaRgn)
newdc->hClipRgn = 0; {
newdc->hMetaRgn = CreateRectRgn( 0, 0, 0, 0 );
CombineRgn( newdc->hMetaRgn, dc->hMetaRgn, 0, RGN_COPY );
}
/* don't bother recomputing hMetaClipRgn, we'll do that in SetDCState */
if(dc->gdiFont) { if(dc->gdiFont) {
newdc->gdiFont = dc->gdiFont; newdc->gdiFont = dc->gdiFont;
...@@ -436,6 +445,16 @@ void WINAPI SetDCState( HDC hdc, HDC hdcs ) ...@@ -436,6 +445,16 @@ void WINAPI SetDCState( HDC hdc, HDC hdcs )
if (dc->hClipRgn) DeleteObject( dc->hClipRgn ); if (dc->hClipRgn) DeleteObject( dc->hClipRgn );
dc->hClipRgn = 0; dc->hClipRgn = 0;
} }
if (dcs->hMetaRgn)
{
if (!dc->hMetaRgn) dc->hMetaRgn = CreateRectRgn( 0, 0, 0, 0 );
CombineRgn( dc->hMetaRgn, dcs->hMetaRgn, 0, RGN_COPY );
}
else
{
if (dc->hMetaRgn) DeleteObject( dc->hMetaRgn );
dc->hMetaRgn = 0;
}
CLIPPING_UpdateGCRegion( dc ); CLIPPING_UpdateGCRegion( dc );
SelectObject( hdc, dcs->hBitmap ); SelectObject( hdc, dcs->hBitmap );
...@@ -777,6 +796,8 @@ BOOL WINAPI DeleteDC( HDC hdc ) ...@@ -777,6 +796,8 @@ BOOL WINAPI DeleteDC( HDC hdc )
dc->saved_dc = dcs->saved_dc; dc->saved_dc = dcs->saved_dc;
dc->saveLevel--; dc->saveLevel--;
if (dcs->hClipRgn) DeleteObject( dcs->hClipRgn ); if (dcs->hClipRgn) DeleteObject( dcs->hClipRgn );
if (dcs->hMetaRgn) DeleteObject( dcs->hMetaRgn );
if (dcs->hMetaClipRgn) DeleteObject( dcs->hMetaClipRgn );
if (dcs->hVisRgn) DeleteObject( dcs->hVisRgn ); if (dcs->hVisRgn) DeleteObject( dcs->hVisRgn );
PATH_DestroyGdiPath(&dcs->path); PATH_DestroyGdiPath(&dcs->path);
GDI_FreeObject( hdcs, dcs ); GDI_FreeObject( hdcs, dcs );
...@@ -801,6 +822,8 @@ BOOL WINAPI DeleteDC( HDC hdc ) ...@@ -801,6 +822,8 @@ BOOL WINAPI DeleteDC( HDC hdc )
dc->saved_visrgn = next; dc->saved_visrgn = next;
} }
if (dc->hClipRgn) DeleteObject( dc->hClipRgn ); if (dc->hClipRgn) DeleteObject( dc->hClipRgn );
if (dc->hMetaRgn) DeleteObject( dc->hMetaRgn );
if (dc->hMetaClipRgn) DeleteObject( dc->hMetaClipRgn );
if (dc->hVisRgn) DeleteObject( dc->hVisRgn ); if (dc->hVisRgn) DeleteObject( dc->hVisRgn );
PATH_DestroyGdiPath(&dc->path); PATH_DestroyGdiPath(&dc->path);
......
...@@ -229,8 +229,10 @@ typedef struct tagDC ...@@ -229,8 +229,10 @@ typedef struct tagDC
int flags; int flags;
DWORD layout; DWORD layout;
HRGN hClipRgn; /* Clip region (may be 0) */ HRGN hClipRgn; /* Clip region (may be 0) */
HRGN hVisRgn; /* Visible region (must never 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) */
HPEN hPen; HPEN hPen;
HBRUSH hBrush; HBRUSH hBrush;
HFONT hFont; HFONT hFont;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment