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