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