📄 pw_region.c
字号:
#include <i_pwin.h>/* -------------------------------------------------------------------------- */#define NO_GAP 0 /**< No gap. */ #define L_GAP 1 /**< Gap on left. */#define T_GAP 2 /**< Gap on top. */#define R_GAP 4 /**< Gap on right. */#define B_GAP 8 /**< Gap on bottom. */#define OUT_LEFT 1 /**< Point - Rectangle out code (left). */#define OUT_RIGHT 2 /**< Point - Rectangle out code (right). */#define OUT_TOP 4 /**< Point - Rectangle out code (top). */#define OUT_BOTTOM 8 /**< Point - Rectangle out code (bottom). *//* -------------------------------------------------------------------------- *//** * Gets the position of the point @p x, @p y according to * the rectangle @p r. * @param r pointer to rectangle r * @param x point's x coord * @param y point's y coord * @return point position code * @internal */ Pw_Int IPw_RectOutCode(Pw_Rectangle* r, Pw_Coord x, Pw_Coord y) { Pw_Int code = 0; IPW_TRACE_ENTER(RE1); IPW_TRACE_RECT(RE1, r); IPW_TRACE2(RE1, d, x, y); IPW_CHECK_PTR(r); if (x < r->x) code = OUT_LEFT; else if (x >= (r->x + r->w)) code = OUT_RIGHT; if (y < r->y) code |= OUT_TOP; else if (y >= (r->y + r->h)) code |= OUT_BOTTOM; IPW_TRACE_EXIT_V(RE1, d, code); return(code); }/** * Calculates the intersection of rectangles @p a and @p b. * The result is returned as rectangle @p a (the old rectangle @p a * is overwritten). * @param a pointer to rectangle a * @param b pointer to rectangle b * @return true if the two rectangles intersect * @internal */ Pw_Bool IPw_RectIntersect(Pw_Rectangle* a, Pw_Rectangle* b){ Pw_Coord nx; Pw_Coord ny; IPW_TRACE_ENTER(RE1); IPW_TRACE_RECT2(RE1, a, b); IPW_CHECK_PTR2(a, b); nx = PW_MAX(a->x, b->x); ny = PW_MAX(a->y, b->y); a->w = PW_MIN(a->x + a->w, b->x + b->w) - nx; a->h = PW_MIN(a->y + a->h, b->y + b->h) - ny; a->x = nx; a->y = ny; IPW_TRACE_RECT(RE1, a); IPW_TRACE_EXIT_V(RE1, d, (a->w > 0 && a->h > 0)); return(a->w > 0 && a->h > 0);}/** * Calculates the union of rectangles @p a and @p b. * The result is returned as rectangle @p a (the old rectangle @p a * is overwritten). * @param a pointer to rectangle a * @param b pointer to rectangle b * @internal */ void IPw_RectUnionize(Pw_Rectangle* a, Pw_Rectangle* b){ Pw_Coord nx; Pw_Coord ny; IPW_TRACE_ENTER(RE1); IPW_TRACE_RECT2(RE1, a, b); IPW_CHECK_PTR2(a, b); /* If b is empty nothing to do */ if (b->w <= 0 || b->h <= 0) { IPW_TRACE_RECT(RE1, a); IPW_TRACE_EXIT(RE1); return; } /* If a is empty just copy b into a */ if (a->w <= 0 || a->h <= 0) { IPW_RECT_COPY(a, b); IPW_TRACE_RECT(RE1, a); IPW_TRACE_EXIT(RE1); return; } nx = PW_MIN(a->x, b->x); ny = PW_MIN(a->y, b->y); a->w = PW_MAX(a->x + a->w, b->x + b->w) - nx; a->h = PW_MAX(a->y + a->h, b->y + b->h) - ny; a->x = nx; a->y = ny; IPW_TRACE_RECT(RE1, a); IPW_TRACE_EXIT(RE1);}/** * Excludes the area of rectangle @p z from rectangle @p a. * The result is returned as rectangle @p a, in case of rectangle * @p a breaking into several rectangles, the newly generated * rectangles are returned as @p b, @p c and @p d. * @param z pointer to rectangle z * @param a pointer to rectangle a * @param b pointer to rectangle b * @param c pointer to rectangle c * @param d pointer to rectangle d * @return the number of newly generated rectangles * @internal */ Pw_Int IPw_RectExclude(Pw_Rectangle* z, Pw_Rectangle* a, Pw_Rectangle* b, Pw_Rectangle* c, Pw_Rectangle* d){ Pw_uInt gaps; IPW_TRACE_ENTER(RE2); IPW_TRACE_RECT2(RE2, z, a); IPW_CHECK_PTR5(z, a, b, c, d); /* If rects z and a don't overlap exit */ if (!IPW_RECT_IS_OVER(a, z)) { IPW_TRACE_EXIT_V(RE2, d, 0); return(0); } gaps = NO_GAP; /* Check for gap on left */ if (a->x < z->x) gaps |= L_GAP; /* Check for gap on top */ if (a->y < z->y) gaps |= T_GAP; /* Check for gap on rigth */ if ((a->x + a->w) > (z->x + z->w)) gaps |= R_GAP; /* Check for gap on bottom */ if ((a->y + a->h) > (z->y + z->h)) gaps |= B_GAP; IPW_TRACE1(RE2, d, gaps); switch (gaps) { /* * No gaps * * +-----------+ * | Z | * | - - - | * | | | | * | A | * | | | | * | - - - | * | | * +-----------+ */ case (NO_GAP): { a->x = 0; a->y = 0; a->w = 0; a->h = 0; IPW_TRACE_RECT(RE2, a); IPW_TRACE_EXIT_V(RE2, d, -1); return(-1); } /* * Gap on left * * +------+ * +-----| | * | | | * | | | * | | | * | A | Z | * | | | * | | | * | | | * +-----| | * +------+ */ case (L_GAP): { a->w = z->x - a->x; IPW_TRACE_RECT(RE2, a); IPW_TRACE_EXIT_V(RE2, d, 0); return(0); } /* * Gap on top * * +-----------+ * | | * | A | * | | * +-------------+ * | | * | | * | Z | * | | * +-------------+ */ case (T_GAP): { a->h = z->y - a->y; IPW_TRACE_RECT(RE2, a); IPW_TRACE_EXIT_V(RE2, d, 0); return(0); } /* * Gap on right * * +-------+ * | |-----+ * | | | * | | | * | | | * | Z | A | * | | | * | | | * | | | * | |-----+ * +-------+ */ case (R_GAP): { Pw_Int dx = z->w + z->x - a->x; a->x += dx; a->w -= dx; IPW_TRACE_RECT(RE2, a); IPW_TRACE_EXIT_V(RE2, d, 0); return(0); } /* * Gap on bottom * * +-------------+ * | | * | Z | * | | * | | * +-------------+ * | | * | A | * | | * +-----------+ */ case (B_GAP): { Pw_Int dy = z->h + z->y - a->y; a->y += dy; a->h -= dy; IPW_TRACE_RECT(RE2, a); IPW_TRACE_EXIT_V(RE2, d, 0); return(0); } /* * Gaps on left and top * * +-----------+ * | | * | A | * | | * +=====+------+ * | | | * | B | | * | | Z | * +-----| | * +------+ */ case (L_GAP | T_GAP): { b->x = a->x; b->y = z->y; b->w = z->x - a->x; b->h = a->y + a->h - b->y; a->h = z->y - a->y; IPW_TRACE_RECT2(RE2, a, b); IPW_TRACE_EXIT_V(RE2, d, 1); return(1); } /* * Gaps on left and right * * +---+ * +---| |---+ * | | | | * | | | | * | | | | * | A | Z | B | * | | | | * | | | | * | | | | * +---| |---+ * +---+ */ case (L_GAP | R_GAP): { b->x = z->x + z->w; b->y = a->y; b->w = a->x + a->w - b->x; b->h = a->h; a->w = z->x - a->x; IPW_TRACE_RECT2(RE2, a, b); IPW_TRACE_EXIT_V(RE2, d, 1); return(1); } /* * Gaps on left and bottom * * +------+ * +-----| | * | | Z | * | A | | * | | | * +=====+------+ * | | * | B | * | | * +-----------+ */ case (L_GAP | B_GAP): { b->x = a->x; b->y = z->y + z->h; b->w = a->w; b->h = a->y + a->h - b->y; a->w = z->x - a->x; a->h = b->y - a->y; IPW_TRACE_RECT2(RE2, a, b); IPW_TRACE_EXIT_V(RE2, d, 1); return(1); } /* * Gaps on top and right * * +-----------+ * | | * | A | * | | * +------+=====+ * | | | * | | B | * | Z | | * | |-----+ * +------+ */ case (T_GAP | R_GAP): { b->x = z->x + z->w; b->y = z->y; b->w = a->x + a->w - b->x; b->h = a->y + a->h - b->y; a->h = b->y - a->y; IPW_TRACE_RECT2(RE2, a, b); IPW_TRACE_EXIT_V(RE2, d, 1); return(1); } /* * Gaps on top and bottom *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -