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