]> git.lyx.org Git - lyx.git/blob - src/mathed/math_scriptinset.C
move things around
[lyx.git] / src / mathed / math_scriptinset.C
1 #ifdef __GNUG__
2 #pragma implementation
3 #endif
4
5 #include "math_scriptinset.h"
6 #include "support/LOstream.h"
7 #include "support.h"
8
9
10 MathScriptInset::MathScriptInset()
11         : MathNestInset(2), up_(false), down_(false), limits_(0), symbol_(0)
12 {}
13
14
15 MathScriptInset::MathScriptInset(bool up, bool down, MathInset * symbol)
16         : MathNestInset(2), up_(up), down_(down), limits_(0), symbol_(symbol)
17 {}
18
19
20 MathScriptInset::MathScriptInset(MathScriptInset const & p)
21         : MathNestInset(p), up_(p.up_), down_(p.down_),
22                 limits_(p.limits_), symbol_(p.symbol_ ? p.symbol_->clone() : 0)
23 {}
24
25
26 MathScriptInset::~MathScriptInset()
27 {
28         delete symbol_;
29 }
30
31
32 MathInset * MathScriptInset::clone() const
33 {   
34         return new MathScriptInset(*this);
35 }
36
37
38 bool MathScriptInset::up() const
39 {
40         return up_;
41 }
42
43
44 bool MathScriptInset::down() const
45 {
46         return down_;
47 }
48
49
50 void MathScriptInset::up(bool b)
51 {
52         up_ = b;
53 }
54
55
56 void MathScriptInset::down(bool b)
57 {
58         down_ = b;
59 }
60
61
62 bool MathScriptInset::idxRight(int &, int &) const
63 {
64         return false;
65 }
66
67
68 bool MathScriptInset::idxLeft(int &, int &) const
69 {
70         return false;
71 }
72
73
74 bool MathScriptInset::idxUp(int & idx, int & pos) const
75 {
76         if (idx == 0 || !up()) 
77                 return false;
78         idx = 0;
79         pos = 0;
80         return true;
81 }
82
83 bool MathScriptInset::idxDown(int & idx, int & pos) const
84 {
85         if (idx == 1 || !down()) 
86                 return false;
87         idx = 1;
88         pos = 0;
89         return true;
90 }
91
92 bool MathScriptInset::idxFirst(int & idx, int & pos) const
93 {
94         idx = up() ? 0 : 1;
95         pos = 0;
96         return true;
97 }
98
99 bool MathScriptInset::idxLast(int & idx, int & pos) const
100 {
101         idx = down() ? 1 : 0;
102         pos = cell(idx).size();
103         return true;
104 }
105
106
107 bool MathScriptInset::idxFirstUp(int & idx, int & pos) const
108 {
109         if (!up()) 
110                 return false;
111         idx = 0;
112         pos = 0;
113         return true;
114 }
115
116
117 bool MathScriptInset::idxFirstDown(int & idx, int & pos) const
118 {
119         if (!down()) 
120                 return false;
121         idx = 1;
122         pos = 0;
123         return true;
124 }
125
126
127 bool MathScriptInset::idxLastUp(int & idx, int & pos) const
128 {
129         if (!up()) 
130                 return false;
131         idx = 0;
132         pos = cell(idx).size();
133         return true;
134 }
135
136
137 bool MathScriptInset::idxLastDown(int & idx, int & pos) const
138 {
139         if (!down()) 
140                 return false;
141         idx = 1;
142         pos = cell(idx).size();
143         return true;
144 }
145
146
147 void MathScriptInset::write(std::ostream & os, bool fragile) const
148 {
149         if (symbol_) {
150                 symbol_->write(os, fragile);
151                 if (limits())
152                         os << (limits() == 1 ? "\\limits" : "\\nolimits");
153         }
154         if (up()) {
155                 os << "^{";
156                 cell(0).write(os, fragile);
157                 os << "}";
158         }
159         if (down()) {
160                 os << "_{";
161                 cell(1).write(os, fragile);
162                 os << "}";
163         }
164         os << " ";
165 }
166
167
168 void MathScriptInset::idxDelete(int & idx, bool & popit, bool & deleteit)
169 {
170         if (idx == 0) 
171                 up(false);
172         else
173                 down(false);
174         popit = true;
175         deleteit = !(up() || down());
176 }
177
178
179 int MathScriptInset::limits() const
180 {  
181         return limits_;
182 }
183
184
185 void MathScriptInset::limits(int limits) 
186 {  
187         limits_ = limits;
188 }
189
190
191 bool MathScriptInset::hasLimits() const
192 {
193         return
194                 symbol_ && (limits_ == 1 || (limits_ == 0 && size() == LM_ST_DISPLAY));
195 }
196
197
198 void MathScriptInset::writeNormal(std::ostream & os) const
199 {
200         if (limits() && symbol_) 
201                 os << "[" << (limits() ? "limits" : "nolimits") << "]";
202         if (up()) {
203                 os << "[superscript ";
204                 cell(0).writeNormal(os);
205                 os << "] ";
206         }
207         if (down()) {
208                 os << "[subscript ";
209                 cell(1).writeNormal(os);
210                 os << "] ";
211         }
212 }
213
214
215 void MathScriptInset::metrics(MathStyles st) const
216 {
217         size_ = st;
218         MathStyles tt = smallerStyleScript(st);
219         
220         xcell(0).metrics(tt);
221         xcell(1).metrics(tt);
222
223         width_   = std::max(xcell(0).width(), xcell(1).width());
224
225         if (hasLimits()) {
226                 symbol_->metrics(st);
227                 int wid  = symbol_->width();
228                 ascent_  = symbol_->ascent();
229                 descent_ = symbol_->descent();
230                 width_   = std::max(width_, wid);
231                 if (up()) {
232                         ascent_  += xcell(0).height() + 2;
233                         dy0_     = - (ascent_ - xcell(0).ascent());
234                 }
235                 if (down()) {
236                         descent_ += xcell(1).height() + 2;
237                         dy1_     = descent_ - xcell(1).descent();
238                 }
239                 dxx_   = (width_ - wid) / 2;
240                 dx0_   = (width_ - xcell(0).width()) / 2;
241                 dx1_   = (width_ - xcell(1).width()) / 2;
242         } else {
243                 int asc = 0;
244                 int des = 0;
245                 int wid = 0;
246                 mathed_char_height(LM_TC_VAR, st, 'I', asc, des);
247                 if (symbol_) {
248                         symbol_->metrics(st);
249                         wid  = symbol_->width();
250                         asc  = symbol_->ascent();
251                         des  = symbol_->descent();
252                 }
253                 ascent_  = up()   ? xcell(0).height() + asc : 0;
254                 descent_ = down() ? xcell(1).height() + des : 0;
255                 width_  += wid;
256                 dy0_     = - asc - xcell(0).descent();
257                 dy1_     =   des + xcell(1).ascent();
258                 dx0_     = wid;
259                 dx1_     = wid;
260                 dxx_     = 0;
261         }
262 }
263
264
265 void MathScriptInset::draw(Painter & pain, int x, int y) const
266 {  
267         xo(x);
268         yo(y);
269
270         if (symbol_)
271                 symbol_->draw(pain, x + dxx_, y);
272         if (up())
273                 xcell(0).draw(pain, x + dx0_, y + dy0_);
274         if (down())
275                 xcell(1).draw(pain, x + dx1_, y + dy1_);
276 }