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