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