]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/xfont_loader.C
New lyx_gui namespace. Some working out to be done still ..
[lyx.git] / src / frontends / xforms / xfont_loader.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
16 #endif
17
18 #include "xfont_loader.h"
19 #include "FontInfo.h"
20 #include "gettext.h"
21 #include "debug.h"
22 #include "lyxrc.h"      // lyxrc.font_*
23 #include "BufferView.h"
24 #include "frontends/LyXView.h"
25
26 #include FORMS_H_LOCATION
27
28 using std::endl;
29
30 extern BufferView * current_view;
31
32
33 // The global fontloader
34 xfont_loader fontloader;
35
36
37 // Initialize font loader
38 xfont_loader::xfont_loader()
39 {
40         reset();
41 }
42
43
44 // Destroy font loader
45 xfont_loader::~xfont_loader()
46 {
47         unload();
48 }
49
50
51 // Update fonts after zoom, dpi, font names, or norm change
52 // For now, we just ditch all fonts we have. Later, we should
53 // reuse the ones that are already loaded.
54 void xfont_loader::update()
55 {
56         unload();
57 }
58
59
60 // Reset font loader
61 void xfont_loader::reset()
62 {
63         // Clear font infos, font structs and font metrics
64         for (int i1 = 0; i1 < LyXFont::NUM_FAMILIES; ++i1)
65                 for (int i2 = 0; i2 < 2; ++i2)
66                         for (int i3 = 0; i3 < 4; ++i3) {
67                                 fontinfo[i1][i2][i3] = 0;
68                                 for (int i4 = 0; i4<10; ++i4) {
69                                         fontstruct[i1][i2][i3][i4] = 0;
70                                 }
71                         }
72 }
73
74
75 // Unload all fonts
76 void xfont_loader::unload()
77 {
78         // Unload all fonts
79         for (int i1 = 0; i1 < LyXFont::NUM_FAMILIES; ++i1)
80                 for (int i2 = 0; i2 < 2; ++i2)
81                         for (int i3 = 0; i3 < 4; ++i3) {
82                                 if (fontinfo[i1][i2][i3]) {
83                                         delete fontinfo[i1][i2][i3];
84                                         fontinfo[i1][i2][i3] = 0;
85                                 }
86                                 for (int i4 = 0; i4 < 10; ++i4) {
87                                         if (fontstruct[i1][i2][i3][i4]) {
88                                                 XFreeFont(fl_get_display(), fontstruct[i1][i2][i3][i4]);
89                                                 fontstruct[i1][i2][i3][i4] = 0;
90                                         }
91                                 }
92                         }
93 }
94
95
96 // Get font info
97 /* Takes care of finding which font that can match the given request. Tries
98 different alternatives. */
99 void xfont_loader::getFontinfo(LyXFont::FONT_FAMILY family,
100                              LyXFont::FONT_SERIES series,
101                              LyXFont::FONT_SHAPE shape)
102 {
103         // Do we have the font info already?
104         if (fontinfo[family][series][shape] != 0)
105                 return;
106
107         // Special fonts
108         switch (family)
109         {
110                 case LyXFont::SYMBOL_FAMILY:
111                         fontinfo[family][series][shape] =
112                                 new FontInfo("-*-symbol-*-*-*-*-*-*-*-*-*-*-adobe-fontspecific");
113                         return;
114
115                 case LyXFont::CMR_FAMILY:
116                         fontinfo[family][series][shape] =
117                                 new FontInfo("-*-cmr10-medium-*-*-*-*-*-*-*-*-*-*-*");
118                         return;
119
120                 case LyXFont::CMSY_FAMILY:
121                         fontinfo[family][series][shape] =
122                                 new FontInfo("-*-cmsy10-*-*-*-*-*-*-*-*-*-*-*-*");
123                         return;
124
125                 case LyXFont::CMM_FAMILY:
126                         fontinfo[family][series][shape] =
127                                 new FontInfo("-*-cmmi10-medium-*-*-*-*-*-*-*-*-*-*-*");
128                         return;
129
130                 case LyXFont::CMEX_FAMILY:
131                         fontinfo[family][series][shape] =
132                                 new FontInfo("-*-cmex10-*-*-*-*-*-*-*-*-*-*-*-*");
133                         return;
134
135                 case LyXFont::MSA_FAMILY:
136                         fontinfo[family][series][shape] =
137                                 new FontInfo("-*-msam10-*-*-*-*-*-*-*-*-*-*-*-*");
138                         return;
139
140                 case LyXFont::MSB_FAMILY:
141                         fontinfo[family][series][shape] =
142                                 new FontInfo("-*-msbm10-*-*-*-*-*-*-*-*-*-*-*-*");
143                         return;
144
145                 case LyXFont::EUFRAK_FAMILY:
146                         fontinfo[family][series][shape] =
147                                 new FontInfo("-*-eufm10-medium-*-*-*-*-*-*-*-*-*-*-*");
148                         return;
149
150                 default:
151                         break;
152         }
153
154
155         // Normal font. Let's search for an existing name that matches.
156         string ffamily;
157         string fseries;
158         string fshape;
159         string norm = lyxrc.font_norm;
160         string fontname;
161
162         FontInfo * fi = new FontInfo;
163         fontinfo[family][series][shape] = fi;
164
165         for (int cfam = 0; cfam < 2; ++cfam) {
166                 // Determine family name
167                 switch (family) {
168                 case LyXFont::ROMAN_FAMILY:
169                         switch (cfam) {
170                         case 0: ffamily = lyxrc.roman_font_name; break;
171                         case 1: ffamily = "-*-times";
172                         default: cfam = 100;
173                         }
174                         break;
175                 case LyXFont::SANS_FAMILY:
176                         switch (cfam) {
177                         case 0: ffamily = lyxrc.sans_font_name; break;
178                         case 1: ffamily = "-*-helvetica";
179                         default: cfam = 100;
180                         }
181                         break;
182                 case LyXFont::TYPEWRITER_FAMILY:
183                         switch (cfam) {
184                         case 0: ffamily = lyxrc.typewriter_font_name; break;
185                         case 1: ffamily = "-*-courier";
186                         default: cfam = 100;
187                         }
188                         break;
189                 default: ;
190                 }
191
192                 for (int cser = 0; cser < 4; ++cser) {
193                         // Determine series name
194                         switch (series) {
195                         case LyXFont::MEDIUM_SERIES:
196                                 switch (cser) {
197                                 case 0: fseries = "-medium"; break;
198                                 case 1: fseries = "-book"; break;
199                                 case 2: fseries = "-light";
200                                 default: cser = 100;
201                                 }
202                                 break;
203                         case LyXFont::BOLD_SERIES:
204                                 switch (cser) {
205                                 case 0: fseries = "-bold"; break;
206                                 case 1: fseries = "-black"; break;
207                                 case 2: fseries = "-demi"; break;
208                                 case 3: fseries = "-demibold";
209                                 default: cser = 100;
210                                 }
211                                 break;
212                         default: ;
213                         }
214
215                         for (int csha = 0; csha < 2; ++csha) {
216                                 // Determine shape name
217                                 switch (shape) {
218                                 case LyXFont::UP_SHAPE:
219                                 case LyXFont::SMALLCAPS_SHAPE:
220                                         switch (csha) {
221                                         case 0: fshape = "-r";
222                                         default: csha = 100;
223                                         }
224                                         break;
225                                 case LyXFont::ITALIC_SHAPE:
226                                         switch (csha) {
227                                         case 0: fshape = "-i"; break;
228                                         case 1: fshape = "-o";
229                                         default: csha = 100;
230                                         }
231                                         break;
232                                 case LyXFont::SLANTED_SHAPE:
233                                         switch (csha) {
234                                         case 0: fshape = "-o"; break;
235                                         case 1: fshape = "-i";
236                                         default: csha = 100;
237                                         }
238                                         break;
239                                 default: ;
240                                 }
241                                 //
242                                 fontname = ffamily + fseries + fshape +
243                                            "-normal-*-*-*-*-*-*-*-" + norm;
244                                 fi->setPattern(fontname);
245                                 if (fi->exist()) {
246                                         return;
247                                 }
248                         }
249                 }
250         }
251 }
252
253
254 // A dummy fontstruct used when there is no gui.
255 namespace {
256
257 XFontStruct dummyXFontStruct;
258 bool dummyXFontStructisGood = false;
259
260 } // namespace anon
261
262 /// Do load font
263 XFontStruct * xfont_loader::doLoad(LyXFont::FONT_FAMILY family,
264                                 LyXFont::FONT_SERIES series,
265                                 LyXFont::FONT_SHAPE shape,
266                                 LyXFont::FONT_SIZE size)
267 {
268         if (!lyxrc.use_gui) {
269                 if (!dummyXFontStructisGood) {
270                         // no character specific info
271                         dummyXFontStruct.per_char = 0;
272                         // unit ascent on character displays
273                         dummyXFontStruct.ascent = 1;
274                         // no descent on character displays
275                         dummyXFontStruct.descent = 0;
276                         dummyXFontStructisGood = true;
277                 }
278
279                 return &dummyXFontStruct;
280         }
281
282         getFontinfo(family, series, shape);
283         int fsize = int((lyxrc.font_sizes[size] * lyxrc.dpi *
284                           (lyxrc.zoom/100.0)) / 72.27 + 0.5);
285
286         string font = fontinfo[family][series][shape]->getFontname(fsize);
287
288         if (font.empty()) {
289                 lyxerr << "No font matches request. Using 'fixed'." << endl;
290                 lyxerr << "Start LyX as 'lyx -dbg 515' to get more information." << endl;
291                 font = "fixed";
292         }
293
294         XFontStruct * fs = 0;
295
296         current_view->owner()->messagePush(_("Loading font into X-Server..."));
297
298         fs = XLoadQueryFont(fl_get_display(), font.c_str());
299
300         if (fs == 0) {
301                 if (font == "fixed") {
302                         lyxerr << "We're doomed. Can't get 'fixed' font." << endl;
303                 } else {
304                         lyxerr << "Could not get font. Using 'fixed'." << endl;
305                         fs = XLoadQueryFont(fl_get_display(), "fixed");
306                 }
307         } else if (lyxerr.debugging(Debug::FONT)) {
308                 // Tell user the font matching
309                 LyXFont f;
310                 f.setFamily(family);
311                 f.setSeries(series);
312                 f.setShape(shape);
313                 f.setSize(size);
314                 // The rest of the attributes are not interesting
315                 f.setEmph(LyXFont::INHERIT);
316                 f.setUnderbar(LyXFont::INHERIT);
317                 f.setNoun(LyXFont::INHERIT);
318                 f.setColor(LColor::inherit);
319                 lyxerr << "Font '" << f.stateText(0)
320                        << "' matched by\n" << font << endl;
321         }
322
323         current_view->owner()->messagePop();
324
325         fontstruct[family][series][shape][size] = fs;
326         return fs;
327 }
328
329
330 bool xfont_loader::available(LyXFont const & f)
331 {
332         if (!lyxrc.use_gui)
333                 return false;
334
335         if (!fontinfo[f.family()][f.series()][f.realShape()])
336                 getFontinfo(f.family(), f.series(), f.realShape());
337         return fontinfo[f.family()][f.series()][f.realShape()]
338                 ->getFontname(f.size()).size();
339 }