]> git.lyx.org Git - lyx.git/blob - src/frontends/gtk/xftFontMetrics.C
Extracted from r14281
[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
28 #include "support/lstrings.h"
29 #include "debug.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 } // 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(char c,LyXFont const & f)
100 {
101         XftFont * font = getXftFont(f);
102         XGlyphInfo glyph;
103         XftTextExtents8(getDisplay(), font,
104                          reinterpret_cast<XftChar8 *>(&c),
105                          1,
106                          &glyph);
107         return XGlyphAscent(glyph);
108 }
109
110
111 int descent(char c,LyXFont const & f)
112 {
113         XftFont * font = getXftFont(f);
114         XGlyphInfo glyph;
115         XftTextExtents8(getDisplay(), font,
116                          reinterpret_cast<XftChar8 *>(&c),
117                          1,
118                          &glyph);
119         return XGlyphDescent(glyph);
120 }
121
122
123 int lbearing(char c,LyXFont const & f)
124 {
125         XftFont * font = getXftFont(f);
126         XGlyphInfo glyph;
127         XftTextExtents8(getDisplay(), font,
128                          reinterpret_cast<XftChar8 *>(&c),
129                          1,
130                          &glyph);
131         return XGlyphLbearing(glyph);
132 }
133
134
135 int rbearing(char c,LyXFont const & f)
136 {
137         XftFont * font = getXftFont(f);
138         XGlyphInfo glyph;
139         XftTextExtents8(getDisplay(), font,
140                          reinterpret_cast<XftChar8 *>(&c),
141                          1,
142                          &glyph);
143         return XGlyphRbearing(glyph);
144 }
145
146
147 int width(char const * s, size_t n, LyXFont const & f)
148 {
149         XftFont * font = getXftFont(f);
150         XGlyphInfo glyph;
151         if (f.realShape() != LyXFont::SMALLCAPS_SHAPE){
152                 XftTextExtents8(getDisplay(), font,
153                                  reinterpret_cast<XftChar8 *>(const_cast<char *>(s)), n, &glyph);
154                 return XGlyphLogWidth(glyph);
155         } else {
156                 int result = 0;
157                 LyXFont smallfont(f);
158                 smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE);
159                 XftFont * fontS = getXftFont(smallfont);
160                 for (size_t i = 0; i < n; ++i) {
161                         char c = lyx::support::uppercase(s[i]);
162                         if (c != s[i]) {
163                                 XftTextExtents8(getDisplay(), fontS,
164                                                  reinterpret_cast<XftChar8 *>(&c),
165                                                  1,
166                                                  &glyph);
167                                 result += XGlyphLogWidth(glyph);
168                         } else {
169                                 XftTextExtents8(getDisplay(), font,
170                                                  reinterpret_cast<XftChar8 *>(&c),
171                                                  1,
172                                                  &glyph);
173                                 result += XGlyphLogWidth(glyph);
174                         }
175                 }
176                 return result;
177         }
178 }
179
180
181 int signedWidth(string const & s, LyXFont const & f)
182 {
183         if (s.empty())
184                 return 0;
185         if (s[0] == '-')
186                 return width(s.c_str() + 1, s.size() - 1, f);
187         else
188                 return width(s.c_str(), s.size(), f);
189 }
190
191
192 void rectText(string const & str, LyXFont const & font,
193         int & width,
194         int & ascent,
195         int & descent)
196 {
197         static int const d = 2;
198         width = font_metrics::width(str, font) + d * 2 + 2;
199         ascent = font_metrics::maxAscent(font) + d;
200         descent = font_metrics::maxDescent(font) + d;
201 }
202
203
204 void buttonText(string const & str, LyXFont const & font,
205         int & width,
206         int & ascent,
207         int & descent)
208 {
209         static int const d = 3;
210
211         width = font_metrics::width(str, font) + d * 2 + 2;
212         ascent = font_metrics::maxAscent(font) + d;
213         descent = font_metrics::maxDescent(font) + d;
214 }
215
216
217 } // namespace font_metrics