]> git.lyx.org Git - lyx.git/blob - src/mathed/math_atom.C
further code uglification to make Jean-Marc's compiler happy
[lyx.git] / src / mathed / math_atom.C
1 /*
2  *  File:        math_inset.C
3  *  Purpose:     Implementation of insets for mathed
4  *  Author:      Alejandro Aguilar Sierra <asierra@servidor.unam.mx> 
5  *  Created:     January 1996
6  *  Description: 
7  *
8  *  Dependencies: Xlib, XForms
9  *
10  *  Copyright: 1996, 1997 Alejandro Aguilar Sierra
11  *
12  *   Version: 0.8beta.
13  *
14  *   You are free to use and modify this code under the terms of
15  *   the GNU General Public Licence version 2 or later.
16  */
17
18 #ifdef __GNUG__
19 #pragma implementation
20 #endif
21
22 #include "math_atom.h"
23 #include "math_scriptinset.h"
24 #include "debug.h"
25 #include "support.h"
26 #include "support/LAssert.h"
27
28
29 MathAtom::MathAtom()
30         : nucleus_(0), limits_(0), xo_(0), yo_(0)
31 {
32         script_[0] = 0;
33         script_[1] = 0;
34 }
35
36
37 MathAtom::MathAtom(MathInset * p)
38         : nucleus_(p), limits_(0), xo_(0), yo_(0)
39 {
40         script_[0] = 0;
41         script_[1] = 0;
42 }
43
44
45 MathAtom::MathAtom(MathInset * p, MathScriptInset * up, MathScriptInset * down)
46         : nucleus_(p), limits_(0), xo_(0), yo_(0)
47 {
48         script_[0] = down;
49         script_[1] = up;
50 }
51
52
53 MathAtom::MathAtom(MathAtom const & p)
54 {
55         copy(p);
56 }
57
58
59 void MathAtom::operator=(MathAtom const & p)
60 {
61         if (this != &p) {
62                 done();
63                 copy(p);
64         }
65 }
66
67
68 MathAtom::~MathAtom()
69 {
70         done();
71 }
72
73
74 void MathAtom::done()
75 {
76         delete nucleus_;
77         delete script_[0];
78         delete script_[1];
79 }
80
81
82 void MathAtom::copy(MathAtom const & p)
83 {
84         //cerr << "calling MathAtom::copy\n";
85         xo_        = p.xo_;
86         yo_        = p.yo_;
87         limits_    = p.limits_;
88         nucleus_   = p.nucleus_;
89         script_[0] = p.script_[0];
90         script_[1] = p.script_[1];
91         if (nucleus_)
92                 nucleus_ = nucleus_->clone();
93         if (script_[0])
94                 script_[0]  = new MathScriptInset(*script_[0]);
95         if (script_[1])
96                 script_[1]  = new MathScriptInset(*script_[1]);
97 }
98
99
100 int MathAtom::height() const
101 {
102         return ascent() + descent();
103 }
104
105
106 std::ostream & operator<<(std::ostream & os, MathAtom const & atom)
107 {
108         atom.write(os, false);
109         return os;
110 }
111
112
113 int MathAtom::xo() const
114 {
115         return xo_;
116 }
117
118
119 int MathAtom::yo() const
120 {
121         return yo_;
122 }
123
124
125 void MathAtom::xo(int x) const
126 {
127         xo_ = x;
128 }
129
130
131 void MathAtom::yo(int y) const
132 {
133         yo_ = y;
134 }
135
136
137 void MathAtom::getXY(int & x, int & y) const
138 {
139    x = xo();
140    y = yo();
141 }
142
143
144 /*
145 void MathAtom::userSetSize(MathStyles sz)
146 {
147         if (sz >= 0) {
148                 size_ = sz;      
149                 flag = flag & ~LMPF_FIXED_SIZE;
150         }
151 }
152 */
153
154 void MathAtom::writeNormal(std::ostream & os) const
155 {
156         os << "[unknown] ";
157 }
158
159
160 void MathAtom::dump() const
161 {
162         lyxerr << "---------------------------------------------\n";
163         write(lyxerr, false);
164         lyxerr << "\n---------------------------------------------\n";
165 }
166
167
168 bool MathAtom::covers(int x, int y) const
169 {
170         return
171                 x >= xo_ &&
172                 x <= xo_ + width() &&
173                 y >= yo_ - ascent() &&
174                 y <= yo_ + descent();
175 }
176
177
178 MathScriptInset * MathAtom::ensure(bool up)
179 {
180         if (!script_[up])
181                 script_[up] = new MathScriptInset(up);
182         return script_[up];
183 }
184
185
186 void MathAtom::validate(LaTeXFeatures &) const
187 {}
188
189
190 void MathAtom::metrics(MathStyles st) const
191 {
192         MathStyles tt = smallerStyleScript(st);
193         if (nucleus())
194                 nucleus()->metrics(st);
195         if (up())
196                 up()->metrics(tt);
197         if (down())
198                 down()->metrics(tt);
199 }
200
201
202 MathScriptInset * MathAtom::up() const
203 {
204         return script_[1];
205 }
206
207
208 MathScriptInset * MathAtom::down() const
209 {
210         return script_[0];
211 }
212
213
214 MathScriptInset * & MathAtom::up()
215 {
216         return script_[1];
217 }
218
219
220 MathScriptInset * & MathAtom::down()
221 {
222         return script_[0];
223 }
224
225
226 int MathAtom::dy0() const
227 {
228         if (!down())
229                 return ndes();
230         int des = down()->ascent();
231         if (hasLimits())
232                 des += ndes() + 2;
233         else 
234                 des = std::max(des, ndes());
235         return des;
236 }
237
238
239 int MathAtom::dy1() const
240 {
241         if (!up())
242                 return nasc();
243         int asc = up()->descent();
244         if (hasLimits())
245                 asc += nasc() + 2;
246         else 
247                 asc = std::max(asc, nasc());
248         asc = std::max(asc, mathed_char_ascent(LM_TC_VAR, LM_ST_TEXT, 'I'));
249         return asc;
250 }
251
252
253 int MathAtom::dx0() const
254 {
255         lyx::Assert(down());
256         return hasLimits() ? (width() - down()->width()) / 2 : nwid();
257 }
258
259
260 int MathAtom::dx1() const
261 {
262         lyx::Assert(up());
263         return hasLimits() ? (width() - up()->width()) / 2 : nwid();
264 }
265
266
267 int MathAtom::dxx() const
268 {
269         lyx::Assert(nucleus());
270         return hasLimits() ? (width() - nwid()) / 2 : 0;
271 }
272
273
274 int MathAtom::ascent() const
275 {
276         return dy1() + (up() ? up()->ascent() : 0);
277 }
278
279
280 int MathAtom::descent() const
281 {
282         return dy0() + (down() ? down()->descent() : 0);
283 }
284
285
286 int MathAtom::width() const
287 {
288         int wid = 0;
289         if (hasLimits()) {
290                 wid = nwid();
291                 if (up())
292                         wid = std::max(wid, up()->width());
293                 if (down())
294                         wid = std::max(wid, down()->width());
295         } else {
296                 if (up())
297                         wid = std::max(wid, up()->width());
298                 if (down())
299                         wid = std::max(wid, down()->width());
300                 wid += nwid();
301         }
302         return wid;
303 }
304
305
306 int MathAtom::nwid() const
307 {
308         return nucleus() ? nucleus()->width() : 0;
309 }
310
311
312 int MathAtom::nasc() const
313 {
314         return nucleus() ? nucleus()->ascent()
315                 : mathed_char_ascent(LM_TC_VAR, LM_ST_TEXT, 'I');
316 }
317
318
319 int MathAtom::ndes() const
320 {
321         return nucleus() ? nucleus()->descent()
322                 : mathed_char_descent(LM_TC_VAR, LM_ST_TEXT, 'I');
323 }
324
325
326 void MathAtom::draw(Painter & pain, int x, int y) const
327 {  
328         xo(x);
329         yo(y);
330         if (nucleus())
331                 nucleus()->draw(pain, x + dxx(), y);
332         if (up())
333                 up()->draw(pain, x + dx1(), y - dy1());
334         if (down())
335                 down()->draw(pain, x + dx0(), y + dy0());
336 }
337
338
339 void MathAtom::write(std::ostream & os, bool fragile) const
340 {
341         if (nucleus()) {
342                 nucleus()->write(os, fragile);
343                 if (nucleus()->takesLimits()) {
344                         if (limits_ == -1)
345                                 os << "\\nolimits ";
346                         if (limits_ == 1)
347                                 os << "\\limits ";
348                 }
349         } else
350                 os << "{}";
351
352         if (up()) {
353                 os << "^{";
354                 up()->write(os, fragile);
355                 os << "}";
356         }
357
358         if (down()) {
359                 os << "_{";
360                 down()->write(os, fragile);
361                 os << "}";
362         }
363 }
364
365
366 bool MathAtom::hasLimits() const
367 {
368         return
369                 limits_ == 1 || (limits_ == 0 && nucleus() && nucleus()->isScriptable());
370 }
371
372
373 void MathAtom::substitute(MathMacro const & m)
374 {
375         if (nucleus())
376                 nucleus()->substitute(m);
377         if (up())
378                 up()->substitute(m);
379         if (down())
380                 down()->substitute(m);
381 }
382
383
384 void MathAtom::removeEmptyScripts()
385 {
386         for (int i = 0; i <= 1; ++i)
387                 if (script_[i] && !script_[i]->cell(0).size()) {
388                         delete script_[i];
389                         script_[i] = 0;
390                 }
391 }