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 // Too hard to make concept checks work with this file
14 #ifdef _GLIBCXX_CONCEPT_CHECKS
15 #undef _GLIBCXX_CONCEPT_CHECKS
17 #ifdef _GLIBCPP_CONCEPT_CHECKS
18 #undef _GLIBCPP_CONCEPT_CHECKS
21 #include "xftFontLoader.h"
24 #include "lyxrc.h" // lyxrc.font_*
25 #include "BufferView.h"
28 #include "frontends/LyXView.h"
29 #include "frontends/lyx_gui.h"
31 #include "support/convert.h"
32 #include "support/lstrings.h"
33 #include "support/systemcall.h"
34 #include "support/filetools.h"
36 #include <cmath> // fabs()
42 // The global fontLoader
43 xftFontLoader fontLoader;
46 // Initialize font loader
47 xftFontLoader::xftFontLoader()
52 // Destroy font loader
53 xftFontLoader::~xftFontLoader()
59 // Update fonts after zoom, dpi, font names, or norm change
60 // For now, we just ditch all fonts we have. Later, we should
61 // reuse the ones that are already loaded.
62 void xftFontLoader::update()
69 void xftFontLoader::unload()
72 for (int i1 = 0; i1 < LyXFont::NUM_FAMILIES; ++i1)
73 for (int i2 = 0; i2 < 2; ++i2)
74 for (int i3 = 0; i3 < 4; ++i3)
75 for (int i4 = 0; i4 < 10; ++i4) {
76 if (fonts_[i1][i2][i3][i4]){
77 XftFontClose(getDisplay(), fonts_[i1][i2][i3][i4]);
78 fonts_[i1][i2][i3][i4] = 0;
84 string xftFontLoader::familyString(LyXFont::FONT_FAMILY family)
88 case LyXFont::ROMAN_FAMILY:
89 ffamily = lyxrc.roman_font_name;
91 case LyXFont::SANS_FAMILY:
92 ffamily = lyxrc.sans_font_name;
94 case LyXFont::TYPEWRITER_FAMILY:
95 ffamily = lyxrc.typewriter_font_name;
97 case LyXFont::CMR_FAMILY:
100 case LyXFont::CMSY_FAMILY:
103 case LyXFont::CMM_FAMILY:
106 case LyXFont::CMEX_FAMILY:
109 case LyXFont::MSA_FAMILY:
112 case LyXFont::MSB_FAMILY:
124 /* Takes care of finding which font that can match the given request. Tries
125 different alternatives. */
126 XftPattern * xftFontLoader::getFontPattern(LyXFont::FONT_FAMILY family,
127 LyXFont::FONT_SERIES series,
128 LyXFont::FONT_SHAPE shape,
129 LyXFont::FONT_SIZE size)
131 // Normal font. Let's search for an existing name that matches.
135 double fsize = convert<double>(lyxrc.font_sizes[size]) * lyxrc.zoom / 100.0;
136 XftPattern *fpat = XftPatternCreate();
138 ffamily = familyString(family);
140 case LyXFont::MEDIUM_SERIES:
141 fweight = XFT_WEIGHT_MEDIUM;
143 case LyXFont::BOLD_SERIES:
144 fweight = XFT_WEIGHT_BOLD;
147 fweight = XFT_WEIGHT_MEDIUM;
152 case LyXFont::UP_SHAPE:
153 case LyXFont::SMALLCAPS_SHAPE:
154 fslant = XFT_SLANT_ROMAN;
156 case LyXFont::ITALIC_SHAPE:
157 fslant = XFT_SLANT_ITALIC;
159 case LyXFont::SLANTED_SHAPE:
160 fslant = XFT_SLANT_OBLIQUE;
163 fslant = XFT_SLANT_ROMAN;
166 XftPatternAddString(fpat, XFT_FAMILY, ffamily.c_str());
167 XftPatternAddInteger(fpat, XFT_WEIGHT, fweight);
168 XftPatternAddInteger(fpat, XFT_SLANT, fslant);
169 XftPatternAddDouble(fpat, XFT_SIZE, fsize);
175 XftFont * xftFontLoader::doLoad(LyXFont::FONT_FAMILY family,
176 LyXFont::FONT_SERIES series,
177 LyXFont::FONT_SHAPE shape,
178 LyXFont::FONT_SIZE size)
180 XftPattern * fpat = getFontPattern(family, series, shape, size);
182 XftPattern * fpat2 = XftFontMatch(getDisplay(), getScreen(),
184 XftFont * font = XftFontOpenPattern(getDisplay(), fpat2);
185 fonts_[family][series][shape][size] = font;
190 bool xftFontLoader::available(LyXFont const & f)
192 if (!lyx_gui::use_gui)
195 static std::vector<bool> cache_set(LyXFont::NUM_FAMILIES, false);
196 static std::vector<bool> cache(LyXFont::NUM_FAMILIES, false);
198 LyXFont::FONT_FAMILY family = f.family();
199 if (cache_set[family])
200 return cache[family];
201 cache_set[family] = true;
203 string const ffamily = familyString(family);
205 cache_set[family] = true;
206 XftPattern * fpat = XftPatternCreate();
207 XftPatternAddString(fpat, XFT_FAMILY, ffamily.c_str());
209 XftPattern * fpat2 = XftFontMatch(getDisplay(), getScreen(),
211 XftPatternDestroy(fpat);
213 XftPatternGetString(fpat2, XFT_FAMILY, 0, &familyM);
214 if (ffamily == familyM) {
215 cache[family] = true;
218 // We don't need to set cache[family] to false, as it
219 // is initialized to false;
222 // We don't care about non-symbol fonts