diff --git a/example.lua b/example.lua index 139dd79..2c7afdc 100644 --- a/example.lua +++ b/example.lua @@ -4,17 +4,19 @@ function tick(t) -- Background - Draw.clear(math.floor(t * 255)) + Draw.clear(0xFF131300 | math.floor(128 + math.sin(t) * 127)) ---[[ -- Color ARGB, x, y - Draw.pixel(0xFFFF0000, 30, 30) + Draw.pixel(0xFFFF0000, + (math.sin(t) * 0.5 + 0.5) * 1920, + (math.cos(t) * 0.5 + 0.5) * 1080) -- Color ARGB, thickness, x1, y1, x2, y2, xn, yn, ... Draw.line(0xFFFF00FF, 8, 100, 100, 200, 400, 300, 600) --> { Vec2, ... } - -- Color ARGB, thickness, x1, y1, x2, y2, xn, yn, ... - Draw.poly(0xFFFF00FF, 8, 100, 100, 200, 400, 300, 600) --> Rect + -- Color ARGB, x1, y1, x2, y2, xn, yn, ... + Draw.poly(0xFFFF00FF, 100, 100, 200, 400, 150, 500) --> Rect + --[[ -- Color ARGB, radius, x, y, start, end Draw.circle(0xFFFF0000, 20, 300, 300) --> Rect -- Color ARGB, outer, inner, x, y, start, end diff --git a/src/api_draw.c b/src/api_draw.c index 28f4fe7..4f147ab 100644 --- a/src/api_draw.c +++ b/src/api_draw.c @@ -5,10 +5,16 @@ #include int api_draw_clear(lua_State *L); +int api_draw_pixel(lua_State *L); +int api_draw_line(lua_State *L); +int api_draw_poly(lua_State *L); bool loadapi_draw(lua_State *lua) { const struct luaL_Reg api_draw[] = { { "clear", api_draw_clear }, + { "pixel", api_draw_pixel }, + { "line", api_draw_line }, + { "poly", api_draw_poly }, }; lua_newtable(lua); luaL_setfuncs(lua, api_draw, 0); @@ -16,15 +22,88 @@ bool loadapi_draw(lua_State *lua) { return true; } +void argb_to_cairo(int color, double *a, double *r, double *g, double *b) { + int ia = (color >> 24) & 0xFF, + ir = (color >> 16) & 0xFF, + ig = (color >> 8) & 0xFF, + ib = color & 0xFF; + *r = ir / 255.0; + *g = ig / 255.0; + *b = ib / 255.0; + *a = ia / 255.0; +} + int api_draw_clear(lua_State *L) { - printf("Draw.clear()\n"); - int color = luaL_checkinteger(L, 1); - printf("Draw.clear(0x%08x)\n", color); cairo_t *cr = global_context.cairo_context.cairo; - int r = (color >> 16) & 0xFF, - g = (color >> 8) & 0xFF, - b = color & 0xFF; - cairo_set_source_rgb(cr, r / 255.0, g / 255.0, b / 255.0); + int color = luaL_checkinteger(L, 1); + double a, r, g, b; + argb_to_cairo(color, &a, &r, &g, &b); + cairo_set_source_rgba(cr, r, g, b, a); cairo_paint(cr); return 0; } + +int api_draw_pixel(lua_State *L) { + cairo_t *cr = global_context.cairo_context.cairo; + int color = luaL_checkinteger(L, 1); + lua_Number x = luaL_checknumber(L, 2); + lua_Number y = luaL_checknumber(L, 3); + double a, r, g, b; + argb_to_cairo(color, &a, &r, &g, &b); + cairo_set_source_rgba(cr, r, g, b, a); + cairo_rectangle(cr, x, y, 1, 1); + cairo_fill(cr); + return 0; +} + +int api_draw_line(lua_State *L) { + cairo_t *cr = global_context.cairo_context.cairo; + + if (lua_gettop(L) < 6) { + return luaL_error(L, "Not enough arguments: should have at least 2 points"); + } + + int color = luaL_checkinteger(L, 1); + double a, r, g, b; + argb_to_cairo(color, &a, &r, &g, &b); + + lua_Number width = luaL_checknumber(L, 2); + lua_Number x = luaL_checknumber(L, 3); + lua_Number y = luaL_checknumber(L, 4); + + cairo_set_source_rgba(cr, r, g, b, a); + cairo_set_line_width(cr, width); + cairo_move_to(cr, x, y); + for (int i = 5; i <= lua_gettop(L); i += 2) { + x = luaL_checknumber(L, i); + y = luaL_checknumber(L, i + 1); + cairo_line_to(cr, x, y); + } + cairo_stroke(cr); + return 0; +} + +int api_draw_poly(lua_State *L) { + cairo_t *cr = global_context.cairo_context.cairo; + + if (lua_gettop(L) < 7) { + return luaL_error(L, "Not enough arguments: should have at least 3 points"); + } + + int color = luaL_checkinteger(L, 1); + double a, r, g, b; + argb_to_cairo(color, &a, &r, &g, &b); + + lua_Number x = luaL_checknumber(L, 2); + lua_Number y = luaL_checknumber(L, 3); + + cairo_set_source_rgba(cr, r, g, b, a); + cairo_move_to(cr, x, y); + for (int i = 4; i <= lua_gettop(L); i += 2) { + x = luaL_checknumber(L, i); + y = luaL_checknumber(L, i + 1); + cairo_line_to(cr, x, y); + } + cairo_fill(cr); + return 0; +}