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