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