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