]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FontInfo.C
non-templated tostr in separate files
[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 #include "debug.h"
16 #include "lyxrc.h"      // lyxrc.use_scalable_fonts
17
18 #include "support/tostr.h"
19 #include "support/lstrings.h"
20 #include "support/lyxlib.h"
21
22 #include "frontends/lyx_gui.h"
23
24 #include <cmath>        // abs()
25
26 using std::endl;
27 using std::abs;
28
29 #include FORMS_H_LOCATION
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 (abs(sizes[i] - size - 0.1) < error) {
48                         error = abs(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         init();
102         pattern = pat;
103 }
104
105
106 /// Query font in X11
107 void FontInfo::query()
108 {
109         if (queried)
110                 return;
111
112         if (pattern.empty()) {
113                 lyxerr << "Cannot use empty font name for font query."
114                        << endl;
115                 queried = true;
116                 return;
117         }
118
119         char ** list = 0;
120         if (lyx_gui::use_gui)
121                 list = XListFonts(fl_get_display(), pattern.c_str(),
122                                   100, &matches);
123
124         if (list == 0) {
125                 // No fonts matched
126                 scalable = false;
127                 sizes.reset();
128         } else {
129                 sizes.reset(new int[matches]);
130                 strings.reset(new string[matches]);
131
132                 // We have matches. Run them through
133                 for (int i = 0; i < matches; ++i) {
134                         string name(list[i]);
135                         lyxerr[Debug::FONT] << "match #" << i << ' '
136                                             << name << endl;
137                         sizes[i] = lyx::atoi(token(name, '-', 7));
138                         strings[i] = name;
139                         if (sizes[i] == 0) {
140                                 if (scaleindex == -1) {
141                                         scaleindex = i;
142                                 }
143                                 scalable = true;
144                         } else if (lyx::atoi(token(name, '-', 12)) == 0)
145                                 // Ignore bogus matches of scalable fonts.
146                                 sizes[i] = 0;
147                 };
148                 XFreeFontNames(list);
149         }
150         queried = true;
151 }
152
153
154 void FontInfo::init()
155 {
156         sizes.reset();
157         strings.reset();
158         matches = 0;
159         queried = false;
160         scalable = false;
161         scaleindex = -1;
162 }