Release 941030
[wine/multimedia.git] / objects / clipping.c
blobd6d8bbac5ab880016dd8be48290b61e6d7148745
1 /*
2 * DC clipping functions
4 * Copyright 1993 Alexandre Julliard
5 */
7 static char Copyright[] = "Copyright Alexandre Julliard, 1993";
9 #include <stdio.h>
10 #include "gdi.h"
11 #include "metafile.h"
12 #include "stddebug.h"
13 /* #define DEBUG_CLIPPING */
14 /* #undef DEBUG_CLIPPING */
15 #include "debug.h"
17 /***********************************************************************
18 * CLIPPING_SetDeviceClipping
20 * Set the clip region of the physical device.
22 static void CLIPPING_SetDeviceClipping( DC * dc )
24 RGNOBJ *obj = (RGNOBJ *) GDI_GetObjPtr(dc->w.hGCClipRgn, REGION_MAGIC);
25 if (!obj)
27 fprintf( stderr, "SetDeviceClipping: Rgn is 0. Please report this.\n");
28 exit(1);
30 if (obj->region.xrgn)
32 XSetRegion( display, dc->u.x.gc, obj->region.xrgn );
33 XSetClipOrigin( display, dc->u.x.gc, dc->w.DCOrgX, dc->w.DCOrgY );
35 else if (obj->region.pixmap)
37 XSetClipMask( display, dc->u.x.gc, obj->region.pixmap );
38 XSetClipOrigin( display, dc->u.x.gc,
39 dc->w.DCOrgX + obj->region.box.left,
40 dc->w.DCOrgY + obj->region.box.top );
42 else /* Clip everything */
44 XSetClipRectangles( display, dc->u.x.gc, 0, 0, NULL, 0, 0 );
49 /***********************************************************************
50 * CLIPPING_UpdateGCRegion
52 * Update the GC clip region when the ClipRgn or VisRgn have changed.
54 void CLIPPING_UpdateGCRegion( DC * dc )
56 if (!dc->w.hGCClipRgn) dc->w.hGCClipRgn = CreateRectRgn( 0, 0, 0, 0 );
58 if (!dc->w.hVisRgn)
60 fprintf( stderr, "UpdateGCRegion: hVisRgn is zero. Please report this.\n" );
61 exit(1);
63 if (!dc->w.hClipRgn)
64 CombineRgn( dc->w.hGCClipRgn, dc->w.hVisRgn, 0, RGN_COPY );
65 else
66 CombineRgn( dc->w.hGCClipRgn, dc->w.hClipRgn, dc->w.hVisRgn, RGN_AND );
67 CLIPPING_SetDeviceClipping( dc );
71 /***********************************************************************
72 * SelectClipRgn (GDI.44)
74 int SelectClipRgn( HDC hdc, HRGN hrgn )
76 int retval;
77 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
78 if (!dc) return ERROR;
80 dprintf_clipping(stddeb, "SelectClipRgn: %d %d\n", hdc, hrgn );
82 if (hrgn)
84 if (!dc->w.hClipRgn) dc->w.hClipRgn = CreateRectRgn(0,0,0,0);
85 retval = CombineRgn( dc->w.hClipRgn, hrgn, 0, RGN_COPY );
87 else
89 if (dc->w.hClipRgn) DeleteObject( dc->w.hClipRgn );
90 dc->w.hClipRgn = 0;
91 retval = SIMPLEREGION; /* Clip region == whole DC */
93 CLIPPING_UpdateGCRegion( dc );
94 return retval;
98 /***********************************************************************
99 * SelectVisRgn (GDI.105)
101 int SelectVisRgn( HDC hdc, HRGN hrgn )
103 int retval;
104 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
105 if (!dc || !hrgn) return ERROR;
107 dprintf_clipping(stddeb, "SelectVisRgn: %d %d\n", hdc, hrgn );
109 retval = CombineRgn( dc->w.hVisRgn, hrgn, 0, RGN_COPY );
110 CLIPPING_UpdateGCRegion( dc );
111 return retval;
115 /***********************************************************************
116 * OffsetClipRgn (GDI.32)
118 int OffsetClipRgn( HDC hdc, short x, short y )
120 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
121 if (!dc)
123 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
124 if (!dc) return ERROR;
125 MF_MetaParam2(dc, META_OFFSETCLIPRGN, x, y);
126 return NULLREGION; /* ?? */
129 dprintf_clipping(stddeb, "OffsetClipRgn: %d %d,%d\n", hdc, x, y );
131 if (dc->w.hClipRgn)
133 int retval = OffsetRgn( dc->w.hClipRgn, x, y );
134 CLIPPING_UpdateGCRegion( dc );
135 return retval;
137 else return SIMPLEREGION; /* Clip region == client area */
141 /***********************************************************************
142 * OffsetVisRgn (GDI.102)
144 int OffsetVisRgn( HDC hdc, short x, short y )
146 int retval;
147 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
148 if (!dc) return ERROR;
149 dprintf_clipping(stddeb, "OffsetVisRgn: %d %d,%d\n", hdc, x, y );
150 retval = OffsetRgn( dc->w.hVisRgn, x, y );
151 CLIPPING_UpdateGCRegion( dc );
152 return retval;
156 /***********************************************************************
157 * CLIPPING_IntersectClipRect
159 * Helper function for {Intersect,Exclude}ClipRect
161 static int CLIPPING_IntersectClipRect( DC * dc, short left, short top,
162 short right, short bottom, BOOL exclude)
164 HRGN tempRgn, newRgn;
165 int ret;
167 if (!(newRgn = CreateRectRgn( 0, 0, 0, 0 ))) return ERROR;
168 if (!(tempRgn = CreateRectRgn( left, top, right, bottom )))
170 DeleteObject( newRgn );
171 return ERROR;
173 ret = CombineRgn( newRgn, dc->w.hClipRgn ? dc->w.hClipRgn : dc->w.hVisRgn,
174 tempRgn, exclude ? RGN_DIFF : RGN_AND);
175 DeleteObject( tempRgn );
177 if (ret != ERROR)
179 if (dc->w.hClipRgn) DeleteObject( dc->w.hClipRgn );
180 dc->w.hClipRgn = newRgn;
181 CLIPPING_UpdateGCRegion( dc );
183 else DeleteObject( newRgn );
184 return ret;
188 /***********************************************************************
189 * ExcludeClipRect (GDI.21)
191 int ExcludeClipRect( HDC hdc, short left, short top,
192 short right, short bottom )
194 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
195 if (!dc)
197 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
198 if (!dc) return ERROR;
199 MF_MetaParam4(dc, META_EXCLUDECLIPRECT, left, top, right, bottom);
200 return NULLREGION; /* ?? */
203 dprintf_clipping(stddeb, "ExcludeClipRect: %d %dx%d,%dx%d\n",
204 hdc, left, top, right, bottom );
205 return CLIPPING_IntersectClipRect( dc, left, top, right, bottom, TRUE );
209 /***********************************************************************
210 * IntersectClipRect (GDI.22)
212 int IntersectClipRect( HDC hdc, short left, short top,
213 short right, short bottom )
215 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
216 if (!dc)
218 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
219 if (!dc) return ERROR;
220 MF_MetaParam4(dc, META_INTERSECTCLIPRECT, left, top, right, bottom);
221 return NULLREGION; /* ?? */
224 dprintf_clipping(stddeb, "IntersectClipRect: %d %dx%d,%dx%d\n",
225 hdc, left, top, right, bottom );
226 return CLIPPING_IntersectClipRect( dc, left, top, right, bottom, FALSE );
230 /***********************************************************************
231 * CLIPPING_IntersectVisRect
233 * Helper function for {Intersect,Exclude}VisRect
235 static int CLIPPING_IntersectVisRect( DC * dc, short left, short top,
236 short right, short bottom, BOOL exclude )
238 HRGN tempRgn, newRgn;
239 int ret;
241 if (!(newRgn = CreateRectRgn( 0, 0, 0, 0 ))) return ERROR;
242 if (!(tempRgn = CreateRectRgn( left, top, right, bottom )))
244 DeleteObject( newRgn );
245 return ERROR;
247 ret = CombineRgn( newRgn, dc->w.hVisRgn, tempRgn,
248 exclude ? RGN_DIFF : RGN_AND);
249 DeleteObject( tempRgn );
251 if (ret != ERROR)
253 RGNOBJ *newObj = (RGNOBJ*)GDI_GetObjPtr( newRgn, REGION_MAGIC);
254 RGNOBJ *prevObj = (RGNOBJ*)GDI_GetObjPtr( dc->w.hVisRgn, REGION_MAGIC);
255 if (newObj && prevObj) newObj->header.hNext = prevObj->header.hNext;
256 DeleteObject( dc->w.hVisRgn );
257 dc->w.hVisRgn = newRgn;
258 CLIPPING_UpdateGCRegion( dc );
260 else DeleteObject( newRgn );
261 return ret;
265 /***********************************************************************
266 * ExcludeVisRect (GDI.73)
268 int ExcludeVisRect( HDC hdc, short left, short top, short right, short bottom )
270 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
271 if (!dc) return ERROR;
272 dprintf_clipping(stddeb, "ExcludeVisRect: %d %dx%d,%dx%d\n",
273 hdc, left, top, right, bottom );
274 return CLIPPING_IntersectVisRect( dc, left, top, right, bottom, TRUE );
278 /***********************************************************************
279 * IntersectVisRect (GDI.98)
281 int IntersectVisRect( HDC hdc, short left, short top,
282 short right, short bottom )
284 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
285 if (!dc) return ERROR;
286 dprintf_clipping(stddeb, "IntersectVisRect: %d %dx%d,%dx%d\n",
287 hdc, left, top, right, bottom );
288 return CLIPPING_IntersectVisRect( dc, left, top, right, bottom, FALSE );
292 /***********************************************************************
293 * PtVisible (GDI.103)
295 BOOL PtVisible( HDC hdc, short x, short y )
297 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
298 if (!dc) return ERROR;
300 dprintf_clipping(stddeb, "PtVisible: %d %d,%d\n", hdc, x, y );
301 if (!dc->w.hGCClipRgn) return FALSE;
302 return PtInRegion( dc->w.hGCClipRgn, XLPTODP(dc,x), YLPTODP(dc,y) );
306 /***********************************************************************
307 * RectVisible (GDI.104)
309 BOOL RectVisible( HDC hdc, LPRECT rect )
311 RECT tmpRect;
312 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
313 if (!dc) return FALSE;
314 dprintf_clipping(stddeb,"RectVisible: %d %p\n", hdc, rect );
315 if (!dc->w.hGCClipRgn) return FALSE;
316 tmpRect.left = XLPTODP(dc, rect->left);
317 tmpRect.top = YLPTODP(dc, rect->top);
318 tmpRect.right = XLPTODP(dc, rect->right);
319 tmpRect.bottom = YLPTODP(dc, rect->bottom);
320 return RectInRegion( dc->w.hGCClipRgn, &tmpRect );
324 /***********************************************************************
325 * GetClipBox (GDI.77)
327 int GetClipBox( HDC hdc, LPRECT rect )
329 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
330 if (!dc) return ERROR;
331 dprintf_clipping(stddeb, "GetClipBox: %d %p\n", hdc, rect );
332 return GetRgnBox( dc->w.hGCClipRgn, rect );
336 /***********************************************************************
337 * SaveVisRgn (GDI.129)
339 HRGN SaveVisRgn( HDC hdc )
341 HRGN copy;
342 RGNOBJ *obj, *copyObj;
343 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
344 if (!dc) return 0;
345 dprintf_clipping(stddeb, "SaveVisRgn: %d\n", hdc );
346 if (!dc->w.hVisRgn)
348 fprintf( stderr, "SaveVisRgn: hVisRgn is zero. Please report this.\n" );
349 exit(1);
351 if (!(obj = (RGNOBJ *) GDI_GetObjPtr( dc->w.hVisRgn, REGION_MAGIC )))
352 return 0;
353 if (!(copy = CreateRectRgn( 0, 0, 0, 0 ))) return 0;
354 CombineRgn( copy, dc->w.hVisRgn, 0, RGN_COPY );
355 if (!(copyObj = (RGNOBJ *) GDI_GetObjPtr( copy, REGION_MAGIC )))
356 return 0;
357 copyObj->header.hNext = obj->header.hNext;
358 obj->header.hNext = copy;
359 return copy;
363 /***********************************************************************
364 * RestoreVisRgn (GDI.130)
366 int RestoreVisRgn( HDC hdc )
368 HRGN saved;
369 RGNOBJ *obj, *savedObj;
370 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
371 if (!dc || !dc->w.hVisRgn) return ERROR;
372 dprintf_clipping(stddeb, "RestoreVisRgn: %d\n", hdc );
373 if (!(obj = (RGNOBJ *) GDI_GetObjPtr( dc->w.hVisRgn, REGION_MAGIC )))
374 return ERROR;
375 if (!(saved = obj->header.hNext)) return ERROR;
376 if (!(savedObj = (RGNOBJ *) GDI_GetObjPtr( saved, REGION_MAGIC )))
377 return ERROR;
378 DeleteObject( dc->w.hVisRgn );
379 dc->w.hVisRgn = saved;
380 CLIPPING_UpdateGCRegion( dc );
381 return savedObj->region.type;