xref: /inferno-os/libdraw/stringwidth.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1 #include "lib9.h"
2 #include "draw.h"
3 
4 int
_stringnwidth(Font * f,char * s,Rune * r,int len)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
stringnwidth(Font * f,char * s,int len)63 stringnwidth(Font *f, char *s, int len)
64 {
65 	return _stringnwidth(f, s, nil, len);
66 }
67 
68 int
stringwidth(Font * f,char * s)69 stringwidth(Font *f, char *s)
70 {
71 	return _stringnwidth(f, s, nil, 1<<24);
72 }
73 
74 Point
stringsize(Font * f,char * s)75 stringsize(Font *f, char *s)
76 {
77 	return Pt(_stringnwidth(f, s, nil, 1<<24), f->height);
78 }
79 
80 int
runestringnwidth(Font * f,Rune * r,int len)81 runestringnwidth(Font *f, Rune *r, int len)
82 {
83 	return _stringnwidth(f, nil, r, len);
84 }
85 
86 int
runestringwidth(Font * f,Rune * r)87 runestringwidth(Font *f, Rune *r)
88 {
89 	return _stringnwidth(f, nil, r, 1<<24);
90 }
91 
92 Point
runestringsize(Font * f,Rune * r)93 runestringsize(Font *f, Rune *r)
94 {
95 	return Pt(_stringnwidth(f, nil, r, 1<<24), f->height);
96 }
97