]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/xfont_metrics.C
Replace 'using namespace abc;' with 'using abc::xyz;'
[lyx.git] / src / frontends / xforms / xfont_metrics.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 unknown
7  * \author John Levon
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "xfont_metrics.h"
15 #include "font_metrics.h"
16 #include "xfont_loader.h"
17
18 #include "encoding.h"
19 #include "language.h"
20 #include "lyxrc.h"
21
22 #include "frontends/lyx_gui.h"
23
24 #include "support/lstrings.h"
25
26 #include <boost/scoped_array.hpp>
27
28 using lyx::support::uppercase;
29
30
31 namespace {
32
33 inline
34 XFontStruct * getXFontstruct(LyXFont const & f)
35 {
36         return fontloader.load
37                 (f.family(), f.series(),
38                 f.realShape(), f.size());
39 }
40
41
42 inline
43 XID getFontID(LyXFont const & f)
44 {
45         return getXFontstruct(f)->fid;
46 }
47
48 } // namespace anon
49
50
51 namespace font_metrics {
52
53 int maxAscent(LyXFont const & f)
54 {
55         return getXFontstruct(f)->ascent;
56 }
57
58
59 int maxDescent(LyXFont const & f)
60 {
61         return getXFontstruct(f)->descent;
62 }
63
64
65 int ascent(char c, LyXFont const & f)
66 {
67         XFontStruct * finfo = getXFontstruct(f);
68         unsigned int uc = static_cast<unsigned char>(c);
69         if (finfo->per_char
70             && uc >= finfo->min_char_or_byte2
71             && uc <= finfo->max_char_or_byte2+256*finfo->max_byte1)
72                 return finfo->per_char[uc - finfo->min_char_or_byte2].ascent;
73         else
74                 return finfo->ascent;
75 }
76
77
78 int descent(char c, LyXFont const & f)
79 {
80         XFontStruct * finfo = getXFontstruct(f);
81         unsigned int uc = static_cast<unsigned char>(c);
82         if (finfo->per_char
83             && uc >= finfo->min_char_or_byte2
84             && uc <= finfo->max_char_or_byte2+256*finfo->max_byte1)
85                 return finfo->per_char[uc - finfo->min_char_or_byte2].descent;
86         else
87                 return finfo->descent;
88 }
89
90
91 int lbearing(char c, LyXFont const & f)
92 {
93         XFontStruct * finfo = getXFontstruct(f);
94         unsigned int uc = static_cast<unsigned char>(c);
95         if (finfo->per_char
96             && uc >= finfo->min_char_or_byte2
97             && uc <= finfo->max_char_or_byte2+256*finfo->max_byte1)
98                 return finfo->per_char[uc - finfo->min_char_or_byte2].lbearing;
99         else
100                 return 0;
101 }
102
103
104 int rbearing(char c, LyXFont const & f)
105 {
106         XFontStruct * finfo = getXFontstruct(f);
107         unsigned int uc = static_cast<unsigned char>(c);
108         if (finfo->per_char
109             && uc >= finfo->min_char_or_byte2
110             && uc <= finfo->max_char_or_byte2+256*finfo->max_byte1)
111                 return finfo->per_char[uc - finfo->min_char_or_byte2].rbearing;
112         else
113                 return width(c, f);
114 }
115
116
117 int width(char const * s, size_t n, LyXFont const & f)
118 {
119         if (!lyx_gui::use_gui)
120                 return n;
121
122         if (lyxrc.font_norm_type == LyXRC::ISO_10646_1) {
123                 boost::scoped_array<XChar2b> xs(new XChar2b[n]);
124                 Encoding const * encoding = f.language()->encoding();
125                 LyXFont font(f);
126                 if (f.isSymbolFont()) {
127 #ifdef USE_UNICODE_FOR_SYMBOLS
128                         font.setFamily(LyXFont::ROMAN_FAMILY);
129                         font.setShape(LyXFont::UP_SHAPE);
130 #endif
131                         encoding = encodings.symbol_encoding();
132                 }
133                 for (size_t i = 0; i < n; ++i) {
134                         Uchar c = encoding->ucs(s[i]);
135                         xs[i].byte1 = c >> 8;
136                         xs[i].byte2 = c & 0xff;
137                 }
138                 int result = xfont_metrics::width(xs.get(), n, font);
139                 return result;
140         }
141
142         if (f.realShape() != LyXFont::SMALLCAPS_SHAPE) {
143                 return ::XTextWidth(getXFontstruct(f), s, n);
144         } else {
145                 // emulate smallcaps since X doesn't support this
146                 int result = 0;
147                 LyXFont smallfont(f);
148                 smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE);
149                 for (size_t i = 0; i < n; ++i) {
150                         char const c = uppercase(s[i]);
151                         if (c != s[i]) {
152                                 result += ::XTextWidth(getXFontstruct(smallfont), &c, 1);
153                         } else {
154                                 result += ::XTextWidth(getXFontstruct(f), &c, 1);
155                         }
156                 }
157                 return result;
158         }
159 }
160
161
162 int signedWidth(string const & s, LyXFont const & f)
163 {
164         if (s.empty())
165                 return 0;
166         if (s[0] == '-')
167                 return -width(s.substr(1, s.length() - 1), f);
168         else
169                 return width(s, f);
170 }
171
172
173 void rectText(string const & str, LyXFont const & font,
174         int & width,
175         int & ascent,
176         int & descent)
177 {
178         static int const d = 2;
179         width = font_metrics::width(str, font) + d * 2 + 2;
180         ascent = font_metrics::maxAscent(font) + d;
181         descent = font_metrics::maxDescent(font) + d;
182 }
183
184
185
186 void buttonText(string const & str, LyXFont const & font,
187         int & width,
188         int & ascent,
189         int & descent)
190 {
191         static int const d = 3;
192
193         width = font_metrics::width(str, font) + d * 2 + 2;
194         ascent = font_metrics::maxAscent(font) + d;
195         descent = font_metrics::maxDescent(font) + d;
196 }
197
198 } // namespace font_metrics
199
200 namespace xfont_metrics {
201
202 int width(XChar2b const * s, int n, LyXFont const & f)
203 {
204         if (!lyx_gui::use_gui)
205                 return n;
206
207         if (f.realShape() != LyXFont::SMALLCAPS_SHAPE) {
208                 return ::XTextWidth16(getXFontstruct(f), s, n);
209         } else {
210                 // emulate smallcaps since X doesn't support this
211                 int result = 0;
212                 static XChar2b c;
213                 LyXFont smallfont(f);
214                 smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE);
215                 for (int i = 0; i < n; ++i) {
216                         if (s[i].byte1)
217                                 c = s[i];
218                         else {
219                                 c.byte1 = s[i].byte1;
220                                 c.byte2 = uppercase(s[i].byte2);
221                         }
222                         if (c.byte2 != s[i].byte2) {
223                                 result += ::XTextWidth16(getXFontstruct(smallfont), &c, 1);
224                         } else {
225                                 result += ::XTextWidth16(getXFontstruct(f), &s[i], 1);
226                 }
227                 }
228                 return result;
229         }
230 }
231
232
233 int XTextWidth(LyXFont const & f, char const * str, int count)
234 {
235         return ::XTextWidth(getXFontstruct(f), str, count);
236 }
237
238
239 int XTextWidth16(LyXFont const & f, XChar2b const * str, int count)
240 {
241         return ::XTextWidth16(getXFontstruct(f), str, count);
242 }
243
244
245 /// hmm, not a metric !
246 void XSetFont(Display * display, GC gc, LyXFont const & f)
247 {
248         ::XSetFont(display, gc, getFontID(f));
249 }
250
251 } // namespace xfont_metrics