]> git.lyx.org Git - lyx.git/blob - src/frontends/gtk/xftFontLoader.C
Joao latest bits
[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 #include <gtkmm.h>
13 #include <cmath>        // fabs()
14
15 #include <X11/Xft/Xft.h>
16 #include "xftFontLoader.h"
17 #include "FontInfo.h"
18 #include "gettext.h"
19 #include "debug.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"
25 #include "GtkmmX.h"
26 #include <vector>
27 #include "frontends/lyx_gui.h"
28
29 using std::endl;
30 using std::string;
31
32 // The global fontLoader
33 xftFontLoader fontLoader;
34
35
36 // Initialize font loader
37 xftFontLoader::xftFontLoader()
38 {
39 }
40
41
42 // Destroy font loader
43 xftFontLoader::~xftFontLoader()
44 {
45         unload();
46 }
47
48
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()
53 {
54         unload();
55 }
56
57
58 // Unload all fonts
59 void xftFontLoader::unload()
60 {
61         // Unload all fonts
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;
69                                         }
70                                 }
71 }
72
73
74 string xftFontLoader::familyString(LyXFont::FONT_FAMILY family)
75 {
76         string ffamily;
77         switch (family) {
78         case LyXFont::ROMAN_FAMILY:
79                 ffamily = lyxrc.roman_font_name;
80                 break;
81         case LyXFont::SANS_FAMILY:
82                 ffamily = lyxrc.sans_font_name;
83                 break;
84         case LyXFont::TYPEWRITER_FAMILY:
85                 ffamily = lyxrc.typewriter_font_name;
86                 break;
87         case LyXFont::CMR_FAMILY:
88                 ffamily = "cmr10";
89                 break;
90         case LyXFont::CMSY_FAMILY:
91                 ffamily = "cmsy10";
92                 break;
93         case LyXFont::CMM_FAMILY:
94                 ffamily = "cmmi10";
95                 break;
96         case LyXFont::CMEX_FAMILY:
97                 ffamily = "cmex10";
98                 break;
99         case LyXFont::MSA_FAMILY:
100                 ffamily = "msam10";
101                 break;
102         case LyXFont::MSB_FAMILY:
103                 ffamily = "msbm10";
104                 break;
105         default:
106                 ffamily = "Sans";
107                 break;
108         }
109         return ffamily;
110 }
111
112
113 // Get font pattern
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)
120 {
121         // Normal font. Let's search for an existing name that matches.
122         string ffamily;
123         int fweight;
124         int fslant;
125         double fsize = lyxrc.font_sizes[size] * lyxrc.zoom / 100.0;
126         XftPattern *fpat = XftPatternCreate();
127
128         ffamily = familyString(family);
129         switch (series) {
130         case LyXFont::MEDIUM_SERIES:
131                 fweight = XFT_WEIGHT_MEDIUM;
132                 break;
133         case LyXFont::BOLD_SERIES:
134                 fweight = XFT_WEIGHT_BOLD;
135                 break;
136         default:
137                 fweight = XFT_WEIGHT_MEDIUM;
138                 break;
139         }
140
141         switch (shape) {
142         case LyXFont::UP_SHAPE:
143         case LyXFont::SMALLCAPS_SHAPE:
144                 fslant = XFT_SLANT_ROMAN;
145                 break;
146         case LyXFont::ITALIC_SHAPE:
147                 fslant = XFT_SLANT_ITALIC;
148                 break;
149         case LyXFont::SLANTED_SHAPE:
150                 fslant = XFT_SLANT_OBLIQUE;
151                 break;
152         default:
153                 fslant = XFT_SLANT_ROMAN;
154                 break;
155         }
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);
160         return fpat;
161 }
162
163
164 /// Do load font
165 XftFont * xftFontLoader::doLoad(LyXFont::FONT_FAMILY family,
166                                LyXFont::FONT_SERIES series,
167                                LyXFont::FONT_SHAPE shape,
168                                LyXFont::FONT_SIZE size)
169 {
170         XftPattern *fpat = getFontPattern(family, series, shape, size);
171         XftResult result;
172         XftPattern *fpat2 = XftFontMatch(getDisplay(), getScreen(),
173                                          fpat, &result);
174         XftFont * font = XftFontOpenPattern(getDisplay(), fpat2);
175         fonts_[family][series][shape][size] = font;
176         return font;
177 }
178
179
180 bool xftFontLoader::available(LyXFont const & f)
181 {
182         if (!lyx_gui::use_gui)
183                 return false;
184
185         static std::vector<bool> cache_set(LyXFont::NUM_FAMILIES, false);
186         static std::vector<bool> cache(LyXFont::NUM_FAMILIES, false);
187
188         LyXFont::FONT_FAMILY family = f.family();
189         if (cache_set[family])
190                 return cache[family];
191         cache_set[family] = true;
192
193         string const ffamily = familyString(family);
194         if (isSpecial(f)) {
195                 cache_set[family] = true;
196                 XftPattern *fpat = XftPatternCreate();
197                 XftPatternAddString(fpat, XFT_FAMILY, ffamily.c_str());
198                 XftResult result;
199                 XftPattern *fpat2 = XftFontMatch(getDisplay(), getScreen(),
200                                                  fpat, &result);
201                 XftPatternDestroy(fpat);
202                 char * familyM;
203                 XftPatternGetString(fpat2, XFT_FAMILY, 0, &familyM);
204                 if (ffamily == familyM) {
205                         cache[family] = true;
206                         return true;
207                 }
208                 // We don't need to set cache[family] to false, as it
209                 // is initialized to false;
210                 return false;
211         }
212         // We don't care about non-symbol fonts
213         return false;
214 }