]> git.lyx.org Git - features.git/blob - src/FontInfo.C
43aa03c5770277ea01e79389ef3b466c3b99ed97
[features.git] / src / FontInfo.C
1 /* This file is part of
2  * ====================================================== 
3  * 
4  *           LyX, The Document Processor
5  *       
6  *          Copyright 1997 Asger Alstrup
7  *           and the LyX Team.
8  *
9  * ====================================================== */
10
11 #include <config.h>
12 #include <cmath>        // fabs()
13
14 #ifdef __GNUG__
15 #pragma implementation "FontInfo.h"
16 #endif
17
18 #include "FontInfo.h"
19 #include "debug.h"
20 #include "lyxrc.h"      // lyxrc.use_scalable_fonts
21 #include "support/lstrings.h"
22 #include "frontends/GUIRunTime.h"
23
24 using std::endl;
25
26 #ifndef CXX_GLOBAL_CSTD
27 using std::fabs;
28 #endif
29
30 /// Load font close to this size
31 string const FontInfo::getFontname(int size)
32 {
33         if (!exist())
34                 return string();
35
36         int closestind = -1;
37         double error = 100000.0;
38
39         for (int i = 0; i < matches; ++i) {
40                 if (sizes[i] == 0) {
41                         // Scalable font should not be considered close
42                 } else if (sizes[i] == size) {
43                         lyxerr[Debug::FONT] << "Exact font match with\n"
44                                             << strings[i] << endl;
45                         return strings[i];
46                 } else if (fabs(sizes[i] - size - 0.1) < error) {
47                         error = fabs(sizes[i] - size - 0.1);
48                         closestind = i;
49                 }
50         }
51
52         if (scalable && lyxrc.use_scalable_fonts) {
53                 // We can use scalable
54                 string const font = resize(strings[scaleindex], size);
55                 lyxerr[Debug::FONT] << "Using scalable font to get\n"
56                                     << font << endl;
57                 return font;
58         }
59
60         // Did any fonts get close?
61         if (closestind == -1) {
62                 // No, and we are not allowed to use scalables, so...
63                 return string();
64         }
65
66         // We use the closest match
67         lyxerr[Debug::FONT] << "Using closest font match to get size "
68                             << size 
69                             << " with\n" << strings[closestind] << endl;
70         return strings[closestind];
71 }
72
73
74 /// Build newly sized font string 
75 string const FontInfo::resize(string const & font, int size) const
76 {
77         string ret(font);
78         // Find the position of the size spec
79         int cut = 0;
80         string::iterator before = string::iterator(0);
81         string::iterator after = string::iterator(0);
82         for (string::iterator sit = ret.begin();
83              sit != ret.end(); ++sit)
84                 if ((*sit) == '-') {
85                         ++cut;
86                         if (cut == 7) before = sit + 1;
87                         else if (cut == 8) {
88                                 after = sit;
89                                 break;
90                         }
91                 }
92         ret.replace(before, after, tostr(size));
93         return ret;
94 }
95
96
97 /// Set new pattern
98 void FontInfo::setPattern(string const & pat)
99 {
100         release();
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 << "Can not use empty font name for font query."
114                        << endl;
115                 queried = true;
116                 return;
117         }
118
119         char ** list = 0;
120         if (lyxrc.use_gui)
121                 list = XListFonts(GUIRunTime::x11Display(), pattern.c_str(),
122                                   100, &matches);
123
124         if (list == 0) {
125                 // No fonts matched
126                 scalable = false;
127                 sizes = 0;
128         } else {
129                 release();
130                 sizes = new int[matches];
131                 strings = new string[matches];
132
133                 // We have matches. Run them through
134                 for (int i = 0; i < matches; ++i) {
135                         string name(list[i]);
136                         sizes[i] = lyx::atoi(token(name, '-', 7));
137                         strings[i] = name;
138                         if (sizes[i] == 0) {
139                                 if (scaleindex == -1) {
140                                         scaleindex = i;
141                                 }
142                                 scalable = true;
143                         };
144                 };
145                 XFreeFontNames(list);
146         }
147         queried = true;
148 }
149
150
151 void FontInfo::init()
152 {
153         sizes = 0;
154         strings = 0;
155         matches = 0;
156         queried = false;
157         scalable = false;
158         scaleindex = -1;
159 }
160
161
162 /// Release allocated stuff
163 void FontInfo::release()
164 {
165         if (sizes) {
166                 delete [] sizes;
167                 sizes = 0;
168         }
169         if (strings) {
170                 delete [] strings;
171                 strings = 0;
172         }
173 }