]> git.lyx.org Git - lyx.git/blob - src/frontends/gtk/xftFontMetrics.C
enable Font cache only for MacOSX and inline width() for other platform.
[lyx.git] / src / frontends / gtk / xftFontMetrics.C
1 /**
2  * \file xfont_metrics.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 "GtkmmX.h"
22 #include "xftFontLoader.h"
23 #include "font_metrics.h"
24 #include "lyxrc.h"
25 #include "encoding.h"
26 #include "language.h"
27
28 #include "support/lstrings.h"
29 #include "debug.h"
30
31 #include <gtkmm.h>
32
33 #include <boost/scoped_array.hpp>
34
35 #include <algorithm>
36
37 using lyx::char_type;
38 using lyx::docstring;
39
40 using std::string;
41
42
43 namespace {
44
45
46 inline XftFont * getXftFont(LyXFont const & f)
47 {
48         return fontLoader.load(f.family(), f.series(),
49                                f.realShape(), f.size());
50 }
51
52
53 inline int XGlyphAscent(XGlyphInfo const & info)
54 {
55         return info.y;
56 }
57
58
59 inline int XGlyphDescent(XGlyphInfo const & info)
60 {
61         return info.height - info.y;
62 }
63
64
65 inline int XGlyphLbearing(XGlyphInfo const & info)
66 {
67         return -info.x;
68 }
69
70
71 inline int XGlyphRbearing(XGlyphInfo const & info)
72 {
73         return -info.x + info.width;
74 }
75
76
77 inline int XGlyphLogWidth(XGlyphInfo const & info)
78 {
79         return info.xOff;
80 }
81
82 } // namespace anon
83
84
85 int font_metrics::maxAscent(LyXFont const & f)
86 {
87         XftFont * font = getXftFont(f);
88         return font->ascent;
89 }
90
91
92 int font_metrics::maxDescent(LyXFont const & f)
93 {
94         XftFont * font = getXftFont(f);
95         return font->descent;
96 }
97
98
99 int font_metrics::ascent(char_type c,LyXFont const & f)
100 {
101         XftFont * font = getXftFont(f);
102         XGlyphInfo glyph;
103         XftTextExtents32(getDisplay(), font,
104                          reinterpret_cast<FcChar32 *>(&c),
105                          1,
106                          &glyph);
107         return XGlyphAscent(glyph);
108 }
109
110
111 int font_metrics::descent(char_type c,LyXFont const & f)
112 {
113         XftFont * font = getXftFont(f);
114         XGlyphInfo glyph;
115         XftTextExtents32(getDisplay(), font,
116                          reinterpret_cast<FcChar32 *>(&c),
117                          1,
118                          &glyph);
119         return XGlyphDescent(glyph);
120 }
121
122
123 int font_metrics::lbearing(char_type c,LyXFont const & f)
124 {
125         XftFont * font = getXftFont(f);
126         XGlyphInfo glyph;
127         XftTextExtents32(getDisplay(), font,
128                          reinterpret_cast<FcChar32 *>(&c),
129                          1,
130                          &glyph);
131         return XGlyphLbearing(glyph);
132 }
133
134
135 int font_metrics::rbearing(char_type c,LyXFont const & f)
136 {
137         XftFont * font = getXftFont(f);
138         XGlyphInfo glyph;
139         XftTextExtents32(getDisplay(), font,
140                          reinterpret_cast<FcChar32 *>(&c),
141                          1,
142                          &glyph);
143         return XGlyphRbearing(glyph);
144 }
145
146
147 int font_metrics::width(char_type const * s, size_t n, LyXFont const & f)
148 {
149         XftFont * font = getXftFont(f);
150         XGlyphInfo glyph;
151         if (f.realShape() != LyXFont::SMALLCAPS_SHAPE){
152                 XftTextExtents32(getDisplay(),
153                                 font,
154                                 reinterpret_cast<FcChar32 const *>(s),
155                                 n,
156                                 &glyph);
157                 return XGlyphLogWidth(glyph);
158         } else {
159                 int result = 0;
160                 LyXFont smallfont(f);
161                 smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE);
162                 XftFont * fontS = getXftFont(smallfont);
163                 for (size_t i = 0; i < n; ++i) {
164                         char_type c = lyx::support::uppercase(s[i]);
165                         if (c != s[i]) {
166                                 XftTextExtents32(getDisplay(),
167                                                  fontS,
168                                                  reinterpret_cast<FcChar32 *>(&c),
169                                                  1,
170                                                  &glyph);
171                                 result += XGlyphLogWidth(glyph);
172                         } else {
173                                 XftTextExtents32(getDisplay(),
174                                                  font,
175                                                  reinterpret_cast<FcChar32 *>(&c),
176                                                  1,
177                                                  &glyph);
178                                 result += XGlyphLogWidth(glyph);
179                         }
180                 }
181                 return result;
182         }
183 }
184
185
186 int font_metrics::signedWidth(docstring const & s, LyXFont const & f)
187 {
188         if (s.empty())
189                 return 0;
190         if (s[0] == '-')
191                 return width(s.substr(1, s.length() - 1), f);
192         else
193                 return width(s, f);
194 }
195
196
197 void font_metrics::rectText(docstring const & str, LyXFont const & font,
198         int & width,
199         int & ascent,
200         int & descent)
201 {
202         static int const d = 2;
203         width = font_metrics::width(str, font) + d * 2 + 2;
204         ascent = font_metrics::maxAscent(font) + d;
205         descent = font_metrics::maxDescent(font) + d;
206 }
207
208
209 void font_metrics::buttonText(docstring const & str, LyXFont const & font,
210         int & width,
211         int & ascent,
212         int & descent)
213 {
214         static int const d = 3;
215
216         width = font_metrics::width(str, font) + d * 2 + 2;
217         ascent = font_metrics::maxAscent(font) + d;
218         descent = font_metrics::maxDescent(font) + d;
219 }