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 Subfont *sf; 69 70 if(s == nil){ 71 s = ""; 72 sptr = nil; 73 }else 74 sptr = &s; 75 if(r == nil){ 76 r = (Rune*) L""; 77 rptr = nil; 78 }else 79 rptr = &r; 80 sf = nil; 81 while((*s || *r) && len > 0){ 82 max = Max; 83 if(len < max) 84 max = len; 85 n = cachechars(f, sptr, rptr, cbuf, max, &wid, &subfontname); 86 if(n > 0){ 87 _setdrawop(dst->display, op); 88 89 m = 47+2*n; 90 if(bg) 91 m += 4+2*4; 92 b = bufimage(dst->display, m); 93 if(b == 0){ 94 fprint(2, "string: %r\n"); 95 break; 96 } 97 if(bg) 98 b[0] = 'x'; 99 else 100 b[0] = 's'; 101 BPLONG(b+1, dst->id); 102 BPLONG(b+5, src->id); 103 BPLONG(b+9, f->cacheimage->id); 104 BPLONG(b+13, pt.x); 105 BPLONG(b+17, pt.y+f->ascent); 106 BPLONG(b+21, clipr.min.x); 107 BPLONG(b+25, clipr.min.y); 108 BPLONG(b+29, clipr.max.x); 109 BPLONG(b+33, clipr.max.y); 110 BPLONG(b+37, sp.x); 111 BPLONG(b+41, sp.y); 112 BPSHORT(b+45, n); 113 b += 47; 114 if(bg){ 115 BPLONG(b, bg->id); 116 BPLONG(b+4, bgp.x); 117 BPLONG(b+8, bgp.y); 118 b += 12; 119 } 120 ec = &cbuf[n]; 121 for(c=cbuf; c<ec; c++, b+=2) 122 BPSHORT(b, *c); 123 pt.x += wid; 124 bgp.x += wid; 125 agefont(f); 126 len -= n; 127 } 128 if(subfontname){ 129 freesubfont(sf); 130 if((sf=_getsubfont(f->display, subfontname)) == 0){ 131 def = f->display ? f->display->defaultfont : nil; 132 if(def && f!=def) 133 f = def; 134 else 135 break; 136 } 137 /* 138 * must not free sf until cachechars has found it in the cache 139 * and picked up its own reference. 140 */ 141 } 142 } 143 return pt; 144 } 145