xref: /plan9/sys/src/libdraw/string.c (revision 4c4c2eb79636563a88ef7964ef5c9c39ec1a9336)
17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <draw.h>
47dd7cddfSDavid du Colombier 
57dd7cddfSDavid du Colombier enum
67dd7cddfSDavid du Colombier {
77dd7cddfSDavid du Colombier 	Max = 100
87dd7cddfSDavid du Colombier };
97dd7cddfSDavid du Colombier 
107dd7cddfSDavid du Colombier Point
string(Image * dst,Point pt,Image * src,Point sp,Font * f,char * s)117dd7cddfSDavid du Colombier string(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s)
127dd7cddfSDavid du Colombier {
13ac57dd0bSDavid du Colombier 	return _string(dst, pt, src, sp, f, s, nil, 1<<24, dst->clipr, nil, ZP, SoverD);
14ac57dd0bSDavid du Colombier }
15ac57dd0bSDavid du Colombier 
16ac57dd0bSDavid du Colombier Point
stringop(Image * dst,Point pt,Image * src,Point sp,Font * f,char * s,Drawop op)17ac57dd0bSDavid du Colombier stringop(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, Drawop op)
18ac57dd0bSDavid du Colombier {
19ac57dd0bSDavid du Colombier 	return _string(dst, pt, src, sp, f, s, nil, 1<<24, dst->clipr, nil, ZP, op);
207dd7cddfSDavid du Colombier }
217dd7cddfSDavid du Colombier 
227dd7cddfSDavid du Colombier Point
stringn(Image * dst,Point pt,Image * src,Point sp,Font * f,char * s,int len)237dd7cddfSDavid du Colombier stringn(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, int len)
247dd7cddfSDavid du Colombier {
25ac57dd0bSDavid du Colombier 	return _string(dst, pt, src, sp, f, s, nil, len, dst->clipr, nil, ZP, SoverD);
26ac57dd0bSDavid du Colombier }
27ac57dd0bSDavid du Colombier 
28ac57dd0bSDavid du Colombier Point
stringnop(Image * dst,Point pt,Image * src,Point sp,Font * f,char * s,int len,Drawop op)29ac57dd0bSDavid du Colombier stringnop(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, int len, Drawop op)
30ac57dd0bSDavid du Colombier {
31ac57dd0bSDavid du Colombier 	return _string(dst, pt, src, sp, f, s, nil, len, dst->clipr, nil, ZP, op);
327dd7cddfSDavid du Colombier }
337dd7cddfSDavid du Colombier 
347dd7cddfSDavid du Colombier Point
runestring(Image * dst,Point pt,Image * src,Point sp,Font * f,Rune * r)357dd7cddfSDavid du Colombier runestring(Image *dst, Point pt, Image *src, Point sp, Font *f, Rune *r)
367dd7cddfSDavid du Colombier {
37ac57dd0bSDavid du Colombier 	return _string(dst, pt, src, sp, f, nil, r, 1<<24, dst->clipr, nil, ZP, SoverD);
38ac57dd0bSDavid du Colombier }
39ac57dd0bSDavid du Colombier 
40ac57dd0bSDavid du Colombier Point
runestringop(Image * dst,Point pt,Image * src,Point sp,Font * f,Rune * r,Drawop op)41ac57dd0bSDavid du Colombier runestringop(Image *dst, Point pt, Image *src, Point sp, Font *f, Rune *r, Drawop op)
42ac57dd0bSDavid du Colombier {
43ac57dd0bSDavid du Colombier 	return _string(dst, pt, src, sp, f, nil, r, 1<<24, dst->clipr, nil, ZP, op);
447dd7cddfSDavid du Colombier }
457dd7cddfSDavid du Colombier 
467dd7cddfSDavid du Colombier Point
runestringn(Image * dst,Point pt,Image * src,Point sp,Font * f,Rune * r,int len)477dd7cddfSDavid du Colombier runestringn(Image *dst, Point pt, Image *src, Point sp, Font *f, Rune *r, int len)
487dd7cddfSDavid du Colombier {
49ac57dd0bSDavid du Colombier 	return _string(dst, pt, src, sp, f, nil, r, len, dst->clipr, nil, ZP, SoverD);
507dd7cddfSDavid du Colombier }
517dd7cddfSDavid du Colombier 
527dd7cddfSDavid du Colombier Point
runestringnop(Image * dst,Point pt,Image * src,Point sp,Font * f,Rune * r,int len,Drawop op)53ac57dd0bSDavid du Colombier runestringnop(Image *dst, Point pt, Image *src, Point sp, Font *f, Rune *r, int len, Drawop op)
54ac57dd0bSDavid du Colombier {
55ac57dd0bSDavid du Colombier 	return _string(dst, pt, src, sp, f, nil, r, len, dst->clipr, nil, ZP, op);
56ac57dd0bSDavid du Colombier }
57ac57dd0bSDavid du Colombier 
58ac57dd0bSDavid du Colombier Point
_string(Image * dst,Point pt,Image * src,Point sp,Font * f,char * s,Rune * r,int len,Rectangle clipr,Image * bg,Point bgp,Drawop op)59ac57dd0bSDavid du Colombier _string(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, Rune *r, int len, Rectangle clipr, Image *bg, Point bgp, Drawop op)
607dd7cddfSDavid du Colombier {
617dd7cddfSDavid du Colombier 	int m, n, wid, max;
627dd7cddfSDavid du Colombier 	ushort cbuf[Max], *c, *ec;
637dd7cddfSDavid du Colombier 	uchar *b;
647dd7cddfSDavid du Colombier 	char *subfontname;
657dd7cddfSDavid du Colombier 	char **sptr;
667dd7cddfSDavid du Colombier 	Rune **rptr;
677dd7cddfSDavid du Colombier 	Font *def;
68c2b843c0SDavid du Colombier 	Subfont *sf;
697dd7cddfSDavid du Colombier 
707dd7cddfSDavid du Colombier 	if(s == nil){
717dd7cddfSDavid du Colombier 		s = "";
727dd7cddfSDavid du Colombier 		sptr = nil;
737dd7cddfSDavid du Colombier 	}else
747dd7cddfSDavid du Colombier 		sptr = &s;
757dd7cddfSDavid du Colombier 	if(r == nil){
76ac57dd0bSDavid du Colombier 		r = (Rune*) L"";
777dd7cddfSDavid du Colombier 		rptr = nil;
787dd7cddfSDavid du Colombier 	}else
797dd7cddfSDavid du Colombier 		rptr = &r;
80c2b843c0SDavid du Colombier 	sf = nil;
81*4c4c2eb7SDavid du Colombier 	while((*s || *r) && len > 0){
827dd7cddfSDavid du Colombier 		max = Max;
837dd7cddfSDavid du Colombier 		if(len < max)
847dd7cddfSDavid du Colombier 			max = len;
857dd7cddfSDavid du Colombier 		n = cachechars(f, sptr, rptr, cbuf, max, &wid, &subfontname);
867dd7cddfSDavid du Colombier 		if(n > 0){
87ac57dd0bSDavid du Colombier 			_setdrawop(dst->display, op);
88ac57dd0bSDavid du Colombier 
897dd7cddfSDavid du Colombier 			m = 47+2*n;
907dd7cddfSDavid du Colombier 			if(bg)
917dd7cddfSDavid du Colombier 				m += 4+2*4;
927dd7cddfSDavid du Colombier 			b = bufimage(dst->display, m);
937dd7cddfSDavid du Colombier 			if(b == 0){
949a747e4fSDavid du Colombier 				fprint(2, "string: %r\n");
957dd7cddfSDavid du Colombier 				break;
967dd7cddfSDavid du Colombier 			}
977dd7cddfSDavid du Colombier 			if(bg)
987dd7cddfSDavid du Colombier 				b[0] = 'x';
997dd7cddfSDavid du Colombier 			else
1007dd7cddfSDavid du Colombier 				b[0] = 's';
1017dd7cddfSDavid du Colombier 			BPLONG(b+1, dst->id);
1027dd7cddfSDavid du Colombier 			BPLONG(b+5, src->id);
1037dd7cddfSDavid du Colombier 			BPLONG(b+9, f->cacheimage->id);
1047dd7cddfSDavid du Colombier 			BPLONG(b+13, pt.x);
1057dd7cddfSDavid du Colombier 			BPLONG(b+17, pt.y+f->ascent);
1067dd7cddfSDavid du Colombier 			BPLONG(b+21, clipr.min.x);
1077dd7cddfSDavid du Colombier 			BPLONG(b+25, clipr.min.y);
1087dd7cddfSDavid du Colombier 			BPLONG(b+29, clipr.max.x);
1097dd7cddfSDavid du Colombier 			BPLONG(b+33, clipr.max.y);
1107dd7cddfSDavid du Colombier 			BPLONG(b+37, sp.x);
1117dd7cddfSDavid du Colombier 			BPLONG(b+41, sp.y);
1127dd7cddfSDavid du Colombier 			BPSHORT(b+45, n);
1137dd7cddfSDavid du Colombier 			b += 47;
1147dd7cddfSDavid du Colombier 			if(bg){
1157dd7cddfSDavid du Colombier 				BPLONG(b, bg->id);
1167dd7cddfSDavid du Colombier 				BPLONG(b+4, bgp.x);
1177dd7cddfSDavid du Colombier 				BPLONG(b+8, bgp.y);
1187dd7cddfSDavid du Colombier 				b += 12;
1197dd7cddfSDavid du Colombier 			}
1207dd7cddfSDavid du Colombier 			ec = &cbuf[n];
1217dd7cddfSDavid du Colombier 			for(c=cbuf; c<ec; c++, b+=2)
1227dd7cddfSDavid du Colombier 				BPSHORT(b, *c);
1237dd7cddfSDavid du Colombier 			pt.x += wid;
1247dd7cddfSDavid du Colombier 			bgp.x += wid;
1257dd7cddfSDavid du Colombier 			agefont(f);
1267dd7cddfSDavid du Colombier 			len -= n;
1277dd7cddfSDavid du Colombier 		}
1287dd7cddfSDavid du Colombier 		if(subfontname){
129c2b843c0SDavid du Colombier 			freesubfont(sf);
130c2b843c0SDavid du Colombier 			if((sf=_getsubfont(f->display, subfontname)) == 0){
131c2b843c0SDavid du Colombier 				def = f->display ? f->display->defaultfont : nil;
1327dd7cddfSDavid du Colombier 				if(def && f!=def)
1337dd7cddfSDavid du Colombier 					f = def;
1347dd7cddfSDavid du Colombier 				else
1357dd7cddfSDavid du Colombier 					break;
1367dd7cddfSDavid du Colombier 			}
137c2b843c0SDavid du Colombier 			/*
138c2b843c0SDavid du Colombier 			 * must not free sf until cachechars has found it in the cache
139c2b843c0SDavid du Colombier 			 * and picked up its own reference.
140c2b843c0SDavid du Colombier 			 */
1417dd7cddfSDavid du Colombier 		}
1427dd7cddfSDavid du Colombier 	}
1437dd7cddfSDavid du Colombier 	return pt;
1447dd7cddfSDavid du Colombier }
145