diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/include/kogata/draw.h | 22 | ||||
-rw-r--r-- | src/lib/libkogata/draw.c | 148 | ||||
-rw-r--r-- | src/sysbin/lx/lxdrawlib.c | 32 | ||||
-rw-r--r-- | src/syslua/lx/tk.lua | 14 |
4 files changed, 178 insertions, 38 deletions
diff --git a/src/lib/include/kogata/draw.h b/src/lib/include/kogata/draw.h index d96f2ee..7eee2ba 100644 --- a/src/lib/include/kogata/draw.h +++ b/src/lib/include/kogata/draw.h @@ -45,8 +45,6 @@ void g_line(fb_t *fb, int x1, int y1, int x2, int y2, color_t c); void g_rect(fb_t *fb, int x, int y, int w, int h, color_t c); void g_fillrect(fb_t *fb, int x, int y, int w, int h, color_t c); -void g_rectregion(fb_t *fb, fb_region_t reg, color_t c); -void g_fillregion(fb_t *fb, fb_region_t reg, color_t c); void g_circle(fb_t *fb, int cx, int cy, int r, color_t c); void g_fillcircle(fb_t *fb, int cx, int cy, int r, color_t c); @@ -56,6 +54,25 @@ void g_blit_region(fb_t *dst, int x, int y, fb_t *src, fb_region_t reg); void g_scroll_up(fb_t *fb, int l); +// ---- Drawing primitives, in a subregion + +void g_region_plot(fb_t *fb, fb_region_t *reg, int x, int y, color_t c); + +void g_region_hline(fb_t *fb, fb_region_t *reg, int x, int y, int w, color_t c); // horizontal line +void g_region_vline(fb_t *fb, fb_region_t *reg, int x, int y, int h, color_t c); // vertical line +void g_region_line(fb_t *fb, fb_region_t *reg, int x1, int y1, int x2, int y2, color_t c); + +void g_region_rect(fb_t *fb, fb_region_t *reg, int x, int y, int w, int h, color_t c); +void g_region_fillrect(fb_t *fb, fb_region_t *reg, int x, int y, int w, int h, color_t c); + +void g_region_circle(fb_t *fb, fb_region_t *reg, int cx, int cy, int r, color_t c); +void g_region_fillcircle(fb_t *fb, fb_region_t *reg, int cx, int cy, int r, color_t c); + +void g_region_blit(fb_t *dst, fb_region_t *reg, int x, int y, fb_t *src); +void g_region_blit_region(fb_t *dst, fb_region_t *dstreg, int x, int y, fb_t *src, fb_region_t srcreg); + +void g_region_scroll_up(fb_t *fb, fb_region_t *reg, int l); + // ---- Text manipulation font_t *g_load_ascii_bitmap_font(const char* filename); @@ -67,6 +84,7 @@ int g_text_width(font_t *f, const char* text, int size); int g_text_height(font_t *f, const char* text, int size); void g_write(fb_t *fb, int x, int y, const char* text, font_t *font, int size, color_t c); +void g_region_write(fb_t *fb, fb_region_t *reg, int x, int y, const char* text, font_t *font, int size, color_t c); /* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/libkogata/draw.c b/src/lib/libkogata/draw.c index 14f1dcf..4e5dcf2 100644 --- a/src/lib/libkogata/draw.c +++ b/src/lib/libkogata/draw.c @@ -112,7 +112,7 @@ color_t g_color_rgb(fb_t *f, uint8_t r, uint8_t g, uint8_t b) { return 0; // unknown? } -// ---- Plot +// ---- Drawing functions static inline void g_plot24(uint8_t* p, color_t c) { p[0] = c & 0xFF; @@ -120,7 +120,11 @@ static inline void g_plot24(uint8_t* p, color_t c) { p[2] = (c >> 16) & 0xFF; } -void g_plot(fb_t *fb, int x, int y, color_t c) { +// # Plot # + +inline void g_plot(fb_t *fb, int x, int y, color_t c) { + if (x < 0 || y < 0 || x >= fb->geom.width || y >= fb->geom.height) return; + if (fb->geom.bpp == 8) { fb->data[y * fb->geom.pitch + x] = (c & 0xFF); } else if (fb->geom.bpp == 15 || fb->geom.bpp == 16) { @@ -134,7 +138,22 @@ void g_plot(fb_t *fb, int x, int y, color_t c) { } } -void g_hline(fb_t *fb, int x, int y, int w, color_t c) { +inline void g_region_plot(fb_t *fb, fb_region_t *reg, int x, int y, color_t c) { + if (x < 0 || y < 0 || x >= reg->w || y >= reg->h) return; + g_plot(fb, x + reg->x, y + reg->y, c); +} + + +// # Horizontal line # + +inline void g_hline(fb_t *fb, int x, int y, int w, color_t c) { + if (x < 0) w = w + x, x = 0; + if (x >= fb->geom.width) return; + if (x + w < 0) return; + if (x + w > fb->geom.width) w = fb->geom.width - x; + if (y < 0 || y >= fb->geom.height) return; + if (w <= 0) return; + if (fb->geom.bpp == 8) { for (int u = x; u < x + w; u++) { fb->data[y * fb->geom.pitch + u] = (c & 0xFF); @@ -151,12 +170,33 @@ void g_hline(fb_t *fb, int x, int y, int w, color_t c) { } else if (fb->geom.bpp == 32) { for (int u = x; u < x + w; u++) { uint32_t *p = (uint32_t*)(fb->data + y * fb->geom.pitch + 4 * u); - *p = c; + *p = c | 0xFF000000; // alpha = 0xFF } } } -void g_vline(fb_t *fb, int x, int y, int h, color_t c) { +inline void g_region_hline(fb_t *fb, fb_region_t *reg, int x, int y, int w, color_t c) { + if (x < 0) w = w + x, x = 0; + if (x >= reg->w) return; + if (x + w < 0) return; + if (x + w > reg->w) w = reg->w - x; + if (y < 0 || y >= reg->h) return; + if (w <= 0) return; + + g_hline(fb, reg->x + x, reg->y + y, w, c); +} + + +// # Vertical line # + +inline void g_vline(fb_t *fb, int x, int y, int h, color_t c) { + if (y < 0) h = h + y, y = 0; + if (y >= fb->geom.height) return; + if (y + h < 0) return; + if (y + h > fb->geom.width) h = fb->geom.height - y; + if (x < 0 || x >= fb->geom.width) return; + if (h <= 0) return; + if (fb->geom.bpp == 8) { for (int v = y; v < y + h; v++) { fb->data[v * fb->geom.pitch + x] = (c & 0xFF); @@ -178,10 +218,31 @@ void g_vline(fb_t *fb, int x, int y, int h, color_t c) { } } +inline void g_region_vline(fb_t *fb, fb_region_t *reg, int x, int y, int h, color_t c) { + if (y < 0) h = h + y, y = 0; + if (y >= reg->h) return; + if (y + h < 0) return; + if (y + h > reg->h) h = reg->h - y; + if (x < 0 || x >= reg->h) return; + if (h <= 0) return; + + g_vline(fb, reg->x + x, reg->y + y, h, c); +} + + +// # Line # + void g_line(fb_t *fb, int x1, int y1, int x2, int y2, color_t c) { // TODO } +void g_region_line(fb_t *fb, fb_region_t *reg, int x1, int y1, int x2, int y2, color_t c) { + // TODO +} + + +// # Rectangle # + void g_rect(fb_t *fb, int x, int y, int w, int h, color_t c) { g_hline(fb, x, y, w, c); g_hline(fb, x, y+h-1, w, c); @@ -189,7 +250,25 @@ void g_rect(fb_t *fb, int x, int y, int w, int h, color_t c) { g_vline(fb, x+w-1, y, h, c); } +void g_region_rect(fb_t *fb, fb_region_t *reg, int x, int y, int w, int h, color_t c) { + g_region_hline(fb, reg, x, y, w, c); + g_region_hline(fb, reg, x, y+h-1, w, c); + g_region_vline(fb, reg, x, y, h, c); + g_region_vline(fb, reg, x+w-1, y, h, c); +} + + +// # Filled rectangle # + void g_fillrect(fb_t *fb, int x, int y, int w, int h, color_t c) { + if (x < 0) w = w + x, x = 0; + if (y < 0) h = h + y, y = 0; + + if (x + w > fb->geom.width) w = fb->geom.width - x; + if (y + h > fb->geom.height) h = fb->geom.height - y; + + if (w <= 0 || h <= 0) return; + if (fb->geom.bpp == 8) { for (int v = y; v < y + h; v++) { for (int u = x; u < x + w; u++) { @@ -219,22 +298,43 @@ void g_fillrect(fb_t *fb, int x, int y, int w, int h, color_t c) { } } -void g_rectregion(fb_t *fb, fb_region_t reg, color_t c) { - g_rect(fb, reg.x, reg.y, reg.w, reg.h, c); -} +void g_region_fillrect(fb_t *fb, fb_region_t *reg, int x, int y, int w, int h, color_t c) { + if (x < 0) w = w + x, x = 0; + if (y < 0) h = h + y, y = 0; + + if (x + w > reg->w) w = reg->w - x; + if (y + h > reg->h) h = reg->h - y; -void g_fillregion(fb_t *fb, fb_region_t reg, color_t c) { - g_fillrect(fb, reg.x, reg.y, reg.w, reg.h, c); + if (w <= 0 || h <= 0) return; + + g_fillrect(fb, x + reg->x, y + reg->y, w, h, c); } + +// # Circle # + void g_circle(fb_t *fb, int cx, int cy, int r, color_t c) { // TODO } +void g_region_circle(fb_t *fb, fb_region_t *reg, int cx, int cy, int r, color_t c) { + // TODO +} + + +// # Filled circle # + void g_fillcircle(fb_t *fb, int cx, int cy, int r, color_t c) { // TODO } +void g_region_fillcircle(fb_t *fb, fb_region_t *reg, int cx, int cy, int r, color_t c) { + // TODO +} + + +// # Blit # + void g_blit(fb_t *dst, int x, int y, fb_t *src) { fb_region_t r; @@ -246,6 +346,17 @@ void g_blit(fb_t *dst, int x, int y, fb_t *src) { g_blit_region(dst, x, y, src, r); } +void g_region_blit(fb_t *dst, fb_region_t *reg, int x, int y, fb_t *src) { + fb_region_t r; + + r.x = 0; + r.y = 0; + r.w = src->geom.width; + r.h = src->geom.height; + + g_region_blit_region(dst, reg, x, y, src, r); +} + void g_blit_region(fb_t *dst, int x, int y, fb_t *src, fb_region_t reg) { if (x < 0 || y < 0 || reg.x < 0 || reg.y < 0 || reg.w < 0 || reg.h < 0) return; // invalid argument @@ -311,6 +422,15 @@ void g_blit_region(fb_t *dst, int x, int y, fb_t *src, fb_region_t reg) { } } +void g_region_blit_region(fb_t *dst, fb_region_t *reg, int x, int y, fb_t *src, fb_region_t r) { + if (x + r.w > reg->w) r.w = reg->w - x; + if (y + r.h > reg->h) r.h = reg->h - y; + + g_blit_region(dst, x + reg->x, y + reg->y, src, r); +} + +// # Scroll # + void g_scroll_up(fb_t *dst, int l) { for (int y = 0; y < dst->geom.height - l; y++) { memcpy(dst->data + y * dst->geom.pitch, @@ -319,6 +439,10 @@ void g_scroll_up(fb_t *dst, int l) { } } +void g_region_scroll_up(fb_t *fb, fb_region_t *reg, int l) { + // TODO +} + // ---- Text manipulation #define FONT_ASCII_BITMAP 1 @@ -562,5 +686,9 @@ void g_write(fb_t *fb, int x, int y, const char* text, font_t *font, int size, c } } +void g_region_write(fb_t *fb, fb_region_t *reg, int x, int y, const char* text, font_t *font, int size, color_t c) { + // TODO +} + /* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/sysbin/lx/lxdrawlib.c b/src/sysbin/lx/lxdrawlib.c index 1a24fcb..d41942c 100644 --- a/src/sysbin/lx/lxdrawlib.c +++ b/src/sysbin/lx/lxdrawlib.c @@ -288,14 +288,15 @@ static int surface_rgb(lua_State *L) { return 1; } +// ############################# DRAWING PRIMITIVES ############## + static int surface_plot(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); color_t c = (color_t)lx_checklightudata(L, 4); - // TODO: relative to subregion! - g_plot(s->fb, x, y, c); + g_region_plot(s->fb, &s->subregion, x, y, c); return 0; } @@ -306,8 +307,7 @@ static int surface_hline(lua_State *L) { 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); + g_region_hline(s->fb, &s->subregion, x, y, w, c); return 0; } @@ -318,8 +318,7 @@ static int surface_vline(lua_State *L) { 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); + g_region_vline(s->fb, &s->subregion, x, y, h, c); return 0; } @@ -331,8 +330,7 @@ static int surface_line(lua_State *L) { 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); + g_region_line(s->fb, &s->subregion, x, y, x2, y2, c); return 0; } @@ -344,8 +342,7 @@ static int surface_rect(lua_State *L) { 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); + g_region_rect(s->fb, &s->subregion, x, y, w, h, c); return 0; } @@ -357,8 +354,7 @@ static int surface_fillrect(lua_State *L) { 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); + g_region_fillrect(s->fb, &s->subregion, x, y, w, h, c); return 0; } @@ -369,8 +365,7 @@ static int surface_circle(lua_State *L) { int r = luaL_checkinteger(L, 4); color_t c = (color_t)lx_checklightudata(L, 5); - // TODO: relative to subregion! - g_circle(s->fb, x, y, r, c); + g_region_circle(s->fb, &s->subregion, x, y, r, c); return 0; } @@ -381,8 +376,7 @@ static int surface_fillcircle(lua_State *L) { int r = luaL_checkinteger(L, 4); color_t c = (color_t)lx_checklightudata(L, 5); - // TODO: relative to subregion! - g_fillcircle(s->fb, x, y, r, c); + g_region_fillcircle(s->fb, &s->subregion, x, y, r, c); return 0; } @@ -392,8 +386,7 @@ static int surface_blit(lua_State *L) { int y = luaL_checkinteger(L, 3); drawlib_surface *s2 = (drawlib_surface*)luaL_checkudata(L, 4, SURFACE); - // TODO: relative to subregion! - g_blit_region(s->fb, x, y, s2->fb, s2->subregion); + g_region_blit_region(s->fb, &s->subregion, x, y, s2->fb, s2->subregion); return 0; } @@ -406,8 +399,7 @@ static int surface_write(lua_State *L) { int size = luaL_checkinteger(L, 6); color_t c = (color_t)lx_checklightudata(L, 7); - // TODO: relative to subregion! - g_write(s->fb, x, y, text, f->font, size, c); + g_region_write(s->fb, &s->subregion, x, y, text, f->font, size, c); return 0; } diff --git a/src/syslua/lx/tk.lua b/src/syslua/lx/tk.lua index 0b0c69c..3771748 100644 --- a/src/syslua/lx/tk.lua +++ b/src/syslua/lx/tk.lua @@ -79,12 +79,14 @@ function tk.image_widget(img) local buf = self:get_draw_buffer(x0, y0, w, h) if buf == nil then return end - for x = x0 - (x0 % 32), x0 + w, 32 do - for y = y0 - (y0 % 32), y0 + h, 32 do - buf:fillrect(x - x0, y - y0, 16, 16, buf:rgb(150, 150, 150)) - buf:fillrect(x - x0 + 16, y - y0 + 16, 16, 16, buf:rgb(150, 150, 150)) - buf:fillrect(x - x0 + 16, y - y0, 16, 16, buf:rgb(200, 200, 200)) - buf:fillrect(x - x0, y - y0 + 16, 16, 16, buf:rgb(200, 200, 200)) + local step = 20 + local halfstep = 10 + for x = x0 - (x0 % step), x0 + w, step do + for y = y0 - (y0 % step), y0 + h, step do + buf:fillrect(x - x0, y - y0, halfstep, halfstep, buf:rgb(150, 150, 150)) + buf:fillrect(x - x0 + halfstep, y - y0 + halfstep, halfstep, halfstep, buf:rgb(150, 150, 150)) + buf:fillrect(x - x0 + halfstep, y - y0, halfstep, halfstep, buf:rgb(170, 170, 170)) + buf:fillrect(x - x0, y - y0 + halfstep, halfstep, halfstep, buf:rgb(170, 170, 170)) end end buf:blit(0, 0, self.img:sub(x0, y0, self.img:width(), self.img:height())) |