]> git.lyx.org Git - lyx.git/blob - src/mathed/math_symbolinset.C
fix #1145
[lyx.git] / src / mathed / math_symbolinset.C
1 /**
2  * \file math_symbolinset.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author André Pönitz
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "math_symbolinset.h"
14 #include "dimension.h"
15 #include "math_mathmlstream.h"
16 #include "math_streamstr.h"
17 #include "math_support.h"
18 #include "math_parser.h"
19 #include "math_atom.h"
20 #include "LaTeXFeatures.h"
21 #include "debug.h"
22
23
24 using std::auto_ptr;
25
26
27 MathSymbolInset::MathSymbolInset(latexkeys const * l)
28         : sym_(l), h_(0)
29 {}
30
31
32 MathSymbolInset::MathSymbolInset(char const * name)
33         : sym_(in_word_set(name)), h_(0)
34 {}
35
36
37 MathSymbolInset::MathSymbolInset(string const & name)
38         : sym_(in_word_set(name.c_str())), h_(0)
39 {}
40
41
42 auto_ptr<InsetBase> MathSymbolInset::clone() const
43 {
44         return auto_ptr<InsetBase>(new MathSymbolInset(*this));
45 }
46
47
48 string MathSymbolInset::name() const
49 {
50         return sym_->name;
51 }
52
53
54 void MathSymbolInset::metrics(MetricsInfo & mi, Dimension & dim) const
55 {
56         //lyxerr << "metrics: symbol: '" << sym_->name
57         //      << "' in font: '" << sym_->inset
58         //      << "' drawn as: '" << sym_->draw
59         //      << "'" << std::endl;
60
61         int const em = mathed_char_width(mi.base.font, 'M');
62         FontSetChanger dummy(mi.base, sym_->inset.c_str());
63         mathed_string_dim(mi.base.font, sym_->draw, dim);
64         // correct height for broken cmex and wasy font
65 #if defined(__APPLE__) && defined(__GNUC__)
66         if (sym_->inset == "cmex") {
67                 h_ = 4 * dim_.des / 5;
68                 dim_.asc += 0*h_;
69                 dim_.des -= h_;
70                 h_ = dim_.asc;
71         } else if (sym_->inset == "wasy") {
72                 h_ = 4 * dim.des / 5;
73                 dim.asc += h_;
74                 dim.des -= h_;
75         }
76 #else
77         if (sym_->inset == "cmex" || sym_->inset == "wasy") {
78                 h_ = 4 * dim.des / 5;
79                 dim.asc += h_;
80                 dim.des -= h_;
81         }
82 #endif
83         // seperate things a bit
84         if (isRelOp())
85                 dim.wid += static_cast<int>(0.5 * em + 0.5);
86         else
87                 dim.wid += static_cast<int>(0.1667 * em + 0.5);
88
89         scriptable_ = false;
90         if (mi.base.style == LM_ST_DISPLAY)
91                 if (sym_->inset == "cmex" || sym_->extra == "funclim")
92                         scriptable_ = true;
93 }
94
95
96 void MathSymbolInset::draw(PainterInfo & pi, int x, int y) const
97 {
98         //lyxerr << "metrics: symbol: '" << sym_->name
99         //      << "' in font: '" << sym_->inset
100         //      << "' drawn as: '" << sym_->draw
101         //      << "'" << std::endl;
102         int const em = mathed_char_width(pi.base.font, 'M');
103         if (isRelOp())
104                 x += static_cast<int>(0.25*em+0.5);
105         else
106                 x += static_cast<int>(0.0833*em+0.5);
107
108         FontSetChanger dummy(pi.base, sym_->inset.c_str());
109         drawStr(pi, pi.base.font, x, y - h_, sym_->draw);
110 }
111
112
113 bool MathSymbolInset::isRelOp() const
114 {
115         return sym_->extra == "mathrel";
116 }
117
118
119 bool MathSymbolInset::isScriptable() const
120 {
121         return scriptable_;
122 }
123
124
125 bool MathSymbolInset::takesLimits() const
126 {
127         return
128                 sym_->inset == "cmex" ||
129                 sym_->inset == "lyxboldsymb" ||
130                 sym_->extra == "funclim";
131 }
132
133
134 void MathSymbolInset::validate(LaTeXFeatures & features) const
135 {
136         if (sym_->inset == "msa" || sym_->inset == "msb")
137                 features.require("amssymb");
138 }
139
140
141 void MathSymbolInset::normalize(NormalStream & os) const
142 {
143         os << "[symbol " << name() << ']';
144 }
145
146
147 void MathSymbolInset::maple(MapleStream & os) const
148 {
149         if (name() == "cdot")
150                 os << '*';
151         else if (name() == "infty")
152                 os << "infinity";
153         else
154                 os << name();
155 }
156
157 void MathSymbolInset::maxima(MaximaStream & os) const
158 {
159         if (name() == "cdot")
160                 os << '*';
161         else if (name() == "infty")
162                 os << "INF";
163         else
164                 os << name();
165 }
166
167
168 void MathSymbolInset::mathematica(MathematicaStream & os) const
169 {
170         if ( name() == "pi")    { os << "Pi"; return;}
171         if ( name() == "infty") { os << "Infinity"; return;}
172         os << name();
173 }
174
175
176 char const * MathMLtype(string const & s)
177 {
178         if (s == "mathop")
179                 return "mo";
180         return "mi";
181 }
182
183
184 bool MathSymbolInset::match(MathAtom const & at) const
185 {
186         MathSymbolInset const * q = at->asSymbolInset();
187         return q && name() == q->name();
188 }
189
190
191 void MathSymbolInset::mathmlize(MathMLStream & os) const
192 {
193         char const * type = MathMLtype(sym_->extra);
194         os << '<' << type << "> ";
195         if (sym_->xmlname == "x") // unknown so far
196                 os << name();
197         else
198                 os << sym_->xmlname;
199         os << " </" << type << '>';
200 }
201
202
203 void MathSymbolInset::octave(OctaveStream & os) const
204 {
205         if (name() == "cdot")
206                 os << '*';
207         else
208                 os << name();
209 }
210
211
212 void MathSymbolInset::write(WriteStream & os) const
213 {
214         os << '\\' << name();
215         os.pendingSpace(true);
216 }
217
218
219 void MathSymbolInset::infoize2(std::ostream & os) const
220 {
221         os << "Symbol: " << name();
222 }