2 /* This file is part of
3 * ======================================================
5 * LyX, The Document Processor
7 * Copyright 1997 Asger Alstrup
10 * ====================================================== */
13 #include <cmath> // fabs()
14 #include <cstdlib> // atoi()
17 #pragma implementation "FontLoader.h"
21 #include "FontLoader.h"
24 #include "lyxrc.h" // lyxrc.font_*
25 #include "BufferView.h"
27 #include "minibuffer.h"
31 extern BufferView * current_view;
33 // Initialize font loader
34 FontLoader::FontLoader()
39 // Destroy font loader
40 FontLoader::~FontLoader()
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()
54 void FontLoader::reset()
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;
68 void FontLoader::unload()
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;
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;
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)
94 // Do we have the font info already?
95 if (fontinfo[family][series][shape] != 0)
98 // Special code for the symbol family
99 if (family == LyXFont::SYMBOL_FAMILY){
100 fontinfo[family][series][shape] = new FontInfo("-*-symbol-*");
104 // Normal font. Let's search for an existing name that matches.
108 string norm = lyxrc.font_norm;
111 FontInfo * fi = new FontInfo();
112 fontinfo[family][series][shape] = fi;
114 for (int cfam = 0; cfam < 2; ++cfam) {
115 // Determine family name
117 case LyXFont::ROMAN_FAMILY:
119 case 0: ffamily = lyxrc.roman_font_name; break;
120 case 1: ffamily = "-*-times";
124 case LyXFont::SANS_FAMILY:
126 case 0: ffamily = lyxrc.sans_font_name; break;
127 case 1: ffamily = "-*-helvetica";
131 case LyXFont::TYPEWRITER_FAMILY:
133 case 0: ffamily = lyxrc.typewriter_font_name; break;
134 case 1: ffamily = "-*-courier";
141 for (int cser = 0; cser < 4; ++cser) {
142 // Determine series name
144 case LyXFont::MEDIUM_SERIES:
146 case 0: fseries = "-medium"; break;
147 case 1: fseries = "-book"; break;
148 case 2: fseries = "-light";
152 case LyXFont::BOLD_SERIES:
154 case 0: fseries = "-bold"; break;
155 case 1: fseries = "-black"; break;
156 case 2: fseries = "-demi"; break;
157 case 3: fseries = "-demibold";
164 for (int csha = 0; csha < 2; ++csha) {
165 // Determine shape name
167 case LyXFont::UP_SHAPE:
168 case LyXFont::SMALLCAPS_SHAPE:
170 case 0: fshape = "-r";
174 case LyXFont::ITALIC_SHAPE:
176 case 0: fshape = "-i"; break;
177 case 1: fshape = "-o";
181 case LyXFont::SLANTED_SHAPE:
183 case 0: fshape = "-o"; break;
184 case 1: fshape = "-i";
191 fontname = ffamily + fseries + fshape +
192 "-normal-*-*-*-*-*-*-*-" + norm;
193 fi->setPattern(fontname);
203 // A dummy fontstruct used when there is no gui.
204 static XFontStruct dummyXFontStruct;
205 static bool dummyXFontStructisGood = false;
208 XFontStruct * FontLoader::doLoad(LyXFont::FONT_FAMILY family,
209 LyXFont::FONT_SERIES series,
210 LyXFont::FONT_SHAPE shape,
211 LyXFont::FONT_SIZE size)
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;
224 return &dummyXFontStruct;
227 getFontinfo(family, series, shape);
228 int fsize = int( (lyxrc.font_sizes[size] * lyxrc.dpi *
229 (lyxrc.zoom/100.0) ) / 72.27 + 0.5 );
231 string font = fontinfo[family][series][shape]->getFontname(fsize);
234 lyxerr << "No font matches request. Using 'fixed'." << endl;
235 lyxerr << "Start LyX as 'lyx -dbg 515' to get more information." << endl;
239 XFontStruct * fs = 0;
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());
246 if (font == "fixed") {
247 lyxerr << "We're doomed. Can't get 'fixed' font." << endl;
249 lyxerr << "Could not get font. Using 'fixed'." << endl;
250 fs = XLoadQueryFont(fl_display, "fixed");
252 } else if (lyxerr.debugging(Debug::FONT)) {
253 // Tell user the font matching
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;
269 current_view->owner()->getMiniBuffer()->Reset();
271 fontstruct[family][series][shape][size] = fs;