henesyinit from p9f47575dc5 years agoHistory
125 lines · 2.7 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <libg.h>#include <layer.h> Pointsubfontstring(Bitmap *db, Point p, Subfont *f, char *s, Fcode c){	Layer *dl, *cover;	Rectangle r, rc;	int fits;	Point sz; 	dl = (Layer*)db;	sz = subfontstrsize(f, s);	if(dl->cache == 0)    Easy:		return _subfontstring(db, p, f, s, c, sz.x);	r.min = p;	r.max.x = p.x+sz.x;	r.max.y = p.y+sz.y;	fits = rectinrect(r, dl->clipr);	if(fits && dl->vis==Visible)		/*		 * Look for a Bitmap we can write on instead of a Layer.		 * r is known to fit within dl->clipr.  As long as we have		 * only Visible covering layers, we know that r will		 * therefore fit within their cliprs and no more clipping		 * is required.		 */		for(cover=dl->cover->layer; ; cover=cover->cover->layer){			if(cover->vis != Visible)				break;			if(cover->cache == 0){				db = cover;				goto Easy;			}		}	/*	 * Either dl or one of the covering layers is not Visible.	 * Do the operation in the cache and restore as necessary.	 * If dl is Visible, r is contained within cover->clipr and	 * the cache must be restored from the cover; otherwise the	 * cache is up to date but the restoration of the screen may	 * require clipping.	 */	if(!fits && !rectclip(&r, dl->clipr))		goto Return;	/* r is now bbox of the portion of dl that will be modified */	cover = dl->cover->layer;	if(dl->vis == Visible)		bitblt(dl->cache, r.min, cover, r, S);	if(!fits){		rc = dl->cache->clipr;		clipr(dl->cache, r);	}	_subfontstring(dl->cache, p, f, s, c, sz.x);	if(!fits)		clipr(dl->cache, rc);	if(dl->vis == Visible)		bitblt(cover, r.min, dl->cache, r, S);	else if(dl->vis==Obscured)		layerop(lupdate, r, dl, (void *)0);    Return:	return Pt(p.x+sz.x, p.y);} Point_subfontstring(Bitmap *d, Point p, Subfont *ft, char *s, Fcode f, int w){	int c, i;	uchar *buf;	char *q, *eq;	Rune r;	int n; 	while(*s){		q = memchr(s, 0, 1024);		if(q == 0){			w = -1;			/*			 * Must find a rune boundary.			 * First try: look for a self-representing			 * character near the end of the first 1024			 */			eq = s + 1023-3;	/* longest rune is 3 bytes */			q = s + 900;			while(q < eq){				c = *(uchar*)q++;				if(c <= ' ')					goto found;			}			/*			 * Second try: interpret runes from start			 */			for(q=s; q<eq; ){				i = chartorune(&r, q);				if(i == 0){					q++;					continue;				}				q += i;			}		}	found:		n = q - s;		buf = bneed(15+n+1);		buf[0] = 's';		BPSHORT(buf+1, d->id);		BPLONG(buf+3, p.x);		BPLONG(buf+7, p.y);		BPSHORT(buf+11, ft->id);		BPSHORT(buf+13, f);		memmove(buf+15, s, n);		buf[15+n] = 0;		if(w > 0)			p.x += w;		else{			p.x += subfontstrwidth(ft, (char*)buf+15);			w = -1;		}		s += n;	}	return p;}