]> git.lyx.org Git - lyx.git/blob - src/FontLoader.C
some using changes small changes in lyxfont and some other things, read the Changelog
[lyx.git] / src / FontLoader.C
1 // -*- C++ -*-
2 /* This file is part of
3  * ====================================================== 
4  * 
5  *           LyX, The Document Processor
6  *       
7  *          Copyright 1997 Asger Alstrup
8  *           and the LyX Team.
9  *
10  * ====================================================== */
11
12 #include <config.h>
13 #include <cmath>        // fabs()
14 #include <cstdlib>      // atoi()
15
16 #ifdef __GNUG__
17 #pragma implementation "FontLoader.h"
18 #endif
19
20 #include "gettext.h"
21 #include "FontLoader.h"
22 #include "FontInfo.h"
23 #include "debug.h"
24 #include "lyxrc.h"      // lyxrc.font_*
25 #include "BufferView.h"
26 #include "LyXView.h"
27 #include "minibuffer.h"
28
29 using std::endl;
30
31 extern BufferView * current_view;
32
33 // Initialize font loader
34 FontLoader::FontLoader()
35 {
36         reset();
37 }
38
39 // Destroy font loader
40 FontLoader::~FontLoader()
41 {
42         unload();
43 }
44
45 // Update fonts after zoom, dpi, font names, or norm change
46 // For now, we just ditch all fonts we have. Later, we should
47 // reuse the ones that are already loaded.
48 void FontLoader::update()
49 {
50         unload();
51 }
52
53 // Reset font loader
54 void FontLoader::reset()
55 {
56         // Clear font infos, font structs and font metrics
57         for (int i1 = 0; i1<4; i1++)
58                 for (int i2 = 0; i2<2; i2++)
59                         for (int i3 = 0; i3<4; i3++) {
60                                 fontinfo[i1][i2][i3] = 0;
61                                 for (int i4 = 0; i4<10; i4++) {
62                                         fontstruct[i1][i2][i3][i4] = 0;
63                                 }
64                         }
65 }
66
67 // Unload all fonts
68 void FontLoader::unload() 
69 {
70         // Unload all fonts
71         for (int i1 = 0; i1<4; i1++)
72                 for (int i2 = 0; i2<2; i2++)
73                         for (int i3 = 0; i3<4; i3++) {
74                                 if (fontinfo[i1][i2][i3]) {
75                                         delete fontinfo[i1][i2][i3];
76                                         fontinfo[i1][i2][i3] = 0;
77                                 }
78                                 for (int i4 = 0; i4<10; i4++) {
79                                         if (fontstruct[i1][i2][i3][i4]) {
80                                                 XFreeFont(fl_display, fontstruct[i1][i2][i3][i4]);
81                                                 fontstruct[i1][i2][i3][i4] = 0;
82                                         }
83                                 }
84                         }
85 }
86
87 // Get font info
88 /* Takes care of finding which font that can match the given request. Tries
89 different alternatives. */
90 void FontLoader::getFontinfo(LyXFont::FONT_FAMILY family, 
91                              LyXFont::FONT_SERIES series, 
92                              LyXFont::FONT_SHAPE shape)
93 {
94         // Do we have the font info already?
95         if (fontinfo[family][series][shape] != 0)
96                 return;
97
98         // Special code for the symbol family
99         if (family == LyXFont::SYMBOL_FAMILY){
100                 fontinfo[family][series][shape] = new FontInfo("-*-symbol-*");
101                 return;
102         }
103
104         // Normal font. Let's search for an existing name that matches.
105         string ffamily;
106         string fseries;
107         string fshape;
108         string norm = lyxrc.font_norm;
109         string fontname;
110
111         FontInfo * fi = new FontInfo();
112         fontinfo[family][series][shape] = fi;
113
114         for (int cfam = 0; cfam < 2; ++cfam) {
115                 // Determine family name
116                 switch (family) {
117                 case LyXFont::ROMAN_FAMILY:
118                         switch (cfam) {
119                         case 0: ffamily = lyxrc.roman_font_name; break;
120                         case 1: ffamily = "-*-times";
121                         default: cfam = 100;
122                         }
123                         break;
124                 case LyXFont::SANS_FAMILY:
125                         switch (cfam) {
126                         case 0: ffamily = lyxrc.sans_font_name; break;
127                         case 1: ffamily = "-*-helvetica";
128                         default: cfam = 100;
129                         }
130                         break;
131                 case LyXFont::TYPEWRITER_FAMILY:
132                         switch (cfam) {
133                         case 0: ffamily = lyxrc.typewriter_font_name; break;
134                         case 1: ffamily = "-*-courier";
135                         default: cfam = 100;
136                         }
137                         break;
138                 default: ;
139                 }
140
141                 for (int cser = 0; cser < 4; ++cser) {
142                         // Determine series name
143                         switch (series) {
144                         case LyXFont::MEDIUM_SERIES:
145                                 switch (cser) {
146                                 case 0: fseries = "-medium"; break;
147                                 case 1: fseries = "-book"; break;
148                                 case 2: fseries = "-light";
149                                 default: cser = 100;
150                                 }
151                                 break;
152                         case LyXFont::BOLD_SERIES:
153                                 switch (cser) {
154                                 case 0: fseries = "-bold"; break;
155                                 case 1: fseries = "-black"; break;
156                                 case 2: fseries = "-demi"; break;
157                                 case 3: fseries = "-demibold";
158                                 default: cser = 100;
159                                 }
160                                 break;
161                         default: ;
162                         }
163
164                         for (int csha = 0; csha < 2; ++csha) {
165                                 // Determine shape name
166                                 switch (shape) {
167                                 case LyXFont::UP_SHAPE:
168                                 case LyXFont::SMALLCAPS_SHAPE:
169                                         switch (csha) {
170                                         case 0: fshape = "-r";
171                                         default: csha = 100;
172                                         }
173                                         break;
174                                 case LyXFont::ITALIC_SHAPE:
175                                         switch (csha) {
176                                         case 0: fshape = "-i"; break;
177                                         case 1: fshape = "-o";
178                                         default: csha = 100;
179                                         }
180                                         break;
181                                 case LyXFont::SLANTED_SHAPE:
182                                         switch (csha) {
183                                         case 0: fshape = "-o"; break;
184                                         case 1: fshape = "-i";
185                                         default: csha = 100;
186                                         }
187                                         break;
188                                 default: ;
189                                 }
190                                 //
191                                 fontname = ffamily + fseries + fshape +
192                                            "-normal-*-*-*-*-*-*-*-" + norm;
193                                 fi->setPattern(fontname);
194                                 if (fi->exist()) {
195                                         return;
196                                 }
197                         }
198                 }
199         }
200 }
201
202
203 // A dummy fontstruct used when there is no gui. 
204 static XFontStruct dummyXFontStruct;
205 static bool dummyXFontStructisGood = false;
206
207 /// Do load font
208 XFontStruct * FontLoader::doLoad(LyXFont::FONT_FAMILY family, 
209                                 LyXFont::FONT_SERIES series, 
210                                 LyXFont::FONT_SHAPE shape, 
211                                 LyXFont::FONT_SIZE size)
212 {
213         if (!lyxrc.use_gui) {
214                 if (!dummyXFontStructisGood) {
215                         // no character specific info
216                         dummyXFontStruct.per_char = 0; 
217                         // unit ascent on character displays
218                         dummyXFontStruct.ascent = 1; 
219                         // no descent on character displays
220                         dummyXFontStruct.descent = 0; 
221                         dummyXFontStructisGood = true;
222                 }
223
224                 return &dummyXFontStruct;
225         }
226
227         getFontinfo(family, series, shape);
228         int fsize = int( (lyxrc.font_sizes[size] * lyxrc.dpi * 
229                           (lyxrc.zoom/100.0) ) / 72.27 + 0.5 );
230
231         string font = fontinfo[family][series][shape]->getFontname(fsize);
232
233         if (font.empty()) {
234                 lyxerr << "No font matches request. Using 'fixed'." << endl;
235                 lyxerr << "Start LyX as 'lyx -dbg 515' to get more information." << endl;
236                 font = "fixed";
237         }
238
239         XFontStruct * fs = 0;
240
241         current_view->owner()->getMiniBuffer()->Store();
242         current_view->owner()->getMiniBuffer()->Set(_("Loading font into X-Server..."));
243         fs = XLoadQueryFont(fl_display, font.c_str());
244         
245         if (fs == 0) {
246                 if (font == "fixed") {
247                         lyxerr << "We're doomed. Can't get 'fixed' font." << endl;
248                 } else {
249                         lyxerr << "Could not get font. Using 'fixed'." << endl;
250                         fs = XLoadQueryFont(fl_display, "fixed");
251                 }
252         } else if (lyxerr.debugging(Debug::FONT)) {
253                 // Tell user the font matching
254                 LyXFont f;
255                 f.setFamily(family);
256                 f.setSeries(series);
257                 f.setShape(shape);
258                 f.setSize(size);
259                 // The rest of the attributes are not interesting
260                 f.setEmph(LyXFont::INHERIT);
261                 f.setUnderbar(LyXFont::INHERIT);
262                 f.setNoun(LyXFont::INHERIT);
263                 f.setLatex(LyXFont::INHERIT);
264                 f.setColor(LColor::inherit);
265                 lyxerr << "Font '" << f.stateText() 
266                        << "' matched by\n" << font << endl;
267         }
268
269         current_view->owner()->getMiniBuffer()->Reset();
270
271         fontstruct[family][series][shape][size] = fs;
272         return fs;
273 }