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