aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2017-05-04 12:33:41 +0200
committerAlex Auvolat <alex@adnab.me>2017-05-04 12:33:41 +0200
commit7a3ab21a27c34033fbe478d68957be8e31f983a2 (patch)
tree373ae85054fbfe1b71dc6b269d78f89dacbffe35
parent9bb1c5371affb2ff0b83256470dec7461b404264 (diff)
downloadkogata-7a3ab21a27c34033fbe478d68957be8e31f983a2.tar.gz
kogata-7a3ab21a27c34033fbe478d68957be8e31f983a2.zip
Drawing in subregion
-rw-r--r--src/lib/include/kogata/draw.h22
-rw-r--r--src/lib/libkogata/draw.c148
-rw-r--r--src/sysbin/lx/lxdrawlib.c32
-rw-r--r--src/syslua/lx/tk.lua14
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()))