]> git.lyx.org Git - lyx.git/blob - src/mathed/math_scriptinset.C
Compilation fixes.
[lyx.git] / src / mathed / math_scriptinset.C
1
2 #include <config.h>
3 #include "Lsstream.h"
4
5 #include "debug.h"
6 #include "support.h"
7 #include "support/LOstream.h"
8 #include "support/LAssert.h"
9
10 #ifdef __GNUG__
11 #pragma implementation
12 #endif
13
14 #include "math_scriptinset.h"
15
16 using std::ostream;
17 using std::ostringstream;
18
19
20 MathScriptInset::MathScriptInset()
21         : MathNestInset(2), limits_(0)
22 {
23         script_[0] = false;
24         script_[1] = false;
25 }
26
27
28 MathScriptInset::MathScriptInset(bool up)
29         : MathNestInset(2), limits_(0)
30 {
31         script_[0] = !up;
32         script_[1] = up;
33 }
34
35
36 MathInset * MathScriptInset::clone() const
37 {
38         return new MathScriptInset(*this);
39 }
40
41
42 MathScriptInset const * MathScriptInset::asScriptInset() const
43 {
44         return this;
45 }
46
47
48 MathScriptInset * MathScriptInset::asScriptInset()
49 {
50         return this;
51 }
52
53
54 MathXArray const & MathScriptInset::up() const
55 {
56         return xcell(1);
57 }
58
59
60 MathXArray const & MathScriptInset::down() const
61 {
62         return xcell(0);
63 }
64
65
66 MathXArray & MathScriptInset::up()
67 {
68         return xcell(1);
69 }
70
71
72 MathXArray & MathScriptInset::down()
73 {
74         return xcell(0);
75 }
76
77
78 void MathScriptInset::ensure(bool up)
79 {
80         script_[up] = true;
81 }
82
83
84 int MathScriptInset::dy0(MathInset const * nuc) const
85 {
86         int nd = ndes(nuc);
87         if (!hasDown())
88                 return nd;
89         int des = down().ascent();
90         if (hasLimits(nuc))
91                 des += nd + 2;
92         else 
93                 des = std::max(des, nd);
94         return des;
95 }
96
97
98 int MathScriptInset::dy1(MathInset const * nuc) const
99 {
100         int na = nasc(nuc);
101         if (!hasUp())
102                 return na;
103         int asc = up().descent();
104         if (hasLimits(nuc))
105                 asc += na + 2;
106         else 
107                 asc = std::max(asc, na);
108         asc = std::max(asc, mathed_char_ascent(LM_TC_VAR, mi_, 'I'));
109         return asc;
110 }
111
112
113 int MathScriptInset::dx0(MathInset const * nuc) const
114 {
115         lyx::Assert(hasDown());
116         return hasLimits(nuc) ? (width(nuc) - down().width()) / 2 : nwid(nuc);
117 }
118
119
120 int MathScriptInset::dx1(MathInset const * nuc) const
121 {
122         lyx::Assert(hasUp());
123         return hasLimits(nuc) ? (width(nuc) - up().width()) / 2 : nwid(nuc);
124 }
125
126
127 int MathScriptInset::dxx(MathInset const * nuc) const
128 {
129         //lyx::Assert(nuc());
130         return hasLimits(nuc)  ?  (width(nuc) - nwid(nuc)) / 2  :  0;
131 }
132
133
134 int MathScriptInset::ascent(MathInset const * nuc) const
135 {
136         return dy1(nuc) + (hasUp() ? up().ascent() : 0);
137 }
138
139
140 int MathScriptInset::descent(MathInset const * nuc) const
141 {
142         return dy0(nuc) + (hasDown() ? down().descent() : 0);
143 }
144
145
146 int MathScriptInset::width(MathInset const * nuc) const
147 {
148         int wid = 0;
149         if (hasLimits(nuc)) {
150                 wid = nwid(nuc);
151                 if (hasUp())
152                         wid = std::max(wid, up().width());
153                 if (hasDown())
154                         wid = std::max(wid, down().width());
155         } else {
156                 if (hasUp())
157                         wid = std::max(wid, up().width());
158                 if (hasDown())
159                         wid = std::max(wid, down().width());
160                 wid += nwid(nuc);
161         }
162         return wid;
163 }
164
165
166 int MathScriptInset::nwid(MathInset const * nuc) const
167 {
168         return nuc ?
169                 nuc->width() :
170                 mathed_char_width(LM_TC_TEX, mi_, '.');
171 }
172
173
174 int MathScriptInset::nasc(MathInset const * nuc) const
175 {
176         return nuc ? nuc->ascent()
177                 : mathed_char_ascent(LM_TC_VAR, mi_, 'I');
178 }
179
180
181 int MathScriptInset::ndes(MathInset const * nuc) const
182 {
183         return nuc ? nuc->descent()
184                 : mathed_char_descent(LM_TC_VAR, mi_, 'I');
185 }
186
187
188 void MathScriptInset::metrics(MathMetricsInfo const & mi) const
189 {       
190         metrics(0, mi);
191 }
192
193
194 void MathScriptInset::metrics(MathInset const * nuc,
195         MathMetricsInfo const & mi) const
196 {       
197         MathNestInset::metrics(mi);
198         if (nuc)
199                 nuc->metrics(mi);
200
201         ascent_  = ascent(nuc);
202         descent_ = descent(nuc);
203         width_   = width(nuc);
204 }
205
206
207 void MathScriptInset::draw(Painter & pain, int x, int y) const
208 {  
209         //lyxerr << "unexpected call to MathScriptInset::draw()\n";
210         draw(0, pain, x, y);
211 }
212
213
214 void MathScriptInset::draw(MathInset const * nuc, Painter & pain,
215         int x, int y) const
216 {  
217         if (nuc)
218                 nuc->draw(pain, x + dxx(nuc), y);
219         else
220                 drawStr(pain, LM_TC_TEX, mi_, x + dxx(nuc), y, ".");
221
222         if (hasUp())
223                 up().draw(pain, x + dx1(nuc), y - dy1(nuc));
224
225         if (hasDown())
226                 down().draw(pain, x + dx0(nuc), y + dy0(nuc));
227 }
228
229
230 void MathScriptInset::write(MathWriteInfo & os) const
231 {  
232         //lyxerr << "unexpected call to MathScriptInset::write()\n";
233         write(0, os);
234 }
235
236
237 void MathScriptInset::write(MathInset const * nuc, MathWriteInfo & os) const
238 {
239         if (nuc) {
240                 nuc->write(os);
241                 if (nuc->takesLimits()) {
242                         if (limits_ == -1)
243                                 os << "\\nolimits ";
244                         if (limits_ == 1)
245                                 os << "\\limits ";
246                 }
247         }
248         else
249                 os << "{}";
250
251         if (hasDown() && down().data_.size())
252                 os << "_{" << down().data_ << '}';
253
254         if (hasUp() && up().data_.size())
255                 os << "^{" << up().data_ << '}';
256 }
257
258
259 void MathScriptInset::writeNormal(ostream & os) const
260 {  
261         //lyxerr << "unexpected call to MathScriptInset::writeNormal()\n";
262         writeNormal(0, os);
263 }
264
265
266 void MathScriptInset::writeNormal(MathInset const * nuc, ostream & os) const
267 {
268         bool d = hasDown() && down().data_.size();
269         bool u = hasUp() && up().data_.size();
270
271         ostringstream osb;
272         if (nuc)
273                 nuc->writeNormal(osb);
274         else
275                 osb << "[par]";
276         string base = osb.str();
277
278         if (u && d) {
279                 os << "[sup [sub " << osb.str() << " ";
280                 down().data_.writeNormal(os);
281                 os << "]";
282                 up().data_.writeNormal(os);
283                 os << ']';
284         } else if (u) {
285                 os << "[sup " << osb.str() << " ";
286                 up().data_.writeNormal(os);
287                 os << ']';
288         } else if (d) {
289                 os << "[sub " << osb.str() << " ";
290                 down().data_.writeNormal(os);
291                 os << ']';
292         }
293 }
294
295
296 bool MathScriptInset::hasLimits(MathInset const * nuc) const
297 {
298         return limits_ == 1 || (limits_ == 0 && nuc && nuc->isScriptable());
299 }
300
301
302 void MathScriptInset::removeEmptyScripts()
303 {
304         for (int i = 0; i <= 1; ++i)
305                 if (script_[i] && !cell(i).size())
306                         script_[i] = false;
307 }
308
309
310 void MathScriptInset::removeScript(bool up)
311 {
312         cell(up).clear();
313         script_[up] = false;
314 }
315
316
317 bool MathScriptInset::has(bool up) const
318 {
319         return script_[up];
320 }
321
322
323 bool MathScriptInset::hasUp() const
324 {
325         return script_[1];
326 }
327
328
329 bool MathScriptInset::hasDown() const
330 {
331         return script_[0];
332 }
333
334
335 bool MathScriptInset::idxRight(MathInset::idx_type &,
336                                  MathInset::pos_type &) const
337 {
338         return false;
339 }
340
341
342 bool MathScriptInset::idxLeft(MathInset::idx_type &,
343                                 MathInset::pos_type &) const
344 {
345         return false;
346 }
347
348