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