]> git.lyx.org Git - lyx.git/blob - src/frontends/gtk/xftFontMetrics.C
fontloader for gtk, probably not efficient
[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 "xftFontMetrics.h"
22
23 #include "GtkmmX.h"
24 #include "xftFontLoader.h"
25 #include "lyxrc.h"
26 #include "encoding.h"
27 #include "language.h"
28
29 #include "support/lstrings.h"
30 #include "debug.h"
31
32 #include <gtkmm.h>
33
34 #include <boost/scoped_array.hpp>
35
36 #include <algorithm>
37
38 using lyx::char_type;
39 using lyx::docstring;
40
41 using std::string;
42
43
44 namespace {
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 } // namespace anon
77
78
79 font_metrics::font_metrics(XftFont * f, XftFont * scf)
80         : font(f), fontS(scf)
81 {
82 }
83
84
85 int font_metrics::maxAscent() const
86 {
87         return font->ascent;
88 }
89
90
91 int font_metrics::maxDescent() const
92 {
93         return font->descent;
94 }
95
96
97 int font_metrics::ascent(char_type c) const
98 {
99         XGlyphInfo glyph;
100         XftTextExtents32(getDisplay(), font,
101                          reinterpret_cast<FcChar32 *>(&c),
102                          1,
103                          &glyph);
104         return XGlyphAscent(glyph);
105 }
106
107
108 int font_metrics::descent(char_type c) const
109 {
110         XGlyphInfo glyph;
111         XftTextExtents32(getDisplay(), font,
112                          reinterpret_cast<FcChar32 *>(&c),
113                          1,
114                          &glyph);
115         return XGlyphDescent(glyph);
116 }
117
118
119 int font_metrics::lbearing(char_type c) const
120 {
121         XGlyphInfo glyph;
122         XftTextExtents32(getDisplay(), font,
123                          reinterpret_cast<FcChar32 *>(&c),
124                          1,
125                          &glyph);
126         return XGlyphLbearing(glyph);
127 }
128
129
130 int font_metrics::rbearing(char_type c) const
131 {
132         XGlyphInfo glyph;
133         XftTextExtents32(getDisplay(), font,
134                          reinterpret_cast<FcChar32 *>(&c),
135                          1,
136                          &glyph);
137         return XGlyphRbearing(glyph);
138 }
139
140
141 int font_metrics::width(char_type const * s, size_t n) const
142 {
143         XGlyphInfo glyph;
144         if (!fontS){
145                 XftTextExtents32(getDisplay(),
146                                 font,
147                                 reinterpret_cast<FcChar32 const *>(s),
148                                 n,
149                                 &glyph);
150                 return XGlyphLogWidth(glyph);
151         } else {
152                 int result = 0;
153                 for (size_t i = 0; i < n; ++i) {
154                         char_type c = lyx::support::uppercase(s[i]);
155                         if (c != s[i]) {
156                                 XftTextExtents32(getDisplay(),
157                                                  fontS,
158                                                  reinterpret_cast<FcChar32 *>(&c),
159                                                  1,
160                                                  &glyph);
161                                 result += XGlyphLogWidth(glyph);
162                         } else {
163                                 XftTextExtents32(getDisplay(),
164                                                  font,
165                                                  reinterpret_cast<FcChar32 *>(&c),
166                                                  1,
167                                                  &glyph);
168                                 result += XGlyphLogWidth(glyph);
169                         }
170                 }
171                 return result;
172         }
173 }
174
175
176 int font_metrics::signedWidth(docstring const & s) const
177 {
178         if (s.empty())
179                 return 0;
180         if (s[0] == '-')
181                 return width(s.substr(1, s.length() - 1).c_str(), s.length() - 1);
182         else
183                 return width(s.c_str(), s.length());
184 }
185
186
187 void font_metrics::rectText(docstring const & str,
188         int & width,
189         int & ascent,
190         int & descent) const
191 {
192         static int const d = 2;
193         width = font_metrics::width(str.c_str(), str.length()) + d * 2 + 2;
194         ascent = font_metrics::maxAscent() + d;
195         descent = font_metrics::maxDescent() + d;
196 }
197
198
199 void font_metrics::buttonText(docstring const & str,
200         int & width,
201         int & ascent,
202         int & descent) const
203 {
204         static int const d = 3;
205
206         width = font_metrics::width(str.c_str(), str.length()) + d * 2 + 2;
207         ascent = font_metrics::maxAscent() + d;
208         descent = font_metrics::maxDescent() + d;
209 }