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