]> git.lyx.org Git - lyx.git/blob - src/FontInfo.C
Michael's "can not -> cannot" patch.
[lyx.git] / src / FontInfo.C
1 /* This file is part of
2  * ====================================================== 
3  * 
4  *           LyX, The Document Processor
5  *       
6  *          Copyright 1997 Asger Alstrup
7  *           and the LyX Team.
8  *
9  * ====================================================== */
10
11 #include <config.h>
12 #include <cmath>        // fabs()
13
14 #ifdef __GNUG__
15 #pragma implementation "FontInfo.h"
16 #endif
17
18 #include "FontInfo.h"
19 #include "debug.h"
20 #include "lyxrc.h"      // lyxrc.use_scalable_fonts
21 #include "support/lstrings.h"
22 #include "support/lyxlib.h"
23 #include "frontends/GUIRunTime.h"
24
25 using std::endl;
26
27 #ifndef CXX_GLOBAL_CSTD
28 using std::fabs;
29 #endif
30
31 /// Load font close to this size
32 string const FontInfo::getFontname(int size)
33 {
34         if (!exist())
35                 return string();
36
37         int closestind = -1;
38         double error = 100000.0;
39
40         for (int i = 0; i < matches; ++i) {
41                 if (sizes[i] == 0) {
42                         // Scalable font should not be considered close
43                 } else if (sizes[i] == size) {
44                         lyxerr[Debug::FONT] << "Exact font match with\n"
45                                             << strings[i] << endl;
46                         return strings[i];
47                 } else if (fabs(sizes[i] - size - 0.1) < error) {
48                         error = fabs(sizes[i] - size - 0.1);
49                         closestind = i;
50                 }
51         }
52
53         if (scalable && (lyxrc.use_scalable_fonts || closestind == -1)) {
54                 // We can use scalable
55                 string const font = resize(strings[scaleindex], size);
56                 lyxerr[Debug::FONT] << "Using scalable font to get\n"
57                                     << font << endl;
58                 return font;
59         }
60
61         // Did any fonts get close?
62         if (closestind == -1) {
63                 // No, so...
64                 return string();
65         }
66
67         // We use the closest match
68         lyxerr[Debug::FONT] << "Using closest font match to get size "
69                             << size 
70                             << " with\n" << strings[closestind] << endl;
71         return strings[closestind];
72 }
73
74
75 /// Build newly sized font string 
76 string const FontInfo::resize(string const & font, int size) const
77 {
78         string ret(font);
79         // Find the position of the size spec
80         int cut = 0;
81         string::iterator before = string::iterator(0);
82         string::iterator after = string::iterator(0);
83         for (string::iterator sit = ret.begin();
84              sit != ret.end(); ++sit)
85                 if ((*sit) == '-') {
86                         ++cut;
87                         if (cut == 7) before = sit + 1;
88                         else if (cut == 8) {
89                                 after = sit;
90                                 break;
91                         }
92                 }
93         ret.replace(before, after, tostr(size));
94         return ret;
95 }
96
97
98 /// Set new pattern
99 void FontInfo::setPattern(string const & pat)
100 {
101         release();
102         init();
103         pattern = pat;
104 }
105
106
107 /// Query font in X11
108 void FontInfo::query()
109 {
110         if (queried)
111                 return;
112
113         if (pattern.empty()) {
114                 lyxerr << "Cannot use empty font name for font query."
115                        << endl;
116                 queried = true;
117                 return;
118         }
119
120         char ** list = 0;
121         if (lyxrc.use_gui)
122                 list = XListFonts(GUIRunTime::x11Display(), pattern.c_str(),
123                                   100, &matches);
124
125         if (list == 0) {
126                 // No fonts matched
127                 scalable = false;
128                 sizes = 0;
129         } else {
130                 release();
131                 sizes = new int[matches];
132                 strings = new string[matches];
133
134                 // We have matches. Run them through
135                 for (int i = 0; i < matches; ++i) {
136                         string name(list[i]);
137                         lyxerr[Debug::FONT] << "match #" << i << " "
138                                             << name << endl; 
139                         sizes[i] = lyx::atoi(token(name, '-', 7));
140                         strings[i] = name;
141                         if (sizes[i] == 0) {
142                                 if (scaleindex == -1) {
143                                         scaleindex = i;
144                                 }
145                                 scalable = true;
146                         };
147                 };
148                 XFreeFontNames(list);
149         }
150         queried = true;
151 }
152
153
154 void FontInfo::init()
155 {
156         sizes = 0;
157         strings = 0;
158         matches = 0;
159         queried = false;
160         scalable = false;
161         scaleindex = -1;
162 }
163
164
165 /// Release allocated stuff
166 void FontInfo::release()
167 {
168         if (sizes) {
169                 delete [] sizes;
170                 sizes = 0;
171         }
172         if (strings) {
173                 delete [] strings;
174                 strings = 0;
175         }
176 }