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