]> git.lyx.org Git - lyx.git/blob - src/frontends/gtk/xftFontLoader.C
Get rid of trailing whitespace 'noise' in future patches for the
[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
31 // The global fontLoader
32 xftFontLoader fontLoader;
33
34
35 // Initialize font loader
36 xftFontLoader::xftFontLoader()
37 {
38 }
39
40
41 // Destroy font loader
42 xftFontLoader::~xftFontLoader()
43 {
44         unload();
45 }
46
47
48 // Update fonts after zoom, dpi, font names, or norm change
49 // For now, we just ditch all fonts we have. Later, we should
50 // reuse the ones that are already loaded.
51 void xftFontLoader::update()
52 {
53         unload();
54 }
55
56
57 // Unload all fonts
58 void xftFontLoader::unload()
59 {
60         // Unload all fonts
61         for (int i1 = 0; i1 < LyXFont::NUM_FAMILIES; ++i1)
62                 for (int i2 = 0; i2 < 2; ++i2)
63                         for (int i3 = 0; i3 < 4; ++i3)
64                                 for (int i4 = 0; i4 < 10; ++i4) {
65                                         if (fonts_[i1][i2][i3][i4]){
66                                                 XftFontClose(getDisplay(), fonts_[i1][i2][i3][i4]);
67                                                 fonts_[i1][i2][i3][i4] = 0;
68                                         }
69                                 }
70 }
71
72
73 string xftFontLoader::familyString(LyXFont::FONT_FAMILY family)
74 {
75         string ffamily;
76         switch (family) {
77         case LyXFont::ROMAN_FAMILY:
78                 ffamily = lyxrc.roman_font_name;
79                 break;
80         case LyXFont::SANS_FAMILY:
81                 ffamily = lyxrc.sans_font_name;
82                 break;
83         case LyXFont::TYPEWRITER_FAMILY:
84                 ffamily = lyxrc.typewriter_font_name;
85                 break;
86         case LyXFont::CMR_FAMILY:
87                 ffamily = "cmr10";
88                 break;
89         case LyXFont::CMSY_FAMILY:
90                 ffamily = "cmsy10";
91                 break;
92         case LyXFont::CMM_FAMILY:
93                 ffamily = "cmmi10";
94                 break;
95         case LyXFont::CMEX_FAMILY:
96                 ffamily = "cmex10";
97                 break;
98         case LyXFont::MSA_FAMILY:
99                 ffamily = "msam10";
100                 break;
101         case LyXFont::MSB_FAMILY:
102                 ffamily = "msbm10";
103                 break;
104         default:
105                 ffamily = "Sans";
106                 break;
107         }
108         return ffamily;
109 }
110
111
112 // Get font pattern
113 /* Takes care of finding which font that can match the given request. Tries
114 different alternatives. */
115 XftPattern * xftFontLoader::getFontPattern(LyXFont::FONT_FAMILY family,
116                                           LyXFont::FONT_SERIES series,
117                                           LyXFont::FONT_SHAPE shape,
118                                           LyXFont::FONT_SIZE size)
119 {
120         // Normal font. Let's search for an existing name that matches.
121         string ffamily;
122         int fweight;
123         int fslant;
124         double fsize = lyxrc.font_sizes[size] * lyxrc.zoom / 100.0;
125         XftPattern *fpat = XftPatternCreate();
126
127         ffamily = familyString(family);
128         switch (series) {
129         case LyXFont::MEDIUM_SERIES:
130                 fweight = XFT_WEIGHT_MEDIUM;
131                 break;
132         case LyXFont::BOLD_SERIES:
133                 fweight = XFT_WEIGHT_BOLD;
134                 break;
135         default:
136                 fweight = XFT_WEIGHT_MEDIUM;
137                 break;
138         }
139
140         switch (shape) {
141         case LyXFont::UP_SHAPE:
142         case LyXFont::SMALLCAPS_SHAPE:
143                 fslant = XFT_SLANT_ROMAN;
144                 break;
145         case LyXFont::ITALIC_SHAPE:
146                 fslant = XFT_SLANT_ITALIC;
147                 break;
148         case LyXFont::SLANTED_SHAPE:
149                 fslant = XFT_SLANT_OBLIQUE;
150                 break;
151         default:
152                 fslant = XFT_SLANT_ROMAN;
153                 break;
154         }
155         XftPatternAddString(fpat, XFT_FAMILY, ffamily.c_str());
156         XftPatternAddInteger(fpat, XFT_WEIGHT, fweight);
157         XftPatternAddInteger(fpat, XFT_SLANT, fslant);
158         XftPatternAddDouble(fpat, XFT_SIZE, fsize);
159         return fpat;
160 }
161
162
163 /// Do load font
164 XftFont * xftFontLoader::doLoad(LyXFont::FONT_FAMILY family,
165                                LyXFont::FONT_SERIES series,
166                                LyXFont::FONT_SHAPE shape,
167                                LyXFont::FONT_SIZE size)
168 {
169         XftPattern *fpat = getFontPattern(family, series, shape, size);
170         XftResult result;
171         XftPattern *fpat2 = XftFontMatch(getDisplay(), getScreen(),
172                                          fpat, &result);
173         XftFont * font = XftFontOpenPattern(getDisplay(), fpat2);
174         fonts_[family][series][shape][size] = font;
175         return font;
176 }
177
178
179 bool xftFontLoader::available(LyXFont const & f)
180 {
181         if (!lyx_gui::use_gui)
182                 return false;
183
184         static std::vector<bool> cache_set(LyXFont::NUM_FAMILIES, false);
185         static std::vector<bool> cache(LyXFont::NUM_FAMILIES, false);
186
187         LyXFont::FONT_FAMILY family = f.family();
188         if (cache_set[family])
189                 return cache[family];
190         cache_set[family] = true;
191
192         string const ffamily = familyString(family);
193         if (isSpecial(f)) {
194                 cache_set[family] = true;
195                 XftPattern *fpat = XftPatternCreate();
196                 XftPatternAddString(fpat, XFT_FAMILY, ffamily.c_str());
197                 XftResult result;
198                 XftPattern *fpat2 = XftFontMatch(getDisplay(), getScreen(),
199                                                  fpat, &result);
200                 XftPatternDestroy(fpat);
201                 char * familyM;
202                 XftPatternGetString(fpat2, XFT_FAMILY, 0, &familyM);
203                 if (ffamily == familyM) {
204                         cache[family] = true;
205                         return true;
206                 }
207                 // We don't need to set cache[family] to false, as it
208                 // is initialized to false;
209                 return false;
210         }
211         // We don't care about non-symbol fonts
212         return false;
213 }