plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

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 }