diff -urN cui21/Makefile cui22/Makefile --- cui21/Makefile Thu Jan 30 22:00:00 2014 +++ cui22/Makefile Thu Jan 30 23:00:00 2014 @@ -1,7 +1,7 @@ CC = gcc -Wall TARG = cui_test -OBJS = cui.o dialog.o button.o label.o panel.o handler.o esc.o key.o +OBJS = cui.o dialog.o button.o label.o panel.o handler.o esc.o key.o rect.o all: $(TARG) diff -urN cui21/cui.c cui22/cui.c --- cui21/cui.c Thu Jan 30 22:40:00 2014 +++ cui22/cui.c Thu Jan 30 23:00:00 2014 @@ -1,4 +1,5 @@ #include "cui.h" +#include "rect.h" #include "esc.h" #include "key.h" #include "handler.h" @@ -56,10 +57,29 @@ void cui_draw_str(cui obj, int x, int y, char *s, int attr) { + struct cui_rect t1, t2; + cui_rect r1 = &t1, r2 = &t2; + int n = strlen(s); + char *s2 = NULL; + + if(!cui_visible_rect(obj, r1)) return; + cui_rect_init(r2, x, y, n, 1); + if(!cui_rect_and(r1, r2, r2)) return; /* r1 and r2 --> r2 */ + + s += r2->x - x; + if(r2->x + r2->w < x + n){ + n = r2->w; + if((s2 = malloc(n + 1)) == NULL) ERR("No Mem"); + memcpy(s2, s, n); + s2[n] = '\0'; + s = s2; + } + x = r2->x; cui_esc_loc(cui_gx(obj) + x, cui_gy(obj) + y); cui_esc_attr(attr); printf("%s", s); fflush(stdout); + if(s2) free(s2); } void @@ -225,6 +245,20 @@ { if(obj == NULL) return TRUE; /* root */ return !(obj->flags & CUI_FLG_HIDE) && cui_is_visible(obj->parent); +} + +int +cui_visible_rect(cui obj, cui_rect r) +{ + struct cui_rect tmp; + cui_rect t = &tmp; + + cui_rect_init(r, 0, 0, obj->w, obj->h); + if(obj->parent == NULL) return !cui_rect_chk_empty(r); /* empty --> FALSE */ + if(!cui_visible_rect(obj->parent, t)) return FALSE; + t->x -= obj->x; + t->y -= obj->y; + return cui_rect_and(r, t, r); /* r and t --> r */ } void diff -urN cui21/cui.h cui22/cui.h --- cui21/cui.h Thu Jan 30 22:30:00 2014 +++ cui22/cui.h Thu Jan 30 23:00:00 2014 @@ -22,6 +22,8 @@ typedef struct cui_handler_list *cui_handler_list; +#include "rect.h" + struct cui_base{ cui parent, children, next; int x, y, w, h; @@ -46,6 +48,8 @@ void cui_hide(cui obj); void cui_show(cui obj); int cui_is_visible(cui obj); +int cui_visible_rect(cui obj, cui_rect r); + void cui_quit(void); void cui_main(cui top_obj); void cui_free(cui obj); diff -urN cui21/rect.c cui22/rect.c --- cui21/rect.c Thu Jan 1 09:00:00 1970 +++ cui22/rect.c Thu Jan 30 23:00:00 2014 @@ -0,0 +1,55 @@ +#include "rect.h" +#include +#include +#include + +void +cui_rect_init(cui_rect r, int x, int y, int w, int h) +{ + r->x = x; + r->y = y; + r->w = w; + r->h = h; +} + +void +cui_rect_wh_to_x2y2(cui_rect r) +{ + r->w += r->x; + r->h += r->y; +} + +void +cui_rect_x2y2_to_wh(cui_rect r) +{ + r->w -= r->x; + r->h -= r->y; +} + +int +cui_rect_and(cui_rect a, cui_rect b, cui_rect r) +{ + struct cui_rect tmp; + cui_rect t = &tmp; + + cui_rect_wh_to_x2y2(a); + cui_rect_wh_to_x2y2(b); + cui_rect_init(t, + a->x > b->x ? a->x : b->x, + a->y > b->y ? a->y : b->y, + a->w < b->w ? a->w : b->w, + a->h < b->h ? a->h : b->h); + cui_rect_x2y2_to_wh(t); + cui_rect_x2y2_to_wh(a); + cui_rect_x2y2_to_wh(b); + *r = *t; + return !cui_rect_chk_empty(r); +} + +int +cui_rect_chk_empty(cui_rect r) +{ + return r->w <= 0 || r->h <= 0; +} + +/* EOF */ diff -urN cui21/rect.h cui22/rect.h --- cui21/rect.h Thu Jan 1 09:00:00 1970 +++ cui22/rect.h Thu Jan 30 23:00:00 2014 @@ -0,0 +1,14 @@ +#ifndef __RECT_H__ +#define __RECT_H__ + +typedef struct cui_rect{ + int x, y, w, h; +} *cui_rect; + +void cui_rect_init(cui_rect r, int x, int y, int w, int h); +void cui_rect_wh_to_x2y2(cui_rect r); +void cui_rect_x2y2_to_wh(cui_rect r); +int cui_rect_and(cui_rect a, cui_rect b, cui_rect r); +int cui_rect_chk_empty(cui_rect r); + +#endif