diff options
Diffstat (limited to 'src/libdraw/stringwidth.c')
-rw-r--r-- | src/libdraw/stringwidth.c | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/libdraw/stringwidth.c b/src/libdraw/stringwidth.c new file mode 100644 index 00000000..c4877912 --- /dev/null +++ b/src/libdraw/stringwidth.c @@ -0,0 +1,97 @@ +#include <u.h> +#include <libc.h> +#include <draw.h> + +static Rune empty[] = { 0 }; +int +_stringnwidth(Font *f, char *s, Rune *r, int len) +{ + int wid, twid, n, max, l; + char *name; + enum { Max = 64 }; + ushort cbuf[Max]; + Rune rune, **rptr; + char *subfontname, **sptr; + Font *def; + + if(s == nil){ + s = ""; + sptr = nil; + }else + sptr = &s; + if(r == nil){ + r = empty; + rptr = nil; + }else + rptr = &r; + twid = 0; + while((*s || *r) && len){ + max = Max; + if(len < max) + max = len; + n = 0; + while((l = cachechars(f, sptr, rptr, cbuf, max, &wid, &subfontname)) <= 0){ + if(++n > 10){ + if(*r) + rune = *r; + else + chartorune(&rune, s); + if(f->name != nil) + name = f->name; + else + name = "unnamed font"; + fprint(2, "stringwidth: bad character set for rune 0x%.4ux in %s\n", rune, name); + return twid; + } + if(subfontname){ + if(_getsubfont(f->display, subfontname) == 0){ + def = f->display->defaultfont; + if(def && f!=def) + f = def; + else + break; + } + } + } + agefont(f); + twid += wid; + len -= l; + } + return twid; +} + +int +stringnwidth(Font *f, char *s, int len) +{ + return _stringnwidth(f, s, nil, len); +} + +int +stringwidth(Font *f, char *s) +{ + return _stringnwidth(f, s, nil, 1<<24); +} + +Point +stringsize(Font *f, char *s) +{ + return Pt(_stringnwidth(f, s, nil, 1<<24), f->height); +} + +int +runestringnwidth(Font *f, Rune *r, int len) +{ + return _stringnwidth(f, nil, r, len); +} + +int +runestringwidth(Font *f, Rune *r) +{ + return _stringnwidth(f, nil, r, 1<<24); +} + +Point +runestringsize(Font *f, Rune *r) +{ + return Pt(_stringnwidth(f, nil, r, 1<<24), f->height); +} |