stringwidth.c (1853B)
1 #include <u.h> 2 #include <libc.h> 3 #include <draw.h> 4 5 static Rune empty[] = { 0 }; 6 int 7 _stringnwidth(Font *f, char *s, Rune *r, int len) 8 { 9 int wid, twid, n, max, l; 10 char *name; 11 enum { Max = 64 }; 12 ushort cbuf[Max]; 13 Rune rune, **rptr; 14 char *subfontname, **sptr; 15 Font *def; 16 Subfont *sf; 17 18 if(s == nil){ 19 s = ""; 20 sptr = nil; 21 }else 22 sptr = &s; 23 if(r == nil){ 24 r = empty; 25 rptr = nil; 26 }else 27 rptr = &r; 28 twid = 0; 29 while(len>0 && (*s || *r)){ 30 max = Max; 31 if(len < max) 32 max = len; 33 n = 0; 34 sf = nil; 35 while((l = cachechars(f, sptr, rptr, cbuf, max, &wid, &subfontname)) <= 0){ 36 if(++n > 10){ 37 if(*r) 38 rune = *r; 39 else 40 chartorune(&rune, s); 41 if(f->name != nil) 42 name = f->name; 43 else 44 name = "unnamed font"; 45 freesubfont(sf); 46 fprint(2, "stringwidth: bad character set for rune 0x%.4ux in %s\n", rune, name); 47 return twid; 48 } 49 if(subfontname){ 50 freesubfont(sf); 51 if((sf=_getsubfont(f->display, subfontname)) == 0){ 52 def = f->display ? f->display->defaultfont : nil; 53 if(def && f!=def) 54 f = def; 55 else 56 break; 57 } 58 /* 59 * must not free sf until cachechars has found it in the cache 60 * and picked up its own reference. 61 */ 62 } 63 } 64 freesubfont(sf); 65 agefont(f); 66 twid += wid; 67 len -= l; 68 } 69 return twid; 70 } 71 72 int 73 stringnwidth(Font *f, char *s, int len) 74 { 75 return _stringnwidth(f, s, nil, len); 76 } 77 78 int 79 stringwidth(Font *f, char *s) 80 { 81 return _stringnwidth(f, s, nil, 1<<24); 82 } 83 84 Point 85 stringsize(Font *f, char *s) 86 { 87 return Pt(_stringnwidth(f, s, nil, 1<<24), f->height); 88 } 89 90 int 91 runestringnwidth(Font *f, Rune *r, int len) 92 { 93 return _stringnwidth(f, nil, r, len); 94 } 95 96 int 97 runestringwidth(Font *f, Rune *r) 98 { 99 return _stringnwidth(f, nil, r, 1<<24); 100 } 101 102 Point 103 runestringsize(Font *f, Rune *r) 104 { 105 return Pt(_stringnwidth(f, nil, r, 1<<24), f->height); 106 }