2 * \file xftFontLoader.C
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
8 * Full author contact details are available in file CREDITS.
13 #include <cmath> // fabs()
15 #include <X11/Xft/Xft.h>
16 #include "xftFontLoader.h"
20 #include "lyxrc.h" // lyxrc.font_*
21 #include "BufferView.h"
22 #include "frontends/LyXView.h"
23 #include "support/systemcall.h"
24 #include "support/filetools.h"
27 #include "frontends/lyx_gui.h"
32 // The global fontLoader
33 xftFontLoader fontLoader;
36 // Initialize font loader
37 xftFontLoader::xftFontLoader()
42 // Destroy font loader
43 xftFontLoader::~xftFontLoader()
49 // Update fonts after zoom, dpi, font names, or norm change
50 // For now, we just ditch all fonts we have. Later, we should
51 // reuse the ones that are already loaded.
52 void xftFontLoader::update()
59 void xftFontLoader::unload()
62 for (int i1 = 0; i1 < LyXFont::NUM_FAMILIES; ++i1)
63 for (int i2 = 0; i2 < 2; ++i2)
64 for (int i3 = 0; i3 < 4; ++i3)
65 for (int i4 = 0; i4 < 10; ++i4) {
66 if (fonts_[i1][i2][i3][i4]){
67 XftFontClose(getDisplay(), fonts_[i1][i2][i3][i4]);
68 fonts_[i1][i2][i3][i4] = 0;
74 string xftFontLoader::familyString(LyXFont::FONT_FAMILY family)
78 case LyXFont::ROMAN_FAMILY:
79 ffamily = lyxrc.roman_font_name;
81 case LyXFont::SANS_FAMILY:
82 ffamily = lyxrc.sans_font_name;
84 case LyXFont::TYPEWRITER_FAMILY:
85 ffamily = lyxrc.typewriter_font_name;
87 case LyXFont::CMR_FAMILY:
90 case LyXFont::CMSY_FAMILY:
93 case LyXFont::CMM_FAMILY:
96 case LyXFont::CMEX_FAMILY:
99 case LyXFont::MSA_FAMILY:
102 case LyXFont::MSB_FAMILY:
114 /* Takes care of finding which font that can match the given request. Tries
115 different alternatives. */
116 XftPattern * xftFontLoader::getFontPattern(LyXFont::FONT_FAMILY family,
117 LyXFont::FONT_SERIES series,
118 LyXFont::FONT_SHAPE shape,
119 LyXFont::FONT_SIZE size)
121 // Normal font. Let's search for an existing name that matches.
125 double fsize = lyxrc.font_sizes[size] * lyxrc.zoom / 100.0;
126 XftPattern *fpat = XftPatternCreate();
128 ffamily = familyString(family);
130 case LyXFont::MEDIUM_SERIES:
131 fweight = XFT_WEIGHT_MEDIUM;
133 case LyXFont::BOLD_SERIES:
134 fweight = XFT_WEIGHT_BOLD;
137 fweight = XFT_WEIGHT_MEDIUM;
142 case LyXFont::UP_SHAPE:
143 case LyXFont::SMALLCAPS_SHAPE:
144 fslant = XFT_SLANT_ROMAN;
146 case LyXFont::ITALIC_SHAPE:
147 fslant = XFT_SLANT_ITALIC;
149 case LyXFont::SLANTED_SHAPE:
150 fslant = XFT_SLANT_OBLIQUE;
153 fslant = XFT_SLANT_ROMAN;
156 XftPatternAddString(fpat, XFT_FAMILY, ffamily.c_str());
157 XftPatternAddInteger(fpat, XFT_WEIGHT, fweight);
158 XftPatternAddInteger(fpat, XFT_SLANT, fslant);
159 XftPatternAddDouble(fpat, XFT_SIZE, fsize);
165 XftFont * xftFontLoader::doLoad(LyXFont::FONT_FAMILY family,
166 LyXFont::FONT_SERIES series,
167 LyXFont::FONT_SHAPE shape,
168 LyXFont::FONT_SIZE size)
170 XftPattern *fpat = getFontPattern(family, series, shape, size);
172 XftPattern *fpat2 = XftFontMatch(getDisplay(), getScreen(),
174 XftFont * font = XftFontOpenPattern(getDisplay(), fpat2);
175 fonts_[family][series][shape][size] = font;
180 bool xftFontLoader::available(LyXFont const & f)
182 if (!lyx_gui::use_gui)
185 static std::vector<bool> cache_set(LyXFont::NUM_FAMILIES, false);
186 static std::vector<bool> cache(LyXFont::NUM_FAMILIES, false);
188 LyXFont::FONT_FAMILY family = f.family();
189 if (cache_set[family])
190 return cache[family];
191 cache_set[family] = true;
193 string const ffamily = familyString(family);
195 cache_set[family] = true;
196 XftPattern *fpat = XftPatternCreate();
197 XftPatternAddString(fpat, XFT_FAMILY, ffamily.c_str());
199 XftPattern *fpat2 = XftFontMatch(getDisplay(), getScreen(),
201 XftPatternDestroy(fpat);
203 XftPatternGetString(fpat2, XFT_FAMILY, 0, &familyM);
204 if (ffamily == familyM) {
205 cache[family] = true;
208 // We don't need to set cache[family] to false, as it
209 // is initialized to false;
212 // We don't care about non-symbol fonts