summaryrefslogtreecommitdiff
path: root/sys/src/cmd/abaco/tabs.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/abaco/tabs.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/abaco/tabs.c')
-rwxr-xr-xsys/src/cmd/abaco/tabs.c332
1 files changed, 332 insertions, 0 deletions
diff --git a/sys/src/cmd/abaco/tabs.c b/sys/src/cmd/abaco/tabs.c
new file mode 100755
index 000000000..eda3f5132
--- /dev/null
+++ b/sys/src/cmd/abaco/tabs.c
@@ -0,0 +1,332 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <memdraw.h>
+#include <thread.h>
+#include <cursor.h>
+#include <mouse.h>
+#include <keyboard.h>
+#include <frame.h>
+#include <plumb.h>
+#include <html.h>
+#include "dat.h"
+#include "fns.h"
+
+void
+drawtable(Box *b, Page *p, Image *im)
+{
+ Rectangle r, cr;
+ Tablecell *c;
+ Table *t;
+
+ t = ((Itable *)b->i)->table;
+ r = rectsubpt(b->r, p->pos);
+ draw(im, r, getcolor(t->background.color), nil, ZP);
+ if(t->border)
+ border(im, r, t->border, display->black, ZP);
+ for(c=t->cells; c!=nil; c=c->next){
+ cr = rectsubpt(c->lay->r, p->pos);
+ if(c->background.color != t->background.color)
+ draw(im, cr, getcolor(c->background.color), nil, ZP);
+ if(t->border)
+ border(im, cr, t->border, display->black, ZP);
+ laydraw(p, im, c->lay);
+ }
+}
+
+enum
+{
+ Tablemax = 2000,
+ Ttoplevel = 1<<0,
+
+};
+
+static
+void
+settable(Table *t)
+{
+ Tablecell *c;
+ Lay *lay;
+
+ for(c=t->cells; c!=nil; c=c->next){
+ lay = layitems(c->content, Rect(0,0,0,0), FALSE);
+ c->minw = Dx(lay->r);
+ layfree(lay);
+ if(dimenkind(c->wspec) == Dnone){
+ lay = layitems(c->content, Rect(0,0,Tablemax,0), FALSE);
+ c->maxw = Dx(lay->r);
+ layfree(lay);
+ }
+ }
+}
+
+void
+settables(Page *p)
+{
+ Table *t;
+ Item *i;
+
+ if(p->doc==nil)
+ return;
+ for(i=p->items; i!=nil; i=i->next)
+ if(i->tag == Itabletag)
+ ((Itable *)i)->table->flags |= Ttoplevel;
+
+ for(t=p->doc->tables; t!=nil; t=t->next)
+ settable(t);
+}
+
+static
+int
+cellwidth(Table *t, Tablecell *c, int sep)
+{
+ int w, i, n;
+
+ n = c->colspan;
+ if(n == 1)
+ return t->cols[c->col].width;
+ if(n == 0)
+ n = t->ncol - c->col;
+
+ w = t->cellspacing*(n-1) + n*sep;
+ for(i=c->col; i<c->col+n; i++)
+ w += t->cols[i].width;
+
+ return w;
+}
+
+static
+int
+cellheight(Table *t, Tablecell *c, int sep)
+{
+ int h, i, n;
+
+ n = c->rowspan;
+ if(n == 1)
+ return t->rows[c->row].height;
+ if(n == 0)
+ n = t->nrow - c->row;
+
+ h = t->cellspacing*(n-1) + n*sep;
+ for(i=c->row; i<c->row+n; i++)
+ h += t->rows[i].height;
+
+ return h;
+}
+
+static
+int
+getwidth(int *w, int n)
+{
+ int i, tot;
+
+ tot = 0;
+ for(i=0; i<n; i++)
+ tot += w[i];
+
+ return tot;
+}
+
+static
+void
+fixcols(Table *t, int *width, int sep, int domax)
+{
+ Tablecell *c;
+ int w, aw, i, d, n, rem;
+
+
+ for(c=t->cells; c!=nil; c=c->next){
+ if(c->colspan == 1)
+ continue;
+
+ n = c->colspan;
+ if(n == 0)
+ n = t->ncol - c->col;
+
+ w = domax ? c->maxw : c->minw;
+ w -= t->cellspacing*(n-1) + n*sep;
+
+ aw = 0;
+ for(i=c->col; i<c->col+n; i++)
+ aw += width[i];
+
+ rem = w-aw;
+ if(rem <= 0)
+ continue;
+
+ for(i=c->col; i<c->col+n; i++){
+ if(aw > 0){
+ d = width[i]*100/aw;
+ d = d*rem/100;
+ }else
+ d = rem/n;
+ width[i] += d;
+ }
+ }
+}
+
+static
+int
+tablewidth(Table *t, int tw, int sep)
+{
+ Tablecell *c;
+ int i, w, tmin, tmax, d;
+ int *maxw, *minw;
+ int totw;
+
+ maxw = emalloc(sizeof(int)*t->ncol);
+ minw = emalloc(sizeof(int)*t->ncol);
+ for(c=t->cells; c!=nil; c=c->next){
+ if(dimenkind(c->wspec) != Dnone){
+ d = c->minw;
+ c->minw = c->maxw = max(dimwidth(c->wspec, tw), c->minw);
+ c->minw = d;
+ }
+ if(c->colspan != 1)
+ continue;
+ maxw[c->col] = max(maxw[c->col], c->maxw);
+ minw[c->col] = max(minw[c->col], c->minw);
+ }
+ totw = 0;
+ fixcols(t, maxw, sep, TRUE);
+ tmax = getwidth(maxw, t->ncol);
+ if(tmax <= tw){
+ d = 0;
+ if(tw>tmax && dimenkind(t->width)!=Dnone && t->availw!=Tablemax)
+ d = (tw-tmax)/t->ncol;
+ for(i=0; i<t->ncol; i++){
+ t->cols[i].width = maxw[i] + d;
+ totw += t->cols[i].width;
+ }
+ }else{
+ fixcols(t, minw, sep, FALSE);
+ tmin = getwidth(minw, t->ncol);
+ w = tw - tmin;
+ d = tmax - tmin;
+ for(i=0; i<t->ncol; i++){
+ if(w<=0 || d<=0)
+ t->cols[i].width = minw[i];
+ else
+ t->cols[i].width = minw[i] + (maxw[i] - minw[i])*w/d;
+ totw += t->cols[i].width;
+ }
+ }
+ free(minw);
+ free(maxw);
+
+ return totw;
+}
+
+static
+void
+fixrows(Table *t, int sep)
+{
+ Tablecell *c;
+ Lay *lay;
+ int h, ah, i, d, n, rem;
+
+ for(c=t->cells; c!=nil; c=c->next){
+ if(c->rowspan == 1)
+ continue;
+ n = c->rowspan;
+ if(n==0 || c->row+n>t->nrow)
+ n = t->nrow - c->row;
+
+ lay = layitems(c->content, Rect(0,0,cellwidth(t, c, sep),0), FALSE);
+ h = max(Dy(lay->r), c->hspec);
+ layfree(lay);
+ h -= t->cellspacing*(n-1) + n*sep;
+ ah = 0;
+ for(i=c->row; i<c->row+n; i++)
+ ah += t->rows[i].height;
+
+ rem = h-ah;
+ if(rem <= 0)
+ continue;
+
+ for(i=c->row; i<c->row+n; i++){
+ if(ah > 0){
+ d = t->rows[i].height*100/ah;
+ d = d*rem/100;
+ }else
+ d = rem/n;
+
+ t->rows[i].height += d;
+ }
+ }
+}
+
+static
+int
+tableheight(Table *t, int sep)
+{
+ Tablecell *c;
+ Lay *lay;
+ int i, h, toth;
+
+ for(i=0; i<t->nrow; i++){
+ h = 0;
+ for(c=t->rows[i].cells; c!=nil; c=c->nextinrow){
+ if(c->rowspan != 1)
+ continue;
+ lay = layitems(c->content, Rect(0, 0, cellwidth(t, c, sep), 0), FALSE);
+ h = max(h, max(Dy(lay->r), c->hspec));
+ layfree(lay);
+ }
+ t->rows[i].height = h;
+ }
+ fixrows(t, sep);
+ toth = 0;
+ for(i=0; i<t->nrow; i++)
+ toth += t->rows[i].height;
+
+ return toth;
+}
+
+void
+tablesize(Table *t, int availw)
+{
+ int w, sep, hsep, vsep;
+
+ t->availw = availw;
+ sep = 2*(t->border+t->cellpadding);
+ hsep = t->cellspacing*(t->ncol+1) + 2*t->border + t->ncol*sep;
+ vsep = t->cellspacing*(t->nrow+1) + 2*t->border + t->nrow*sep;
+ w = dimwidth(t->width, availw);
+ w -= hsep;
+ w = w>0 ? w : 0;
+ t->totw = tablewidth(t, w, sep);
+ t->totw += hsep;
+ t->toth = tableheight(t, sep);
+ t->toth += vsep;
+}
+
+void
+laytable(Itable *it, Rectangle r)
+{
+ Rectangle cr;
+ Tablecell *c;
+ Table *t;
+ int x, y, h, w;
+ int sep, i;
+
+ t = it->table;
+
+ sep = (t->cellpadding+t->border) * 2;
+ r = insetrect(r, t->cellspacing+t->border);
+ for(c=t->cells; c!=nil; c=c->next){
+ w = cellwidth(t, c, sep);
+ h = cellheight(t, c, sep);
+ x = r.min.x;
+ if(c->col > 0)
+ for(i=0; i<c->col; i++)
+ x += t->cols[i].width + sep + t->cellspacing;
+ y = r.min.y;
+ if(c->row > 0)
+ for(i=0;i <c->row; i++)
+ y += t->rows[i].height + sep + t->cellspacing;
+ cr = Rect(x, y, x+w+sep, y+h+sep);
+ c->lay = layitems(c->content, insetrect(cr, sep/2), TRUE);
+ c->lay->r = cr;
+ }
+}