1 #include <u.h> 2 #include <libc.h> 3 #include <draw.h> 4 5 int 6 _stringnwidth(Font *f, char *s, Rune *r, int len) 7 { 8 int wid, twid, n, max, l; 9 enum { Max = 64 }; 10 ushort cbuf[Max]; 11 Rune **rptr; 12 char *subfontname, **sptr; 13 Font *def; 14 15 if(s == nil){ 16 s = ""; 17 sptr = nil; 18 }else 19 sptr = &s; 20 if(r == nil){ 21 r = L""; 22 rptr = nil; 23 }else 24 rptr = &r; 25 twid = 0; 26 while((*s || *r)&& len){ 27 max = Max; 28 if(len < max) 29 max = len; 30 n = 0; 31 while((l = cachechars(f, sptr, rptr, cbuf, max, &wid, &subfontname)) <= 0){ 32 if(++n > 10){ 33 _drawprint(2, "stringwidth: bad character set\n"); 34 return twid; 35 } 36 if(subfontname){ 37 if(_getsubfont(f->display, subfontname) == 0){ 38 def = f->display->defaultfont; 39 if(def && f!=def) 40 f = def; 41 else 42 break; 43 } 44 } 45 } 46 agefont(f); 47 twid += wid; 48 len -= l; 49 } 50 return twid; 51 } 52 53 int 54 stringnwidth(Font *f, char *s, int len) 55 { 56 return _stringnwidth(f, s, nil, len); 57 } 58 59 int 60 stringwidth(Font *f, char *s) 61 { 62 return _stringnwidth(f, s, nil, 1<<24); 63 } 64 65 Point 66 stringsize(Font *f, char *s) 67 { 68 return Pt(_stringnwidth(f, s, nil, 1<<24), f->height); 69 } 70 71 int 72 runestringnwidth(Font *f, Rune *r, int len) 73 { 74 return _stringnwidth(f, nil, r, len); 75 } 76 77 int 78 runestringwidth(Font *f, Rune *r) 79 { 80 return _stringnwidth(f, nil, r, 1<<24); 81 } 82 83 Point 84 runestringsize(Font *f, Rune *r) 85 { 86 return Pt(_stringnwidth(f, nil, r, 1<<24), f->height); 87 } 88