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