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