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