xref: /inferno-os/libdraw/stringwidth.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsyth #include "lib9.h"
2*37da2899SCharles.Forsyth #include "draw.h"
3*37da2899SCharles.Forsyth 
4*37da2899SCharles.Forsyth int
_stringnwidth(Font * f,char * s,Rune * r,int len)5*37da2899SCharles.Forsyth _stringnwidth(Font *f, char *s, Rune *r, int len)
6*37da2899SCharles.Forsyth {
7*37da2899SCharles.Forsyth 	int wid, twid, n, max, l;
8*37da2899SCharles.Forsyth 	char *name;
9*37da2899SCharles.Forsyth 	enum { Max = 64 };
10*37da2899SCharles.Forsyth 	ushort cbuf[Max];
11*37da2899SCharles.Forsyth 	Rune rune, **rptr;
12*37da2899SCharles.Forsyth 	char *subfontname, **sptr;
13*37da2899SCharles.Forsyth 	Font *def;
14*37da2899SCharles.Forsyth 	static Rune rnull;
15*37da2899SCharles.Forsyth 
16*37da2899SCharles.Forsyth 	if(s == nil){
17*37da2899SCharles.Forsyth 		s = "";
18*37da2899SCharles.Forsyth 		sptr = nil;
19*37da2899SCharles.Forsyth 	}else
20*37da2899SCharles.Forsyth 		sptr = &s;
21*37da2899SCharles.Forsyth 	if(r == nil){
22*37da2899SCharles.Forsyth 		r = &rnull;
23*37da2899SCharles.Forsyth 		rptr = nil;
24*37da2899SCharles.Forsyth 	}else
25*37da2899SCharles.Forsyth 		rptr = &r;
26*37da2899SCharles.Forsyth 	twid = 0;
27*37da2899SCharles.Forsyth 	while(len>0 && (*s || *r)){
28*37da2899SCharles.Forsyth 		max = Max;
29*37da2899SCharles.Forsyth 		if(len < max)
30*37da2899SCharles.Forsyth 			max = len;
31*37da2899SCharles.Forsyth 		n = 0;
32*37da2899SCharles.Forsyth 		while((l = cachechars(f, sptr, rptr, cbuf, max, &wid, &subfontname)) <= 0){
33*37da2899SCharles.Forsyth 			if(++n > 10){
34*37da2899SCharles.Forsyth 				if(*r)
35*37da2899SCharles.Forsyth 					rune = *r;
36*37da2899SCharles.Forsyth 				else
37*37da2899SCharles.Forsyth 					chartorune(&rune, s);
38*37da2899SCharles.Forsyth 				if(f->name != nil)
39*37da2899SCharles.Forsyth 					name = f->name;
40*37da2899SCharles.Forsyth 				else
41*37da2899SCharles.Forsyth 					name = "unnamed font";
42*37da2899SCharles.Forsyth 				_drawprint(2, "stringwidth: bad character set for rune 0x%.4ux in %s\n", rune, name);
43*37da2899SCharles.Forsyth 				return twid;
44*37da2899SCharles.Forsyth 			}
45*37da2899SCharles.Forsyth 			if(subfontname){
46*37da2899SCharles.Forsyth 				if(_getsubfont(f->display, subfontname) == 0){
47*37da2899SCharles.Forsyth 					def = f->display->defaultfont;
48*37da2899SCharles.Forsyth 					if(def && f!=def)
49*37da2899SCharles.Forsyth 						f = def;
50*37da2899SCharles.Forsyth 					else
51*37da2899SCharles.Forsyth 						break;
52*37da2899SCharles.Forsyth 				}
53*37da2899SCharles.Forsyth 			}
54*37da2899SCharles.Forsyth 		}
55*37da2899SCharles.Forsyth 		agefont(f);
56*37da2899SCharles.Forsyth 		twid += wid;
57*37da2899SCharles.Forsyth 		len -= l;
58*37da2899SCharles.Forsyth 	}
59*37da2899SCharles.Forsyth 	return twid;
60*37da2899SCharles.Forsyth }
61*37da2899SCharles.Forsyth 
62*37da2899SCharles.Forsyth int
stringnwidth(Font * f,char * s,int len)63*37da2899SCharles.Forsyth stringnwidth(Font *f, char *s, int len)
64*37da2899SCharles.Forsyth {
65*37da2899SCharles.Forsyth 	return _stringnwidth(f, s, nil, len);
66*37da2899SCharles.Forsyth }
67*37da2899SCharles.Forsyth 
68*37da2899SCharles.Forsyth int
stringwidth(Font * f,char * s)69*37da2899SCharles.Forsyth stringwidth(Font *f, char *s)
70*37da2899SCharles.Forsyth {
71*37da2899SCharles.Forsyth 	return _stringnwidth(f, s, nil, 1<<24);
72*37da2899SCharles.Forsyth }
73*37da2899SCharles.Forsyth 
74*37da2899SCharles.Forsyth Point
stringsize(Font * f,char * s)75*37da2899SCharles.Forsyth stringsize(Font *f, char *s)
76*37da2899SCharles.Forsyth {
77*37da2899SCharles.Forsyth 	return Pt(_stringnwidth(f, s, nil, 1<<24), f->height);
78*37da2899SCharles.Forsyth }
79*37da2899SCharles.Forsyth 
80*37da2899SCharles.Forsyth int
runestringnwidth(Font * f,Rune * r,int len)81*37da2899SCharles.Forsyth runestringnwidth(Font *f, Rune *r, int len)
82*37da2899SCharles.Forsyth {
83*37da2899SCharles.Forsyth 	return _stringnwidth(f, nil, r, len);
84*37da2899SCharles.Forsyth }
85*37da2899SCharles.Forsyth 
86*37da2899SCharles.Forsyth int
runestringwidth(Font * f,Rune * r)87*37da2899SCharles.Forsyth runestringwidth(Font *f, Rune *r)
88*37da2899SCharles.Forsyth {
89*37da2899SCharles.Forsyth 	return _stringnwidth(f, nil, r, 1<<24);
90*37da2899SCharles.Forsyth }
91*37da2899SCharles.Forsyth 
92*37da2899SCharles.Forsyth Point
runestringsize(Font * f,Rune * r)93*37da2899SCharles.Forsyth runestringsize(Font *f, Rune *r)
94*37da2899SCharles.Forsyth {
95*37da2899SCharles.Forsyth 	return Pt(_stringnwidth(f, nil, r, 1<<24), f->height);
96*37da2899SCharles.Forsyth }
97