Release 941017
[wine/gsoc-2012-control.git] / objects / region.c
blobad3379b333b54fbab3af269f6c68dc595cc5fd3a
1 /*
2 * GDI region objects
4 * Copyright 1993, 1994 Alexandre Julliard
5 */
7 static char Copyright[] = "Copyright Alexandre Julliard, 1993, 1994";
9 #include <stdlib.h>
10 #include <stdio.h>
12 #include "gdi.h"
13 #include "stddebug.h"
14 /* #define DEBUG_REGION /* */
15 /* #undef DEBUG_REGION /* */
16 #include "debug.h"
18 /* GC used for region operations */
19 static GC regionGC = 0;
21 /***********************************************************************
22 * REGION_Init
24 BOOL REGION_Init()
26 Pixmap tmpPixmap;
28 /* CreateGC needs a drawable */
29 tmpPixmap = XCreatePixmap( display, rootWindow, 1, 1, 1 );
30 if (tmpPixmap)
32 regionGC = XCreateGC( display, tmpPixmap, 0, NULL );
33 XFreePixmap( display, tmpPixmap );
34 if (!regionGC) return FALSE;
35 XSetForeground( display, regionGC, 1 );
36 XSetGraphicsExposures( display, regionGC, False );
37 return TRUE;
39 else return FALSE;
43 /***********************************************************************
44 * REGION_MakePixmap
46 * Make a pixmap of an X region.
48 static BOOL REGION_MakePixmap( REGION *region )
50 int width = region->box.right - region->box.left;
51 int height = region->box.bottom - region->box.top;
53 if (!region->xrgn) return TRUE; /* Null region */
54 region->pixmap = XCreatePixmap( display, rootWindow, width, height, 1 );
55 if (!region->pixmap) return FALSE;
56 XSetRegion( display, regionGC, region->xrgn );
57 XSetClipOrigin( display, regionGC, -region->box.left, -region->box.top );
58 XSetFunction( display, regionGC, GXset );
59 XFillRectangle( display, region->pixmap, regionGC, 0, 0, width, height );
60 XSetClipMask( display, regionGC, None ); /* Clear clip region */
61 return TRUE;
65 /***********************************************************************
66 * REGION_SetRect
68 * Set the bounding box of the region and create the pixmap (or the X rgn).
69 * The hrgn must be valid.
71 static BOOL REGION_SetRect( HRGN hrgn, LPRECT rect, BOOL createXrgn )
73 int width, height;
75 /* Fill region */
77 REGION * region = &((RGNOBJ *)GDI_HEAP_ADDR( hrgn ))->region;
78 width = rect->right - rect->left;
79 height = rect->bottom - rect->top;
80 if ((width <= 0) || (height <= 0))
82 region->type = NULLREGION;
83 region->box.left = 0;
84 region->box.right = 0;
85 region->box.top = 0;
86 region->box.bottom = 0;
87 region->pixmap = 0;
88 region->xrgn = 0;
89 return TRUE;
91 region->type = SIMPLEREGION;
92 region->box = *rect;
93 region->xrgn = 0;
94 region->pixmap = 0;
96 if (createXrgn) /* Create and set the X region */
98 XRectangle xrect = { region->box.left, region->box.top, width, height};
99 if (!(region->xrgn = XCreateRegion())) return FALSE;
100 XUnionRectWithRegion( &xrect, region->xrgn, region->xrgn );
102 else /* Create the pixmap */
104 region->pixmap = XCreatePixmap( display, rootWindow, width, height, 1);
105 if (!region->pixmap) return FALSE;
106 /* Fill the pixmap */
107 XSetFunction( display, regionGC, GXclear );
108 XFillRectangle(display, region->pixmap, regionGC, 0, 0, width, height);
110 return TRUE;
114 /***********************************************************************
115 * REGION_DeleteObject
117 BOOL REGION_DeleteObject( HRGN hrgn, RGNOBJ * obj )
119 if (obj->region.pixmap) XFreePixmap( display, obj->region.pixmap );
120 if (obj->region.xrgn) XDestroyRegion( obj->region.xrgn );
121 return GDI_FreeObject( hrgn );
125 /***********************************************************************
126 * OffsetRgn (GDI.101)
128 int OffsetRgn( HRGN hrgn, short x, short y )
130 RGNOBJ * obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC );
131 if (!obj) return ERROR;
132 dprintf_region(stddeb, "OffsetRgn: %d %d,%d\n", hrgn, x, y );
133 OffsetRect( &obj->region.box, x, y );
134 if (obj->region.xrgn) XOffsetRegion( obj->region.xrgn, x, y );
135 return obj->region.type;
139 /***********************************************************************
140 * GetRgnBox (GDI.134)
142 int GetRgnBox( HRGN hrgn, LPRECT rect )
144 RGNOBJ * obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC );
145 if (!obj) return ERROR;
146 dprintf_region(stddeb, "GetRgnBox: %d\n", hrgn );
147 *rect = obj->region.box;
148 return obj->region.type;
152 /***********************************************************************
153 * CreateRectRgn (GDI.64)
155 HRGN CreateRectRgn( short left, short top, short right, short bottom )
157 RECT rect = { left, top, right, bottom };
158 return CreateRectRgnIndirect( &rect );
162 /***********************************************************************
163 * CreateRectRgnIndirect (GDI.65)
165 HRGN CreateRectRgnIndirect( LPRECT rect )
167 HRGN hrgn;
169 dprintf_region(stddeb, "CreateRectRgnIndirect: %d,%d-%d,%d\n",
170 rect->left, rect->top, rect->right, rect->bottom );
172 /* Create region */
174 if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0;
175 if (!REGION_SetRect( hrgn, rect, TRUE ))
177 GDI_FreeObject( hrgn );
178 return 0;
180 return hrgn;
184 /***********************************************************************
185 * CreateRoundRectRgn (GDI.444)
187 HRGN CreateRoundRectRgn( short left, short top, short right, short bottom,
188 short ellipse_width, short ellipse_height )
190 RECT rect = { left, top, right, bottom };
191 RGNOBJ * rgnObj;
192 HRGN hrgn;
194 dprintf_region(stddeb, "CreateRoundRectRgn: %d,%d-%d,%d %dx%d\n",
195 left, top, right, bottom, ellipse_width, ellipse_height );
197 /* Create region */
199 if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0;
200 if (!REGION_SetRect( hrgn, &rect, FALSE ))
202 GDI_FreeObject( hrgn );
203 return 0;
205 rgnObj = (RGNOBJ *) GDI_HEAP_ADDR( hrgn );
207 /* Fill pixmap */
209 if (rgnObj->region.type != NULLREGION)
211 int width = rgnObj->region.box.right - rgnObj->region.box.left;
212 int height = rgnObj->region.box.bottom - rgnObj->region.box.top;
213 XSetFunction( display, regionGC, GXcopy );
214 XFillRectangle( display, rgnObj->region.pixmap, regionGC,
215 0, ellipse_height / 2,
216 width, height - ellipse_height );
217 XFillRectangle( display, rgnObj->region.pixmap, regionGC,
218 ellipse_width / 2, 0,
219 width - ellipse_width, height );
220 XFillArc( display, rgnObj->region.pixmap, regionGC,
221 0, 0,
222 ellipse_width, ellipse_height, 0, 360*64 );
223 XFillArc( display, rgnObj->region.pixmap, regionGC,
224 width - ellipse_width, 0,
225 ellipse_width, ellipse_height, 0, 360*64 );
226 XFillArc( display, rgnObj->region.pixmap, regionGC,
227 0, height - ellipse_height,
228 ellipse_width, ellipse_height, 0, 360*64 );
229 XFillArc( display, rgnObj->region.pixmap, regionGC,
230 width - ellipse_width, height - ellipse_height,
231 ellipse_width, ellipse_height, 0, 360*64 );
234 return hrgn;
238 /***********************************************************************
239 * SetRectRgn (GDI.172)
241 void SetRectRgn( HRGN hrgn, short left, short top, short right, short bottom )
243 RECT rect = { left, top, right, bottom };
244 RGNOBJ * rgnObj;
246 dprintf_region(stddeb, "SetRectRgn: %d %d,%d-%d,%d\n",
247 hrgn, left, top, right, bottom );
249 /* Free previous pixmap */
251 if (!(rgnObj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) return;
252 if (rgnObj->region.pixmap) XFreePixmap( display, rgnObj->region.pixmap );
253 if (rgnObj->region.xrgn) XDestroyRegion( rgnObj->region.xrgn );
254 REGION_SetRect( hrgn, &rect, TRUE );
258 /***********************************************************************
259 * CreateEllipticRgn (GDI.54)
261 HRGN CreateEllipticRgn( short left, short top, short right, short bottom )
263 RECT rect = { left, top, right, bottom };
264 return CreateEllipticRgnIndirect( &rect );
268 /***********************************************************************
269 * CreateEllipticRgnIndirect (GDI.55)
271 HRGN CreateEllipticRgnIndirect( LPRECT rect )
273 RGNOBJ * rgnObj;
274 HRGN hrgn;
276 dprintf_region(stddeb, "CreateEllipticRgnIndirect: %d,%d-%d,%d\n",
277 rect->left, rect->top, rect->right, rect->bottom );
279 /* Create region */
281 if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0;
282 if (!REGION_SetRect( hrgn, rect, FALSE ))
284 GDI_FreeObject( hrgn );
285 return 0;
287 rgnObj = (RGNOBJ *) GDI_HEAP_ADDR( hrgn );
289 /* Fill pixmap */
291 if (rgnObj->region.type != NULLREGION)
293 int width = rgnObj->region.box.right - rgnObj->region.box.left;
294 int height = rgnObj->region.box.bottom - rgnObj->region.box.top;
295 XSetFunction( display, regionGC, GXcopy );
296 XFillArc( display, rgnObj->region.pixmap, regionGC,
297 0, 0, width, height, 0, 360*64 );
300 return hrgn;
304 /***********************************************************************
305 * CreatePolygonRgn (GDI.63)
307 HRGN CreatePolygonRgn( POINT * points, short count, short mode )
309 return CreatePolyPolygonRgn( points, &count, 1, mode );
313 /***********************************************************************
314 * CreatePolyPolygonRgn (GDI.451)
316 HRGN CreatePolyPolygonRgn( POINT * points, short * count,
317 short nbpolygons, short mode )
319 RGNOBJ * rgnObj;
320 HRGN hrgn;
321 int i, j, maxPoints;
322 XPoint *xpoints, *pt;
323 XRectangle rect;
324 Region xrgn;
326 dprintf_region(stddeb, "CreatePolyPolygonRgn: %d polygons\n", nbpolygons );
328 /* Allocate points array */
330 if (!nbpolygons) return 0;
331 for (i = maxPoints = 0; i < nbpolygons; i++)
332 if (maxPoints < count[i]) maxPoints = count[i];
333 if (!maxPoints) return 0;
334 if (!(xpoints = (XPoint *) malloc( sizeof(XPoint) * maxPoints )))
335 return 0;
337 /* Allocate region */
339 if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC )))
341 free( xpoints );
342 return 0;
344 rgnObj = (RGNOBJ *) GDI_HEAP_ADDR( hrgn );
345 rgnObj->region.type = SIMPLEREGION;
346 rgnObj->region.pixmap = 0;
348 /* Create X region */
350 for (i = 0; i < nbpolygons; i++, count++)
352 for (j = *count, pt = xpoints; j > 0; j--, points++, pt++)
354 pt->x = points->x;
355 pt->y = points->y;
357 xrgn = XPolygonRegion( xpoints, *count,
358 (mode == WINDING) ? WindingRule : EvenOddRule );
359 if (!xrgn) break;
360 if (i > 0)
362 Region tmprgn = XCreateRegion();
363 if (mode == WINDING) XUnionRegion(xrgn,rgnObj->region.xrgn,tmprgn);
364 else XXorRegion( xrgn, rgnObj->region.xrgn, tmprgn );
365 XDestroyRegion( rgnObj->region.xrgn );
366 rgnObj->region.xrgn = tmprgn;
368 else rgnObj->region.xrgn = xrgn;
371 free( xpoints );
372 if (!xrgn)
374 GDI_FreeObject( hrgn );
375 return 0;
377 XClipBox( rgnObj->region.xrgn, &rect );
378 SetRect( &rgnObj->region.box, rect.x, rect.y,
379 rect.x + rect.width, rect.y + rect.height);
380 return hrgn;
384 /***********************************************************************
385 * PtInRegion (GDI.161)
387 BOOL PtInRegion( HRGN hrgn, short x, short y )
389 BOOL res;
390 RGNOBJ * obj;
391 POINT pt = { x, y };
393 if (!(obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) return FALSE;
394 if (!PtInRect( &obj->region.box, pt )) return FALSE;
395 if (obj->region.xrgn)
397 return XPointInRegion( obj->region.xrgn, x, y );
399 else
401 XImage *image = XGetImage( display, obj->region.pixmap,
402 x - obj->region.box.left, y - obj->region.box.top,
403 1, 1, AllPlanes, ZPixmap );
404 if (!image) return FALSE;
405 res = (XGetPixel( image, 0, 0 ) != 0);
406 XDestroyImage( image );
408 return res;
412 /***********************************************************************
413 * RectInRegion (GDI.181)
415 BOOL RectInRegion( HRGN hrgn, LPRECT rect )
417 XImage * image;
418 RGNOBJ * obj;
419 RECT intersect;
420 int x, y;
422 if (!(obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) return FALSE;
423 if (obj->region.xrgn)
425 return (XRectInRegion( obj->region.xrgn, rect->left, rect->top,
426 rect->right-rect->left,
427 rect->bottom-rect->top ) != RectangleOut);
429 else
431 if (!IntersectRect( &intersect, &obj->region.box, rect )) return FALSE;
433 image = XGetImage( display, obj->region.pixmap,
434 intersect.left - obj->region.box.left,
435 intersect.top - obj->region.box.top,
436 intersect.right - intersect.left,
437 intersect.bottom - intersect.top,
438 AllPlanes, ZPixmap );
439 if (!image) return FALSE;
440 for (y = 0; y < image->height; y++)
441 for (x = 0; x < image->width; x++)
442 if (XGetPixel( image, x, y ) != 0)
444 XDestroyImage( image );
445 return TRUE;
448 XDestroyImage( image );
450 return FALSE;
454 /***********************************************************************
455 * EqualRgn (GDI.72)
457 BOOL EqualRgn( HRGN rgn1, HRGN rgn2 )
459 RGNOBJ *obj1, *obj2;
460 XImage *image1, *image2;
461 Pixmap pixmap1, pixmap2;
462 int width, height, x, y;
464 /* Compare bounding boxes */
466 if (!(obj1 = (RGNOBJ *) GDI_GetObjPtr( rgn1, REGION_MAGIC ))) return FALSE;
467 if (!(obj2 = (RGNOBJ *) GDI_GetObjPtr( rgn2, REGION_MAGIC ))) return FALSE;
468 if (obj1->region.type == NULLREGION)
469 return (obj2->region.type == NULLREGION);
470 else if (obj2->region.type == NULLREGION) return FALSE;
471 if (!EqualRect( &obj1->region.box, &obj2->region.box )) return FALSE;
472 if (obj1->region.xrgn && obj2->region.xrgn)
474 return XEqualRegion( obj1->region.xrgn, obj2->region.xrgn );
477 /* Get pixmap contents */
479 if (!(pixmap1 = obj1->region.pixmap) &&
480 !REGION_MakePixmap( &obj1->region )) return FALSE;
481 if (!(pixmap2 = obj2->region.pixmap) &&
482 !REGION_MakePixmap( &obj2->region )) return FALSE;
483 width = obj1->region.box.right - obj1->region.box.left;
484 height = obj1->region.box.bottom - obj1->region.box.top;
485 image1 = XGetImage( display, obj1->region.pixmap,
486 0, 0, width, height, AllPlanes, ZPixmap );
487 image2 = XGetImage( display, obj2->region.pixmap,
488 0, 0, width, height, AllPlanes, ZPixmap );
489 if (!image1 || !image2)
491 if (image1) XDestroyImage( image1 );
492 if (image2) XDestroyImage( image2 );
493 return FALSE;
496 /* Compare pixmaps */
497 for (y = 0; y < height; y++)
498 for (x = 0; x < width; x++)
499 if (XGetPixel( image1, x, y ) != XGetPixel( image2, x, y))
501 XDestroyImage( image1 );
502 XDestroyImage( image2 );
503 return FALSE;
506 XDestroyImage( image1 );
507 XDestroyImage( image2 );
508 return TRUE;
512 /***********************************************************************
513 * REGION_CopyIntersection
515 * Copy to dest->pixmap the area of src->pixmap delimited by
516 * the intersection of dest and src regions, using the current GC function.
518 void REGION_CopyIntersection( REGION * dest, REGION * src )
520 RECT inter;
521 if (!IntersectRect( &inter, &dest->box, &src->box )) return;
522 XCopyArea( display, src->pixmap, dest->pixmap, regionGC,
523 inter.left - src->box.left, inter.top - src->box.top,
524 inter.right - inter.left, inter.bottom - inter.top,
525 inter.left - dest->box.left, inter.top - dest->box.top );
529 /***********************************************************************
530 * REGION_CopyRegion
532 * Copy region src into dest.
534 static int REGION_CopyRegion( RGNOBJ *src, RGNOBJ *dest )
536 if (dest->region.pixmap) XFreePixmap( display, dest->region.pixmap );
537 dest->region.type = src->region.type;
538 dest->region.box = src->region.box;
539 dest->region.pixmap = 0;
540 if (src->region.xrgn) /* Copy only the X region */
542 Region tmprgn = XCreateRegion();
543 if (!dest->region.xrgn) dest->region.xrgn = XCreateRegion();
544 XUnionRegion( tmprgn, src->region.xrgn, dest->region.xrgn );
545 XDestroyRegion( tmprgn );
547 else /* Copy the pixmap (if any) */
549 if (dest->region.xrgn)
551 XDestroyRegion( dest->region.xrgn );
552 dest->region.xrgn = 0;
554 if (src->region.pixmap)
556 int width = src->region.box.right - src->region.box.left;
557 int height = src->region.box.bottom - src->region.box.top;
559 dest->region.pixmap = XCreatePixmap( display, rootWindow,
560 width, height, 1 );
561 XSetFunction( display, regionGC, GXcopy );
562 XCopyArea( display, src->region.pixmap, dest->region.pixmap,
563 regionGC, 0, 0, width, height, 0, 0 );
566 return dest->region.type;
570 /***********************************************************************
571 * CombineRgn (GDI.451)
573 int CombineRgn( HRGN hDest, HRGN hSrc1, HRGN hSrc2, short mode )
575 RGNOBJ *destObj, *src1Obj, *src2Obj;
576 REGION * region;
577 int width, height;
578 BOOL res;
580 dprintf_region(stddeb, "CombineRgn: %d %d %d %d\n",
581 hDest, hSrc1, hSrc2, mode );
583 if (!(destObj = (RGNOBJ *) GDI_GetObjPtr( hDest, REGION_MAGIC )))
584 return ERROR;
585 if (!(src1Obj = (RGNOBJ *) GDI_GetObjPtr( hSrc1, REGION_MAGIC )))
586 return ERROR;
587 if (mode == RGN_COPY) return REGION_CopyRegion( src1Obj, destObj );
589 if (!(src2Obj = (RGNOBJ *) GDI_GetObjPtr( hSrc2, REGION_MAGIC )))
590 return ERROR;
591 region = &destObj->region;
593 if (src1Obj->region.xrgn && src2Obj->region.xrgn)
595 /* Perform the operation with X regions */
597 if (region->pixmap) XFreePixmap( display, region->pixmap );
598 region->pixmap = 0;
599 if (!region->xrgn) region->xrgn = XCreateRegion();
600 switch(mode)
602 case RGN_AND:
603 XIntersectRegion( src1Obj->region.xrgn, src2Obj->region.xrgn,
604 region->xrgn );
605 break;
606 case RGN_OR:
607 XUnionRegion( src1Obj->region.xrgn, src2Obj->region.xrgn,
608 region->xrgn );
609 break;
610 case RGN_XOR:
611 XXorRegion( src1Obj->region.xrgn, src2Obj->region.xrgn,
612 region->xrgn );
613 break;
614 case RGN_DIFF:
615 XSubtractRegion( src1Obj->region.xrgn, src2Obj->region.xrgn,
616 region->xrgn );
617 break;
618 default:
619 return ERROR;
621 if (XEmptyRegion(region->xrgn))
623 XDestroyRegion( region->xrgn );
624 region->type = NULLREGION;
625 region->xrgn = 0;
626 return NULLREGION;
628 else
630 XRectangle rect;
631 XClipBox( region->xrgn, &rect );
632 region->type = COMPLEXREGION;
633 region->box.left = rect.x;
634 region->box.top = rect.y;
635 region->box.right = rect.x + rect.width;
636 region->box.bottom = rect.y + rect.height;
637 return COMPLEXREGION;
640 else /* Create pixmaps if needed */
642 if (!src1Obj->region.pixmap)
643 if (!REGION_MakePixmap( &src1Obj->region )) return ERROR;
644 if (!src2Obj->region.pixmap)
645 if (!REGION_MakePixmap( &src2Obj->region )) return ERROR;
649 switch(mode)
651 case RGN_AND:
652 res = IntersectRect( &region->box, &src1Obj->region.box,
653 &src2Obj->region.box );
654 region->type = COMPLEXREGION;
655 break;
657 case RGN_OR:
658 case RGN_XOR:
659 res = UnionRect( &region->box, &src1Obj->region.box,
660 &src2Obj->region.box );
661 region->type = COMPLEXREGION;
662 break;
664 case RGN_DIFF:
665 res = SubtractRect( &region->box, &src1Obj->region.box,
666 &src2Obj->region.box );
667 region->type = COMPLEXREGION;
668 break;
670 default:
671 return ERROR;
674 if (region->pixmap) XFreePixmap( display, region->pixmap );
675 if (region->xrgn) XDestroyRegion( region->xrgn );
676 if (!res)
678 region->type = NULLREGION;
679 region->pixmap = 0;
680 region->xrgn = 0;
681 return NULLREGION;
684 width = region->box.right - region->box.left;
685 height = region->box.bottom - region->box.top;
686 if (!width || !height)
688 fprintf(stderr, "CombineRgn: width or height is 0. Please report this.\n" );
689 fprintf(stderr, "src1=%d,%d-%d,%d src2=%d,%d-%d,%d dst=%d,%d-%d,%d op=%d\n",
690 src1Obj->region.box.left, src1Obj->region.box.top,
691 src1Obj->region.box.right, src1Obj->region.box.bottom,
692 src2Obj->region.box.left, src2Obj->region.box.top,
693 src2Obj->region.box.right, src2Obj->region.box.bottom,
694 region->box.left, region->box.top,
695 region->box.right, region->box.bottom, mode );
696 exit(1);
698 region->pixmap = XCreatePixmap( display, rootWindow, width, height, 1 );
699 region->xrgn = 0;
701 switch(mode)
703 case RGN_AND:
704 XSetFunction( display, regionGC, GXcopy );
705 REGION_CopyIntersection( region, &src1Obj->region );
706 XSetFunction( display, regionGC, GXand );
707 REGION_CopyIntersection( region, &src2Obj->region );
708 break;
710 case RGN_OR:
711 case RGN_XOR:
712 XSetFunction( display, regionGC, GXclear );
713 XFillRectangle( display, region->pixmap, regionGC,
714 0, 0, width, height );
715 XSetFunction( display, regionGC, (mode == RGN_OR) ? GXor : GXxor);
716 REGION_CopyIntersection( region, &src1Obj->region );
717 REGION_CopyIntersection( region, &src2Obj->region );
718 break;
720 case RGN_DIFF:
721 XSetFunction( display, regionGC, GXclear );
722 XFillRectangle( display, region->pixmap, regionGC,
723 0, 0, width, height );
724 XSetFunction( display, regionGC, GXcopy );
725 REGION_CopyIntersection( region, &src1Obj->region );
726 XSetFunction( display, regionGC, GXandInverted );
727 REGION_CopyIntersection( region, &src2Obj->region );
728 break;
730 return region->type;