Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
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;
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 }
72 int
73 stringnwidth(Font *f, char *s, int len)
74 {
75 return _stringnwidth(f, s, nil, len);
76 }
78 int
79 stringwidth(Font *f, char *s)
80 {
81 return _stringnwidth(f, s, nil, 1<<24);
82 }
84 Point
85 stringsize(Font *f, char *s)
86 {
87 return Pt(_stringnwidth(f, s, nil, 1<<24), f->height);
88 }
90 int
91 runestringnwidth(Font *f, Rune *r, int len)
92 {
93 return _stringnwidth(f, nil, r, len);
94 }
96 int
97 runestringwidth(Font *f, Rune *r)
98 {
99 return _stringnwidth(f, nil, r, 1<<24);
102 Point
103 runestringsize(Font *f, Rune *r)
105 return Pt(_stringnwidth(f, nil, r, 1<<24), f->height);