]> git.lyx.org Git - lyx.git/blob - src/frontends/gtk/xftFontLoader.C
some tabular fixes for the problems reported by Helge
[lyx.git] / src / frontends / gtk / xftFontLoader.C
1 /**
2  * \file xftFontLoader.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Huang Ying
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 // Too hard to make concept checks work with this file
14 #ifdef _GLIBCXX_CONCEPT_CHECKS
15 #undef _GLIBCXX_CONCEPT_CHECKS
16 #endif
17 #ifdef _GLIBCPP_CONCEPT_CHECKS
18 #undef _GLIBCPP_CONCEPT_CHECKS
19 #endif
20
21 #include "xftFontLoader.h"
22 #include "FontInfo.h"
23 #include "gettext.h"
24 #include "debug.h"
25 #include "lyxrc.h"      // lyxrc.font_*
26 #include "BufferView.h"
27 #include "GtkmmX.h"
28
29 #include "frontends/LyXView.h"
30 #include "frontends/lyx_gui.h"
31
32 #include "support/convert.h"
33 #include "support/lstrings.h"
34 #include "support/systemcall.h"
35 #include "support/filetools.h"
36
37 #include <cmath>        // fabs()
38 #include <vector>
39
40 using std::endl;
41 using std::string;
42
43 // The global fontLoader
44 xftFontLoader fontLoader;
45
46
47 // Initialize font loader
48 xftFontLoader::xftFontLoader()
49 {
50 }
51
52
53 // Destroy font loader
54 xftFontLoader::~xftFontLoader()
55 {
56         unload();
57 }
58
59
60 // Update fonts after zoom, dpi, font names, or norm change
61 // For now, we just ditch all fonts we have. Later, we should
62 // reuse the ones that are already loaded.
63 void xftFontLoader::update()
64 {
65         unload();
66 }
67
68
69 // Unload all fonts
70 void xftFontLoader::unload()
71 {
72         // Unload all fonts
73         for (int i1 = 0; i1 < LyXFont::NUM_FAMILIES; ++i1)
74                 for (int i2 = 0; i2 < 2; ++i2)
75                         for (int i3 = 0; i3 < 4; ++i3)
76                                 for (int i4 = 0; i4 < 10; ++i4) {
77                                         if (fonts_[i1][i2][i3][i4]){
78                                                 XftFontClose(getDisplay(), fonts_[i1][i2][i3][i4]);
79                                                 fonts_[i1][i2][i3][i4] = 0;
80                                         }
81                                 }
82 }
83
84
85 string xftFontLoader::familyString(LyXFont::FONT_FAMILY family)
86 {
87         string ffamily;
88         switch (family) {
89         case LyXFont::ROMAN_FAMILY:
90                 ffamily = lyxrc.roman_font_name;
91                 break;
92         case LyXFont::SANS_FAMILY:
93                 ffamily = lyxrc.sans_font_name;
94                 break;
95         case LyXFont::TYPEWRITER_FAMILY:
96                 ffamily = lyxrc.typewriter_font_name;
97                 break;
98         case LyXFont::CMR_FAMILY:
99                 ffamily = "cmr10";
100                 break;
101         case LyXFont::CMSY_FAMILY:
102                 ffamily = "cmsy10";
103                 break;
104         case LyXFont::CMM_FAMILY:
105                 ffamily = "cmmi10";
106                 break;
107         case LyXFont::CMEX_FAMILY:
108                 ffamily = "cmex10";
109                 break;
110         case LyXFont::MSA_FAMILY:
111                 ffamily = "msam10";
112                 break;
113         case LyXFont::MSB_FAMILY:
114                 ffamily = "msbm10";
115                 break;
116         default:
117                 ffamily = "Sans";
118                 break;
119         }
120         return ffamily;
121 }
122
123
124 // Get font pattern
125 /* Takes care of finding which font that can match the given request. Tries
126 different alternatives. */
127 XftPattern * xftFontLoader::getFontPattern(LyXFont::FONT_FAMILY family,
128                                           LyXFont::FONT_SERIES series,
129                                           LyXFont::FONT_SHAPE shape,
130                                           LyXFont::FONT_SIZE size)
131 {
132         // Normal font. Let's search for an existing name that matches.
133         string ffamily;
134         int fweight;
135         int fslant;
136         double fsize = convert<double>(lyxrc.font_sizes[size]) * lyxrc.zoom / 100.0;
137         XftPattern *fpat = XftPatternCreate();
138
139         ffamily = familyString(family);
140         switch (series) {
141         case LyXFont::MEDIUM_SERIES:
142                 fweight = XFT_WEIGHT_MEDIUM;
143                 break;
144         case LyXFont::BOLD_SERIES:
145                 fweight = XFT_WEIGHT_BOLD;
146                 break;
147         default:
148                 fweight = XFT_WEIGHT_MEDIUM;
149                 break;
150         }
151
152         switch (shape) {
153         case LyXFont::UP_SHAPE:
154         case LyXFont::SMALLCAPS_SHAPE:
155                 fslant = XFT_SLANT_ROMAN;
156                 break;
157         case LyXFont::ITALIC_SHAPE:
158                 fslant = XFT_SLANT_ITALIC;
159                 break;
160         case LyXFont::SLANTED_SHAPE:
161                 fslant = XFT_SLANT_OBLIQUE;
162                 break;
163         default:
164                 fslant = XFT_SLANT_ROMAN;
165                 break;
166         }
167         XftPatternAddString(fpat, XFT_FAMILY, ffamily.c_str());
168         XftPatternAddInteger(fpat, XFT_WEIGHT, fweight);
169         XftPatternAddInteger(fpat, XFT_SLANT, fslant);
170         XftPatternAddDouble(fpat, XFT_SIZE, fsize);
171         return fpat;
172 }
173
174
175 /// Do load font
176 XftFont * xftFontLoader::doLoad(LyXFont::FONT_FAMILY family,
177                                LyXFont::FONT_SERIES series,
178                                LyXFont::FONT_SHAPE shape,
179                                LyXFont::FONT_SIZE size)
180 {
181         XftPattern * fpat = getFontPattern(family, series, shape, size);
182         XftResult result;
183         XftPattern * fpat2 = XftFontMatch(getDisplay(), getScreen(),
184                                           fpat, &result);
185         XftFont * font = XftFontOpenPattern(getDisplay(), fpat2);
186         fonts_[family][series][shape][size] = font;
187         return font;
188 }
189
190
191 bool xftFontLoader::available(LyXFont const & f)
192 {
193         if (!lyx_gui::use_gui)
194                 return false;
195
196         static std::vector<bool> cache_set(LyXFont::NUM_FAMILIES, false);
197         static std::vector<bool> cache(LyXFont::NUM_FAMILIES, false);
198
199         LyXFont::FONT_FAMILY family = f.family();
200         if (cache_set[family])
201                 return cache[family];
202         cache_set[family] = true;
203
204         string const ffamily = familyString(family);
205         if (isSpecial(f)) {
206                 cache_set[family] = true;
207                 XftPattern * fpat = XftPatternCreate();
208                 XftPatternAddString(fpat, XFT_FAMILY, ffamily.c_str());
209                 XftResult result;
210                 XftPattern * fpat2 = XftFontMatch(getDisplay(), getScreen(),
211                                                   fpat, &result);
212                 XftPatternDestroy(fpat);
213                 char * familyM;
214                 XftPatternGetString(fpat2, XFT_FAMILY, 0, &familyM);
215                 if (ffamily == familyM) {
216                         cache[family] = true;
217                         return true;
218                 }
219                 // We don't need to set cache[family] to false, as it
220                 // is initialized to false;
221                 return false;
222         }
223         // We don't care about non-symbol fonts
224         return false;
225 }