changelog shortlog tags branches files raw gz bz2 help

Mercurial > hg > plan9front / changeset: mothra: wrap long text and images to fit

changeset 4241: 9cac2fa385e6
parent 4240: b62414ff39c6
child 4242: e817c2e887e7
author: cinap_lenrek@felloff.net
date: Sat, 31 Jan 2015 20:01:24 +0100
files: sys/src/cmd/mothra/libpanel/rtext.c sys/src/cmd/mothra/libpanel/rtext.h sys/src/cmd/mothra/mothra.c
description: mothra: wrap long text and images to fit
     1.1--- a/sys/src/cmd/mothra/libpanel/rtext.c
     1.2+++ b/sys/src/cmd/mothra/libpanel/rtext.c
     1.3@@ -65,6 +65,55 @@ int pl_space(int space, int pos, int ind
     1.4 		return ((pos-indent+pl_tabmin)/pl_tabsize+PL_ARG(space))*pl_tabsize+indent-pos;
     1.5 	}
     1.6 }
     1.7+
     1.8+static void
     1.9+unwrap(Rtext *t)
    1.10+{
    1.11+	Rtext *w;
    1.12+
    1.13+	if(t == nil)
    1.14+		return;
    1.15+	while((w = t->next) != nil){
    1.16+		if(PL_OP(w->space) != PL_WRAP)
    1.17+			return;
    1.18+		t->next = w->next;
    1.19+		free(w);
    1.20+	}
    1.21+}
    1.22+
    1.23+static void
    1.24+wrap(Rtext *t, int x)
    1.25+{
    1.26+	Rtext *w;
    1.27+	char *s;
    1.28+	Rune r;
    1.29+
    1.30+	w = nil;
    1.31+	if(t->b){
    1.32+		if(PL_OP(t->space) == PL_WRAP)
    1.33+			x += PL_ARG(t->space);
    1.34+		if(t->b->repl || x >= Dx(t->b->r) || x > PL_ARGMASK)
    1.35+			return;
    1.36+		plrtbitmap(&w, PL_WRAP|x, 0, t->b, t->flags, t->user);
    1.37+	}
    1.38+	else if(t->p) {
    1.39+		return;
    1.40+	}
    1.41+	else {
    1.42+		s = t->text;
    1.43+		while(*s != '\0'){
    1.44+			if((t->wid - stringwidth(t->font, s)) >= x)
    1.45+				break;
    1.46+			s += chartorune(&r, s);
    1.47+		}
    1.48+		if(*s == '\0')
    1.49+			return;
    1.50+		plrtstr(&w, PL_WRAP, 0, t->font, s, t->flags, t->user);
    1.51+	}
    1.52+	w->next = t->next;
    1.53+	t->next = w;
    1.54+}
    1.55+
    1.56 /*
    1.57  * initialize rectangles & nextlines of text starting at t,
    1.58  * galley width is wid.  Returns the total length of the text
    1.59@@ -82,18 +131,23 @@ int pl_rtfmt(Rtext *t, int wid){
    1.60 		x=0;
    1.61 		tp=t;
    1.62 		for(;;){
    1.63+			unwrap(tp);
    1.64 			if(tp->b){
    1.65-				a=tp->b->r.max.y-tp->b->r.min.y+BORD;
    1.66+				a=Dy(tp->b->r)+BORD;
    1.67 				d=BORD;
    1.68-				w=tp->b->r.max.x-tp->b->r.min.x+BORD*2;
    1.69+				w=Dx(tp->b->r)+BORD*2;
    1.70+				if(PL_OP(t->space) == PL_WRAP)
    1.71+					w -= PL_ARG(t->space);
    1.72+				if(tp->b->repl)
    1.73+					w = wid;
    1.74 			}
    1.75 			else if(tp->p){
    1.76 				/* what if plpack fails? */
    1.77 				plpack(tp->p, Rect(0,0,wid,wid));
    1.78 				plmove(tp->p, subpt(Pt(0,0), tp->p->r.min));
    1.79-				a=tp->p->r.max.y-tp->p->r.min.y;
    1.80+				a=Dy(tp->p->r);
    1.81 				d=0;
    1.82-				w=tp->p->r.max.x-tp->p->r.min.x;
    1.83+				w=Dx(tp->p->r);
    1.84 			}
    1.85 			else{
    1.86 				a=tp->font->ascent;
    1.87@@ -114,6 +168,7 @@ int pl_rtfmt(Rtext *t, int wid){
    1.88 		}
    1.89 		if(eline==t){	/* No progress!  Force fit the first block! */
    1.90 			if(tp==t){
    1.91+				wrap(tp, wid - x);
    1.92 				if(a>ascent) ascent=a;
    1.93 				if(d>descent) descent=d;
    1.94 				eline=tp->next;
    1.95@@ -128,8 +183,12 @@ int pl_rtfmt(Rtext *t, int wid){
    1.96 			t->r.min.x=p.x;
    1.97 			if(t->b){
    1.98 				t->r.max.y=p.y+BORD;
    1.99-				t->r.min.y=p.y-(t->b->r.max.y-t->b->r.min.y)-BORD;
   1.100-				p.x+=(t->b->r.max.x-t->b->r.min.x)+BORD*2;
   1.101+				t->r.min.y=p.y-Dy(t->b->r)-BORD;
   1.102+				p.x+=Dx(t->b->r)+BORD*2;
   1.103+				if(PL_OP(t->space) == PL_WRAP)
   1.104+					p.x -= PL_ARG(t->space);
   1.105+				if(t->b->repl)
   1.106+					p.x = wid;
   1.107 			}
   1.108 			else if(t->p){
   1.109 				t->r.max.y=p.y;
   1.110@@ -184,7 +243,11 @@ void pl_rtdraw(Image *b, Rectangle r, Rt
   1.111 		if(dr.max.y>r.min.y
   1.112 		&& dr.min.y<r.max.y){
   1.113 			if(t->b){
   1.114-				draw(b, insetrect(dr, BORD), t->b, 0, t->b->r.min);
   1.115+				Point sp;
   1.116+				sp = t->b->r.min;
   1.117+				if(PL_OP(t->space) == PL_WRAP)
   1.118+					sp.x += PL_ARG(t->space);
   1.119+				draw(b, insetrect(dr, BORD), t->b, 0, sp);
   1.120 				if(t->flags&PL_HOT) border(b, dr, 1, display->black, ZP);
   1.121 				if(t->flags&PL_SEL)
   1.122 					pl_highlight(b, dr);
   1.123@@ -293,13 +356,16 @@ void plrtseltext(Rtext *t, Rtext *s, Rte
   1.124 
   1.125 char *plrtsnarftext(Rtext *w){
   1.126 	char *b, *p, *e, *t;
   1.127-	int n;
   1.128+	int n, m;
   1.129 
   1.130 	b=p=e=0;
   1.131 	for(; w; w = w->next){
   1.132 		if((w->flags&PL_SEL)==0 || w->text==0)
   1.133 			continue;
   1.134-		n = strlen(w->text)+64;
   1.135+		m = strlen(w->text);
   1.136+		if(w->next!=0 && PL_OP(w->next->space)==PL_WRAP && w->next->text>w->text)
   1.137+			m -= strlen(w->next->text);
   1.138+		n = m+64;
   1.139 		if(p+n >= e){
   1.140 			n = (p+n+64)-b;
   1.141 			t = pl_erealloc(b, n);
   1.142@@ -307,12 +373,12 @@ char *plrtsnarftext(Rtext *w){
   1.143 			e = t+n;
   1.144 			b = t;
   1.145 		}
   1.146-		if(w->space == 0)
   1.147-			p += sprint(p, "%s", w->text);
   1.148+		if(w->space == 0 || PL_OP(w->space) == PL_WRAP)
   1.149+			p += sprint(p, "%.*s", m, w->text);
   1.150 		else if(w->space > 0)
   1.151-			p += sprint(p, " %s", w->text);
   1.152+			p += sprint(p, " %.*s", m, w->text);
   1.153 		else if(PL_OP(w->space) == PL_TAB)
   1.154-			p += sprint(p, "\t%s", w->text);
   1.155+			p += sprint(p, "\t%.*s", m, w->text);
   1.156 		if(w->nextline == w->next)
   1.157 			p += sprint(p, "\n");
   1.158 	}
     2.1--- a/sys/src/cmd/mothra/libpanel/rtext.h
     2.2+++ b/sys/src/cmd/mothra/libpanel/rtext.h
     2.3@@ -8,4 +8,5 @@
     2.4 #define	PL_OP(t)	((t)&~PL_ARGMASK)
     2.5 #define	PL_ARG(t)	((t)&PL_ARGMASK)
     2.6 #define	PL_TAB		PL_SPECIAL(0)		/* # of tab stops before text */
     2.7+#define	PL_WRAP		PL_SPECIAL(1)
     2.8 void pltabsize(int, int);			/* set min tab and tab size */
     3.1--- a/sys/src/cmd/mothra/mothra.c
     3.2+++ b/sys/src/cmd/mothra/mothra.c
     3.3@@ -318,11 +318,11 @@ void main(int argc, char *argv[]){
     3.4 	plinit(screen->depth);
     3.5 	if(debug) notify(dienow);
     3.6 	getfonts();
     3.7-	hrule=allocimage(display, Rect(0, 0, 2048, 5), screen->chan, 0, DWhite);
     3.8+	hrule=allocimage(display, Rect(0, 0, 1, 5), screen->chan, 1, DWhite);
     3.9 	if(hrule==0)
    3.10 		sysfatal("can't allocimage!");
    3.11-	draw(hrule, Rect(0,1,1280,3), display->black, 0, ZP);
    3.12-	linespace=allocimage(display, Rect(0, 0, 2048, 5), screen->chan, 0, DWhite);
    3.13+	draw(hrule, Rect(0,1,1,3), display->black, 0, ZP);
    3.14+	linespace=allocimage(display, Rect(0, 0, 1, 5), screen->chan, 1, DWhite);
    3.15 	if(linespace==0)
    3.16 		sysfatal("can't allocimage!");
    3.17 	bullet=allocimage(display, Rect(0,0,25, 8), screen->chan, 0, DWhite);