simple library for fancy terminal io based on termbox
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

218 lines
4.7 KiB

/* termbox utils
*
* Utility functions for use with termbox
*
* Gunnar Zötl <gz@tset.de>, 2015
* Released under the terms of the MIT license. See file LICENSE for details.
*/
#include <string.h>
#include <stdlib.h>
#include "termbox.h"
#include "tbutils.h"
void tbu_blitbuffer(struct tb_cell *to, int tw, int th, int x, int y, const struct tb_cell *from, int w, int h)
{
if (x + w < 0 || x >= tw || w <= 0)
return;
if (y + h < 0 || y >= th || h <= 0)
return;
int xo = 0, yo = 0, ww = w, hh = h;
if (x < 0) {
xo = -x;
ww -= xo;
x = 0;
}
if (y < 0) {
yo = -y;
hh -= yo;
y = 0;
}
if (ww > tw - x) {
ww = tw - x;
}
if (hh > th - y) {
hh = th - y;
}
int sy;
struct tb_cell *dst = &CELL(to, tw, x, y);
const struct tb_cell *src = from + yo * w + xo;
size_t size = sizeof(struct tb_cell) * ww;
for (sy = 0; sy < hh; ++sy) {
memcpy(dst, src, size);
dst += tw;
src += w;
}
}
void tbu_blit(int x, int y, const struct tb_cell *from, int w, int h)
{
int bbw = tb_width();
int bbh = tb_height();
struct tb_cell *bb = tb_cell_buffer();
tbu_blitbuffer(bb, bbw, bbh, x, y, from, w, h);
}
void tbu_fillbufferregion(struct tb_cell *buf, int bw, int bh, int x, int y, int w, int h, const struct tb_cell *fill)
{
if (x + w < 0 || x >= bw || w <= 0)
return;
if (y + h < 0 || y >= bh || h <= 0)
return;
if (x < 0) {
w += x;
x = 0;
}
if (y < 0) {
h += y;
y = 0;
}
if (x + w > bw) {
w = bw - x;
}
if (y + h > bh) {
h = bh - y;
}
int sx, sy;
struct tb_cell *dst = &CELL(buf, bw, x, y);
for (sy = 0; sy < h; ++sy) {
for (sx = 0; sx < w; ++sx) {
dst[sx] = *fill;
}
dst += bw;
}
}
void tbu_fillregion(int x, int y, int w, int h, const struct tb_cell *fill)
{
int bbw = tb_width();
int bbh = tb_height();
struct tb_cell *bb = tb_cell_buffer();
tbu_fillbufferregion(bb, bbw, bbh, x, y, w, h, fill);
}
void tbu_copybufferregion(struct tb_cell *buf, int bw, int bh, int tx, int ty, int x, int y, int w, int h)
{
if (w < 1 || h < 1)
return;
if (x >= bw || x + w < 0 || y >= bh || y + h < 0)
return;
if (tx >= bw || tx + w < 0 || ty >= bh || ty + h < 0)
return;
if (x < 0) {
int dx = -x;
x = 0;
tx += dx;
w -= dx;
}
if (x + w > bw) {
w = bw - x;
}
if (tx < 0) {
int dx = -tx;
tx = 0;
x += dx;
w -= dx;
}
if (tx + w > bw) {
w = bw - tx;
}
if (y < 0) {
int dy = -y;
y = 0;
ty += dy;
h -= dy;
}
if (y + h > bh) {
h = bh - y;
}
if (ty < 0) {
int dy = -ty;
ty = 0;
y += dy;
h -= dy;
}
if (ty + h > bh) {
h = bh - ty;
}
int ys = 1;
if (ty > y) {
y = y + h - 1;
ty = ty + h - 1;
ys = -1;
}
int ry;
int from = x, to = tx;
if (y > 0) {
from += y * bw;
}
if (ty > 0) {
to += ty * bw;
}
for (ry = 0; ry < h; ++ry) {
int cfy = from + (ry * ys * bw);
int cty = to + (ry * ys * bw);
memmove(&buf[cty], &buf[cfy], w * sizeof(struct tb_cell));
}
}
void tbu_copyregion(int tx, int ty, int x, int y, int w, int h)
{
int bbw = tb_width();
int bbh = tb_height();
struct tb_cell *bb = tb_cell_buffer();
tbu_copybufferregion(bb, bbw, bbh, tx, ty, x, y, w, h);
}
void tbu_scrollbufferregion(struct tb_cell *buf, int bw, int bh, int x, int y, int w, int h, int sx, int sy, const struct tb_cell *fill)
{
int fx = x, tx = x;
int fy = y, ty = y;
if (sx < 0) {
sx = -1;
fx = x + 1;
} else if (sx > 0) {
sx = 1;
tx = x + 1;
}
if (sy < 0) {
sy = -1;
fy = y + 1;
} else if (sy > 0) {
sy = 1;
ty = y + 1;
}
tbu_copybufferregion(buf, bw, bh, tx, ty, fx, fy, w - abs(sx), h - abs(sy));
if (sx != 0) {
int fillx = sx > 0 ? x : x + w - 1;
tbu_fillbufferregion(buf, bw, bh, fillx, y, 1, h, fill);
}
if (sy != 0) {
int filly = sy > 0 ? y : y + h - 1;
tbu_fillbufferregion(buf, bw, bh, x, filly, w, 1, fill);
}
}
void tbu_scrollregion(int x, int y, int w, int h, int sx, int sy, const struct tb_cell *fill)
{
int bbw = tb_width();
int bbh = tb_height();
struct tb_cell *bb = tb_cell_buffer();
tbu_scrollbufferregion(bb, bbw, bbh, x, y, w, h, sx, sy, fill);
}