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