2 * DC clipping functions
4 * Copyright 1993 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "wine/winuser16.h"
26 #include "wine/debug.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(clipping
);
31 /***********************************************************************
32 * CLIPPING_UpdateGCRegion
34 * Update the GC clip region when the ClipRgn or VisRgn have changed.
36 void CLIPPING_UpdateGCRegion( DC
* dc
)
38 if (!dc
->hGCClipRgn
) dc
->hGCClipRgn
= CreateRectRgn( 0, 0, 0, 0 );
42 ERR("hVisRgn is zero. Please report this.\n" );
46 if (dc
->flags
& DC_DIRTY
) ERR( "DC is dirty. Please report this.\n" );
49 CombineRgn( dc
->hGCClipRgn
, dc
->hVisRgn
, 0, RGN_COPY
);
51 CombineRgn(dc
->hGCClipRgn
, dc
->hClipRgn
, dc
->hVisRgn
, RGN_AND
);
52 if (dc
->funcs
->pSetDeviceClipping
)
53 dc
->funcs
->pSetDeviceClipping( dc
->physDev
, dc
->hGCClipRgn
);
57 /***********************************************************************
58 * SelectClipRgn (GDI32.@)
60 INT WINAPI
SelectClipRgn( HDC hdc
, HRGN hrgn
)
62 return ExtSelectClipRgn( hdc
, hrgn
, RGN_COPY
);
66 /******************************************************************************
67 * ExtSelectClipRgn [GDI32.@]
69 INT WINAPI
ExtSelectClipRgn( HDC hdc
, HRGN hrgn
, INT fnMode
)
72 DC
* dc
= DC_GetDCUpdate( hdc
);
73 if (!dc
) return ERROR
;
75 TRACE("%04x %04x %d\n", hdc
, hrgn
, fnMode
);
77 if (dc
->funcs
->pExtSelectClipRgn
)
79 retval
= dc
->funcs
->pExtSelectClipRgn( dc
->physDev
, hrgn
, fnMode
);
80 GDI_ReleaseObj( hdc
);
86 if (fnMode
== RGN_COPY
)
88 if (dc
->hClipRgn
) DeleteObject( dc
->hClipRgn
);
90 retval
= SIMPLEREGION
; /* Clip region == whole DC */
94 FIXME("Unimplemented: hrgn NULL in mode: %d\n", fnMode
);
95 GDI_ReleaseObj( hdc
);
104 GetRgnBox( dc
->hVisRgn
, &rect
);
105 dc
->hClipRgn
= CreateRectRgnIndirect( &rect
);
108 if(fnMode
== RGN_COPY
)
109 retval
= CombineRgn( dc
->hClipRgn
, hrgn
, 0, fnMode
);
111 retval
= CombineRgn( dc
->hClipRgn
, dc
->hClipRgn
, hrgn
, fnMode
);
114 CLIPPING_UpdateGCRegion( dc
);
115 GDI_ReleaseObj( hdc
);
119 /***********************************************************************
120 * SelectVisRgn (GDI.105)
122 INT16 WINAPI
SelectVisRgn16( HDC16 hdc
, HRGN16 hrgn
)
127 if (!hrgn
) return ERROR
;
128 if (!(dc
= DC_GetDCPtr( hdc
))) return ERROR
;
130 TRACE("%04x %04x\n", hdc
, hrgn
);
132 dc
->flags
&= ~DC_DIRTY
;
134 retval
= CombineRgn16( dc
->hVisRgn
, hrgn
, 0, RGN_COPY
);
135 CLIPPING_UpdateGCRegion( dc
);
136 GDI_ReleaseObj( hdc
);
141 /***********************************************************************
142 * OffsetClipRgn (GDI32.@)
144 INT WINAPI
OffsetClipRgn( HDC hdc
, INT x
, INT y
)
146 INT ret
= SIMPLEREGION
;
147 DC
*dc
= DC_GetDCUpdate( hdc
);
148 if (!dc
) return ERROR
;
150 TRACE("%04x %d,%d\n", hdc
, x
, y
);
152 if(dc
->funcs
->pOffsetClipRgn
)
153 ret
= dc
->funcs
->pOffsetClipRgn( dc
->physDev
, x
, y
);
154 else if (dc
->hClipRgn
) {
155 ret
= OffsetRgn( dc
->hClipRgn
, XLSTODS(dc
,x
), YLSTODS(dc
,y
));
156 CLIPPING_UpdateGCRegion( dc
);
158 GDI_ReleaseObj( hdc
);
163 /***********************************************************************
164 * OffsetVisRgn (GDI.102)
166 INT16 WINAPI
OffsetVisRgn16( HDC16 hdc
, INT16 x
, INT16 y
)
169 DC
* dc
= DC_GetDCUpdate( hdc
);
170 if (!dc
) return ERROR
;
171 TRACE("%04x %d,%d\n", hdc
, x
, y
);
172 retval
= OffsetRgn( dc
->hVisRgn
, x
, y
);
173 CLIPPING_UpdateGCRegion( dc
);
174 GDI_ReleaseObj( hdc
);
179 /***********************************************************************
180 * ExcludeClipRect (GDI32.@)
182 INT WINAPI
ExcludeClipRect( HDC hdc
, INT left
, INT top
,
183 INT right
, INT bottom
)
187 DC
*dc
= DC_GetDCUpdate( hdc
);
188 if (!dc
) return ERROR
;
190 TRACE("%04x %dx%d,%dx%d\n", hdc
, left
, top
, right
, bottom
);
192 if(dc
->funcs
->pExcludeClipRect
)
193 ret
= dc
->funcs
->pExcludeClipRect( dc
->physDev
, left
, top
, right
, bottom
);
200 rect
.bottom
= bottom
;
201 LPtoDP( hdc
, (POINT
*)&rect
, 2 );
203 if (!(newRgn
= CreateRectRgn( rect
.left
, rect
.top
, rect
.right
, rect
.bottom
))) ret
= ERROR
;
208 dc
->hClipRgn
= CreateRectRgn( 0, 0, 0, 0 );
209 CombineRgn( dc
->hClipRgn
, dc
->hVisRgn
, 0, RGN_COPY
);
211 ret
= CombineRgn( dc
->hClipRgn
, dc
->hClipRgn
, newRgn
, RGN_DIFF
);
212 DeleteObject( newRgn
);
214 if (ret
!= ERROR
) CLIPPING_UpdateGCRegion( dc
);
216 GDI_ReleaseObj( hdc
);
221 /***********************************************************************
222 * IntersectClipRect (GDI32.@)
224 INT WINAPI
IntersectClipRect( HDC hdc
, INT left
, INT top
, INT right
, INT bottom
)
227 DC
*dc
= DC_GetDCUpdate( hdc
);
228 if (!dc
) return ERROR
;
230 TRACE("%04x %d,%d - %d,%d\n", hdc
, left
, top
, right
, bottom
);
232 if(dc
->funcs
->pIntersectClipRect
)
233 ret
= dc
->funcs
->pIntersectClipRect( dc
->physDev
, left
, top
, right
, bottom
);
241 rect
.bottom
= bottom
;
242 LPtoDP( hdc
, (POINT
*)&rect
, 2 );
246 dc
->hClipRgn
= CreateRectRgn( rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
253 if (!(newRgn
= CreateRectRgn( rect
.left
, rect
.top
, rect
.right
, rect
.bottom
))) ret
= ERROR
;
256 ret
= CombineRgn( dc
->hClipRgn
, dc
->hClipRgn
, newRgn
, RGN_AND
);
257 DeleteObject( newRgn
);
260 if (ret
!= ERROR
) CLIPPING_UpdateGCRegion( dc
);
262 GDI_ReleaseObj( hdc
);
267 /***********************************************************************
268 * ExcludeVisRect (GDI.73)
270 INT16 WINAPI
ExcludeVisRect16( HDC16 hdc
, INT16 left
, INT16 top
,
271 INT16 right
, INT16 bottom
)
276 DC
* dc
= DC_GetDCUpdate( hdc
);
277 if (!dc
) return ERROR
;
282 rect
.bottom
= bottom
;
283 LPtoDP( hdc
, (POINT
*)&rect
, 2 );
285 TRACE("%04x %d,%d - %d,%d\n", hdc
, rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
287 if (!(tempRgn
= CreateRectRgn( rect
.left
, rect
.top
, rect
.right
, rect
.bottom
))) ret
= ERROR
;
290 ret
= CombineRgn( dc
->hVisRgn
, dc
->hVisRgn
, tempRgn
, RGN_DIFF
);
291 DeleteObject( tempRgn
);
293 if (ret
!= ERROR
) CLIPPING_UpdateGCRegion( dc
);
294 GDI_ReleaseObj( hdc
);
299 /***********************************************************************
300 * IntersectVisRect (GDI.98)
302 INT16 WINAPI
IntersectVisRect16( HDC16 hdc
, INT16 left
, INT16 top
,
303 INT16 right
, INT16 bottom
)
308 DC
* dc
= DC_GetDCUpdate( hdc
);
309 if (!dc
) return ERROR
;
314 rect
.bottom
= bottom
;
315 LPtoDP( hdc
, (POINT
*)&rect
, 2 );
317 TRACE("%04x %d,%d - %d,%d\n", hdc
, rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
319 if (!(tempRgn
= CreateRectRgn( rect
.left
, rect
.top
, rect
.right
, rect
.bottom
))) ret
= ERROR
;
322 ret
= CombineRgn( dc
->hVisRgn
, dc
->hVisRgn
, tempRgn
, RGN_AND
);
323 DeleteObject( tempRgn
);
325 if (ret
!= ERROR
) CLIPPING_UpdateGCRegion( dc
);
326 GDI_ReleaseObj( hdc
);
331 /***********************************************************************
332 * PtVisible (GDI32.@)
334 BOOL WINAPI
PtVisible( HDC hdc
, INT x
, INT y
)
337 DC
*dc
= DC_GetDCUpdate( hdc
);
339 TRACE("%04x %d,%d\n", hdc
, x
, y
);
340 if (!dc
) return FALSE
;
347 LPtoDP( hdc
, &pt
, 1 );
348 ret
= PtInRegion( dc
->hGCClipRgn
, pt
.x
, pt
.y
);
350 GDI_ReleaseObj( hdc
);
355 /***********************************************************************
356 * RectVisible (GDI32.@)
358 BOOL WINAPI
RectVisible( HDC hdc
, const RECT
* rect
)
362 DC
*dc
= DC_GetDCUpdate( hdc
);
363 if (!dc
) return FALSE
;
364 TRACE("%04x %d,%dx%d,%d\n",
365 hdc
, rect
->left
, rect
->top
, rect
->right
, rect
->bottom
);
368 /* copy rectangle to avoid overwriting by LPtoDP */
370 LPtoDP( hdc
, (LPPOINT
)&tmpRect
, 2 );
371 ret
= RectInRegion( dc
->hGCClipRgn
, &tmpRect
);
373 GDI_ReleaseObj( hdc
);
378 /***********************************************************************
379 * GetClipBox (GDI32.@)
381 INT WINAPI
GetClipBox( HDC hdc
, LPRECT rect
)
384 DC
*dc
= DC_GetDCUpdate( hdc
);
385 if (!dc
) return ERROR
;
386 ret
= GetRgnBox( dc
->hGCClipRgn
, rect
);
387 DPtoLP( hdc
, (LPPOINT
)rect
, 2 );
388 GDI_ReleaseObj( hdc
);
393 /***********************************************************************
394 * GetClipRgn (GDI32.@)
396 INT WINAPI
GetClipRgn( HDC hdc
, HRGN hRgn
)
400 if (hRgn
&& (dc
= DC_GetDCPtr( hdc
)))
404 if( CombineRgn(hRgn
, dc
->hClipRgn
, 0, RGN_COPY
) != ERROR
) ret
= 1;
407 GDI_ReleaseObj( hdc
);
412 /***********************************************************************
413 * SaveVisRgn (GDI.129)
415 HRGN16 WINAPI
SaveVisRgn16( HDC16 hdc
)
418 GDIOBJHDR
*obj
, *copyObj
;
419 DC
*dc
= DC_GetDCUpdate( hdc
);
422 TRACE("%04x\n", hdc
);
424 if (!(obj
= GDI_GetObjPtr( dc
->hVisRgn
, REGION_MAGIC
)))
426 GDI_ReleaseObj( hdc
);
429 if (!(copy
= CreateRectRgn( 0, 0, 0, 0 )))
431 GDI_ReleaseObj( dc
->hVisRgn
);
432 GDI_ReleaseObj( hdc
);
435 CombineRgn( copy
, dc
->hVisRgn
, 0, RGN_COPY
);
436 if (!(copyObj
= GDI_GetObjPtr( copy
, REGION_MAGIC
)))
438 DeleteObject( copy
);
439 GDI_ReleaseObj( dc
->hVisRgn
);
440 GDI_ReleaseObj( hdc
);
443 copyObj
->hNext
= obj
->hNext
;
445 GDI_ReleaseObj( copy
);
446 GDI_ReleaseObj( dc
->hVisRgn
);
447 GDI_ReleaseObj( hdc
);
452 /***********************************************************************
453 * RestoreVisRgn (GDI.130)
455 INT16 WINAPI
RestoreVisRgn16( HDC16 hdc
)
458 GDIOBJHDR
*obj
, *savedObj
;
459 DC
*dc
= DC_GetDCPtr( hdc
);
462 if (!dc
) return ERROR
;
464 TRACE("%04x\n", hdc
);
466 if (!(obj
= GDI_GetObjPtr( dc
->hVisRgn
, REGION_MAGIC
))) goto done
;
469 if ((savedObj
= GDI_GetObjPtr( saved
, REGION_MAGIC
)))
471 ret
= CombineRgn( dc
->hVisRgn
, saved
, 0, RGN_COPY
);
472 obj
->hNext
= savedObj
->hNext
;
473 GDI_ReleaseObj( saved
);
474 DeleteObject( saved
);
475 dc
->flags
&= ~DC_DIRTY
;
476 CLIPPING_UpdateGCRegion( dc
);
478 GDI_ReleaseObj( dc
->hVisRgn
);
480 GDI_ReleaseObj( hdc
);