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