From cb4ecc878f544adfe93ae69812a9abb9d289b1c5 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 3 Mar 2004 05:29:44 +0000 Subject: [PATCH] Implemented Get/SetBoundsRect based on a patch by Ken Belleau. --- dlls/gdi/gdi16.c | 27 +++++++++++++ dlls/gdi/gdi_private.h | 6 ++- include/gdi.h | 1 + objects/dc.c | 86 +++++++++++++++++++++++++++++++----------- 4 files changed, 96 insertions(+), 24 deletions(-) diff --git a/dlls/gdi/gdi16.c b/dlls/gdi/gdi16.c index 87190bc80f4..3a9eba39d15 100644 --- a/dlls/gdi/gdi16.c +++ b/dlls/gdi/gdi16.c @@ -1546,6 +1546,33 @@ void WINAPI PlayMetaFileRecord16( HDC16 hdc, HANDLETABLE16 *ht, METARECORD *mr, } +/*********************************************************************** + * SetBoundsRect (GDI.193) + */ +UINT16 WINAPI SetBoundsRect16( HDC16 hdc, const RECT16* rect, UINT16 flags ) +{ + if (rect) + { + RECT rect32; + CONV_RECT16TO32( rect, &rect32 ); + return SetBoundsRect( HDC_32( hdc ), &rect32, flags ); + } + else return SetBoundsRect( HDC_32( hdc ), NULL, flags ); +} + + +/*********************************************************************** + * GetBoundsRect (GDI.194) + */ +UINT16 WINAPI GetBoundsRect16( HDC16 hdc, LPRECT16 rect, UINT16 flags) +{ + RECT rect32; + UINT ret = GetBoundsRect( HDC_32( hdc ), &rect32, flags ); + if (rect) CONV_RECT32TO16( &rect32, rect ); + return ret; +} + + /*********************************************************************** * EngineEnumerateFont (GDI.300) */ diff --git a/dlls/gdi/gdi_private.h b/dlls/gdi/gdi_private.h index 39281535855..816a00fada2 100644 --- a/dlls/gdi/gdi_private.h +++ b/dlls/gdi/gdi_private.h @@ -171,8 +171,10 @@ typedef struct tagDC_FUNCS } DC_FUNCTIONS; /* DC flags */ -#define DC_SAVED 0x0002 /* It is a saved DC */ -#define DC_DIRTY 0x0004 /* hVisRgn has to be updated */ +#define DC_SAVED 0x0002 /* It is a saved DC */ +#define DC_DIRTY 0x0004 /* hVisRgn has to be updated */ +#define DC_BOUNDS_ENABLE 0x0008 /* Bounding rectangle tracking is enabled */ +#define DC_BOUNDS_SET 0x0010 /* Bounding rectangle has been set */ /* Certain functions will do no further processing if the driver returns this. Used by mfdrv for example. */ diff --git a/include/gdi.h b/include/gdi.h index 3c4569590fb..af2006a4405 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -153,6 +153,7 @@ typedef struct tagDC XFORM xformWorld2Vport; /* World-to-viewport transformation */ XFORM xformVport2World; /* Inverse of the above transformation */ BOOL vport2WorldValid; /* Is xformVport2World valid? */ + RECT BoundsRect; /* Current bounding rect */ } DC; /* extra stock object: default 1x1 bitmap for memory DCs */ diff --git a/objects/dc.c b/objects/dc.c index 6c5430a8ee8..1543cec7bb6 100644 --- a/objects/dc.c +++ b/objects/dc.c @@ -116,6 +116,10 @@ DC *DC_AllocDC( const DC_FUNCTIONS *funcs, WORD magic ) dc->xformWorld2Vport = dc->xformWorld2Wnd; dc->xformVport2World = dc->xformWorld2Wnd; dc->vport2WorldValid = TRUE; + dc->BoundsRect.left = 0; + dc->BoundsRect.top = 0; + dc->BoundsRect.right = 0; + dc->BoundsRect.bottom = 0; PATH_InitGdiPath(&dc->path); return dc; } @@ -322,6 +326,7 @@ HDC WINAPI GetDCState( HDC hdc ) newdc->vportOrgY = dc->vportOrgY; newdc->vportExtX = dc->vportExtX; newdc->vportExtY = dc->vportExtY; + newdc->BoundsRect = dc->BoundsRect; newdc->hSelf = (HDC)handle; newdc->saveLevel = 0; @@ -402,6 +407,7 @@ void WINAPI SetDCState( HDC hdc, HDC hdcs ) dc->xformWorld2Vport = dcs->xformWorld2Vport; dc->xformVport2World = dcs->xformVport2World; dc->vport2WorldValid = dcs->vport2WorldValid; + dc->BoundsRect = dcs->BoundsRect; dc->wndOrgX = dcs->wndOrgX; dc->wndOrgY = dcs->wndOrgY; @@ -1371,41 +1377,77 @@ HCOLORSPACE WINAPI SetColorSpace( HDC hDC, HCOLORSPACE hColorSpace ) return hColorSpace; } -/*********************************************************************** - * GetBoundsRect (GDI.194) - */ -UINT16 WINAPI GetBoundsRect16(HDC16 hdc, LPRECT16 rect, UINT16 flags) -{ - return DCB_RESET | DCB_DISABLE; /* bounding rectangle always empty and disabled*/ -} - /*********************************************************************** * GetBoundsRect (GDI32.@) */ UINT WINAPI GetBoundsRect(HDC hdc, LPRECT rect, UINT flags) { - FIXME("(): stub\n"); - return DCB_RESET; /* bounding rectangle always empty */ + UINT ret; + DC *dc = DC_GetDCPtr( hdc ); + + if ( !dc ) return 0; + + if (rect) *rect = dc->BoundsRect; + + ret = ((dc->flags & DC_BOUNDS_SET) ? DCB_SET : DCB_RESET); + + if (flags & DCB_RESET) + { + dc->BoundsRect.left = 0; + dc->BoundsRect.top = 0; + dc->BoundsRect.right = 0; + dc->BoundsRect.bottom = 0; + dc->flags &= ~DC_BOUNDS_SET; + } + GDI_ReleaseObj( hdc ); + return ret; } -/*********************************************************************** - * SetBoundsRect (GDI.193) - */ -UINT16 WINAPI SetBoundsRect16(HDC16 hdc, const RECT16* rect, UINT16 flags) -{ - if ( (flags & DCB_ACCUMULATE) || (flags & DCB_ENABLE) ) - FIXME("(%04x, %p, %04x): stub\n", hdc, rect, flags ); - - return DCB_RESET | DCB_DISABLE; /* bounding rectangle always empty and disabled*/ -} /*********************************************************************** * SetBoundsRect (GDI32.@) */ UINT WINAPI SetBoundsRect(HDC hdc, const RECT* rect, UINT flags) { - FIXME("(): stub\n"); - return DCB_DISABLE; /* bounding rectangle always empty */ + UINT ret; + DC *dc; + + if ((flags & DCB_ENABLE) && (flags & DCB_DISABLE)) return 0; + if (!(dc = DC_GetDCPtr( hdc ))) return 0; + + ret = ((dc->flags & DC_BOUNDS_ENABLE) ? DCB_ENABLE : DCB_DISABLE) | + ((dc->flags & DC_BOUNDS_SET) ? DCB_SET : DCB_RESET); + + if (flags & DCB_RESET) + { + dc->BoundsRect.left = 0; + dc->BoundsRect.top = 0; + dc->BoundsRect.right = 0; + dc->BoundsRect.bottom = 0; + dc->flags &= ~DC_BOUNDS_SET; + } + + if ((flags & DCB_ACCUMULATE) && rect && rect->left < rect->right && rect->top < rect->bottom) + { + if (dc->flags & DC_BOUNDS_SET) + { + dc->BoundsRect.left = min( dc->BoundsRect.left, rect->left ); + dc->BoundsRect.top = min( dc->BoundsRect.top, rect->top ); + dc->BoundsRect.right = max( dc->BoundsRect.right, rect->right ); + dc->BoundsRect.bottom = max( dc->BoundsRect.bottom, rect->bottom ); + } + else + { + dc->BoundsRect = *rect; + dc->flags |= DC_BOUNDS_SET; + } + } + + if (flags & DCB_ENABLE) dc->flags |= DC_BOUNDS_ENABLE; + if (flags & DCB_DISABLE) dc->flags &= ~DC_BOUNDS_ENABLE; + + GDI_ReleaseObj( hdc ); + return ret; }