]> git.lyx.org Git - lyx.git/blob - src/mathed/InsetMathSymbol.cpp
93f9f5e828a25ce8d8cebba1c0c98788542995e9
[lyx.git] / src / mathed / InsetMathSymbol.cpp
1 /**
2  * \file InsetMathSymbol.cpp
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 "InsetMathSymbol.h"
14 #include "Dimension.h"
15 #include "MathStream.h"
16 #include "MathStream.h"
17 #include "MathSupport.h"
18 #include "MathParser.h"
19 #include "MathAtom.h"
20 #include "LaTeXFeatures.h"
21
22 #include "debug.h"
23 #include "LyXRC.h"
24
25 #include "support/textutils.h"
26
27 namespace lyx {
28
29 using std::string;
30 using std::auto_ptr;
31
32
33 InsetMathSymbol::InsetMathSymbol(latexkeys const * l)
34         : sym_(l), h_(0), scriptable_(false)
35 {}
36
37
38 InsetMathSymbol::InsetMathSymbol(char const * name)
39         : sym_(in_word_set(from_ascii(name))), h_(0), scriptable_(false)
40 {}
41
42
43 InsetMathSymbol::InsetMathSymbol(docstring const & name)
44         : sym_(in_word_set(name)), h_(0), scriptable_(false)
45 {}
46
47
48 auto_ptr<Inset> InsetMathSymbol::doClone() const
49 {
50         return auto_ptr<Inset>(new InsetMathSymbol(*this));
51 }
52
53
54 docstring InsetMathSymbol::name() const
55 {
56         return sym_->name;
57 }
58
59
60 bool InsetMathSymbol::metrics(MetricsInfo & mi, Dimension & dim) const
61 {
62         //lyxerr << "metrics: symbol: '" << sym_->name
63         //      << "' in font: '" << sym_->inset
64         //      << "' drawn as: '" << sym_->draw
65         //      << "'" << std::endl;
66
67         int const em = mathed_char_width(mi.base.font, 'M');
68         FontSetChanger dummy(mi.base, sym_->inset);
69         mathed_string_dim(mi.base.font, sym_->draw, dim);
70         docstring::const_reverse_iterator rit = sym_->draw.rbegin();
71         kerning_ = mathed_char_kerning(mi.base.font, *rit);
72         // correct height for broken cmex and wasy font
73         if (sym_->inset == "cmex" || sym_->inset == "wasy") {
74                 h_ = 4 * dim.des / 5;
75                 dim.asc += h_;
76                 dim.des -= h_;
77         }
78         // seperate things a bit
79         if (isRelOp())
80                 dim.wid += static_cast<int>(0.5 * em + 0.5);
81         else
82                 dim.wid += static_cast<int>(0.1667 * em + 0.5);
83
84         scriptable_ = false;
85         if (mi.base.style == LM_ST_DISPLAY)
86                 if (sym_->inset == "cmex" || sym_->inset == "esint" ||
87                     sym_->extra == "funclim")
88                         scriptable_ = true;
89
90         if (dim_ == dim)
91                 return false;
92
93         dim_ = dim;
94         return true;
95 }
96
97
98 void InsetMathSymbol::draw(PainterInfo & pi, int x, int y) const
99 {
100         //lyxerr << "metrics: symbol: '" << sym_->name
101         //      << "' in font: '" << sym_->inset
102         //      << "' drawn as: '" << sym_->draw
103         //      << "'" << std::endl;
104         int const em = mathed_char_width(pi.base.font, 'M');
105         if (isRelOp())
106                 x += static_cast<int>(0.25*em+0.5);
107         else
108                 x += static_cast<int>(0.0833*em+0.5);
109
110         FontSetChanger dummy(pi.base, sym_->inset.c_str());
111         pi.draw(x, y - h_, sym_->draw);
112 }
113
114
115 bool InsetMathSymbol::isRelOp() const
116 {
117         return sym_->extra == "mathrel";
118 }
119
120
121 bool InsetMathSymbol::isOrdAlpha() const
122 {
123         return sym_->extra == "mathord" || sym_->extra == "mathalpha";
124 }
125
126
127 bool InsetMathSymbol::isScriptable() const
128 {
129         return scriptable_;
130 }
131
132
133 bool InsetMathSymbol::takesLimits() const
134 {
135         return
136                 sym_->inset == "cmex" ||
137                 sym_->inset == "lyxboldsymb" ||
138                 sym_->inset == "esint" ||
139                 sym_->extra == "funclim";
140 }
141
142
143 void InsetMathSymbol::validate(LaTeXFeatures & features) const
144 {
145         if (!sym_->requires.empty())
146                 features.require(to_utf8(sym_->requires));
147 }
148
149
150 void InsetMathSymbol::normalize(NormalStream & os) const
151 {
152         os << "[symbol " << name() << ']';
153 }
154
155
156 void InsetMathSymbol::maple(MapleStream & os) const
157 {
158         if (name() == "cdot")
159                 os << '*';
160         else if (name() == "infty")
161                 os << "infinity";
162         else
163                 os << name();
164 }
165
166 void InsetMathSymbol::maxima(MaximaStream & os) const
167 {
168         if (name() == "cdot")
169                 os << '*';
170         else if (name() == "infty")
171                 os << "inf";
172         else if (name() == "pi")
173                 os << "%pi";
174         else
175                 os << name();
176 }
177
178
179 void InsetMathSymbol::mathematica(MathematicaStream & os) const
180 {
181         if ( name() == "pi")    { os << "Pi"; return;}
182         if ( name() == "infty") { os << "Infinity"; return;}
183         if ( name() == "cdot")  { os << '*'; return;}
184         os << name();
185 }
186
187
188 char const * MathMLtype(docstring const & s)
189 {
190         if (s == "mathop")
191                 return "mo";
192         return "mi";
193 }
194
195
196 void InsetMathSymbol::mathmlize(MathStream & os) const
197 {
198         char const * type = MathMLtype(sym_->extra);
199         os << '<' << type << "> ";
200         if (sym_->xmlname == "x") // unknown so far
201                 os << name();
202         else
203                 os << sym_->xmlname;
204         os << " </" << type << '>';
205 }
206
207
208 void InsetMathSymbol::octave(OctaveStream & os) const
209 {
210         if (name() == "cdot")
211                 os << '*';
212         else
213                 os << name();
214 }
215
216
217 void InsetMathSymbol::write(WriteStream & os) const
218 {
219         os << '\\' << name();
220
221         // $,#, etc. In theory the restriction based on catcodes, but then
222         // we do not handle catcodes very well, let alone cat code changes,
223         // so being outside the alpha range is good enough.
224         if (name().size() == 1 && !isAlphaASCII(name()[0]))
225                 return;
226
227         os.pendingSpace(true);
228 }
229
230
231 void InsetMathSymbol::infoize2(odocstream & os) const
232 {
233         os << "Symbol: " << name();
234 }
235
236
237 } // namespace lyx