ref: a83d17efc1ba3d5feeddf053d2141f42d97e9e8e
dir: /geometry.c/
#include <draw.h> #include <stdlib.h> #include <lua.h> #include <lualib.h> #include <lauxlib.h> void pushrect(lua_State *L, Rectangle r) { lua_newtable(L); lua_newtable(L); lua_pushinteger(L, r.min.x); lua_setfield(L, -2, "x"); lua_pushinteger(L, r.min.y); lua_setfield(L, -2, "y"); lua_setfield(L, -2, "min"); lua_newtable(L); lua_pushinteger(L, r.max.x); lua_setfield(L, -2, "x"); lua_pushinteger(L, r.max.y); lua_setfield(L, -2, "y"); lua_setfield(L, -2, "max"); } Rectangle checkrect(lua_State *L, int index) { Rectangle r; if(lua_istable(L, index) == 0) luaL_argerror(L, index, "rectangle table expected"); lua_pushstring(L, "min"); lua_gettable(L, index); lua_pushstring(L, "x"); lua_gettable(L, -2); r.min.x = luaL_checkinteger(L, -1); lua_pushstring(L, "y"); lua_gettable(L, -3); r.min.y = luaL_checkinteger(L, -1); lua_pop(L, 3); /* table | x | y */ lua_pushstring(L, "max"); lua_gettable(L, index); lua_pushstring(L, "x"); lua_gettable(L, -2); r.max.x = luaL_checkinteger(L, -1); lua_pushstring(L, "y"); lua_gettable(L, -3); r.max.y = luaL_checkinteger(L, -1); lua_pop(L, 3); return r; } void pushpoint(lua_State *L, Point p) { lua_newtable(L); lua_pushinteger(L, p.x); lua_setfield(L, -2, "x"); lua_pushinteger(L, p.y); lua_setfield(L, -2, "y"); } Point getpoint(lua_State *L, int index) { Point p; lua_pushstring(L, "x"); lua_gettable(L, index); p.x = luaL_checkinteger(L, -1); lua_pushstring(L, "y"); lua_gettable(L, index); p.y = luaL_checkinteger(L, -1); lua_pop(L, 2); return p; } Point checkpoint(lua_State *L, int index) { if(lua_istable(L, index) == 0) luaL_argerror(L, index, "point table expected"); return getpoint(L, index); } Point optpoint(lua_State *L, int index) { if(lua_istable(L, index) == 0) return ZP; return getpoint(L, index); } Point* checkpoints(lua_State *L, int index, int *np) { Point *p; int i; if(lua_istable(L, index) == 0) luaL_argerror(L, index, "table of points expected"); *np = luaL_len(L, index); if(*np == 0) luaL_argerror(L, index, "table of points is empty"); p = calloc(*np, sizeof(Point)); if(p == nil) luaL_error(L, "out of memory"); for(i = 1; i <= *np; i++){ lua_rawgeti(L, index, i); p[i-1] = checkpoint(L, lua_gettop(L)); } return p; } static int lpt(lua_State *L) { int x, y; x = luaL_checkinteger(L, 1); y = luaL_checkinteger(L, 2); pushpoint(L, Pt(x, y)); return 1; } static int lrect(lua_State *L) { int x0, x1, y0, y1; x0 = luaL_checkinteger(L, 1); y0 = luaL_checkinteger(L, 2); x1 = luaL_checkinteger(L, 3); y1 = luaL_checkinteger(L, 4); pushrect(L, Rect(x0, y0, x1, y1)); return 1; } static int laddpt(lua_State *L) { Point p, q, r; p = checkpoint(L, 1); q = checkpoint(L, 2); r = addpt(p, q); pushpoint(L, r); return 1; } static int lsubpt(lua_State *L) { Point p, q, r; p = checkpoint(L, 1); q = checkpoint(L, 2); r = subpt(p, q); pushpoint(L, r); return 1; } static int lmulpt(lua_State *L) { Point p; int a; p = checkpoint(L, 1); a = luaL_checkinteger(L, 2); pushpoint(L, mulpt(p, a)); return 1; } static int ldivpt(lua_State *L) { Point p; int a; p = checkpoint(L, 1); a = luaL_checkinteger(L, 2); pushpoint(L, divpt(p, a)); return 1; } static int lrectaddpt(lua_State *L) { Rectangle r; Point p; r = checkrect(L, 1); p = checkpoint(L, 2); pushrect(L, rectaddpt(r, p)); return 1; } static int lrectsubpt(lua_State *L) { Rectangle r; Point p; r = checkrect(L, 1); p = checkpoint(L, 2); pushrect(L, rectsubpt(r, p)); return 1; } static int linsetrect(lua_State *L) { Rectangle r; int n; r = checkrect(L, 1); n = luaL_checkinteger(L, 2); pushrect(L, insetrect(r, n)); return 1; } static int lcanonrect(lua_State *L) { Rectangle r; r = checkrect(L, 1); pushrect(L, canonrect(r)); return 1; } static const struct luaL_Reg libgeometry [] = { { "pt", lpt }, { "rect", lrect }, { "addpt", laddpt }, { "subpt", lsubpt }, { "mulpt", lmulpt }, { "divpt", ldivpt }, { "rectaddpt", lrectaddpt }, { "rectsubpt", lrectsubpt }, { "insetrect", linsetrect }, { "canonrect", lcanonrect }, { NULL, NULL }, }; int openlibgeometry(lua_State *L) { luaL_newlib(L, libgeometry); pushpoint(L, ZP); lua_setfield(L, -2, "ZP"); return 1; }