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