17dd7cddfSDavid du Colombier #include <u.h> 27dd7cddfSDavid du Colombier #include <libc.h> 37dd7cddfSDavid du Colombier #include <draw.h> 47dd7cddfSDavid du Colombier 57dd7cddfSDavid du Colombier int 67dd7cddfSDavid du Colombier _stringnwidth(Font *f, char *s, Rune *r, int len) 77dd7cddfSDavid du Colombier { 87dd7cddfSDavid du Colombier int wid, twid, n, max, l; 9*9a747e4fSDavid du Colombier char *name; 107dd7cddfSDavid du Colombier enum { Max = 64 }; 117dd7cddfSDavid du Colombier ushort cbuf[Max]; 12*9a747e4fSDavid du Colombier Rune rune, **rptr; 137dd7cddfSDavid du Colombier char *subfontname, **sptr; 147dd7cddfSDavid du Colombier Font *def; 157dd7cddfSDavid du Colombier 167dd7cddfSDavid du Colombier if(s == nil){ 177dd7cddfSDavid du Colombier s = ""; 187dd7cddfSDavid du Colombier sptr = nil; 197dd7cddfSDavid du Colombier }else 207dd7cddfSDavid du Colombier sptr = &s; 217dd7cddfSDavid du Colombier if(r == nil){ 227dd7cddfSDavid du Colombier r = L""; 237dd7cddfSDavid du Colombier rptr = nil; 247dd7cddfSDavid du Colombier }else 257dd7cddfSDavid du Colombier rptr = &r; 267dd7cddfSDavid du Colombier twid = 0; 277dd7cddfSDavid du Colombier while((*s || *r) && len){ 287dd7cddfSDavid du Colombier max = Max; 297dd7cddfSDavid du Colombier if(len < max) 307dd7cddfSDavid du Colombier max = len; 317dd7cddfSDavid du Colombier n = 0; 327dd7cddfSDavid du Colombier while((l = cachechars(f, sptr, rptr, cbuf, max, &wid, &subfontname)) <= 0){ 337dd7cddfSDavid du Colombier if(++n > 10){ 34*9a747e4fSDavid du Colombier if(*r) 35*9a747e4fSDavid du Colombier rune = *r; 36*9a747e4fSDavid du Colombier else 37*9a747e4fSDavid du Colombier chartorune(&rune, s); 38*9a747e4fSDavid du Colombier if(f->name != nil) 39*9a747e4fSDavid du Colombier name = f->name; 40*9a747e4fSDavid du Colombier else 41*9a747e4fSDavid du Colombier name = "unnamed font"; 42*9a747e4fSDavid du Colombier fprint(2, "stringwidth: bad character set for rune 0x%.4ux in %s\n", rune, name); 437dd7cddfSDavid du Colombier return twid; 447dd7cddfSDavid du Colombier } 457dd7cddfSDavid du Colombier if(subfontname){ 467dd7cddfSDavid du Colombier if(_getsubfont(f->display, subfontname) == 0){ 477dd7cddfSDavid du Colombier def = f->display->defaultfont; 487dd7cddfSDavid du Colombier if(def && f!=def) 497dd7cddfSDavid du Colombier f = def; 507dd7cddfSDavid du Colombier else 517dd7cddfSDavid du Colombier break; 527dd7cddfSDavid du Colombier } 537dd7cddfSDavid du Colombier } 547dd7cddfSDavid du Colombier } 557dd7cddfSDavid du Colombier agefont(f); 567dd7cddfSDavid du Colombier twid += wid; 577dd7cddfSDavid du Colombier len -= l; 587dd7cddfSDavid du Colombier } 597dd7cddfSDavid du Colombier return twid; 607dd7cddfSDavid du Colombier } 617dd7cddfSDavid du Colombier 627dd7cddfSDavid du Colombier int 637dd7cddfSDavid du Colombier stringnwidth(Font *f, char *s, int len) 647dd7cddfSDavid du Colombier { 657dd7cddfSDavid du Colombier return _stringnwidth(f, s, nil, len); 667dd7cddfSDavid du Colombier } 677dd7cddfSDavid du Colombier 687dd7cddfSDavid du Colombier int 697dd7cddfSDavid du Colombier stringwidth(Font *f, char *s) 707dd7cddfSDavid du Colombier { 717dd7cddfSDavid du Colombier return _stringnwidth(f, s, nil, 1<<24); 727dd7cddfSDavid du Colombier } 737dd7cddfSDavid du Colombier 747dd7cddfSDavid du Colombier Point 757dd7cddfSDavid du Colombier stringsize(Font *f, char *s) 767dd7cddfSDavid du Colombier { 777dd7cddfSDavid du Colombier return Pt(_stringnwidth(f, s, nil, 1<<24), f->height); 787dd7cddfSDavid du Colombier } 797dd7cddfSDavid du Colombier 807dd7cddfSDavid du Colombier int 817dd7cddfSDavid du Colombier runestringnwidth(Font *f, Rune *r, int len) 827dd7cddfSDavid du Colombier { 837dd7cddfSDavid du Colombier return _stringnwidth(f, nil, r, len); 847dd7cddfSDavid du Colombier } 857dd7cddfSDavid du Colombier 867dd7cddfSDavid du Colombier int 877dd7cddfSDavid du Colombier runestringwidth(Font *f, Rune *r) 887dd7cddfSDavid du Colombier { 897dd7cddfSDavid du Colombier return _stringnwidth(f, nil, r, 1<<24); 907dd7cddfSDavid du Colombier } 917dd7cddfSDavid du Colombier 927dd7cddfSDavid du Colombier Point 937dd7cddfSDavid du Colombier runestringsize(Font *f, Rune *r) 947dd7cddfSDavid du Colombier { 957dd7cddfSDavid du Colombier return Pt(_stringnwidth(f, nil, r, 1<<24), f->height); 967dd7cddfSDavid du Colombier } 97