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