1 #include <u.h> 2 #include <libc.h> 3 #include <draw.h> 4 5 enum 6 { 7 Max = 100 8 }; 9 10 Point 11 string(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s) 12 { 13 return _string(dst, pt, src, sp, f, s, nil, 1<<24, dst->clipr, nil, ZP); 14 } 15 16 Point 17 stringn(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, int len) 18 { 19 return _string(dst, pt, src, sp, f, s, nil, len, dst->clipr, nil, ZP); 20 } 21 22 Point 23 runestring(Image *dst, Point pt, Image *src, Point sp, Font *f, Rune *r) 24 { 25 return _string(dst, pt, src, sp, f, nil, r, 1<<24, dst->clipr, nil, ZP); 26 } 27 28 Point 29 runestringn(Image *dst, Point pt, Image *src, Point sp, Font *f, Rune *r, int len) 30 { 31 return _string(dst, pt, src, sp, f, nil, r, len, dst->clipr, nil, ZP); 32 } 33 34 Point 35 _string(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, Rune *r, int len, Rectangle clipr, Image *bg, Point bgp) 36 { 37 int m, n, wid, max; 38 ushort cbuf[Max], *c, *ec; 39 uchar *b; 40 char *subfontname; 41 char **sptr; 42 Rune **rptr; 43 Font *def; 44 45 if(s == nil){ 46 s = ""; 47 sptr = nil; 48 }else 49 sptr = &s; 50 if(r == nil){ 51 r = L""; 52 rptr = nil; 53 }else 54 rptr = &r; 55 while((*s || *r) && len){ 56 max = Max; 57 if(len < max) 58 max = len; 59 n = cachechars(f, sptr, rptr, cbuf, max, &wid, &subfontname); 60 if(n > 0){ 61 m = 47+2*n; 62 if(bg) 63 m += 4+2*4; 64 b = bufimage(dst->display, m); 65 if(b == 0){ 66 fprint(2, "string: %r\n"); 67 break; 68 } 69 if(bg) 70 b[0] = 'x'; 71 else 72 b[0] = 's'; 73 BPLONG(b+1, dst->id); 74 BPLONG(b+5, src->id); 75 BPLONG(b+9, f->cacheimage->id); 76 BPLONG(b+13, pt.x); 77 BPLONG(b+17, pt.y+f->ascent); 78 BPLONG(b+21, clipr.min.x); 79 BPLONG(b+25, clipr.min.y); 80 BPLONG(b+29, clipr.max.x); 81 BPLONG(b+33, clipr.max.y); 82 BPLONG(b+37, sp.x); 83 BPLONG(b+41, sp.y); 84 BPSHORT(b+45, n); 85 b += 47; 86 if(bg){ 87 BPLONG(b, bg->id); 88 BPLONG(b+4, bgp.x); 89 BPLONG(b+8, bgp.y); 90 b += 12; 91 } 92 ec = &cbuf[n]; 93 for(c=cbuf; c<ec; c++, b+=2) 94 BPSHORT(b, *c); 95 pt.x += wid; 96 bgp.x += wid; 97 agefont(f); 98 len -= n; 99 } 100 if(subfontname){ 101 if(_getsubfont(f->display, subfontname) == 0){ 102 def = f->display->defaultfont; 103 if(def && f!=def) 104 f = def; 105 else 106 break; 107 } 108 } 109 } 110 return pt; 111 } 112