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