]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/xfont_loader.C
support for wasy symbols
[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                 case LyXFont::WASY_FAMILY:
151                         fontinfo[family][series][shape] =
152                                 new FontInfo("-*-wasy10-medium-*-*-*-*-*-*-*-*-*-*-*");
153                         return;
154
155                 default:
156                         break;
157         }
158
159
160         // Normal font. Let's search for an existing name that matches.
161         string ffamily;
162         string fseries;
163         string fshape;
164         string norm = lyxrc.font_norm;
165         string fontname;
166
167         FontInfo * fi = new FontInfo;
168         fontinfo[family][series][shape] = fi;
169
170         for (int cfam = 0; cfam < 2; ++cfam) {
171                 // Determine family name
172                 switch (family) {
173                 case LyXFont::ROMAN_FAMILY:
174                         switch (cfam) {
175                         case 0: ffamily = lyxrc.roman_font_name; break;
176                         case 1: ffamily = "-*-times";
177                         default: cfam = 100;
178                         }
179                         break;
180                 case LyXFont::SANS_FAMILY:
181                         switch (cfam) {
182                         case 0: ffamily = lyxrc.sans_font_name; break;
183                         case 1: ffamily = "-*-helvetica";
184                         default: cfam = 100;
185                         }
186                         break;
187                 case LyXFont::TYPEWRITER_FAMILY:
188                         switch (cfam) {
189                         case 0: ffamily = lyxrc.typewriter_font_name; break;
190                         case 1: ffamily = "-*-courier";
191                         default: cfam = 100;
192                         }
193                         break;
194                 default: ;
195                 }
196
197                 for (int cser = 0; cser < 4; ++cser) {
198                         // Determine series name
199                         switch (series) {
200                         case LyXFont::MEDIUM_SERIES:
201                                 switch (cser) {
202                                 case 0: fseries = "-medium"; break;
203                                 case 1: fseries = "-book"; break;
204                                 case 2: fseries = "-light";
205                                 default: cser = 100;
206                                 }
207                                 break;
208                         case LyXFont::BOLD_SERIES:
209                                 switch (cser) {
210                                 case 0: fseries = "-bold"; break;
211                                 case 1: fseries = "-black"; break;
212                                 case 2: fseries = "-demi"; break;
213                                 case 3: fseries = "-demibold";
214                                 default: cser = 100;
215                                 }
216                                 break;
217                         default: ;
218                         }
219
220                         for (int csha = 0; csha < 2; ++csha) {
221                                 // Determine shape name
222                                 switch (shape) {
223                                 case LyXFont::UP_SHAPE:
224                                 case LyXFont::SMALLCAPS_SHAPE:
225                                         switch (csha) {
226                                         case 0: fshape = "-r";
227                                         default: csha = 100;
228                                         }
229                                         break;
230                                 case LyXFont::ITALIC_SHAPE:
231                                         switch (csha) {
232                                         case 0: fshape = "-i"; break;
233                                         case 1: fshape = "-o";
234                                         default: csha = 100;
235                                         }
236                                         break;
237                                 case LyXFont::SLANTED_SHAPE:
238                                         switch (csha) {
239                                         case 0: fshape = "-o"; break;
240                                         case 1: fshape = "-i";
241                                         default: csha = 100;
242                                         }
243                                         break;
244                                 default: ;
245                                 }
246                                 //
247                                 fontname = ffamily + fseries + fshape +
248                                            "-normal-*-*-*-*-*-*-*-" + norm;
249                                 fi->setPattern(fontname);
250                                 if (fi->exist()) {
251                                         return;
252                                 }
253                         }
254                 }
255         }
256 }
257
258
259 // A dummy fontstruct used when there is no gui.
260 namespace {
261
262 XFontStruct dummyXFontStruct;
263 bool dummyXFontStructisGood = false;
264
265 } // namespace anon
266
267 /// Do load font
268 XFontStruct * xfont_loader::doLoad(LyXFont::FONT_FAMILY family,
269                                 LyXFont::FONT_SERIES series,
270                                 LyXFont::FONT_SHAPE shape,
271                                 LyXFont::FONT_SIZE size)
272 {
273         if (!lyxrc.use_gui) {
274                 if (!dummyXFontStructisGood) {
275                         // no character specific info
276                         dummyXFontStruct.per_char = 0;
277                         // unit ascent on character displays
278                         dummyXFontStruct.ascent = 1;
279                         // no descent on character displays
280                         dummyXFontStruct.descent = 0;
281                         dummyXFontStructisGood = true;
282                 }
283
284                 return &dummyXFontStruct;
285         }
286
287         getFontinfo(family, series, shape);
288         int fsize = int((lyxrc.font_sizes[size] * lyxrc.dpi *
289                           (lyxrc.zoom/100.0)) / 72.27 + 0.5);
290
291         string font = fontinfo[family][series][shape]->getFontname(fsize);
292
293         if (font.empty()) {
294                 lyxerr << "No font matches request. Using 'fixed'." << endl;
295                 lyxerr << "Start LyX as 'lyx -dbg 515' to get more information." << endl;
296                 font = "fixed";
297         }
298
299         XFontStruct * fs = 0;
300
301         current_view->owner()->messagePush(_("Loading font into X-Server..."));
302
303         fs = XLoadQueryFont(fl_get_display(), font.c_str());
304
305         if (fs == 0) {
306                 if (font == "fixed") {
307                         lyxerr << "We're doomed. Can't get 'fixed' font." << endl;
308                 } else {
309                         lyxerr << "Could not get font. Using 'fixed'." << endl;
310                         fs = XLoadQueryFont(fl_get_display(), "fixed");
311                 }
312         } else if (lyxerr.debugging(Debug::FONT)) {
313                 // Tell user the font matching
314                 LyXFont f;
315                 f.setFamily(family);
316                 f.setSeries(series);
317                 f.setShape(shape);
318                 f.setSize(size);
319                 // The rest of the attributes are not interesting
320                 f.setEmph(LyXFont::INHERIT);
321                 f.setUnderbar(LyXFont::INHERIT);
322                 f.setNoun(LyXFont::INHERIT);
323                 f.setColor(LColor::inherit);
324                 lyxerr << "Font '" << f.stateText(0)
325                        << "' matched by\n" << font << endl;
326         }
327
328         current_view->owner()->messagePop();
329
330         fontstruct[family][series][shape][size] = fs;
331         return fs;
332 }
333
334
335 bool xfont_loader::available(LyXFont const & f)
336 {
337         if (!lyxrc.use_gui)
338                 return false;
339
340         if (!fontinfo[f.family()][f.series()][f.realShape()])
341                 getFontinfo(f.family(), f.series(), f.realShape());
342         return fontinfo[f.family()][f.series()][f.realShape()]
343                 ->getFontname(f.size()).size();
344 }