]> git.lyx.org Git - lyx.git/blob - src/mathed/math_scriptinset.C
remove unneeded member
[lyx.git] / src / mathed / math_scriptinset.C
1 #ifdef __GNUG__
2 #pragma implementation
3 #endif
4
5 #include "math_scriptinset.h"
6 #include "math_support.h"
7 #include "math_symbolinset.h"
8 #include "math_mathmlstream.h"
9 #include "support/LAssert.h"
10 #include "debug.h"
11
12
13 using std::max;
14
15
16 MathScriptInset::MathScriptInset()
17         : MathNestInset(2), limits_(0)
18 {
19         script_[0] = false;
20         script_[1] = false;
21 }
22
23
24 MathScriptInset::MathScriptInset(bool up)
25         : MathNestInset(2), limits_(0)
26 {
27         script_[0] = !up;
28         script_[1] = up;
29 }
30
31
32 MathInset * MathScriptInset::clone() const
33 {
34         return new MathScriptInset(*this);
35 }
36
37
38 MathScriptInset const * MathScriptInset::asScriptInset() const
39 {
40         return this;
41 }
42
43
44 MathScriptInset * MathScriptInset::asScriptInset()
45 {
46         return this;
47 }
48
49
50 MathXArray const & MathScriptInset::up() const
51 {
52         return xcell(1);
53 }
54
55
56 MathXArray const & MathScriptInset::down() const
57 {
58         return xcell(0);
59 }
60
61
62 MathXArray & MathScriptInset::up()
63 {
64         return xcell(1);
65 }
66
67
68 MathXArray & MathScriptInset::down()
69 {
70         return xcell(0);
71 }
72
73
74 void MathScriptInset::ensure(bool up)
75 {
76         script_[up] = true;
77 }
78
79
80 int MathScriptInset::dy0(MathInset const * nuc) const
81 {
82         int nd = ndes(nuc);
83         if (!hasDown())
84                 return nd;
85         int des = down().ascent();
86         if (hasLimits(nuc))
87                 des += nd + 2;
88         else
89                 des = max(des, nd);
90         return des;
91 }
92
93
94 int MathScriptInset::dy1(MathInset const * nuc) const
95 {
96         int na = nasc(nuc);
97         if (!hasUp())
98                 return na;
99         int asc = up().descent();
100         if (hasLimits(nuc))
101                 asc += na + 2;
102         else
103                 asc = max(asc, na);
104         asc = max(asc, mathed_char_ascent(font_, 'I'));
105         return asc;
106 }
107
108
109 int MathScriptInset::dx0(MathInset const * nuc) const
110 {
111         lyx::Assert(hasDown());
112         return hasLimits(nuc) ? (width2(nuc) - down().width()) / 2 : nwid(nuc);
113 }
114
115
116 int MathScriptInset::dx1(MathInset const * nuc) const
117 {
118         lyx::Assert(hasUp());
119         return hasLimits(nuc) ? (width2(nuc) - up().width()) / 2 : nwid(nuc);
120 }
121
122
123 int MathScriptInset::dxx(MathInset const * nuc) const
124 {
125         //lyx::Assert(nuc());
126         return hasLimits(nuc)  ?  (width2(nuc) - nwid(nuc)) / 2  :  0;
127 }
128
129
130 void MathScriptInset::dimensions2
131         (MathInset const * nuc, int & w, int & a, int & d) const
132 {
133         a = dy1(nuc) + (hasUp() ? up().ascent() : 0);
134         d = dy0(nuc) + (hasDown() ? down().descent() : 0);
135         w = width2(nuc);
136 }
137
138
139 int MathScriptInset::width2(MathInset const * nuc) const
140 {
141         int w = 0;
142         if (hasLimits(nuc)) {
143                 w = nwid(nuc);
144                 if (hasUp())
145                         w = max(w, up().width());
146                 if (hasDown())
147                         w = max(w, down().width());
148         } else {
149                 if (hasUp())
150                         w = max(w, up().width());
151                 if (hasDown())
152                         w = max(w, down().width());
153                 w += nwid(nuc);
154         }
155         return w;
156 }
157
158
159 int MathScriptInset::nwid(MathInset const * nuc) const
160 {
161         return nuc ?  nuc->width() : mathed_char_width(font_, '.');
162 }
163
164
165 int MathScriptInset::nasc(MathInset const * nuc) const
166 {
167         return nuc ? nuc->ascent() : mathed_char_ascent(font_, 'I');
168 }
169
170
171 int MathScriptInset::ndes(MathInset const * nuc) const
172 {
173         return nuc ? nuc->descent() : mathed_char_descent(font_, 'I');
174 }
175
176
177 void MathScriptInset::metrics(MathMetricsInfo & mi) const
178 {
179         metrics(0, mi);
180 }
181
182
183 void MathScriptInset::metrics(MathInset const * nuc, MathMetricsInfo & mi) const
184 {
185         if (nuc)
186                 nuc->metrics(mi);
187         MathNestInset::metrics(mi);
188         MathScriptChanger dummy(mi.base);
189         dimensions2(nuc, width_, ascent_, descent_);
190 }
191
192
193 void MathScriptInset::draw(MathPainterInfo & pi, int x, int y) const
194 {
195         //lyxerr << "unexpected call to MathScriptInset::draw()\n";
196         draw(0, pi, x, y);
197 }
198
199
200 void MathScriptInset::draw(MathInset const * nuc, MathPainterInfo & pi,
201         int x, int y) const
202 {
203         if (nuc)
204                 nuc->draw(pi, x + dxx(nuc), y);
205         else if (editing())
206                 drawStr(pi, font_, x + dxx(nuc), y, ".");
207
208         MathScriptChanger dummy(pi.base);
209         if (hasUp())
210                 up().draw(pi, x + dx1(nuc), y - dy1(nuc));
211         if (hasDown())
212                 down().draw(pi, x + dx0(nuc), y + dy0(nuc));
213 }
214
215
216 void MathScriptInset::metricsT(TextMetricsInfo const & mi) const
217 {
218         metricsT(0, mi);
219 }
220
221
222 void MathScriptInset::metricsT(MathInset const * nuc,
223         TextMetricsInfo const & mi) const
224 {
225         if (hasUp())
226                 up().metricsT(mi);
227         if (hasDown())
228                 down().metricsT(mi);
229         if (nuc)
230                 nuc->metricsT(mi);
231         //ascent_  = ascent2(nuc);
232         //descent_ = descent2(nuc);
233         //width_   = width2(nuc);
234 }
235
236
237 void MathScriptInset::drawT(TextPainter & pain, int x, int y) const
238 {
239         //lyxerr << "unexpected call to MathScriptInset::draw()\n";
240         drawT(0, pain, x, y);
241 }
242
243
244 void MathScriptInset::drawT(MathInset const * nuc, TextPainter & pain,
245         int x, int y) const
246 {
247         if (nuc)
248                 nuc->drawT(pain, x + dxx(nuc), y);
249         if (hasUp())
250                 up().drawT(pain, x + dx1(nuc), y - dy1(nuc));
251         if (hasDown())
252                 down().drawT(pain, x + dx0(nuc), y + dy0(nuc));
253 }
254
255
256
257 bool MathScriptInset::hasLimits(MathInset const * nuc) const
258 {
259         // obvious cases
260         if (limits_ == 1)
261                 return true;
262         if (limits_ == -1)
263                 return false;
264
265         // we can only display limits if the nucleus wants some
266         if (!nuc)
267                 return false;
268         if (!nuc->isScriptable())
269                 return false;
270
271         // per default \int has limits beside the \int even in displayed formulas
272         if (nuc->asSymbolInset())
273                 if (nuc->asSymbolInset()->name().find("int") != string::npos)
274                         return false;
275
276         // assume "real" limits for everything else
277         return true;
278 }
279
280
281 void MathScriptInset::removeEmptyScripts()
282 {
283         for (int i = 0; i <= 1; ++i)
284                 if (script_[i] && cell(i).size() == 0) {
285                         cell(i).clear();
286                         script_[i] = false;
287                 }
288 }
289
290
291 void MathScriptInset::removeScript(bool up)
292 {
293         cell(up).clear();
294         script_[up] = false;
295 }
296
297
298 bool MathScriptInset::has(bool up) const
299 {
300         return script_[up];
301 }
302
303
304 bool MathScriptInset::empty() const
305 {
306         return !script_[0] && !script_[1];
307 }
308
309
310 bool MathScriptInset::hasUp() const
311 {
312         return script_[1];
313 }
314
315
316 bool MathScriptInset::hasDown() const
317 {
318         return script_[0];
319 }
320
321
322 bool MathScriptInset::idxRight(MathInset::idx_type &,
323                                  MathInset::pos_type &) const
324 {
325         return false;
326 }
327
328
329 bool MathScriptInset::idxLeft(MathInset::idx_type &,
330                                 MathInset::pos_type &) const
331 {
332         return false;
333 }
334
335
336 void MathScriptInset::write(WriteStream & os) const
337 {
338         //lyxerr << "unexpected call to MathScriptInset::write()\n";
339         write2(0, os);
340 }
341
342
343 void MathScriptInset::write2(MathInset const * nuc, WriteStream & os) const
344 {
345         if (nuc) {
346                 os << nuc;
347                 if (nuc->takesLimits()) {
348                         if (limits_ == -1)
349                                 os << "\\nolimits ";
350                         if (limits_ == 1)
351                                 os << "\\limits ";
352                 }
353         } else
354                         if (os.firstitem())
355                                 lyxerr[Debug::MATHED] << "suppressing {} when writing\n";
356                         else
357                                 os << "{}";
358
359         if (hasDown() && down().data().size())
360                 os << "_{" << down().data() << '}';
361
362         if (hasUp() && up().data().size())
363                 os << "^{" << up().data() << '}';
364 }
365
366
367 void MathScriptInset::normalize(NormalStream & os) const
368 {
369         //lyxerr << "unexpected call to MathScriptInset::normalize()\n";
370         normalize2(0, os);
371 }
372
373
374 void MathScriptInset::normalize2(MathInset const * nuc, NormalStream & os) const
375 {
376         bool d = hasDown() && down().data().size();
377         bool u = hasUp() && up().data().size();
378
379         if (u)
380                 os << "[sup ";
381         if (d)
382                 os << "[sub ";
383
384         if (nuc)
385                 os << nuc << ' ';
386         else
387                 os << "[par]";
388
389         if (d)
390                 os << down().data() << ']';
391         if (u)
392                 os << up().data() << ']';
393 }
394
395
396 void MathScriptInset::maplize2(MathInset const * nuc, MapleStream & os) const
397 {
398         if (nuc)
399                 os << nuc;
400         if (hasDown() && down().data().size())
401                 os << '[' << down().data() << ']';
402         if (hasUp() && up().data().size())
403                 os << "^(" << up().data() << ')';
404 }
405
406
407 void MathScriptInset::mathematicize2(MathInset const * nuc, MathematicaStream & os) const
408 {
409         bool d = hasDown() && down().data().size();
410         bool u = hasUp() && up().data().size();
411
412         if (nuc)
413                 if (d)  //subscript only if nuc !
414                         os << "Subscript[" << nuc;
415                 else
416                         os << nuc;
417         if (u)
418                 os << "^(" << up().data() << ")";
419
420         if (nuc)
421                 if (d)
422                 os << "," << down().data() << "]"; 
423 }
424
425
426 void MathScriptInset::mathmlize2(MathInset const * nuc, MathMLStream & os) const
427 {
428         bool d = hasDown() && down().data().size();
429         bool u = hasUp() && up().data().size();
430
431         if (u && d)
432                 os << MTag("msubsup");
433         else if (u)
434                 os << MTag("msup");
435         else if (d)
436                 os << MTag("msub");
437
438         if (nuc)
439                 os << nuc;
440         else
441                 os << "<mrow/>";
442
443         if (u && d)
444                 os << down().data() << up().data() << ETag("msubsup");
445         else if (u)
446                 os << up().data() << ETag("msup");
447         else if (d)
448                 os << down().data() << ETag("msub");
449 }
450
451
452 void MathScriptInset::octavize2(MathInset const * nuc, OctaveStream & os) const
453 {
454         if (nuc)
455                 os << nuc;
456         if (hasDown() && down().data().size())
457                 os << '[' << down().data() << ']';
458         if (hasUp() && up().data().size())
459                 os << "^(" << up().data() << ')';
460 }
461
462
463 void MathScriptInset::infoize(std::ostream & os) const
464 {
465         if (limits_)
466                 os << (limits_ == 1 ? "Displayed limits" : "Inlined limits");
467 }