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