Removed dependencies on the internals of the region object.
Do not store the region type in the object, it's trivial to determine from the rectangle count. Rewrote a few routines to not depend on internal clipping or region functions.
This commit is contained in:
parent
6a96749209
commit
07439cd2d0
|
@ -22,7 +22,6 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "gdi.h"
|
#include "gdi.h"
|
||||||
#include "region.h"
|
|
||||||
#include "mfdrv/metafiledrv.h"
|
#include "mfdrv/metafiledrv.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
|
|
||||||
#include "gdi.h"
|
#include "gdi.h"
|
||||||
#include "ttydrv.h"
|
#include "ttydrv.h"
|
||||||
#include "region.h"
|
|
||||||
#include "win.h"
|
#include "win.h"
|
||||||
#include "winpos.h"
|
#include "winpos.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
@ -203,6 +202,7 @@ static void DCE_AddClipRects( HWND parent, HWND end, HRGN hrgnClip, LPRECT lpRec
|
||||||
WND *pWnd;
|
WND *pWnd;
|
||||||
int i;
|
int i;
|
||||||
HWND *list = WIN_ListChildren( parent );
|
HWND *list = WIN_ListChildren( parent );
|
||||||
|
HRGN hrgn = 0;
|
||||||
|
|
||||||
if (!list) return;
|
if (!list) return;
|
||||||
for (i = 0; list[i]; i++)
|
for (i = 0; list[i]; i++)
|
||||||
|
@ -217,15 +217,14 @@ static void DCE_AddClipRects( HWND parent, HWND end, HRGN hrgnClip, LPRECT lpRec
|
||||||
rect.bottom = pWnd->rectWindow.bottom + y;
|
rect.bottom = pWnd->rectWindow.bottom + y;
|
||||||
if( IntersectRect( &rect, &rect, lpRect ))
|
if( IntersectRect( &rect, &rect, lpRect ))
|
||||||
{
|
{
|
||||||
if(!REGION_UnionRectWithRgn( hrgnClip, &rect ))
|
if (!hrgn) hrgn = CreateRectRgnIndirect( &rect );
|
||||||
{
|
else SetRectRgn( hrgn, rect.left, rect.top, rect.right, rect.bottom );
|
||||||
WIN_ReleaseWndPtr( pWnd );
|
CombineRgn( hrgnClip, hrgnClip, hrgn, RGN_OR );
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WIN_ReleaseWndPtr( pWnd );
|
WIN_ReleaseWndPtr( pWnd );
|
||||||
}
|
}
|
||||||
|
if (hrgn) DeleteObject( hrgn );
|
||||||
HeapFree( GetProcessHeap(), 0, list );
|
HeapFree( GetProcessHeap(), 0, list );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
#include "hook.h"
|
#include "hook.h"
|
||||||
#include "win.h"
|
#include "win.h"
|
||||||
#include "winpos.h"
|
#include "winpos.h"
|
||||||
#include "region.h"
|
|
||||||
#include "dce.h"
|
#include "dce.h"
|
||||||
#include "cursoricon.h"
|
#include "cursoricon.h"
|
||||||
#include "nonclient.h"
|
#include "nonclient.h"
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
#include "winnt.h"
|
#include "winnt.h"
|
||||||
#include "x11drv.h"
|
#include "x11drv.h"
|
||||||
#include "bitmap.h"
|
#include "bitmap.h"
|
||||||
#include "region.h"
|
|
||||||
#include "wine/unicode.h"
|
#include "wine/unicode.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
|
@ -563,8 +562,7 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
|
||||||
XRenderColor col;
|
XRenderColor col;
|
||||||
int idx;
|
int idx;
|
||||||
TEXTMETRICW tm;
|
TEXTMETRICW tm;
|
||||||
RGNOBJ *obj;
|
RGNDATA *data;
|
||||||
XRectangle *pXrect;
|
|
||||||
SIZE sz;
|
SIZE sz;
|
||||||
RECT rc;
|
RECT rc;
|
||||||
BOOL done_extents = FALSE;
|
BOOL done_extents = FALSE;
|
||||||
|
@ -713,12 +711,9 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
|
||||||
if (flags & ETO_CLIPPED)
|
if (flags & ETO_CLIPPED)
|
||||||
{
|
{
|
||||||
SaveVisRgn16( hdc );
|
SaveVisRgn16( hdc );
|
||||||
CLIPPING_IntersectVisRect( dc, rc.left, rc.top, rc.right,
|
IntersectVisRect16( dc->hSelf, lprect->left, lprect->top, lprect->right, lprect->bottom );
|
||||||
rc.bottom, FALSE );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(!physDev->xrender->pict) {
|
if(!physDev->xrender->pict) {
|
||||||
XRenderPictureAttributes pa;
|
XRenderPictureAttributes pa;
|
||||||
pa.subwindow_mode = IncludeInferiors;
|
pa.subwindow_mode = IncludeInferiors;
|
||||||
|
@ -736,53 +731,15 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
|
||||||
TRACE("using existing pict = %lx dc = %p\n", physDev->xrender->pict, dc);
|
TRACE("using existing pict = %lx dc = %p\n", physDev->xrender->pict, dc);
|
||||||
}
|
}
|
||||||
|
|
||||||
obj = (RGNOBJ *) GDI_GetObjPtr(dc->hGCClipRgn, REGION_MAGIC);
|
if ((data = X11DRV_GetRegionData( dc->hGCClipRgn, 0 )))
|
||||||
if (!obj)
|
|
||||||
{
|
{
|
||||||
ERR("Rgn is 0. Please report this.\n");
|
wine_tsx11_lock();
|
||||||
return FALSE;
|
pXRenderSetPictureClipRectangles( gdi_display, physDev->xrender->pict,
|
||||||
|
0, 0, (XRectangle *)data->Buffer, data->rdh.nCount );
|
||||||
|
wine_tsx11_unlock();
|
||||||
|
HeapFree( GetProcessHeap(), 0, data );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj->rgn->numRects > 0)
|
|
||||||
{
|
|
||||||
XRectangle *pXr;
|
|
||||||
RECT *pRect = obj->rgn->rects;
|
|
||||||
RECT *pEndRect = obj->rgn->rects + obj->rgn->numRects;
|
|
||||||
|
|
||||||
pXrect = HeapAlloc( GetProcessHeap(), 0,
|
|
||||||
sizeof(*pXrect) * obj->rgn->numRects );
|
|
||||||
if(!pXrect)
|
|
||||||
{
|
|
||||||
WARN("Can't alloc buffer\n");
|
|
||||||
GDI_ReleaseObj( dc->hGCClipRgn );
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(pXr = pXrect; pRect < pEndRect; pRect++, pXr++)
|
|
||||||
{
|
|
||||||
pXr->x = pRect->left;
|
|
||||||
pXr->y = pRect->top;
|
|
||||||
pXr->width = pRect->right - pRect->left;
|
|
||||||
pXr->height = pRect->bottom - pRect->top;
|
|
||||||
TRACE("Adding clip rect %d,%d - %d,%d\n", pRect->left, pRect->top,
|
|
||||||
pRect->right, pRect->bottom);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
TRACE("no clip rgn\n");
|
|
||||||
pXrect = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
wine_tsx11_lock();
|
|
||||||
pXRenderSetPictureClipRectangles( gdi_display, physDev->xrender->pict,
|
|
||||||
0, 0, pXrect, obj->rgn->numRects );
|
|
||||||
wine_tsx11_unlock();
|
|
||||||
|
|
||||||
if(pXrect)
|
|
||||||
HeapFree( GetProcessHeap(), 0, pXrect );
|
|
||||||
|
|
||||||
GDI_ReleaseObj( dc->hGCClipRgn );
|
|
||||||
|
|
||||||
if(GetBkMode(hdc) != TRANSPARENT) {
|
if(GetBkMode(hdc) != TRANSPARENT) {
|
||||||
if(!((flags & ETO_CLIPPED) && (flags & ETO_OPAQUE))) {
|
if(!((flags & ETO_CLIPPED) && (flags & ETO_OPAQUE))) {
|
||||||
if(!(flags & ETO_OPAQUE) || x < rc.left || x + width >= rc.right ||
|
if(!(flags & ETO_OPAQUE) || x < rc.left || x + width >= rc.right ||
|
||||||
|
|
|
@ -26,62 +26,100 @@
|
||||||
|
|
||||||
#include "gdi.h"
|
#include "gdi.h"
|
||||||
#include "x11drv.h"
|
#include "x11drv.h"
|
||||||
#include "region.h"
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
|
WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* X11DRV_SetDeviceClipping
|
* X11DRV_GetRegionData
|
||||||
* Copy RECT32s to a temporary buffer of XRectangles and call
|
|
||||||
* TSXSetClipRectangles().
|
|
||||||
*
|
*
|
||||||
* Could write using GetRegionData but this would be slower.
|
* Calls GetRegionData on the given region and converts the rectangle
|
||||||
|
* array to XRectangle format. The returned buffer must be freed by
|
||||||
|
* caller using HeapFree(GetProcessHeap(),...).
|
||||||
|
* If hdc_lptodp is not 0, the rectangles are converted through LPtoDP.
|
||||||
*/
|
*/
|
||||||
void X11DRV_SetDeviceClipping( X11DRV_PDEVICE *physDev, HRGN hrgn )
|
RGNDATA *X11DRV_GetRegionData( HRGN hrgn, HDC hdc_lptodp )
|
||||||
{
|
{
|
||||||
XRectangle *pXrect;
|
RGNDATA *data;
|
||||||
|
DWORD size;
|
||||||
|
int i;
|
||||||
|
RECT *rect, tmp;
|
||||||
|
XRectangle *xrect;
|
||||||
|
|
||||||
RGNOBJ *obj = (RGNOBJ *) GDI_GetObjPtr(hrgn, REGION_MAGIC);
|
if (!(size = GetRegionData( hrgn, 0, NULL ))) return NULL;
|
||||||
if (!obj)
|
if (sizeof(XRectangle) > sizeof(RECT))
|
||||||
{
|
{
|
||||||
ERR("Rgn is 0. Please report this.\n");
|
/* add extra size for XRectangle array */
|
||||||
return;
|
int count = (size - sizeof(RGNDATAHEADER)) / sizeof(RECT);
|
||||||
|
size += count * (sizeof(XRectangle) - sizeof(RECT));
|
||||||
|
}
|
||||||
|
if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) return NULL;
|
||||||
|
if (!GetRegionData( hrgn, size, data ))
|
||||||
|
{
|
||||||
|
HeapFree( GetProcessHeap(), 0, data );
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj->rgn->numRects > 0)
|
rect = (RECT *)data->Buffer;
|
||||||
|
xrect = (XRectangle *)data->Buffer;
|
||||||
|
if (hdc_lptodp) /* map to device coordinates */
|
||||||
{
|
{
|
||||||
XRectangle *pXr;
|
LPtoDP( hdc_lptodp, (POINT *)rect, data->rdh.nCount * 2 );
|
||||||
RECT *pRect = obj->rgn->rects;
|
for (i = 0; i < data->rdh.nCount; i++)
|
||||||
RECT *pEndRect = obj->rgn->rects + obj->rgn->numRects;
|
|
||||||
|
|
||||||
pXrect = HeapAlloc( GetProcessHeap(), 0,
|
|
||||||
sizeof(*pXrect) * obj->rgn->numRects );
|
|
||||||
if(!pXrect)
|
|
||||||
{
|
|
||||||
WARN("Can't alloc buffer\n");
|
|
||||||
GDI_ReleaseObj( hrgn );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(pXr = pXrect; pRect < pEndRect; pRect++, pXr++)
|
|
||||||
{
|
{
|
||||||
pXr->x = pRect->left;
|
if (rect[i].right < rect[i].left)
|
||||||
pXr->y = pRect->top;
|
{
|
||||||
pXr->width = pRect->right - pRect->left;
|
INT tmp = rect[i].right;
|
||||||
pXr->height = pRect->bottom - pRect->top;
|
rect[i].right = rect[i].left;
|
||||||
|
rect[i].left = tmp;
|
||||||
|
}
|
||||||
|
if (rect[i].bottom < rect[i].top)
|
||||||
|
{
|
||||||
|
INT tmp = rect[i].bottom;
|
||||||
|
rect[i].bottom = rect[i].top;
|
||||||
|
rect[i].top = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sizeof(XRectangle) > sizeof(RECT))
|
||||||
|
{
|
||||||
|
/* need to start from the end */
|
||||||
|
for (i = data->rdh.nCount-1; i >=0; i--)
|
||||||
|
{
|
||||||
|
tmp = rect[i];
|
||||||
|
xrect[i].x = tmp.left;
|
||||||
|
xrect[i].y = tmp.top;
|
||||||
|
xrect[i].width = tmp.right - tmp.left;
|
||||||
|
xrect[i].height = tmp.bottom - tmp.top;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
pXrect = NULL;
|
{
|
||||||
|
for (i = 0; i < data->rdh.nCount; i++)
|
||||||
|
{
|
||||||
|
tmp = rect[i];
|
||||||
|
xrect[i].x = tmp.left;
|
||||||
|
xrect[i].y = tmp.top;
|
||||||
|
xrect[i].width = tmp.right - tmp.left;
|
||||||
|
xrect[i].height = tmp.bottom - tmp.top;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* X11DRV_SetDeviceClipping
|
||||||
|
*/
|
||||||
|
void X11DRV_SetDeviceClipping( X11DRV_PDEVICE *physDev, HRGN hrgn )
|
||||||
|
{
|
||||||
|
RGNDATA *data;
|
||||||
|
|
||||||
|
if (!(data = X11DRV_GetRegionData( hrgn, 0 ))) return;
|
||||||
TSXSetClipRectangles( gdi_display, physDev->gc, 0, 0,
|
TSXSetClipRectangles( gdi_display, physDev->gc, 0, 0,
|
||||||
pXrect, obj->rgn->numRects, YXBanded );
|
(XRectangle *)data->Buffer, data->rdh.nCount, YXBanded );
|
||||||
|
HeapFree( GetProcessHeap(), 0, data );
|
||||||
if(pXrect)
|
|
||||||
HeapFree( GetProcessHeap(), 0, pXrect );
|
|
||||||
|
|
||||||
GDI_ReleaseObj( hrgn );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,6 @@
|
||||||
#include "bitmap.h"
|
#include "bitmap.h"
|
||||||
#include "gdi.h"
|
#include "gdi.h"
|
||||||
#include "palette.h"
|
#include "palette.h"
|
||||||
#include "region.h"
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(graphics);
|
WINE_DEFAULT_DEBUG_CHANNEL(graphics);
|
||||||
|
@ -940,48 +939,29 @@ X11DRV_GetPixel( X11DRV_PDEVICE *physDev, INT x, INT y )
|
||||||
BOOL
|
BOOL
|
||||||
X11DRV_PaintRgn( X11DRV_PDEVICE *physDev, HRGN hrgn )
|
X11DRV_PaintRgn( X11DRV_PDEVICE *physDev, HRGN hrgn )
|
||||||
{
|
{
|
||||||
RECT box;
|
|
||||||
HRGN tmpVisRgn, prevVisRgn;
|
|
||||||
DC *dc = physDev->dc;
|
DC *dc = physDev->dc;
|
||||||
HDC hdc = physDev->hdc; /* FIXME: should not mix dc/hdc this way */
|
|
||||||
|
|
||||||
if (!(tmpVisRgn = CreateRectRgn( 0, 0, 0, 0 ))) return FALSE;
|
|
||||||
|
|
||||||
/* Transform region into device co-ords */
|
|
||||||
if ( !REGION_LPTODP( hdc, tmpVisRgn, hrgn )
|
|
||||||
|| OffsetRgn( tmpVisRgn, dc->DCOrgX, dc->DCOrgY ) == ERROR) {
|
|
||||||
DeleteObject( tmpVisRgn );
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Modify visible region */
|
|
||||||
if (!(prevVisRgn = SaveVisRgn16( hdc ))) {
|
|
||||||
DeleteObject( tmpVisRgn );
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
CombineRgn( tmpVisRgn, prevVisRgn, tmpVisRgn, RGN_AND );
|
|
||||||
SelectVisRgn16( hdc, tmpVisRgn );
|
|
||||||
DeleteObject( tmpVisRgn );
|
|
||||||
|
|
||||||
/* Fill the region */
|
|
||||||
|
|
||||||
GetRgnBox( dc->hGCClipRgn, &box );
|
|
||||||
if (X11DRV_SetupGCForBrush( physDev ))
|
if (X11DRV_SetupGCForBrush( physDev ))
|
||||||
{
|
{
|
||||||
/* Update the pixmap from the DIB section */
|
int i;
|
||||||
X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE);
|
XRectangle *rect;
|
||||||
|
RGNDATA *data = X11DRV_GetRegionData( hrgn, physDev->hdc );
|
||||||
|
|
||||||
TSXFillRectangle( gdi_display, physDev->drawable, physDev->gc,
|
if (!data) return FALSE;
|
||||||
box.left, box.top,
|
rect = (XRectangle *)data->Buffer;
|
||||||
box.right-box.left, box.bottom-box.top );
|
for (i = 0; i < data->rdh.nCount; i++)
|
||||||
|
{
|
||||||
|
rect[i].x += dc->DCOrgX;
|
||||||
|
rect[i].y += dc->DCOrgY;
|
||||||
|
}
|
||||||
|
|
||||||
/* Update the DIBSection from the pixmap */
|
X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE);
|
||||||
X11DRV_UnlockDIBSection(physDev, TRUE);
|
wine_tsx11_lock();
|
||||||
|
XFillRectangles( gdi_display, physDev->drawable, physDev->gc, rect, data->rdh.nCount );
|
||||||
|
wine_tsx11_unlock();
|
||||||
|
X11DRV_UnlockDIBSection(physDev, TRUE);
|
||||||
|
HeapFree( GetProcessHeap(), 0, data );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restore the visible region */
|
|
||||||
|
|
||||||
RestoreVisRgn16( hdc );
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -151,7 +151,10 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
|
||||||
{
|
{
|
||||||
SIZE sz;
|
SIZE sz;
|
||||||
if (!X11DRV_GetTextExtentPoint( physDev, wstr, count, &sz ))
|
if (!X11DRV_GetTextExtentPoint( physDev, wstr, count, &sz ))
|
||||||
return FALSE;
|
{
|
||||||
|
result = FALSE;
|
||||||
|
goto END;
|
||||||
|
}
|
||||||
width = INTERNAL_XWSTODS(dc, sz.cx);
|
width = INTERNAL_XWSTODS(dc, sz.cx);
|
||||||
}
|
}
|
||||||
ascent = pfo->lpX11Trans ? pfo->lpX11Trans->ascent : font->ascent;
|
ascent = pfo->lpX11Trans ? pfo->lpX11Trans->ascent : font->ascent;
|
||||||
|
@ -206,8 +209,7 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
|
||||||
if (flags & ETO_CLIPPED)
|
if (flags & ETO_CLIPPED)
|
||||||
{
|
{
|
||||||
SaveVisRgn16( dc->hSelf );
|
SaveVisRgn16( dc->hSelf );
|
||||||
CLIPPING_IntersectVisRect( dc, rect.left, rect.top, rect.right,
|
IntersectVisRect16( dc->hSelf, lprect->left, lprect->top, lprect->right, lprect->bottom );
|
||||||
rect.bottom, FALSE );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw the text background if necessary */
|
/* Draw the text background if necessary */
|
||||||
|
@ -395,9 +397,7 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
|
||||||
dc->DCOrgX + x + width, dc->DCOrgY + y - lineAscent );
|
dc->DCOrgX + x + width, dc->DCOrgY + y - lineAscent );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & ETO_CLIPPED)
|
if (flags & ETO_CLIPPED) RestoreVisRgn16( dc->hSelf );
|
||||||
RestoreVisRgn16( dc->hSelf );
|
|
||||||
|
|
||||||
goto END;
|
goto END;
|
||||||
|
|
||||||
FAIL:
|
FAIL:
|
||||||
|
|
|
@ -580,16 +580,7 @@ extern DC * DC_GetDCUpdate( HDC hdc );
|
||||||
extern void DC_InitDC( DC * dc );
|
extern void DC_InitDC( DC * dc );
|
||||||
extern void DC_UpdateXforms( DC * dc );
|
extern void DC_UpdateXforms( DC * dc );
|
||||||
|
|
||||||
|
|
||||||
#define CLIP_INTERSECT 0x0001
|
|
||||||
#define CLIP_EXCLUDE 0x0002
|
|
||||||
#define CLIP_KEEPRGN 0x0004
|
|
||||||
|
|
||||||
/* objects/clipping.c */
|
/* objects/clipping.c */
|
||||||
INT CLIPPING_IntersectClipRect( DC * dc, INT left, INT top,
|
|
||||||
INT right, INT bottom, UINT flags );
|
|
||||||
INT CLIPPING_IntersectVisRect( DC * dc, INT left, INT top,
|
|
||||||
INT right, INT bottom, BOOL exclude );
|
|
||||||
extern void CLIPPING_UpdateGCRegion( DC * dc );
|
extern void CLIPPING_UpdateGCRegion( DC * dc );
|
||||||
|
|
||||||
/* objects/enhmetafile.c */
|
/* objects/enhmetafile.c */
|
||||||
|
|
|
@ -25,26 +25,11 @@
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "wingdi.h"
|
#include "wingdi.h"
|
||||||
|
|
||||||
typedef struct {
|
struct _RGNOBJ;
|
||||||
INT size;
|
|
||||||
INT numRects;
|
|
||||||
INT type; /* NULL, SIMPLE or COMPLEX */
|
|
||||||
RECT *rects;
|
|
||||||
RECT extents;
|
|
||||||
} WINEREGION;
|
|
||||||
|
|
||||||
/* GDI logical region object */
|
extern BOOL REGION_DeleteObject( HRGN hrgn, struct _RGNOBJ * obj );
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
GDIOBJHDR header;
|
|
||||||
WINEREGION *rgn;
|
|
||||||
} RGNOBJ;
|
|
||||||
|
|
||||||
extern BOOL REGION_DeleteObject( HRGN hrgn, RGNOBJ * obj );
|
|
||||||
extern BOOL REGION_UnionRectWithRgn( HRGN hrgn, const RECT *lpRect );
|
|
||||||
extern HRGN REGION_CropRgn( HRGN hDst, HRGN hSrc, const RECT *lpRect, const POINT *lpPt );
|
extern HRGN REGION_CropRgn( HRGN hDst, HRGN hSrc, const RECT *lpRect, const POINT *lpPt );
|
||||||
extern BOOL REGION_FrameRgn( HRGN dest, HRGN src, INT x, INT y );
|
extern BOOL REGION_FrameRgn( HRGN dest, HRGN src, INT x, INT y );
|
||||||
extern BOOL REGION_LPTODP( HDC hdc, HRGN hDest, HRGN hSrc );
|
|
||||||
|
|
||||||
#endif /* __WINE_REGION_H */
|
#endif /* __WINE_REGION_H */
|
||||||
|
|
||||||
|
|
|
@ -198,6 +198,7 @@ extern HBITMAP X11DRV_BITMAP_CreateBitmapFromPixmap(Pixmap pixmap, BOOL bDeleteP
|
||||||
extern Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc );
|
extern Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc );
|
||||||
extern Pixmap X11DRV_BITMAP_CreatePixmapFromBitmap( HBITMAP hBmp, HDC hdc );
|
extern Pixmap X11DRV_BITMAP_CreatePixmapFromBitmap( HBITMAP hBmp, HDC hdc );
|
||||||
|
|
||||||
|
extern RGNDATA *X11DRV_GetRegionData( HRGN hrgn, HDC hdc_lptodp );
|
||||||
extern void X11DRV_SetDrawable( HDC hdc, Drawable drawable, int mode, int org_x, int org_y );
|
extern void X11DRV_SetDrawable( HDC hdc, Drawable drawable, int mode, int org_x, int org_y );
|
||||||
extern void X11DRV_StartGraphicsExposures( HDC hdc );
|
extern void X11DRV_StartGraphicsExposures( HDC hdc );
|
||||||
extern void X11DRV_EndGraphicsExposures( HDC hdc, HRGN hrgn );
|
extern void X11DRV_EndGraphicsExposures( HDC hdc, HRGN hrgn );
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
#include "wingdi.h"
|
#include "wingdi.h"
|
||||||
#include "wine/winuser16.h"
|
#include "wine/winuser16.h"
|
||||||
#include "gdi.h"
|
#include "gdi.h"
|
||||||
#include "region.h"
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(clipping);
|
WINE_DEFAULT_DEBUG_CHANNEL(clipping);
|
||||||
|
@ -204,54 +203,6 @@ INT16 WINAPI OffsetVisRgn16( HDC16 hdc, INT16 x, INT16 y )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* CLIPPING_IntersectClipRect
|
|
||||||
*
|
|
||||||
* Helper function for {Intersect,Exclude}ClipRect, can be called from
|
|
||||||
* elsewhere (like ExtTextOut()) to skip redundant metafile update and
|
|
||||||
* coordinate conversion.
|
|
||||||
*/
|
|
||||||
INT CLIPPING_IntersectClipRect( DC * dc, INT left, INT top,
|
|
||||||
INT right, INT bottom, UINT flags )
|
|
||||||
{
|
|
||||||
HRGN newRgn;
|
|
||||||
INT ret;
|
|
||||||
|
|
||||||
left += dc->DCOrgX;
|
|
||||||
right += dc->DCOrgX;
|
|
||||||
top += dc->DCOrgY;
|
|
||||||
bottom += dc->DCOrgY;
|
|
||||||
|
|
||||||
if (!(newRgn = CreateRectRgn( left, top, right, bottom ))) return ERROR;
|
|
||||||
if (!dc->hClipRgn)
|
|
||||||
{
|
|
||||||
if( flags & CLIP_INTERSECT )
|
|
||||||
{
|
|
||||||
dc->hClipRgn = newRgn;
|
|
||||||
CLIPPING_UpdateGCRegion( dc );
|
|
||||||
return SIMPLEREGION;
|
|
||||||
}
|
|
||||||
else if( flags & CLIP_EXCLUDE )
|
|
||||||
{
|
|
||||||
dc->hClipRgn = CreateRectRgn( 0, 0, 0, 0 );
|
|
||||||
CombineRgn( dc->hClipRgn, dc->hVisRgn, 0, RGN_COPY );
|
|
||||||
}
|
|
||||||
else WARN("No hClipRgn and flags are %x\n",flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = CombineRgn( newRgn, dc->hClipRgn, newRgn,
|
|
||||||
(flags & CLIP_EXCLUDE) ? RGN_DIFF : RGN_AND );
|
|
||||||
if (ret != ERROR)
|
|
||||||
{
|
|
||||||
if (!(flags & CLIP_KEEPRGN)) DeleteObject( dc->hClipRgn );
|
|
||||||
dc->hClipRgn = newRgn;
|
|
||||||
CLIPPING_UpdateGCRegion( dc );
|
|
||||||
}
|
|
||||||
else DeleteObject( newRgn );
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* ExcludeClipRect (GDI.21)
|
* ExcludeClipRect (GDI.21)
|
||||||
*/
|
*/
|
||||||
|
@ -268,6 +219,7 @@ INT16 WINAPI ExcludeClipRect16( HDC16 hdc, INT16 left, INT16 top,
|
||||||
INT WINAPI ExcludeClipRect( HDC hdc, INT left, INT top,
|
INT WINAPI ExcludeClipRect( HDC hdc, INT left, INT top,
|
||||||
INT right, INT bottom )
|
INT right, INT bottom )
|
||||||
{
|
{
|
||||||
|
HRGN newRgn;
|
||||||
INT ret;
|
INT ret;
|
||||||
DC *dc = DC_GetDCUpdate( hdc );
|
DC *dc = DC_GetDCUpdate( hdc );
|
||||||
if (!dc) return ERROR;
|
if (!dc) return ERROR;
|
||||||
|
@ -276,13 +228,25 @@ INT WINAPI ExcludeClipRect( HDC hdc, INT left, INT top,
|
||||||
|
|
||||||
if(dc->funcs->pExcludeClipRect)
|
if(dc->funcs->pExcludeClipRect)
|
||||||
ret = dc->funcs->pExcludeClipRect( dc->physDev, left, top, right, bottom );
|
ret = dc->funcs->pExcludeClipRect( dc->physDev, left, top, right, bottom );
|
||||||
else {
|
else
|
||||||
left = XLPTODP( dc, left );
|
{
|
||||||
right = XLPTODP( dc, right );
|
left = dc->DCOrgX + XLPTODP( dc, left );
|
||||||
top = YLPTODP( dc, top );
|
right = dc->DCOrgX + XLPTODP( dc, right );
|
||||||
bottom = YLPTODP( dc, bottom );
|
top = dc->DCOrgY + YLPTODP( dc, top );
|
||||||
|
bottom = dc->DCOrgY + YLPTODP( dc, bottom );
|
||||||
|
|
||||||
ret = CLIPPING_IntersectClipRect( dc, left, top, right, bottom, CLIP_EXCLUDE );
|
if (!(newRgn = CreateRectRgn( left, top, right, bottom ))) ret = ERROR;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!dc->hClipRgn)
|
||||||
|
{
|
||||||
|
dc->hClipRgn = CreateRectRgn( 0, 0, 0, 0 );
|
||||||
|
CombineRgn( dc->hClipRgn, dc->hVisRgn, 0, RGN_COPY );
|
||||||
|
}
|
||||||
|
ret = CombineRgn( dc->hClipRgn, dc->hClipRgn, newRgn, RGN_DIFF );
|
||||||
|
DeleteObject( newRgn );
|
||||||
|
}
|
||||||
|
if (ret != ERROR) CLIPPING_UpdateGCRegion( dc );
|
||||||
}
|
}
|
||||||
GDI_ReleaseObj( hdc );
|
GDI_ReleaseObj( hdc );
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -313,88 +277,61 @@ INT WINAPI IntersectClipRect( HDC hdc, INT left, INT top,
|
||||||
|
|
||||||
if(dc->funcs->pIntersectClipRect)
|
if(dc->funcs->pIntersectClipRect)
|
||||||
ret = dc->funcs->pIntersectClipRect( dc->physDev, left, top, right, bottom );
|
ret = dc->funcs->pIntersectClipRect( dc->physDev, left, top, right, bottom );
|
||||||
else {
|
else
|
||||||
left = XLPTODP( dc, left );
|
{
|
||||||
right = XLPTODP( dc, right );
|
left = dc->DCOrgX + XLPTODP( dc, left );
|
||||||
top = YLPTODP( dc, top );
|
right = dc->DCOrgX + XLPTODP( dc, right );
|
||||||
bottom = YLPTODP( dc, bottom );
|
top = dc->DCOrgY + YLPTODP( dc, top );
|
||||||
|
bottom = dc->DCOrgY + YLPTODP( dc, bottom );
|
||||||
|
|
||||||
ret = CLIPPING_IntersectClipRect( dc, left, top, right, bottom, CLIP_INTERSECT );
|
if (!dc->hClipRgn)
|
||||||
|
{
|
||||||
|
dc->hClipRgn = CreateRectRgn( left, top, right, bottom );
|
||||||
|
ret = SIMPLEREGION;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HRGN newRgn;
|
||||||
|
|
||||||
|
if (!(newRgn = CreateRectRgn( left, top, right, bottom ))) ret = ERROR;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = CombineRgn( dc->hClipRgn, dc->hClipRgn, newRgn, RGN_AND );
|
||||||
|
DeleteObject( newRgn );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ret != ERROR) CLIPPING_UpdateGCRegion( dc );
|
||||||
}
|
}
|
||||||
GDI_ReleaseObj( hdc );
|
GDI_ReleaseObj( hdc );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* CLIPPING_IntersectVisRect
|
|
||||||
*
|
|
||||||
* Helper function for {Intersect,Exclude}VisRect, can be called from
|
|
||||||
* elsewhere (like ExtTextOut()) to skip redundant metafile update and
|
|
||||||
* coordinate conversion.
|
|
||||||
*/
|
|
||||||
INT CLIPPING_IntersectVisRect( DC * dc, INT left, INT top,
|
|
||||||
INT right, INT bottom,
|
|
||||||
BOOL exclude )
|
|
||||||
{
|
|
||||||
HRGN tempRgn, newRgn;
|
|
||||||
INT ret;
|
|
||||||
|
|
||||||
left += dc->DCOrgX;
|
|
||||||
right += dc->DCOrgX;
|
|
||||||
top += dc->DCOrgY;
|
|
||||||
bottom += dc->DCOrgY;
|
|
||||||
|
|
||||||
if (!(newRgn = CreateRectRgn( 0, 0, 0, 0 ))) return ERROR;
|
|
||||||
if (!(tempRgn = CreateRectRgn( left, top, right, bottom )))
|
|
||||||
{
|
|
||||||
DeleteObject( newRgn );
|
|
||||||
return ERROR;
|
|
||||||
}
|
|
||||||
ret = CombineRgn( newRgn, dc->hVisRgn, tempRgn,
|
|
||||||
exclude ? RGN_DIFF : RGN_AND );
|
|
||||||
DeleteObject( tempRgn );
|
|
||||||
|
|
||||||
if (ret != ERROR)
|
|
||||||
{
|
|
||||||
RGNOBJ *newObj = (RGNOBJ*)GDI_GetObjPtr( newRgn, REGION_MAGIC);
|
|
||||||
if (newObj)
|
|
||||||
{
|
|
||||||
RGNOBJ *prevObj = (RGNOBJ*)GDI_GetObjPtr( dc->hVisRgn, REGION_MAGIC);
|
|
||||||
if (prevObj)
|
|
||||||
{
|
|
||||||
newObj->header.hNext = prevObj->header.hNext;
|
|
||||||
GDI_ReleaseObj( dc->hVisRgn );
|
|
||||||
}
|
|
||||||
GDI_ReleaseObj( newRgn );
|
|
||||||
}
|
|
||||||
DeleteObject( dc->hVisRgn );
|
|
||||||
dc->hVisRgn = newRgn;
|
|
||||||
CLIPPING_UpdateGCRegion( dc );
|
|
||||||
}
|
|
||||||
else DeleteObject( newRgn );
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* ExcludeVisRect (GDI.73)
|
* ExcludeVisRect (GDI.73)
|
||||||
*/
|
*/
|
||||||
INT16 WINAPI ExcludeVisRect16( HDC16 hdc, INT16 left, INT16 top,
|
INT16 WINAPI ExcludeVisRect16( HDC16 hdc, INT16 left, INT16 top,
|
||||||
INT16 right, INT16 bottom )
|
INT16 right, INT16 bottom )
|
||||||
{
|
{
|
||||||
|
HRGN tempRgn;
|
||||||
INT16 ret;
|
INT16 ret;
|
||||||
DC * dc = DC_GetDCUpdate( hdc );
|
DC * dc = DC_GetDCUpdate( hdc );
|
||||||
if (!dc) return ERROR;
|
if (!dc) return ERROR;
|
||||||
|
|
||||||
left = XLPTODP( dc, left );
|
left = dc->DCOrgX + XLPTODP( dc, left );
|
||||||
right = XLPTODP( dc, right );
|
right = dc->DCOrgX + XLPTODP( dc, right );
|
||||||
top = YLPTODP( dc, top );
|
top = dc->DCOrgY + YLPTODP( dc, top );
|
||||||
bottom = YLPTODP( dc, bottom );
|
bottom = dc->DCOrgY + YLPTODP( dc, bottom );
|
||||||
|
|
||||||
TRACE("%04x %dx%d,%dx%d\n", hdc, left, top, right, bottom );
|
TRACE("%04x %dx%d,%dx%d\n", hdc, left, top, right, bottom );
|
||||||
|
|
||||||
ret = CLIPPING_IntersectVisRect( dc, left, top, right, bottom, TRUE );
|
if (!(tempRgn = CreateRectRgn( left, top, right, bottom ))) ret = ERROR;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = CombineRgn( dc->hVisRgn, dc->hVisRgn, tempRgn, RGN_DIFF );
|
||||||
|
DeleteObject( tempRgn );
|
||||||
|
}
|
||||||
|
if (ret != ERROR) CLIPPING_UpdateGCRegion( dc );
|
||||||
GDI_ReleaseObj( hdc );
|
GDI_ReleaseObj( hdc );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -406,18 +343,25 @@ INT16 WINAPI ExcludeVisRect16( HDC16 hdc, INT16 left, INT16 top,
|
||||||
INT16 WINAPI IntersectVisRect16( HDC16 hdc, INT16 left, INT16 top,
|
INT16 WINAPI IntersectVisRect16( HDC16 hdc, INT16 left, INT16 top,
|
||||||
INT16 right, INT16 bottom )
|
INT16 right, INT16 bottom )
|
||||||
{
|
{
|
||||||
|
HRGN tempRgn;
|
||||||
INT16 ret;
|
INT16 ret;
|
||||||
DC * dc = DC_GetDCUpdate( hdc );
|
DC * dc = DC_GetDCUpdate( hdc );
|
||||||
if (!dc) return ERROR;
|
if (!dc) return ERROR;
|
||||||
|
|
||||||
left = XLPTODP( dc, left );
|
left = dc->DCOrgX + XLPTODP( dc, left );
|
||||||
right = XLPTODP( dc, right );
|
right = dc->DCOrgX + XLPTODP( dc, right );
|
||||||
top = YLPTODP( dc, top );
|
top = dc->DCOrgY + YLPTODP( dc, top );
|
||||||
bottom = YLPTODP( dc, bottom );
|
bottom = dc->DCOrgY + YLPTODP( dc, bottom );
|
||||||
|
|
||||||
TRACE("%04x %dx%d,%dx%d\n", hdc, left, top, right, bottom );
|
TRACE("%04x %dx%d,%dx%d\n", hdc, left, top, right, bottom );
|
||||||
|
|
||||||
ret = CLIPPING_IntersectVisRect( dc, left, top, right, bottom, FALSE );
|
if (!(tempRgn = CreateRectRgn( left, top, right, bottom ))) ret = ERROR;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = CombineRgn( dc->hVisRgn, dc->hVisRgn, tempRgn, RGN_AND );
|
||||||
|
DeleteObject( tempRgn );
|
||||||
|
}
|
||||||
|
if (ret != ERROR) CLIPPING_UpdateGCRegion( dc );
|
||||||
GDI_ReleaseObj( hdc );
|
GDI_ReleaseObj( hdc );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -562,13 +506,13 @@ INT WINAPI GetClipRgn( HDC hdc, HRGN hRgn )
|
||||||
HRGN16 WINAPI SaveVisRgn16( HDC16 hdc )
|
HRGN16 WINAPI SaveVisRgn16( HDC16 hdc )
|
||||||
{
|
{
|
||||||
HRGN copy;
|
HRGN copy;
|
||||||
RGNOBJ *obj, *copyObj;
|
GDIOBJHDR *obj, *copyObj;
|
||||||
DC *dc = DC_GetDCUpdate( hdc );
|
DC *dc = DC_GetDCUpdate( hdc );
|
||||||
|
|
||||||
if (!dc) return 0;
|
if (!dc) return 0;
|
||||||
TRACE("%04x\n", hdc );
|
TRACE("%04x\n", hdc );
|
||||||
|
|
||||||
if (!(obj = (RGNOBJ *) GDI_GetObjPtr( dc->hVisRgn, REGION_MAGIC )))
|
if (!(obj = GDI_GetObjPtr( dc->hVisRgn, REGION_MAGIC )))
|
||||||
{
|
{
|
||||||
GDI_ReleaseObj( hdc );
|
GDI_ReleaseObj( hdc );
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -580,15 +524,15 @@ HRGN16 WINAPI SaveVisRgn16( HDC16 hdc )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
CombineRgn( copy, dc->hVisRgn, 0, RGN_COPY );
|
CombineRgn( copy, dc->hVisRgn, 0, RGN_COPY );
|
||||||
if (!(copyObj = (RGNOBJ *) GDI_GetObjPtr( copy, REGION_MAGIC )))
|
if (!(copyObj = GDI_GetObjPtr( copy, REGION_MAGIC )))
|
||||||
{
|
{
|
||||||
DeleteObject( copy );
|
DeleteObject( copy );
|
||||||
GDI_ReleaseObj( dc->hVisRgn );
|
GDI_ReleaseObj( dc->hVisRgn );
|
||||||
GDI_ReleaseObj( hdc );
|
GDI_ReleaseObj( hdc );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
copyObj->header.hNext = obj->header.hNext;
|
copyObj->hNext = obj->hNext;
|
||||||
obj->header.hNext = copy;
|
obj->hNext = copy;
|
||||||
GDI_ReleaseObj( copy );
|
GDI_ReleaseObj( copy );
|
||||||
GDI_ReleaseObj( dc->hVisRgn );
|
GDI_ReleaseObj( dc->hVisRgn );
|
||||||
GDI_ReleaseObj( hdc );
|
GDI_ReleaseObj( hdc );
|
||||||
|
@ -602,25 +546,27 @@ HRGN16 WINAPI SaveVisRgn16( HDC16 hdc )
|
||||||
INT16 WINAPI RestoreVisRgn16( HDC16 hdc )
|
INT16 WINAPI RestoreVisRgn16( HDC16 hdc )
|
||||||
{
|
{
|
||||||
HRGN saved;
|
HRGN saved;
|
||||||
RGNOBJ *obj, *savedObj;
|
GDIOBJHDR *obj, *savedObj;
|
||||||
DC *dc = DC_GetDCPtr( hdc );
|
DC *dc = DC_GetDCPtr( hdc );
|
||||||
INT16 ret = ERROR;
|
INT16 ret = ERROR;
|
||||||
|
|
||||||
if (!dc) return ERROR;
|
if (!dc) return ERROR;
|
||||||
if (!dc->hVisRgn) goto done;
|
|
||||||
TRACE("%04x\n", hdc );
|
TRACE("%04x\n", hdc );
|
||||||
if (!(obj = (RGNOBJ *) GDI_GetObjPtr( dc->hVisRgn, REGION_MAGIC ))) goto done;
|
|
||||||
|
|
||||||
saved = obj->header.hNext;
|
if (!(obj = GDI_GetObjPtr( dc->hVisRgn, REGION_MAGIC ))) goto done;
|
||||||
|
saved = obj->hNext;
|
||||||
|
|
||||||
|
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 );
|
GDI_ReleaseObj( dc->hVisRgn );
|
||||||
if (!saved || !(savedObj = (RGNOBJ *) GDI_GetObjPtr( saved, REGION_MAGIC ))) goto done;
|
|
||||||
|
|
||||||
DeleteObject( dc->hVisRgn );
|
|
||||||
dc->hVisRgn = saved;
|
|
||||||
dc->flags &= ~DC_DIRTY;
|
|
||||||
CLIPPING_UpdateGCRegion( dc );
|
|
||||||
ret = savedObj->rgn->type; /* FIXME */
|
|
||||||
GDI_ReleaseObj( saved );
|
|
||||||
done:
|
done:
|
||||||
GDI_ReleaseObj( hdc );
|
GDI_ReleaseObj( hdc );
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -897,7 +897,7 @@ BOOL WINAPI DeleteObject( HGDIOBJ obj )
|
||||||
case FONT_MAGIC: return FONT_DeleteObject( obj, (FONTOBJ*)header );
|
case FONT_MAGIC: return FONT_DeleteObject( obj, (FONTOBJ*)header );
|
||||||
case PALETTE_MAGIC: return PALETTE_DeleteObject(obj,(PALETTEOBJ*)header);
|
case PALETTE_MAGIC: return PALETTE_DeleteObject(obj,(PALETTEOBJ*)header);
|
||||||
case BITMAP_MAGIC: return BITMAP_DeleteObject( obj, (BITMAPOBJ*)header);
|
case BITMAP_MAGIC: return BITMAP_DeleteObject( obj, (BITMAPOBJ*)header);
|
||||||
case REGION_MAGIC: return REGION_DeleteObject( obj, (RGNOBJ*)header );
|
case REGION_MAGIC: return REGION_DeleteObject( obj, (struct _RGNOBJ*)header );
|
||||||
case DC_MAGIC:
|
case DC_MAGIC:
|
||||||
GDI_ReleaseObj( obj );
|
GDI_ReleaseObj( obj );
|
||||||
return DeleteDC(obj);
|
return DeleteDC(obj);
|
||||||
|
|
139
objects/region.c
139
objects/region.c
|
@ -104,6 +104,21 @@ SOFTWARE.
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(region);
|
WINE_DEFAULT_DEBUG_CHANNEL(region);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
INT size;
|
||||||
|
INT numRects;
|
||||||
|
RECT *rects;
|
||||||
|
RECT extents;
|
||||||
|
} WINEREGION;
|
||||||
|
|
||||||
|
/* GDI logical region object */
|
||||||
|
typedef struct _RGNOBJ
|
||||||
|
{
|
||||||
|
GDIOBJHDR header;
|
||||||
|
WINEREGION *rgn;
|
||||||
|
} RGNOBJ;
|
||||||
|
|
||||||
|
|
||||||
/* 1 if two RECTs overlap.
|
/* 1 if two RECTs overlap.
|
||||||
* 0 if two RECTs do not overlap.
|
* 0 if two RECTs do not overlap.
|
||||||
*/
|
*/
|
||||||
|
@ -134,7 +149,6 @@ static inline int xmemcheck(WINEREGION *reg, LPRECT *rect, LPRECT *firstrect ) {
|
||||||
(pReg)->numRects = 0; \
|
(pReg)->numRects = 0; \
|
||||||
(pReg)->extents.left = (pReg)->extents.top = 0; \
|
(pReg)->extents.left = (pReg)->extents.top = 0; \
|
||||||
(pReg)->extents.right = (pReg)->extents.bottom = 0; \
|
(pReg)->extents.right = (pReg)->extents.bottom = 0; \
|
||||||
(pReg)->type = NULLREGION; \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define REGION_NOT_EMPTY(pReg) pReg->numRects
|
#define REGION_NOT_EMPTY(pReg) pReg->numRects
|
||||||
|
@ -423,6 +437,21 @@ static void REGION_UnionRectWithRegion(const RECT *rect, WINEREGION *rgn);
|
||||||
|
|
||||||
#define RGN_DEFAULT_RECTS 2
|
#define RGN_DEFAULT_RECTS 2
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* get_region_type
|
||||||
|
*/
|
||||||
|
inline static INT get_region_type( const RGNOBJ *obj )
|
||||||
|
{
|
||||||
|
switch(obj->rgn->numRects)
|
||||||
|
{
|
||||||
|
case 0: return NULLREGION;
|
||||||
|
case 1: return SIMPLEREGION;
|
||||||
|
default: return COMPLEXREGION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* REGION_DumpRegion
|
* REGION_DumpRegion
|
||||||
* Outputs the contents of a WINEREGION
|
* Outputs the contents of a WINEREGION
|
||||||
|
@ -542,7 +571,7 @@ INT WINAPI OffsetRgn( HRGN hrgn, INT x, INT y )
|
||||||
obj->rgn->extents.bottom += y;
|
obj->rgn->extents.bottom += y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret = obj->rgn->type;
|
ret = get_region_type( obj );
|
||||||
GDI_ReleaseObj( hrgn );
|
GDI_ReleaseObj( hrgn );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -573,7 +602,7 @@ INT WINAPI GetRgnBox( HRGN hrgn, LPRECT rect )
|
||||||
rect->top = obj->rgn->extents.top;
|
rect->top = obj->rgn->extents.top;
|
||||||
rect->right = obj->rgn->extents.right;
|
rect->right = obj->rgn->extents.right;
|
||||||
rect->bottom = obj->rgn->extents.bottom;
|
rect->bottom = obj->rgn->extents.bottom;
|
||||||
ret = obj->rgn->type;
|
ret = get_region_type( obj );
|
||||||
GDI_ReleaseObj(hrgn);
|
GDI_ReleaseObj(hrgn);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -671,8 +700,7 @@ BOOL WINAPI SetRectRgn( HRGN hrgn, INT left, INT top,
|
||||||
obj->rgn->rects->top = obj->rgn->extents.top = top;
|
obj->rgn->rects->top = obj->rgn->extents.top = top;
|
||||||
obj->rgn->rects->right = obj->rgn->extents.right = right;
|
obj->rgn->rects->right = obj->rgn->extents.right = right;
|
||||||
obj->rgn->rects->bottom = obj->rgn->extents.bottom = bottom;
|
obj->rgn->rects->bottom = obj->rgn->extents.bottom = bottom;
|
||||||
obj->rgn->numRects = 1;
|
obj->rgn->numRects = 1;
|
||||||
obj->rgn->type = SIMPLEREGION;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
EMPTY_REGION(obj->rgn);
|
EMPTY_REGION(obj->rgn);
|
||||||
|
@ -804,7 +832,6 @@ HRGN WINAPI CreateRoundRectRgn( INT left, INT top,
|
||||||
rect.bottom = bottom;
|
rect.bottom = bottom;
|
||||||
REGION_UnionRectWithRegion( &rect, obj->rgn );
|
REGION_UnionRectWithRegion( &rect, obj->rgn );
|
||||||
}
|
}
|
||||||
obj->rgn->type = SIMPLEREGION; /* FIXME? */
|
|
||||||
GDI_ReleaseObj( hrgn );
|
GDI_ReleaseObj( hrgn );
|
||||||
return hrgn;
|
return hrgn;
|
||||||
}
|
}
|
||||||
|
@ -1091,10 +1118,10 @@ BOOL WINAPI EqualRgn( HRGN hrgn1, HRGN hrgn2 )
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* REGION_UnionRectWithRegion
|
* REGION_UnionRectWithRegion
|
||||||
* Adds a rectangle to a WINEREGION
|
* Adds a rectangle to a WINEREGION
|
||||||
* See below for REGION_UnionRectWithRgn
|
|
||||||
*/
|
*/
|
||||||
static void REGION_UnionRectWithRegion(const RECT *rect, WINEREGION *rgn)
|
static void REGION_UnionRectWithRegion(const RECT *rect, WINEREGION *rgn)
|
||||||
{
|
{
|
||||||
|
@ -1103,26 +1130,10 @@ static void REGION_UnionRectWithRegion(const RECT *rect, WINEREGION *rgn)
|
||||||
region.rects = ®ion.extents;
|
region.rects = ®ion.extents;
|
||||||
region.numRects = 1;
|
region.numRects = 1;
|
||||||
region.size = 1;
|
region.size = 1;
|
||||||
region.type = SIMPLEREGION;
|
|
||||||
region.extents = *rect;
|
region.extents = *rect;
|
||||||
REGION_UnionRegion(rgn, rgn, ®ion);
|
REGION_UnionRegion(rgn, rgn, ®ion);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* REGION_UnionRectWithRgn
|
|
||||||
* Adds a rectangle to a HRGN
|
|
||||||
* A helper used by scroll.c
|
|
||||||
*/
|
|
||||||
BOOL REGION_UnionRectWithRgn( HRGN hrgn, const RECT *lpRect )
|
|
||||||
{
|
|
||||||
RGNOBJ *obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC );
|
|
||||||
|
|
||||||
if(!obj) return FALSE;
|
|
||||||
REGION_UnionRectWithRegion( lpRect, obj->rgn );
|
|
||||||
GDI_ReleaseObj(hrgn);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* REGION_CreateFrameRgn
|
* REGION_CreateFrameRgn
|
||||||
|
@ -1163,65 +1174,6 @@ BOOL REGION_FrameRgn( HRGN hDest, HRGN hSrc, INT x, INT y )
|
||||||
return bRet;
|
return bRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* REGION_LPTODP
|
|
||||||
*
|
|
||||||
* Convert region to device co-ords for the supplied dc.
|
|
||||||
*/
|
|
||||||
BOOL REGION_LPTODP( HDC hdc, HRGN hDest, HRGN hSrc )
|
|
||||||
{
|
|
||||||
RECT *pCurRect, *pEndRect;
|
|
||||||
RGNOBJ *srcObj, *destObj;
|
|
||||||
DC * dc = DC_GetDCPtr( hdc );
|
|
||||||
RECT tmpRect;
|
|
||||||
BOOL ret = FALSE;
|
|
||||||
|
|
||||||
TRACE(" hdc=%04x dest=%04x src=%04x\n",
|
|
||||||
hdc, hDest, hSrc) ;
|
|
||||||
if (!dc) return ret;
|
|
||||||
|
|
||||||
if (dc->MapMode == MM_TEXT) /* Requires only a translation */
|
|
||||||
{
|
|
||||||
if( CombineRgn( hDest, hSrc, 0, RGN_COPY ) == ERROR ) goto done;
|
|
||||||
OffsetRgn( hDest, dc->vportOrgX - dc->wndOrgX,
|
|
||||||
dc->vportOrgY - dc->wndOrgY );
|
|
||||||
ret = TRUE;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!( srcObj = (RGNOBJ *) GDI_GetObjPtr( hSrc, REGION_MAGIC) ))
|
|
||||||
goto done;
|
|
||||||
if(!( destObj = (RGNOBJ *) GDI_GetObjPtr( hDest, REGION_MAGIC) ))
|
|
||||||
{
|
|
||||||
GDI_ReleaseObj( hSrc );
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
EMPTY_REGION( destObj->rgn );
|
|
||||||
|
|
||||||
pEndRect = srcObj->rgn->rects + srcObj->rgn->numRects;
|
|
||||||
for(pCurRect = srcObj->rgn->rects; pCurRect < pEndRect; pCurRect++)
|
|
||||||
{
|
|
||||||
tmpRect = *pCurRect;
|
|
||||||
tmpRect.left = XLPTODP( dc, tmpRect.left );
|
|
||||||
tmpRect.top = YLPTODP( dc, tmpRect.top );
|
|
||||||
tmpRect.right = XLPTODP( dc, tmpRect.right );
|
|
||||||
tmpRect.bottom = YLPTODP( dc, tmpRect.bottom );
|
|
||||||
|
|
||||||
if (tmpRect.left > tmpRect.right)
|
|
||||||
{ INT tmp = tmpRect.left; tmpRect.left = tmpRect.right; tmpRect.right = tmp; }
|
|
||||||
if (tmpRect.top > tmpRect.bottom)
|
|
||||||
{ INT tmp = tmpRect.top; tmpRect.top = tmpRect.bottom; tmpRect.bottom = tmp; }
|
|
||||||
|
|
||||||
REGION_UnionRectWithRegion( &tmpRect, destObj->rgn );
|
|
||||||
}
|
|
||||||
ret = TRUE;
|
|
||||||
|
|
||||||
GDI_ReleaseObj( hDest );
|
|
||||||
GDI_ReleaseObj( hSrc );
|
|
||||||
done:
|
|
||||||
GDI_ReleaseObj( hdc );
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* CombineRgn (GDI.47)
|
* CombineRgn (GDI.47)
|
||||||
|
@ -1256,7 +1208,7 @@ INT WINAPI CombineRgn(HRGN hDest, HRGN hSrc1, HRGN hSrc2, INT mode)
|
||||||
if (mode == RGN_COPY)
|
if (mode == RGN_COPY)
|
||||||
{
|
{
|
||||||
REGION_CopyRegion( destObj->rgn, src1Obj->rgn );
|
REGION_CopyRegion( destObj->rgn, src1Obj->rgn );
|
||||||
result = destObj->rgn->type;
|
result = get_region_type( destObj );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1282,7 +1234,7 @@ INT WINAPI CombineRgn(HRGN hDest, HRGN hSrc1, HRGN hSrc2, INT mode)
|
||||||
REGION_SubtractRegion( destObj->rgn, src1Obj->rgn, src2Obj->rgn );
|
REGION_SubtractRegion( destObj->rgn, src1Obj->rgn, src2Obj->rgn );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
result = destObj->rgn->type;
|
result = get_region_type( destObj );
|
||||||
GDI_ReleaseObj( hSrc2 );
|
GDI_ReleaseObj( hSrc2 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1361,8 +1313,6 @@ static void REGION_CopyRegion(WINEREGION *dst, WINEREGION *src)
|
||||||
dst->extents.top = src->extents.top;
|
dst->extents.top = src->extents.top;
|
||||||
dst->extents.right = src->extents.right;
|
dst->extents.right = src->extents.right;
|
||||||
dst->extents.bottom = src->extents.bottom;
|
dst->extents.bottom = src->extents.bottom;
|
||||||
dst->type = src->type;
|
|
||||||
|
|
||||||
memcpy((char *) dst->rects, (char *) src->rects,
|
memcpy((char *) dst->rects, (char *) src->rects,
|
||||||
(int) (src->numRects * sizeof(RECT)));
|
(int) (src->numRects * sizeof(RECT)));
|
||||||
}
|
}
|
||||||
|
@ -1892,10 +1842,6 @@ static void REGION_IntersectRegion(WINEREGION *newReg, WINEREGION *reg1,
|
||||||
* due to coalescing, so we have to examine fewer rectangles.
|
* due to coalescing, so we have to examine fewer rectangles.
|
||||||
*/
|
*/
|
||||||
REGION_SetExtents(newReg);
|
REGION_SetExtents(newReg);
|
||||||
newReg->type = (newReg->numRects) ?
|
|
||||||
((newReg->numRects > 1) ? COMPLEXREGION : SIMPLEREGION)
|
|
||||||
: NULLREGION ;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -2071,10 +2017,6 @@ static void REGION_UnionRegion(WINEREGION *newReg, WINEREGION *reg1,
|
||||||
newReg->extents.top = min(reg1->extents.top, reg2->extents.top);
|
newReg->extents.top = min(reg1->extents.top, reg2->extents.top);
|
||||||
newReg->extents.right = max(reg1->extents.right, reg2->extents.right);
|
newReg->extents.right = max(reg1->extents.right, reg2->extents.right);
|
||||||
newReg->extents.bottom = max(reg1->extents.bottom, reg2->extents.bottom);
|
newReg->extents.bottom = max(reg1->extents.bottom, reg2->extents.bottom);
|
||||||
newReg->type = (newReg->numRects) ?
|
|
||||||
((newReg->numRects > 1) ? COMPLEXREGION : SIMPLEREGION)
|
|
||||||
: NULLREGION ;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -2279,10 +2221,6 @@ static void REGION_SubtractRegion(WINEREGION *regD, WINEREGION *regM,
|
||||||
* due to coalescing, so we have to examine fewer rectangles.
|
* due to coalescing, so we have to examine fewer rectangles.
|
||||||
*/
|
*/
|
||||||
REGION_SetExtents (regD);
|
REGION_SetExtents (regD);
|
||||||
regD->type = (regD->numRects) ?
|
|
||||||
((regD->numRects > 1) ? COMPLEXREGION : SIMPLEREGION)
|
|
||||||
: NULLREGION ;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -2876,9 +2814,6 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count,
|
||||||
}
|
}
|
||||||
REGION_FreeStorage(SLLBlock.next);
|
REGION_FreeStorage(SLLBlock.next);
|
||||||
REGION_PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region);
|
REGION_PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region);
|
||||||
region->type = (region->numRects) ?
|
|
||||||
((region->numRects > 1) ? COMPLEXREGION : SIMPLEREGION)
|
|
||||||
: NULLREGION;
|
|
||||||
|
|
||||||
for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) {
|
for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) {
|
||||||
tmpPtBlock = curPtBlock->next;
|
tmpPtBlock = curPtBlock->next;
|
||||||
|
@ -3120,8 +3055,6 @@ empty:
|
||||||
rgnDst->extents.top = rgnDst->rects[0].top;
|
rgnDst->extents.top = rgnDst->rects[0].top;
|
||||||
rgnDst->extents.bottom = rgnDst->rects[j].bottom;
|
rgnDst->extents.bottom = rgnDst->rects[j].bottom;
|
||||||
|
|
||||||
rgnDst->type = (j >= 1) ? COMPLEXREGION : SIMPLEREGION;
|
|
||||||
|
|
||||||
if( TRACE_ON(region) )
|
if( TRACE_ON(region) )
|
||||||
{
|
{
|
||||||
TRACE("result:\n");
|
TRACE("result:\n");
|
||||||
|
|
|
@ -35,7 +35,6 @@
|
||||||
#include "dce.h"
|
#include "dce.h"
|
||||||
#include "win.h"
|
#include "win.h"
|
||||||
#include "gdi.h"
|
#include "gdi.h"
|
||||||
#include "region.h"
|
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
#include "wine/server.h"
|
#include "wine/server.h"
|
||||||
#include "controls.h"
|
#include "controls.h"
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
#include "region.h"
|
|
||||||
#include "win.h"
|
#include "win.h"
|
||||||
#include "hook.h"
|
#include "hook.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
|
|
Loading…
Reference in New Issue