]> git.lyx.org Git - features.git/blob - src/frontends/gtk/xftFontMetrics.C
466feffba1432d2de78137b3c6b44aeddb3a9861
[features.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 #include "GtkmmX.h"
14 #include "xftFontLoader.h"
15 #include "font_metrics.h"
16 #include "lyxrc.h"
17 #include "encoding.h"
18 #include "language.h"
19 #include "codeConvert.h"
20
21 #include "support/lstrings.h"
22
23 #include <gtkmm.h>
24
25 #include <boost/scoped_array.hpp>
26
27 #include <algorithm>
28
29 using std::string;
30
31
32 namespace {
33
34
35 inline XftFont * getXftFont(LyXFont const & f)
36 {
37         return fontLoader.load(f.family(), f.series(),
38                                f.realShape(), f.size());
39 }
40
41
42 inline int XGlyphAscent(XGlyphInfo const & info)
43 {
44         return info.y;
45 }
46
47
48 inline int XGlyphDescent(XGlyphInfo const & info)
49 {
50         return info.height - info.y;
51 }
52
53
54 inline int XGlyphLbearing(XGlyphInfo const & info)
55 {
56         return -info.x;
57 }
58
59
60 inline int XGlyphRbearing(XGlyphInfo const & info)
61 {
62         return -info.x + info.width;
63 }
64
65
66 inline int XGlyphLogWidth(XGlyphInfo const & info)
67 {
68         return info.xOff;
69 }
70
71
72 wchar_t C2WC(char ch)
73 {
74         wchar_t wcs[2] = {0, 0};
75         char mbs[2] = {0, 0};
76         mbs[0] = ch;
77         mbstowcs(wcs, mbs, 2);
78         return wcs[0];
79 }
80
81
82 } // namespace anon
83
84
85 namespace font_metrics {
86
87
88 int maxAscent(LyXFont const & f)
89 {
90         XftFont * font = getXftFont(f);
91         return font->ascent;
92 }
93
94
95 int maxDescent(LyXFont const & f)
96 {
97         XftFont * font = getXftFont(f);
98         return font->descent;
99 }
100
101
102 int ascent(wchar_t c,LyXFont const & f)
103 {
104         XftFont * font = getXftFont(f);
105         XGlyphInfo glyph;
106         XftTextExtents32(getDisplay(), font,
107                          wcsToXftChar32StrFast(&c),
108                          1,
109                          &glyph);
110         return XGlyphAscent(glyph);
111 }
112
113
114 int ascent(char c, LyXFont const & f)
115 {
116         return ascent(C2WC(c), f);
117 }
118
119
120 int descent(wchar_t c,LyXFont const & f)
121 {
122         XftFont * font = getXftFont(f);
123         XGlyphInfo glyph;
124         XftTextExtents32(getDisplay(), font,
125                          wcsToXftChar32StrFast(&c),
126                          1,
127                          &glyph);
128         return XGlyphDescent(glyph);
129 }
130
131
132 int descent(char c, LyXFont const & f)
133 {
134         return descent(C2WC(c), f);
135 }
136
137
138 int lbearing(wchar_t c,LyXFont const & f)
139 {
140         XftFont * font = getXftFont(f);
141         XGlyphInfo glyph;
142         XftTextExtents32(getDisplay(), font,
143                          wcsToXftChar32StrFast(&c),
144                          1,
145                          &glyph);
146         return XGlyphLbearing(glyph);
147 }
148
149
150 int rbearing(wchar_t c,LyXFont const & f)
151 {
152         XftFont * font = getXftFont(f);
153         XGlyphInfo glyph;
154         XftTextExtents32(getDisplay(), font,
155                          wcsToXftChar32StrFast(&c),
156                          1,
157                          &glyph);
158         return XGlyphRbearing(glyph);
159 }
160
161
162 int lbearing(char c, LyXFont const & f)
163 {
164         return lbearing(C2WC(c), f);
165 }
166
167
168 int rbearing(char c, LyXFont const & f)
169 {
170         return rbearing(C2WC(c), f);
171 }
172
173
174 int width(wchar_t const * s, size_t n, LyXFont const & f)
175 {
176         XftFont * font = getXftFont(f);
177         XGlyphInfo glyph;
178         if (f.realShape() != LyXFont::SMALLCAPS_SHAPE){
179                 XftTextExtents32(getDisplay(), font,
180                                  const_cast<XftChar32 *>(
181                                          wcsToXftChar32StrFast(s)),
182                                  n,
183                                  &glyph);
184                 return XGlyphLogWidth(glyph);
185         } else {
186                 int result = 0;
187                 LyXFont smallfont(f);
188                 smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE);
189                 XftFont * fontS = getXftFont(smallfont);
190                 for (size_t i = 0; i < n; ++i) {
191                         wchar_t wc = lyx::support::uppercase(s[i]);
192                         if (wc != s[i]) {
193                                 XftTextExtents32(getDisplay(), fontS,
194                                                  wcsToXftChar32StrFast(&wc),
195                                                  1,
196                                                  &glyph);
197                                 result += XGlyphLogWidth(glyph);
198                         } else {
199                                 XftTextExtents32(getDisplay(), font,
200                                                  wcsToXftChar32StrFast(&wc),
201                                                  1,
202                                                  &glyph);
203                                 result += XGlyphLogWidth(glyph);
204                         }
205                 }
206                 return result;
207         }
208 }
209
210
211 int width(wchar_t c,LyXFont const & f)
212 {
213         return width(&c, 1, f);
214 }
215
216
217 int width(char const * s, size_t n, LyXFont const & f)
218 {
219         boost::scoped_array<wchar_t> wcs(new wchar_t[n]);
220         size_t len;
221         if (fontLoader.isSpecial(f)) {
222                 unsigned char const * us =
223                         reinterpret_cast<unsigned char const *>(s);
224                 len = n;
225                 std::copy(us, us + n, wcs.get());
226         } else
227                 len = mbstowcs(wcs.get(), s, n);
228         return width(wcs.get(), len, f);
229 }
230
231
232 int signedWidth(string const & s, LyXFont const & f)
233 {
234         if (s.empty())
235                 return 0;
236         boost::scoped_array<wchar_t> wcs(new wchar_t[s.length() + 1]);
237         int len = mbstowcs(wcs.get(), s.c_str(), s.length());
238         if (wcs[0] == '-')
239                 return width(wcs.get() + 1, len - 1, f);
240         else
241                 return width(wcs.get(), len, f);
242 }
243
244
245 void rectText(string const & str, LyXFont const & font,
246         int & width,
247         int & ascent,
248         int & descent)
249 {
250         static int const d = 2;
251         width = font_metrics::width(str, font) + d * 2 + 2;
252         ascent = font_metrics::maxAscent(font) + d;
253         descent = font_metrics::maxDescent(font) + d;
254 }
255
256
257 void buttonText(string const & str, LyXFont const & font,
258         int & width,
259         int & ascent,
260         int & descent)
261 {
262         static int const d = 3;
263
264         width = font_metrics::width(str, font) + d * 2 + 2;
265         ascent = font_metrics::maxAscent(font) + d;
266         descent = font_metrics::maxDescent(font) + d;
267 }
268
269
270 } // namespace font_metrics