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