]> git.lyx.org Git - lyx.git/blob - src/frontends/gtk/xftFontLoader.C
enable Font cache only for MacOSX and inline width() for other platform.
[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 "gettext.h"
23 #include "debug.h"
24 #include "lyxrc.h"      // lyxrc.font_*
25 #include "BufferView.h"
26 #include "GtkmmX.h"
27
28 #include "frontends/LyXView.h"
29 #include "frontends/lyx_gui.h"
30
31 #include "support/convert.h"
32 #include "support/lstrings.h"
33 #include "support/systemcall.h"
34 #include "support/filetools.h"
35
36 #include <cmath>        // fabs()
37 #include <vector>
38
39 using std::endl;
40 using std::string;
41
42 // The global fontLoader
43 xftFontLoader fontLoader;
44
45
46 // Initialize font loader
47 xftFontLoader::xftFontLoader()
48 {
49 }
50
51
52 // Destroy font loader
53 xftFontLoader::~xftFontLoader()
54 {
55         unload();
56 }
57
58
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()
63 {
64         unload();
65 }
66
67
68 // Unload all fonts
69 void xftFontLoader::unload()
70 {
71         // Unload all fonts
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;
79                                         }
80                                 }
81 }
82
83
84 string xftFontLoader::familyString(LyXFont::FONT_FAMILY family)
85 {
86         string ffamily;
87         switch (family) {
88         case LyXFont::ROMAN_FAMILY:
89                 ffamily = lyxrc.roman_font_name;
90                 break;
91         case LyXFont::SANS_FAMILY:
92                 ffamily = lyxrc.sans_font_name;
93                 break;
94         case LyXFont::TYPEWRITER_FAMILY:
95                 ffamily = lyxrc.typewriter_font_name;
96                 break;
97         case LyXFont::CMR_FAMILY:
98                 ffamily = "cmr10";
99                 break;
100         case LyXFont::CMSY_FAMILY:
101                 ffamily = "cmsy10";
102                 break;
103         case LyXFont::CMM_FAMILY:
104                 ffamily = "cmmi10";
105                 break;
106         case LyXFont::CMEX_FAMILY:
107                 ffamily = "cmex10";
108                 break;
109         case LyXFont::MSA_FAMILY:
110                 ffamily = "msam10";
111                 break;
112         case LyXFont::MSB_FAMILY:
113                 ffamily = "msbm10";
114                 break;
115         default:
116                 ffamily = "Sans";
117                 break;
118         }
119         return ffamily;
120 }
121
122
123 // Get font pattern
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)
130 {
131         // Normal font. Let's search for an existing name that matches.
132         string ffamily;
133         int fweight;
134         int fslant;
135         double fsize = convert<double>(lyxrc.font_sizes[size]) * lyxrc.zoom / 100.0;
136         XftPattern *fpat = XftPatternCreate();
137
138         ffamily = familyString(family);
139         switch (series) {
140         case LyXFont::MEDIUM_SERIES:
141                 fweight = XFT_WEIGHT_MEDIUM;
142                 break;
143         case LyXFont::BOLD_SERIES:
144                 fweight = XFT_WEIGHT_BOLD;
145                 break;
146         default:
147                 fweight = XFT_WEIGHT_MEDIUM;
148                 break;
149         }
150
151         switch (shape) {
152         case LyXFont::UP_SHAPE:
153         case LyXFont::SMALLCAPS_SHAPE:
154                 fslant = XFT_SLANT_ROMAN;
155                 break;
156         case LyXFont::ITALIC_SHAPE:
157                 fslant = XFT_SLANT_ITALIC;
158                 break;
159         case LyXFont::SLANTED_SHAPE:
160                 fslant = XFT_SLANT_OBLIQUE;
161                 break;
162         default:
163                 fslant = XFT_SLANT_ROMAN;
164                 break;
165         }
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);
170         return fpat;
171 }
172
173
174 /// Do load font
175 XftFont * xftFontLoader::doLoad(LyXFont::FONT_FAMILY family,
176                                LyXFont::FONT_SERIES series,
177                                LyXFont::FONT_SHAPE shape,
178                                LyXFont::FONT_SIZE size)
179 {
180         XftPattern * fpat = getFontPattern(family, series, shape, size);
181         XftResult result;
182         XftPattern * fpat2 = XftFontMatch(getDisplay(), getScreen(),
183                                           fpat, &result);
184         XftFont * font = XftFontOpenPattern(getDisplay(), fpat2);
185         fonts_[family][series][shape][size] = font;
186         return font;
187 }
188
189
190 bool xftFontLoader::available(LyXFont const & f)
191 {
192         if (!lyx_gui::use_gui)
193                 return false;
194
195         static std::vector<bool> cache_set(LyXFont::NUM_FAMILIES, false);
196         static std::vector<bool> cache(LyXFont::NUM_FAMILIES, false);
197
198         LyXFont::FONT_FAMILY family = f.family();
199         if (cache_set[family])
200                 return cache[family];
201         cache_set[family] = true;
202
203         string const ffamily = familyString(family);
204         if (isSpecial(f)) {
205                 cache_set[family] = true;
206                 XftPattern * fpat = XftPatternCreate();
207                 XftPatternAddString(fpat, XFT_FAMILY, ffamily.c_str());
208                 XftResult result;
209                 XftPattern * fpat2 = XftFontMatch(getDisplay(), getScreen(),
210                                                   fpat, &result);
211                 XftPatternDestroy(fpat);
212                 char * familyM;
213                 XftPatternGetString(fpat2, XFT_FAMILY, 0, &familyM);
214                 if (ffamily == familyM) {
215                         cache[family] = true;
216                         return true;
217                 }
218                 // We don't need to set cache[family] to false, as it
219                 // is initialized to false;
220                 return false;
221         }
222         // We don't care about non-symbol fonts
223         return false;
224 }