aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lib/include/kogata/draw.h3
-rw-r--r--src/lib/libkogata/draw.c20
-rw-r--r--src/sysapp/login/main.lua26
-rw-r--r--src/sysbin/lx/lxdrawlib.c178
4 files changed, 207 insertions, 20 deletions
diff --git a/src/lib/include/kogata/draw.h b/src/lib/include/kogata/draw.h
index d00036f..d8a2e13 100644
--- a/src/lib/include/kogata/draw.h
+++ b/src/lib/include/kogata/draw.h
@@ -57,7 +57,8 @@ void g_scroll_up(fb_t *fb, int l);
// ---- Text manipulation
font_t *g_load_font(const char* fontname);
-void g_free_font(font_t *f);
+void g_incref_font(font_t *f);
+void g_decref_font(font_t *f);
int g_text_width(font_t *f, const char* text);
int g_text_height(font_t *f, const char* text);
diff --git a/src/lib/libkogata/draw.c b/src/lib/libkogata/draw.c
index d9a4268..29cae31 100644
--- a/src/lib/libkogata/draw.c
+++ b/src/lib/libkogata/draw.c
@@ -244,6 +244,7 @@ typedef struct font {
uint32_t nchars;
} ascii_bitmap;
};
+ int nrefs;
} font_t;
font_t *g_load_ascii_bitmap_font(fd_t f) {
@@ -272,6 +273,8 @@ font_t *g_load_ascii_bitmap_font(fd_t f) {
size_t rd = sc_read(f, sizeof(h), h.ch * h.nchars, (char*)font->ascii_bitmap.data);
if (rd != h.ch * h.nchars) goto error;
+ font->nrefs = 1;
+
return font;
error:
@@ -291,12 +294,19 @@ font_t *g_load_font(const char* fontname) {
return 0;
}
-void g_free_font(font_t *f) {
- if (f->type == FONT_ASCII_BITMAP) {
- free(f->ascii_bitmap.data);
- }
+void g_incref_font(font_t *f) {
+ f->nrefs++;
+}
- free(f);
+void g_decref_font(font_t *f) {
+ f->nrefs--;
+
+ if (f->nrefs == 0) {
+ if (f->type == FONT_ASCII_BITMAP) {
+ free(f->ascii_bitmap.data);
+ }
+ free(f);
+ }
}
int g_text_width(font_t *font, const char* text) {
diff --git a/src/sysapp/login/main.lua b/src/sysapp/login/main.lua
index 50ecd20..0c54769 100644
--- a/src/sysapp/login/main.lua
+++ b/src/sysapp/login/main.lua
@@ -18,15 +18,35 @@ for x = 0, 255 do
end
end
+local fnt = draw.load_font('default')
+
local i = 1
while true do
- surface:plot(i % (vesa_info.width-3),
- i % (vesa_info.height-1),
+ surface:rect((i*3) % (vesa_info.width-3),
+ (i*3) % (vesa_info.height-5),
+ 3, 3,
surface:rgb(i % 256,
(i + 96) % 256,
(i + 2*96) % 256))
i = i + 1
- if i % 100000 == 0 then print(i) end
+ if i % 10000 == 0 then
+ local x0 = math.random(vesa_info.width)-1
+ local x1 = math.random(vesa_info.width)-1
+ local y0 = math.random(vesa_info.height)-1
+ local y1 = math.random(vesa_info.height)-1
+ if x0 > x1 then x0, x1 = x1, x0 end
+ if y0 > y1 then y0, y1 = y1, y0 end
+ local c = surface:rgb(math.random(0, 255), math.random(0, 255), math.random(0, 255))
+ surface:fillrect(x0, y0, x1-x0, y1-y0, c)
+ end
+ if i % 10000 == 0 then
+ print(i)
+ local txt = tostring(i)
+ surface:fillrect(0, 0, fnt:text_width(txt),
+ fnt:text_height(txt),
+ surface:rgb(0, 0, 0))
+ surface:write(0, 0, txt, fnt, surface:rgb(255, 0, 0))
+ end
end
os.exit()
diff --git a/src/sysbin/lx/lxdrawlib.c b/src/sysbin/lx/lxdrawlib.c
index 71c9819..91bf07f 100644
--- a/src/sysbin/lx/lxdrawlib.c
+++ b/src/sysbin/lx/lxdrawlib.c
@@ -1,5 +1,5 @@
/*
-** Lua eXtended ioctl library
+** Lua eXtended draw library
*/
#define lxdrawlib_c
@@ -25,6 +25,12 @@
typedef struct {
+ font_t *font;
+} drawlib_font;
+
+#define FONT "lx.draw.font"
+
+typedef struct {
fb_t *fb;
fb_region_t subregion;
bool has_subregion;
@@ -32,6 +38,57 @@ typedef struct {
#define SURFACE "lx.draw.surface"
+// ====================================================================
+// FONTS
+
+static int draw_loadfont(lua_State *L) {
+ const char* name = luaL_checkstring(L, 1);
+ font_t *f = g_load_font(name);
+ if (f == NULL) {
+ lua_pushnil(L);
+ return 1;
+ }
+
+ drawlib_font *ff = (drawlib_font*)lua_newuserdata(L, sizeof(drawlib_font));
+ luaL_getmetatable(L, FONT);
+ lua_setmetatable(L, -2);
+
+ ff->font = f;
+
+ return 1;
+}
+
+static int font_gc(lua_State *L) {
+ drawlib_font *f = (drawlib_font*)luaL_checkudata(L, 1, FONT);
+
+ if(f->font == NULL) {
+ luaL_error(L, "f->font == NULL ?");
+ }
+ g_decref_font(f->font);
+ f->font = NULL;
+
+ return 0;
+}
+
+static int font_text_width(lua_State *L) {
+ drawlib_font *f = (drawlib_font*)luaL_checkudata(L, 1, FONT);
+ const char* txt = luaL_checkstring(L, 2);
+
+ lua_pushinteger(L, g_text_width(f->font, txt));
+ return 1;
+}
+
+static int font_text_height(lua_State *L) {
+ drawlib_font *f = (drawlib_font*)luaL_checkudata(L, 1, FONT);
+ const char* txt = luaL_checkstring(L, 2);
+
+ lua_pushinteger(L, g_text_height(f->font, txt));
+ return 1;
+}
+
+// ====================================================================
+// SURFACES
+
static int draw_from_fd(lua_State *L) {
int fd = luaL_checkinteger(L, 1);
luaL_checktype(L, 2, LUA_TTABLE);
@@ -43,20 +100,22 @@ static int draw_from_fd(lua_State *L) {
geom.pitch = getintfield(L, 2, "pitch");
geom.memory_model = getintfield(L, 2, "memory_model");
+ fb_t *fb = g_fb_from_file(fd, &geom);
+ if (fb == NULL) {
+ lua_pushnil(L);
+ return 1;
+ }
+
drawlib_surface *s = (drawlib_surface*)lua_newuserdata(L, sizeof(drawlib_surface));
luaL_getmetatable(L, SURFACE);
lua_setmetatable(L, -2);
- s->fb = g_fb_from_file(fd, &geom);
- if (s->fb == NULL) {
- lua_pop(L, 1);
- lua_pushnil(L);
- } else {
- s->subregion.x = s->subregion.y = 0;
- s->subregion.w = geom.width;
- s->subregion.h = geom.height;
- s->has_subregion = false;
- }
+ s->fb = fb;
+ s->subregion.x = s->subregion.y = 0;
+ s->subregion.w = geom.width;
+ s->subregion.h = geom.height;
+ s->has_subregion = false;
+
return 1;
}
@@ -124,14 +183,92 @@ static int surface_plot(lua_State *L) {
int y = luaL_checkinteger(L, 3);
color_t c = (color_t)lx_checklightudata(L, 4);
+ // TODO: relative to subregion!
g_plot(s->fb, x, y, c);
return 0;
}
+static int surface_hline(lua_State *L) {
+ drawlib_surface *s = (drawlib_surface*)luaL_checkudata(L, 1, SURFACE);
+ int x = luaL_checkinteger(L, 2);
+ int y = luaL_checkinteger(L, 3);
+ int w = luaL_checkinteger(L, 4);
+ color_t c = (color_t)lx_checklightudata(L, 5);
+
+ // TODO: relative to subregion!
+ g_hline(s->fb, x, y, w, c);
+ return 0;
+}
+
+static int surface_vline(lua_State *L) {
+ drawlib_surface *s = (drawlib_surface*)luaL_checkudata(L, 1, SURFACE);
+ int x = luaL_checkinteger(L, 2);
+ int y = luaL_checkinteger(L, 3);
+ int h = luaL_checkinteger(L, 4);
+ color_t c = (color_t)lx_checklightudata(L, 5);
+
+ // TODO: relative to subregion!
+ g_vline(s->fb, x, y, h, c);
+ return 0;
+}
+
+static int surface_line(lua_State *L) {
+ drawlib_surface *s = (drawlib_surface*)luaL_checkudata(L, 1, SURFACE);
+ int x = luaL_checkinteger(L, 2);
+ int y = luaL_checkinteger(L, 3);
+ int x2 = luaL_checkinteger(L, 4);
+ int y2 = luaL_checkinteger(L, 5);
+ color_t c = (color_t)lx_checklightudata(L, 6);
+
+ // TODO: relative to subregion!
+ g_line(s->fb, x, y, x2, y2, c);
+ return 0;
+}
+
+static int surface_rect(lua_State *L) {
+ drawlib_surface *s = (drawlib_surface*)luaL_checkudata(L, 1, SURFACE);
+ int x = luaL_checkinteger(L, 2);
+ int y = luaL_checkinteger(L, 3);
+ int w = luaL_checkinteger(L, 4);
+ int h = luaL_checkinteger(L, 5);
+ color_t c = (color_t)lx_checklightudata(L, 6);
+
+ // TODO: relative to subregion!
+ g_rect(s->fb, x, y, w, h, c);
+ return 0;
+}
+
+static int surface_fillrect(lua_State *L) {
+ drawlib_surface *s = (drawlib_surface*)luaL_checkudata(L, 1, SURFACE);
+ int x = luaL_checkinteger(L, 2);
+ int y = luaL_checkinteger(L, 3);
+ int w = luaL_checkinteger(L, 4);
+ int h = luaL_checkinteger(L, 5);
+ color_t c = (color_t)lx_checklightudata(L, 6);
+
+ // TODO: relative to subregion!
+ g_fillrect(s->fb, x, y, w, h, c);
+ return 0;
+}
+
+static int surface_write(lua_State *L) {
+ drawlib_surface *s = (drawlib_surface*)luaL_checkudata(L, 1, SURFACE);
+ int x = luaL_checkinteger(L, 2);
+ int y = luaL_checkinteger(L, 3);
+ const char *text = luaL_checkstring(L, 4);
+ drawlib_font *f = (drawlib_font*)luaL_checkudata(L, 5, FONT);
+ color_t c = (color_t)lx_checklightudata(L, 6);
+
+ // TODO: relative to subregion!
+ g_write(s->fb, x, y, text, f->font, c);
+ return 0;
+}
+
/* }====================================================== */
static const luaL_Reg drawlib[] = {
{"from_fd", draw_from_fd},
+ {"load_font", draw_loadfont},
{NULL, NULL}
};
@@ -139,10 +276,23 @@ static const luaL_Reg surface_meta[] = {
{"sub", surface_sub},
{"rgb", surface_rgb},
{"plot", surface_plot},
+ {"hline", surface_hline},
+ {"vline", surface_vline},
+ {"line", surface_line},
+ {"rect", surface_rect},
+ {"fillrect", surface_fillrect},
+ {"write", surface_write},
{"__gc", surface_gc},
{NULL, NULL}
};
+static const luaL_Reg font_meta[] = {
+ {"text_width", font_text_width},
+ {"text_height", font_text_height},
+ {"__gc", font_gc},
+ {NULL, NULL}
+};
+
LUAMOD_API int lx_open_draw (lua_State *L) {
luaL_newlib(L, drawlib);
@@ -153,6 +303,12 @@ LUAMOD_API int lx_open_draw (lua_State *L) {
lua_setfield(L, -2, "__index");
lua_pop(L, 1);
+ luaL_newmetatable(L, FONT);
+ luaL_setfuncs(L, font_meta, 0);
+ lua_pushvalue(L, -1);
+ lua_setfield(L, -2, "__index");
+ lua_pop(L, 1);
+
return 1;
}