📄 region.c
字号:
/*********************************************************************** * UnionRegion */BOOL GUIAPI UnionRegion (CLIPRGN *dst, const CLIPRGN *src1, const CLIPRGN *src2){ /* checks all the simple cases */ /* * Region 1 and 2 are the same or region 1 is empty */ if ( (src1 == src2) || (!(src1->head)) ) { if (dst != src2) CopyRegion (dst, src2); return TRUE; } /* * if nothing to union (region 2 empty) */ if (!(src2->head)) { if (dst != src1) CopyRegion (dst, src1); return TRUE; } /* * Region 1 completely subsumes region 2 */ if ((src1->head == src1->tail) && (src1->rcBound.left <= src2->rcBound.left) && (src1->rcBound.top <= src2->rcBound.top) && (src1->rcBound.right >= src2->rcBound.right) && (src1->rcBound.bottom >= src2->rcBound.bottom)) { if (dst != src1) CopyRegion (dst, src1); return TRUE; } /* * Region 2 completely subsumes region 1 */ if ((src2->head == src2->tail) && (src2->rcBound.left <= src1->rcBound.left) && (src2->rcBound.top <= src1->rcBound.top) && (src2->rcBound.right >= src1->rcBound.right) && (src2->rcBound.bottom >= src1->rcBound.bottom)) { if (dst != src2) CopyRegion(dst, src2); return TRUE; } REGION_RegionOp (dst, src1, src2, REGION_UnionO, REGION_UnionNonO, REGION_UnionNonO); dst->rcBound.left = MIN (src1->rcBound.left, src2->rcBound.left); dst->rcBound.top = MIN (src1->rcBound.top, src2->rcBound.top); dst->rcBound.right = MAX (src1->rcBound.right, src2->rcBound.right); dst->rcBound.bottom = MAX (src1->rcBound.bottom, src2->rcBound.bottom); dst->type = (dst->head) ? COMPLEXREGION : NULLREGION ; return TRUE;}/* XorRegion */BOOL GUIAPI XorRegion (CLIPRGN *dst, const CLIPRGN *src1, const CLIPRGN *src2){ CLIPRGN tmpa, tmpb; InitClipRgn (&tmpa, src1->heap); InitClipRgn (&tmpb, src2->heap); SubtractRegion (&tmpa, src1, src2); SubtractRegion (&tmpb, src2, src1); UnionRegion (dst, &tmpa, &tmpb); EmptyClipRgn (&tmpa); EmptyClipRgn (&tmpb); return TRUE;}/* Adds a rectangle to a region */BOOL GUIAPI AddClipRect (PCLIPRGN region, const RECT *rect){ CLIPRGN my_region; CLIPRECT my_cliprect; if (IsRectEmpty (rect)) return FALSE;#ifdef _REGION_DEBUG fprintf (stderr, "\n***************Before Union by rect (%d, %d, %d, %d):\n", rect->left, rect->top, rect->right, rect->bottom); dumpRegion (region);#endif my_cliprect.rc = *rect; my_cliprect.next = NULL; my_cliprect.prev = NULL; my_region.type = SIMPLEREGION; my_region.rcBound = *rect; my_region.head = &my_cliprect; my_region.tail = &my_cliprect; my_region.heap = NULL; UnionRegion (region, region, &my_region);#ifdef _REGION_DEBUG dumpRegion (region); fprintf (stderr, "***************After Union\n");#endif return TRUE;}/* Intersect a rect with a region */BOOL GUIAPI IntersectClipRect (PCLIPRGN region, const RECT* rect){ CLIPRGN my_region; CLIPRECT my_cliprect; if (IsRectEmpty (rect)) return FALSE;#ifdef _REGION_DEBUG fprintf (stderr, "\n***************before intersect by rect (%d, %d, %d, %d):\n", rect->left, rect->top, rect->right, rect->bottom); dumpRegion (region);#endif my_cliprect.rc = *rect; my_cliprect.next = NULL; my_cliprect.prev = NULL; my_region.type = SIMPLEREGION; my_region.rcBound = *rect; my_region.head = &my_cliprect; my_region.tail = &my_cliprect; my_region.heap = NULL; ClipRgnIntersect (region, region, &my_region);#ifdef _REGION_DEBUG dumpRegion (region); fprintf (stderr, "***************After intersect\n");#endif return TRUE;}BOOL GUIAPI SubtractClipRect (PCLIPRGN region, const RECT* rect){ CLIPRGN my_region; CLIPRECT my_cliprect; if (IsRectEmpty (rect)) return FALSE;#ifdef _REGION_DEBUG fprintf (stderr, "\n***************Before subtract by rect (%d, %d, %d, %d):\n", rect->left, rect->top, rect->right, rect->bottom); dumpRegion (region);#endif my_cliprect.rc = *rect; my_cliprect.next = NULL; my_cliprect.prev = NULL; my_region.type = SIMPLEREGION; my_region.rcBound = *rect; my_region.head = &my_cliprect; my_region.tail = &my_cliprect; my_region.heap = NULL; SubtractRegion (region, region, &my_region);#ifdef _REGION_DEBUG dumpRegion (region); fprintf (stderr, "***************After subtraction\n");#endif return TRUE;}void GUIAPI OffsetRegion (PCLIPRGN region, int x, int y){ CLIPRECT* cliprect = region->head; while (cliprect) { OffsetRect (&cliprect->rc, x, y); cliprect = cliprect->next; } if (region->head) { OffsetRect (®ion->rcBound, x, y); }}static void cb_region (void* context, int x1, int x2, int y){#if 0 CLIPRGN* region = (CLIPRGN*) context; CLIPRECT* newcliprect; newcliprect = ClipRectAlloc (region->heap); if (x2 > x1) { newcliprect->rc.left = x1; newcliprect->rc.right = x2 + 1; } else { newcliprect->rc.left = x2; newcliprect->rc.right = x1 + 1; } newcliprect->rc.top = y; newcliprect->rc.bottom = y + 1; if (region->head == NULL || (newcliprect->rc.top >= region->tail->rc.bottom && (newcliprect->rc.left != region->tail->rc.left || newcliprect->rc.right != region->tail->rc.right))) { /* simply append to tail */ goto append; } else if (newcliprect->rc.top == region->tail->rc.bottom && newcliprect->rc.left == region->tail->rc.left && newcliprect->rc.right == region->tail->rc.right) { /* merge with the tail */ region->tail->rc.bottom += 1; FreeClipRect (region->heap, newcliprect); } else if (newcliprect->rc.bottom == region->head->rc.top && newcliprect->rc.left == region->head->rc.left && newcliprect->rc.right == region->head->rc.right) { /* merge with the head */ region->head->rc.top -= 1; FreeClipRect (region->heap, newcliprect); } else if (newcliprect->rc.top > region->tail->rc.bottom) { /* simply append to tail */ goto append; } else if (newcliprect->rc.bottom < region->head->rc.top) { /* simply insert to head */ newcliprect->prev = NULL; newcliprect->next = region->head; region->head->prev = newcliprect; region->head = newcliprect; } else { /* find a position to insert */ CLIPRECT* cliprect = region->head; CLIPRECT* prev; printf ("get here.\n"); printf ("new cliprc: (%d, %d, %d, %d)\n", newcliprect->rc.left, newcliprect->rc.top, newcliprect->rc.right, newcliprect->rc.bottom); printf ("head cliprc: (%d, %d, %d, %d)\n", region->head->rc.left, region->head->rc.top, region->head->rc.right, region->head->rc.bottom); printf ("tail cliprc: (%d, %d, %d, %d)\n", region->tail->rc.left, region->tail->rc.top, region->tail->rc.right, region->tail->rc.bottom); while (cliprect && newcliprect->rc.top >= cliprect->rc.top) { cliprect = cliprect->next; } if (cliprect == NULL) /* simply append to the tail */ goto append; printf ("current cliprc: (%d, %d, %d, %d)\n", cliprect->rc.left, cliprect->rc.top, cliprect->rc.right, cliprect->rc.bottom); /* merge with prev or next? */ if ((prev = cliprect->prev) && prev->rc.bottom == newcliprect->rc.top && prev->rc.left == newcliprect->rc.left && prev->rc.right == newcliprect->rc.right) { prev->rc.bottom += 1; FreeClipRect (region->heap, newcliprect); printf ("merge with previous.\n"); } else if (cliprect->rc.top == newcliprect->rc.bottom && cliprect->rc.left == newcliprect->rc.left && cliprect->rc.right == newcliprect->rc.right) { cliprect->rc.top -= 1; FreeClipRect (region->heap, newcliprect); printf ("merge with current.\n"); } else { /* insert before of current cliprc */ cliprect->prev->next = newcliprect; newcliprect->prev = cliprect->prev; cliprect->prev = newcliprect; newcliprect->next = cliprect; printf ("insert before of current.\n"); } } return;append: newcliprect->next = NULL; newcliprect->prev = region->tail; if (region->tail) region->tail->next = newcliprect; region->tail = newcliprect; if (region->head == NULL) region->head = newcliprect;#else CLIPRGN* region = (CLIPRGN*) context; CLIPRGN newregion; CLIPRECT newcliprect; if (x2 > x1) { newcliprect.rc.left = x1; newcliprect.rc.right = x2 + 1; } else { newcliprect.rc.left = x2; newcliprect.rc.right = x1 + 1; } newcliprect.rc.top = y; newcliprect.rc.bottom = y + 1; newcliprect.next = NULL; newcliprect.prev = NULL; newregion.type = SIMPLEREGION; newregion.rcBound = newcliprect.rc; newregion.head = &newcliprect; newregion.tail = &newcliprect; newregion.heap = NULL; UnionRegion (region, region, &newregion);#endif}BOOL GUIAPI InitCircleRegion (PCLIPRGN dst, int x, int y, int r){ EmptyClipRgn (dst); if (r < 1) { CLIPRECT* newcliprect; NEWCLIPRECT (dst, newcliprect); newcliprect->rc.left = x; newcliprect->rc.top = y; newcliprect->rc.right = x + 1; newcliprect->rc.bottom = y + 1; return TRUE; } CircleGenerator (dst, x, y, r, cb_region); dst->type = COMPLEXREGION;// REGION_SetExtents (dst); return TRUE;}BOOL GUIAPI InitEllipseRegion (PCLIPRGN dst, int x, int y, int rx, int ry){ EmptyClipRgn (dst); if (rx < 1 || ry < 1) { CLIPRECT* newcliprect; NEWCLIPRECT (dst, newcliprect); newcliprect->rc.left = x; newcliprect->rc.top = y; newcliprect->rc.right = x + 1; newcliprect->rc.bottom = y + 1; return TRUE; } EllipseGenerator (dst, x, y, rx, ry, cb_region); dst->type = COMPLEXREGION;// REGION_SetExtents (dst); return TRUE;}BOOL GUIAPI InitPolygonRegion (PCLIPRGN dst, const POINT* pts, int vertices){ EmptyClipRgn (dst); if (PolygonIsMonotoneVertical (pts, vertices)) { if (MonotoneVerticalPolygonGenerator (dst, pts, vertices, cb_region)) goto ok; } else if (PolygonGenerator (dst, pts, vertices, cb_region)) { goto ok; } return FALSE;ok: dst->type = COMPLEXREGION;// REGION_SetExtents (dst); return TRUE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -