blob: 522fbc0115d07609314b5133b5ef1adf11eddbb7 [file] [log] [blame]
rsc76193d72003-09-30 17:47:42 +00001#include <u.h>
2#include <libc.h>
3#include <draw.h>
4
5static Rune empty[] = { 0 };
6int
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;
rscb2f9ee02005-07-13 03:57:24 +000016 Subfont *sf;
rsc76193d72003-09-30 17:47:42 +000017
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;
rsc4e206882004-04-25 20:26:27 +000029 while(len>0 && (*s || *r)){
rsc76193d72003-09-30 17:47:42 +000030 max = Max;
31 if(len < max)
32 max = len;
33 n = 0;
rscb2f9ee02005-07-13 03:57:24 +000034 sf = nil;
rsc76193d72003-09-30 17:47:42 +000035 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";
rscb2f9ee02005-07-13 03:57:24 +000045 freesubfont(sf);
rsc76193d72003-09-30 17:47:42 +000046 fprint(2, "stringwidth: bad character set for rune 0x%.4ux in %s\n", rune, name);
47 return twid;
48 }
49 if(subfontname){
rscb2f9ee02005-07-13 03:57:24 +000050 freesubfont(sf);
51 if((sf=_getsubfont(f->display, subfontname)) == 0){
52 def = f->display ? f->display->defaultfont : nil;
rsc76193d72003-09-30 17:47:42 +000053 if(def && f!=def)
54 f = def;
55 else
56 break;
57 }
rscb2f9ee02005-07-13 03:57:24 +000058 /*
59 * must not free sf until cachechars has found it in the cache
60 * and picked up its own reference.
61 */
rsc76193d72003-09-30 17:47:42 +000062 }
63 }
rscb2f9ee02005-07-13 03:57:24 +000064 freesubfont(sf);
rsc76193d72003-09-30 17:47:42 +000065 agefont(f);
66 twid += wid;
67 len -= l;
68 }
69 return twid;
70}
71
72int
73stringnwidth(Font *f, char *s, int len)
74{
75 return _stringnwidth(f, s, nil, len);
76}
77
78int
79stringwidth(Font *f, char *s)
80{
81 return _stringnwidth(f, s, nil, 1<<24);
82}
83
84Point
85stringsize(Font *f, char *s)
86{
87 return Pt(_stringnwidth(f, s, nil, 1<<24), f->height);
88}
89
90int
91runestringnwidth(Font *f, Rune *r, int len)
92{
93 return _stringnwidth(f, nil, r, len);
94}
95
96int
97runestringwidth(Font *f, Rune *r)
98{
99 return _stringnwidth(f, nil, r, 1<<24);
100}
101
102Point
103runestringsize(Font *f, Rune *r)
104{
105 return Pt(_stringnwidth(f, nil, r, 1<<24), f->height);
106}