static int region_subrect(lua_State *L) { struct Region *region = luaL_checkudata(L, 1, TEK_CLASS_UI_REGION_NAME); TAPTR exec = region->rg_ExecBase; struct TNode *next, *node; TBOOL success; struct TList r1; TINT s[4]; s[0] = luaL_checkinteger(L, 2); s[1] = luaL_checkinteger(L, 3); s[2] = luaL_checkinteger(L, 4); s[3] = luaL_checkinteger(L, 5); TINITLIST(&r1); success = TTRUE; node = region->rg_List.tlh_Head; for (; success && (next = node->tln_Succ); node = next) { struct TNode *next2, *node2; struct RectNode *rn = (struct RectNode *) node; struct TList temp; TINITLIST(&temp); success = cutrect(exec, &temp, rn->rn_Rect, s); node2 = temp.tlh_Head; for (; success && (next2 = node2->tln_Succ); node2 = next2) { struct RectNode *rn2 = (struct RectNode *) node2; success = insertrect(exec, &r1, rn2->rn_Rect[0], rn2->rn_Rect[1], rn2->rn_Rect[2], rn2->rn_Rect[3]); } freelist(exec, &temp); } if (success) { freelist(exec, ®ion->rg_List); relinklist(®ion->rg_List, &r1); } else { freelist(exec, &r1); luaL_error(L, "out of memory"); } return 0; }
static int lib_new(lua_State *L) { TINT x0 = luaL_checkinteger(L, 1); TINT y0 = luaL_checkinteger(L, 2); TINT x1 = luaL_checkinteger(L, 3); TINT y1 = luaL_checkinteger(L, 4); struct Region *region = lua_newuserdata(L, sizeof(struct Region)); /* s: udata */ TINITLIST(®ion->rg_List); region->rg_ExecBase = TNULL; lua_getfield(L, LUA_REGISTRYINDEX, TEK_CLASS_UI_REGION_NAME); /* s: udata, metatable */ lua_rawgeti(L, -1, 1); /* s: udata, metatable, execbase */ region->rg_ExecBase = *(TAPTR *) lua_touserdata(L, -1); lua_pop(L, 1); /* s: udata, metatable */ lua_setmetatable(L, -2); /* s: udata */ if (insertrect(region->rg_ExecBase, ®ion->rg_List, x0, y0, x1, y1) == TFALSE) luaL_error(L, "out of memory"); return 1; }
static TBOOL cutrectlist(TAPTR exec, struct TList *inlist, struct TList *outlist, const TINT s[4]) { TBOOL success = TTRUE; struct TNode *next, *node = inlist->tlh_Head; for (; success && (next = node->tln_Succ); node = next) { struct RectNode *rn = (struct RectNode *) node; struct TList temp; TINITLIST(&temp); success = cutrect(exec, &temp, rn->rn_Rect, s); if (success) { struct TNode *next2, *node2 = temp.tlh_Head; for (; success && (next2 = node2->tln_Succ); node2 = next2) { struct RectNode *rn2 = (struct RectNode *) node2; success = insertrect(exec, outlist, rn2->rn_Rect[0], rn2->rn_Rect[1], rn2->rn_Rect[2], rn2->rn_Rect[3]); /* note that if unsuccessful, outlist is unusable as well */ } } freelist(exec, &temp); } return success; }
static TBOOL orrect(TAPTR exec, struct TList *list, TINT s[4]) { struct TList temp; TINITLIST(&temp); if (cutrectlist(exec, list, &temp, s)) { if (insertrect(exec, &temp, s[0], s[1], s[2], s[3])) { freelist(exec, list); relinklist(list, &temp); return TTRUE; } } freelist(exec, &temp); return TFALSE; }
TLIBAPI void region_initrectlist(struct RectList *rl) { TINITLIST(&rl->rl_List); rl->rl_NumNodes = 0; }