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, SoverD); 14 } 15 16 Point 17 stringop(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, Drawop op) 18 { 19 return _string(dst, pt, src, sp, f, s, nil, 1<<24, dst->clipr, nil, ZP, op); 20 } 21 22 Point 23 stringn(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, int len) 24 { 25 return _string(dst, pt, src, sp, f, s, nil, len, dst->clipr, nil, ZP, SoverD); 26 } 27 28 Point 29 stringnop(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, int len, Drawop op) 30 { 31 return _string(dst, pt, src, sp, f, s, nil, len, dst->clipr, nil, ZP, op); 32 } 33 34 Point 35 runestring(Image *dst, Point pt, Image *src, Point sp, Font *f, Rune *r) 36 { 37 return _string(dst, pt, src, sp, f, nil, r, 1<<24, dst->clipr, nil, ZP, SoverD); 38 } 39 40 Point 41 runestringop(Image *dst, Point pt, Image *src, Point sp, Font *f, Rune *r, Drawop op) 42 { 43 return _string(dst, pt, src, sp, f, nil, r, 1<<24, dst->clipr, nil, ZP, op); 44 } 45 46 Point 47 runestringn(Image *dst, Point pt, Image *src, Point sp, Font *f, Rune *r, int len) 48 { 49 return _string(dst, pt, src, sp, f, nil, r, len, dst->clipr, nil, ZP, SoverD); 50 } 51 52 Point 53 runestringnop(Image *dst, Point pt, Image *src, Point sp, Font *f, Rune *r, int len, Drawop op) 54 { 55 return _string(dst, pt, src, sp, f, nil, r, len, dst->clipr, nil, ZP, op); 56 } 57 58 Point 59 _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) 60 { 61 int m, n, wid, max; 62 ushort cbuf[Max], *c, *ec; 63 uchar *b; 64 char *subfontname; 65 char **sptr; 66 Rune **rptr; 67 Font *def; 68 69 if(s == nil){ 70 s = ""; 71 sptr = nil; 72 }else 73 sptr = &s; 74 if(r == nil){ 75 r = (Rune*) L""; 76 rptr = nil; 77 }else 78 rptr = &r; 79 while((*s || *r) && len){ 80 max = Max; 81 if(len < max) 82 max = len; 83 n = cachechars(f, sptr, rptr, cbuf, max, &wid, &subfontname); 84 if(n > 0){ 85 _setdrawop(dst->display, op); 86 87 m = 47+2*n; 88 if(bg) 89 m += 4+2*4; 90 b = bufimage(dst->display, m); 91 if(b == 0){ 92 fprint(2, "string: %r\n"); 93 break; 94 } 95 if(bg) 96 b[0] = 'x'; 97 else 98 b[0] = 's'; 99 BPLONG(b+1, dst->id); 100 BPLONG(b+5, src->id); 101 BPLONG(b+9, f->cacheimage->id); 102 BPLONG(b+13, pt.x); 103 BPLONG(b+17, pt.y+f->ascent); 104 BPLONG(b+21, clipr.min.x); 105 BPLONG(b+25, clipr.min.y); 106 BPLONG(b+29, clipr.max.x); 107 BPLONG(b+33, clipr.max.y); 108 BPLONG(b+37, sp.x); 109 BPLONG(b+41, sp.y); 110 BPSHORT(b+45, n); 111 b += 47; 112 if(bg){ 113 BPLONG(b, bg->id); 114 BPLONG(b+4, bgp.x); 115 BPLONG(b+8, bgp.y); 116 b += 12; 117 } 118 ec = &cbuf[n]; 119 for(c=cbuf; c<ec; c++, b+=2) 120 BPSHORT(b, *c); 121 pt.x += wid; 122 bgp.x += wid; 123 agefont(f); 124 len -= n; 125 } 126 if(subfontname){ 127 if(_getsubfont(f->display, subfontname) == 0){ 128 def = f->display->defaultfont; 129 if(def && f!=def) 130 f = def; 131 else 132 break; 133 } 134 } 135 } 136 return pt; 137 } 138