]> git.lyx.org Git - lyx.git/blob - src/frontends/qt2/qfont_loader.C
2e34c41b8d809d6f5ae8bdce31cfd5080b9294ba
[lyx.git] / src / frontends / qt2 / qfont_loader.C
1 /**
2  * \file qfont_loader.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 #ifdef __GNUG__
15 #pragma implementation
16 #endif
17
18 #include "qfont_loader.h"
19 #include "gettext.h"
20 #include "debug.h"
21 #include "lyxrc.h"
22 #include "BufferView.h"
23
24 #include <qglobal.h>
25 #if QT_VERSION < 300
26 #include "support/lstrings.h"
27 #endif
28
29 #ifdef Q_WS_X11
30 #include <qwidget.h>
31 #include <X11/Xlib.h>
32 #include "support/systemcall.h"
33 #include "support/filetools.h"
34 #endif
35
36 using std::endl;
37
38
39 qfont_loader::qfont_loader()
40 {
41         for (int i1 = 0; i1 < LyXFont::NUM_FAMILIES; ++i1) {
42                 for (int i2 = 0; i2 < 2; ++i2) {
43                         for (int i3 = 0; i3 < 4; ++i3) {
44                                 for (int i4 = 0; i4 < 10; ++i4) {
45                                         fontinfo_[i1][i2][i3][i4] = 0;
46                                 }
47                         }
48                 }
49         }
50 }
51
52
53 qfont_loader::~qfont_loader()
54 {
55 }
56
57
58 void qfont_loader::update()
59 {
60         for (int i1 = 0; i1 < LyXFont::NUM_FAMILIES; ++i1) {
61                 for (int i2 = 0; i2 < 2; ++i2) {
62                         for (int i3 = 0; i3 < 4; ++i3) {
63                                 for (int i4 = 0; i4 < 10; ++i4) {
64                                         delete fontinfo_[i1][i2][i3][i4];
65                                         fontinfo_[i1][i2][i3][i4] = 0;
66                                 }
67                         }
68                 }
69         }
70 }
71
72
73 QFont const & qfont_loader::get(LyXFont const & f)
74 {
75         QFont const & ret(getfontinfo(f)->font);
76
77         if (lyxerr.debugging(Debug::FONT)) {
78                 lyxerr[Debug::FONT] << "Font '" << f.stateText(0)
79                         << "' matched by\n" << ret.rawName() << endl;
80         }
81
82         lyxerr[Debug::FONT] << "The font has size: "
83                             << ret.pointSizeFloat() << endl;
84
85         return ret;
86 }
87
88 namespace {
89
90 string const symbolPattern(LyXFont::FONT_FAMILY family)
91 {
92         switch (family) {
93         case LyXFont::SYMBOL_FAMILY:
94                 return "-*-symbol-*-*-*-*-*-*-*-*-*-*-adobe-fontspecific";
95
96         case LyXFont::CMR_FAMILY:
97                 return "-*-cmr10-medium-*-*-*-*-*-*-*-*-*-*-*";
98
99         case LyXFont::CMSY_FAMILY:
100                 return "-*-cmsy10-*-*-*-*-*-*-*-*-*-*-*-*";
101
102         case LyXFont::CMM_FAMILY:
103                 return "-*-cmmi10-medium-*-*-*-*-*-*-*-*-*-*-*";
104
105         case LyXFont::CMEX_FAMILY:
106                 return "-*-cmex10-*-*-*-*-*-*-*-*-*-*-*-*";
107
108         case LyXFont::MSA_FAMILY:
109                 return "-*-msam10-*-*-*-*-*-*-*-*-*-*-*-*";
110
111         case LyXFont::MSB_FAMILY:
112                 return "-*-msbm10-*-*-*-*-*-*-*-*-*-*-*-*";
113
114         case LyXFont::EUFRAK_FAMILY:
115                 return "-*-eufm10-medium-*-*-*-*-*-*-*-*-*-*-*";
116
117         case LyXFont::WASY_FAMILY:
118                 return "-*-wasy10-medium-*-*-*-*-*-*-*-*-*-*-*";
119
120         default:
121                 return string();
122         }       
123 }
124
125 bool addFontPath()
126 {
127 #ifdef Q_WS_X11
128         string const dir =  OnlyPath(LibFileSearch("xfonts", "fonts.dir"));
129         if (!dir.empty()) {
130                 QWidget w;
131                 int n;
132                 char ** p = XGetFontPath(w.x11Display(), &n);
133                 if (std::find(p, p + n, dir) != p + n)
134                         return false;
135                 lyxerr << "Adding " << dir << " to the font path.\n";
136                 string const command = "xset fp+ " + dir;
137                 Systemcall s;
138                 if (!s.startscript(Systemcall::Wait, command)) 
139                         return true;
140                 lyxerr << "Unable to add font path.\n";
141         }
142 #endif
143         return false;
144 }
145
146 bool isAvailable(QFont const & font, LyXFont const & f) {
147 #if QT_VERSION >= 300
148         return font.exactMatch();
149 #else
150         string tmp = symbolPattern(f.family());
151         if (tmp.empty())
152                 return false;
153         else
154                 return token(tmp, '-', 2) == 
155                         token(font.rawName().latin1(), '-', 2);
156 #endif
157 }
158
159 } // namespace anon
160
161 qfont_loader::font_info::font_info(LyXFont const & f)
162         : metrics(font)
163 {
164
165         string pat = symbolPattern(f.family());
166         if (!pat.empty()) {
167                 static bool first_time = true;
168                 font.setRawName(pat.c_str());
169                 if (f.family() != LyXFont::SYMBOL_FAMILY &&
170                     !isAvailable(font, f) && first_time) {
171                         first_time = false;
172                         if (addFontPath()) {
173                                 font.setRawName(pat.c_str());
174                         }
175                 }
176         } else 
177                 switch (f.family()) {
178                 case LyXFont::ROMAN_FAMILY:
179                         font.setFamily(lyxrc.roman_font_name.c_str());
180                         break;
181                 case LyXFont::SANS_FAMILY:
182                         font.setFamily(lyxrc.sans_font_name.c_str());
183                         break;
184                 case LyXFont::TYPEWRITER_FAMILY:
185                         font.setFamily(lyxrc.typewriter_font_name.c_str());
186                         break;
187                 default:
188                         break;
189         }
190
191         font.setPointSizeFloat(lyxrc.font_sizes[f.size()]
192                                * lyxrc.zoom / 100.0);
193
194         switch (f.series()) {
195                 case LyXFont::MEDIUM_SERIES:
196                         font.setWeight(QFont::Normal);
197                         break;
198                 case LyXFont::BOLD_SERIES:
199                         font.setWeight(QFont::Bold);
200                         break;
201         }
202
203         switch (f.realShape()) {
204                 case LyXFont::ITALIC_SHAPE:
205                 case LyXFont::SLANTED_SHAPE:
206                         font.setItalic(true);
207                         break;
208         }
209
210         // Is this an exact match?
211         if (font.exactMatch()) {
212                 lyxerr[Debug::FONT] << "This font is an exact match" << endl;
213         } else {
214                 lyxerr[Debug::FONT] << "This font is NOT an exact match"
215                                     << endl;
216         }
217
218         lyxerr[Debug::FONT] << "XFLD: " << font.rawName() << endl;
219
220         metrics = QFontMetrics(font);
221 }
222
223
224 qfont_loader::font_info const * qfont_loader::getfontinfo(LyXFont const & f)
225 {
226         if (!lyxrc.use_gui) {
227                 // FIXME
228         }
229
230         font_info const * fi = fontinfo_[f.family()][f.series()][f.realShape()][f.size()];
231         if (!fi) {
232                 fi = new font_info(f);
233                 fontinfo_[f.family()][f.series()][f.realShape()][f.size()] = fi;
234         }
235
236         return fi;
237 }
238
239
240 bool qfont_loader::available(LyXFont const & f)
241 {
242         if (!lyxrc.use_gui)
243                 return false;
244
245         return isAvailable(getfontinfo(f)->font, f);
246 }