lite-xl/src/api/renderer.c

162 lines
4.3 KiB
C

#include "api.h"
#include "renderer.h"
#include "rencache.h"
extern RenCache *window_rencache;
static RenColor checkcolor(lua_State *L, int idx, int def) {
RenColor color;
if (lua_isnoneornil(L, idx)) {
return (RenColor) { def, def, def, 255 };
}
lua_rawgeti(L, idx, 1);
lua_rawgeti(L, idx, 2);
lua_rawgeti(L, idx, 3);
lua_rawgeti(L, idx, 4);
color.r = luaL_checknumber(L, -4);
color.g = luaL_checknumber(L, -3);
color.b = luaL_checknumber(L, -2);
color.a = luaL_optnumber(L, -1, 255);
lua_pop(L, 4);
return color;
}
static RenCache *opt_rencache_arg(lua_State *L, int *index) {
RenCache *rencache;
if (lua_touserdata(L, 1)) {
return luaL_checkudata(L, *(index++), API_TYPE_RENCACHE);
}
return window_rencache;
}
static int f_show_debug(lua_State *L) {
int index = 1;
RenCache *rencache = opt_rencache_arg(L, &index);
luaL_checkany(L, index);
rencache_show_debug(rencache, lua_toboolean(L, index));
return 0;
}
static int f_get_size(lua_State *L) {
int w, h;
ren_get_size(window_ren_surface, &w, &h);
lua_pushnumber(L, w);
lua_pushnumber(L, h);
return 2;
}
static int f_begin_frame(lua_State *L) {
int index = 1;
RenCache *rencache = opt_rencache_arg(L, &index);
rencache_begin_frame(rencache, window_ren_surface, L);
return 0;
}
static int f_end_frame(lua_State *L) {
int index = 1;
RenCache *rencache = opt_rencache_arg(L, &index);
rencache_end_frame(rencache, L);
return 0;
}
static int f_set_clip_rect(lua_State *L) {
RenRect rect;
int index = 1;
RenCache *rencache = opt_rencache_arg(L, &index);
rect.x = luaL_checknumber(L, index);
rect.y = luaL_checknumber(L, index + 1);
rect.width = luaL_checknumber(L, index + 2);
rect.height = luaL_checknumber(L, index + 3);
rencache_set_clip_rect(rencache, rect);
return 0;
}
static int f_draw_rect(lua_State *L) {
RenRect rect;
int index = 1;
RenCache *rencache = opt_rencache_arg(L, &index);
rect.x = luaL_checknumber(L, index);
rect.y = luaL_checknumber(L, index + 1);
rect.width = luaL_checknumber(L, index + 2);
rect.height = luaL_checknumber(L, index + 3);
RenColor color = checkcolor(L, index + 4, 255);
rencache_draw_rect(rencache, rect, color);
return 0;
}
static int draw_text_subpixel_impl(lua_State *L, bool draw_subpixel) {
int index = 1;
RenCache *rencache = opt_rencache_arg(L, &index);
FontDesc *font_desc = luaL_checkudata(L, index, API_TYPE_FONT);
const char *text = luaL_checkstring(L, index + 1);
/* The coordinate below will be in subpixel iff draw_subpixel is true.
Otherwise it will be in pixels. */
int x_subpixel = luaL_checknumber(L, index + 2);
int y = luaL_checknumber(L, index + 3);
RenColor color = checkcolor(L, index + 4, 255);
CPReplaceTable *rep_table;
RenColor replace_color;
if (lua_gettop(L) >= index + 6) {
rep_table = luaL_checkudata(L, index + 5, API_TYPE_REPLACE);
replace_color = checkcolor(L, index + 6, 255);
} else {
rep_table = NULL;
replace_color = (RenColor) {0};
}
x_subpixel = rencache_draw_text(rencache, L, font_desc, 1, text, x_subpixel, y, color, draw_subpixel, rep_table, replace_color);
lua_pushnumber(L, x_subpixel);
return 1;
}
static int f_draw_text(lua_State *L) {
return draw_text_subpixel_impl(L, false);
}
static int f_draw_text_subpixel(lua_State *L) {
return draw_text_subpixel_impl(L, true);
}
static const luaL_Reg lib[] = {
{ "show_debug", f_show_debug },
{ "get_size", f_get_size },
{ "begin_frame", f_begin_frame },
{ "end_frame", f_end_frame },
{ "set_clip_rect", f_set_clip_rect },
{ "draw_rect", f_draw_rect },
{ "draw_text", f_draw_text },
{ "draw_text_subpixel", f_draw_text_subpixel },
{ NULL, NULL }
};
int luaopen_renderer_font(lua_State *L);
int luaopen_renderer_replacements(lua_State *L);
int luaopen_renderer(lua_State *L) {
luaL_newlib(L, lib);
window_rencache = lua_newuserdata(L, sizeof(RenCache));
rencache_init(window_rencache);
luaL_setmetatable(L, API_TYPE_RENCACHE);
lua_pushvalue(L, -1);
luaL_ref(L, -1);
lua_setfield(L, -2, "window");
luaopen_renderer_font(L);
lua_setfield(L, -2, "font");
luaopen_renderer_replacements(L);
lua_setfield(L, -2, "replacements");
return 1;
}