From bb97e8aaa15217afe1f3fcdc93662ab03b8ae9d9 Mon Sep 17 00:00:00 2001 From: Tomasz Kramkowski Date: Thu, 11 Feb 2021 12:15:12 +0000 Subject: init commit --- window.c | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 window.c (limited to 'window.c') diff --git a/window.c b/window.c new file mode 100644 index 0000000..314d589 --- /dev/null +++ b/window.c @@ -0,0 +1,179 @@ +#include +#include +#include +#include +#include + +#include "window.h" +#include "sdl.h" + +#define UD_WINDOW "libluiml.window" + +struct window { + SDL_Window *win; + SDL_Renderer *ren; + PangoContext *pc; +}; + +/* window:destroy_window() */ +static int destroy_window(lua_State *L) +{ + struct window *w; + + w = luaL_checkudata(L, 1, UD_WINDOW); + SDL_DestroyWindow(w->win); + g_object_unref(w->pc); + + release_sdl(); + + return 0; +} + +#include "window_wait_event.c" + +/* window:get_dimensions() -> width, height */ +static int get_dimensions(lua_State *L) +{ + struct window *w; + int width, height; + + w = luaL_checkudata(L, 1, UD_WINDOW); + + SDL_GetWindowSize(w->win, &width, &height); + + lua_pushnumber(L, width); + lua_pushnumber(L, height); + + return 2; +} + +double clamp(double v, double min, double max) +{ + if (v < min) return min; + if (v > max) return max; + return v; +} + +/* window:draw_rect(x, y, width, height, r, g, b) */ +static int draw_rect(lua_State *L) +{ + struct window *w; + SDL_Rect r; + struct { + Uint8 r, g, b; + } colour; + + w = luaL_checkudata(L, 1, UD_WINDOW); + r.x = luaL_checknumber(L, 2); + r.y = luaL_checknumber(L, 3); + r.w = luaL_checknumber(L, 4); + r.h = luaL_checknumber(L, 5); + colour.r = round(clamp(luaL_checknumber(L, 6), 0, 1) * 255.0); + colour.g = round(clamp(luaL_checknumber(L, 7), 0, 1) * 255.0); + colour.b = round(clamp(luaL_checknumber(L, 8), 0, 1) * 255.0); + + SDL_SetRenderDrawColor(w->ren, colour.r, colour.g, colour.b, SDL_ALPHA_OPAQUE); + SDL_RenderFillRect(w->ren, &r); + + return 0; +} + +static int draw_text(lua_State *L) +{ + PangoRectangle extents; + PangoLayout *layout; + int width, height; + struct window *w; + const char *s; + SDL_Rect r; + size_t l; + + w = luaL_checkudata(L, 1, UD_WINDOW); + r.x = luaL_checknumber(L, 2); + r.y = luaL_checknumber(L, 3); + r.w = luaL_checknumber(L, 4); + r.h = luaL_checknumber(L, 5); + s = luaL_checklstring(L, 6, &l); + + layout = pango_layout_new(w->pc); + pango_layout_set_width(layout, r.w * PANGO_SCALE); + pango_layout_set_height(layout, r.h * PANGO_SCALE); + pango_layout_set_text(layout, s, l); + pango_layout_get_extents(layout, NULL, &extents); + width = PANGO_PIXELS(extents.width); + height = PANGO_PIXELS(extents.height); + + return 0; +} + +static int show(lua_State *L) +{ + struct window *w; + + w = luaL_checkudata(L, 1, UD_WINDOW); + + SDL_RenderPresent(w->ren); + + return 0; +} + +/* create_window(title) -> window */ +int create_window(lua_State *L) +{ + static const struct luaL_Reg window_metatable[] = { + {"__gc", destroy_window}, + {"wait_event", wait_event}, + {"get_dimensions", get_dimensions}, + {"draw_rect", draw_rect}, + {"draw_text", draw_text}, + {"show", show}, + {NULL, NULL}, + }; + PangoFontMap *fontmap; + const char *title, *failed; + struct window *w; + + if (luaL_newmetatable(L, UD_WINDOW)) { + lua_pushstring(L, "__index"); + lua_pushvalue(L, -2); + lua_settable(L, -3); + luaL_register(L, NULL, window_metatable); + lua_pop(L, 1); + } + + title = luaL_checkstring(L, 1); + + acquire_sdl(); + + w = lua_newuserdata(L, sizeof *w); + w->win = SDL_CreateWindow(title, + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + 640, 480, SDL_WINDOW_RESIZABLE); + + if (w->win == NULL) { + failed = "SDL_CreateWindow"; + goto fail_win; + } + + w->ren = SDL_CreateRenderer(w->win, 0, SDL_RENDERER_PRESENTVSYNC); + + if (w->ren == NULL) { + failed = "SDL_CreateRenderer"; + goto fail_ren; + } + + + fontmap = pango_ft2_font_map_new(); + w->pc = pango_font_map_create_context(fontmap); + g_object_unref(fontmap); + + luaL_getmetatable(L, UD_WINDOW); + lua_setmetatable(L, -2); + + return 1; + +fail_ren: SDL_DestroyWindow(w->win); +fail_win: release_sdl(); + return sdl_error(L, failed); +} -- cgit v1.2.3-54-g00ecf