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