]> git.lyx.org Git - lyx.git/blob - src/mathed/math_xdata.C
add missing using's
[lyx.git] / src / mathed / math_xdata.C
1 #include <config.h>
2
3 #ifdef __GNUG__
4 #pragma implementation
5 #endif
6
7 #include "math_scriptinset.h"
8 #include "math_support.h"
9 #include "frontends/Painter.h"
10 #include "textpainter.h"
11 #include "debug.h"
12
13
14 using std::max;
15 using std::min;
16 using std::abs;
17
18
19 extern MathScriptInset const * asScript(MathArray::const_iterator it);
20
21
22 MathXArray::MathXArray()
23         : width_(0), ascent_(0), descent_(0), xo_(0), yo_(0), size_(),
24           clean_(false), drawn_(false)
25 {}
26
27
28 void MathXArray::touch() const
29 {
30         clean_  = false;
31         drawn_  = false;
32 }
33
34
35 void MathXArray::metrics(MathMetricsInfo const & mi) const
36 {
37         //if (clean_)
38         //      return;
39
40         size_   = mi;
41         clean_  = true;
42         drawn_  = false;
43
44         if (data_.empty()) {
45                 LyXFont font;
46                 whichFont(font, LM_TC_VAR, mi);
47                 mathed_char_dim(font, 'I', ascent_, descent_, width_);
48                 return;
49         }
50
51         ascent_  = 0;
52         descent_ = 0;
53         width_   = 0;
54
55         for (const_iterator it = begin(); it != end(); ++it) {
56                 MathInset const * p = it->nucleus();
57                 MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it);
58                 if (q) {
59                         q->metrics(p, mi);
60                         ascent_  = max(ascent_,  q->ascent2(p));
61                         descent_ = max(descent_, q->descent2(p));
62                         width_  += q->width2(p);
63                         ++it;
64                 } else {
65                         p->metrics(mi);
66                         ascent_  = max(ascent_,  p->ascent());
67                         descent_ = max(descent_, p->descent());
68                         width_  += p->width();
69                 }
70         }
71         //lyxerr << "MathXArray::metrics(): '" << ascent_ << " "
72         //      << descent_ << " " << width_ << "'\n";
73 }
74
75
76 void MathXArray::draw(Painter & pain, int x, int y) const
77 {
78         //if (drawn_ && x == xo_ && y == yo_)
79         //      return;
80
81         //lyxerr << "x: " << x << " y: " << y << " " << pain.workAreaHeight() << endl;
82
83         xo_    = x;
84         yo_    = y;
85         drawn_ = true;
86
87         if (y + descent_ <= 0)                   // don't draw above the workarea
88                 return;
89         if (y - ascent_ >= pain.paperHeight())   // don't draw below the workarea
90                 return;
91         if (x + width_ <= 0)                     // don't draw left of workarea
92                 return;
93         if (x >= pain.paperWidth())              // don't draw right of workarea
94                 return;
95
96         const_iterator it = begin(), et = end();
97
98         if (it == et) {
99                 pain.rectangle(x, y - ascent_, width_, height(), LColor::mathline);
100                 return;
101         }
102
103         for (; it != et; ++it) {
104                 MathInset const * p = it->nucleus();
105                 MathScriptInset const * q = (it + 1 == et) ? 0 : asScript(it);
106                 if (q) {
107                         q->draw(p, pain, x, y);
108                         x += q->width2(p);
109                         ++it;
110                 } else {
111                         p->draw(pain, x, y);
112                         x += p->width();
113                 }
114         }
115 }
116
117
118 void MathXArray::metricsT(TextMetricsInfo const & mi) const
119 {
120         //if (clean_)
121         //      return;
122
123         ascent_  = 0;
124         descent_ = 0;
125         width_   = 0;
126
127         for (const_iterator it = begin(); it != end(); ++it) {
128                 MathInset const * p = it->nucleus();
129                 MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it);
130                 if (q) {
131                         q->metricsT(p, mi);
132                         ascent_  = max(ascent_,  q->ascent2(p));
133                         descent_ = max(descent_, q->descent2(p));
134                         width_  += q->width2(p);
135                         ++it;
136                 } else {
137                         p->metricsT(mi);
138                         ascent_  = max(ascent_,  p->ascent());
139                         descent_ = max(descent_, p->descent());
140                         width_  += p->width();
141                 }
142         }
143 }
144
145
146 void MathXArray::drawT(TextPainter & pain, int x, int y) const
147 {
148         //if (drawn_ && x == xo_ && y == yo_)
149         //      return;
150
151         //lyxerr << "x: " << x << " y: " << y << " " << pain.workAreaHeight() << endl;
152
153         xo_    = x;
154         yo_    = y;
155         drawn_ = true;
156
157         const_iterator it = begin(), et = end();
158
159         for (; it != et; ++it) {
160                 MathInset const * p = it->nucleus();
161                 MathScriptInset const * q = (it + 1 == et) ? 0 : asScript(it);
162                 if (q) {
163                         q->drawT(p, pain, x, y);
164                         x += q->width2(p);
165                         ++it;
166                 } else {
167                         p->drawT(pain, x, y);
168                         x += p->width();
169                 }
170         }
171 }
172
173
174 int MathXArray::pos2x(size_type targetpos) const
175 {
176         int x = 0;
177         const_iterator target = min(begin() + targetpos, end());
178         for (const_iterator it = begin(); it < target; ++it) {
179                 MathInset const * p = it->nucleus();
180                 MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it);
181                 if (q) {
182                         ++it;
183                         if (it < target)
184                                 x += q->width2(p);
185                         else  // "half" position
186                                 x += q->dxx(p) + q->nwid(p);
187                 } else
188                         x += p->width();
189         }
190         return x;
191 }
192
193
194 MathArray::size_type MathXArray::x2pos(int targetx) const
195 {
196         const_iterator it = begin();
197         int lastx = 0;
198         int currx = 0;
199         for (; currx < targetx && it < end(); ++it) {
200                 lastx = currx;
201
202                 int wid = 0;
203                 MathInset const * p = it->nucleus();
204                 MathScriptInset const * q = 0;
205                 if (it + 1 != end())
206                         q = asScript(it);
207                 if (q) {
208                         wid = q->width2(p);
209                         ++it;
210                 } else
211                         wid = p->width();
212
213                 currx += wid;
214         }
215         if (abs(lastx - targetx) < abs(currx - targetx) && it != begin())
216                 --it;
217         return it - begin();
218 }
219
220
221 int MathXArray::dist(int x, int y) const
222 {
223         int xx = 0;
224         int yy = 0;
225
226         if (x < xo_)
227                 xx = xo_ - x;
228         else if (x > xo_ + width_)
229                 xx = x - xo_ - width_;
230
231         if (y < yo_ - ascent_)
232                 yy = yo_ - ascent_ - y;
233         else if (y > yo_ + descent_)
234                 yy = y - yo_ - descent_;
235
236         return xx + yy;
237 }
238
239
240 void MathXArray::boundingBox(int & x1, int & x2, int & y1, int & y2)
241 {
242         x1 = xo_;
243         x2 = xo_ + width_;
244         y1 = yo_ - ascent_;
245         y2 = yo_ + descent_;
246 }
247
248 /*
249 void MathXArray::findPos(MathPosFinder & f) const
250 {
251         double x = xo_;
252         double y = yo_;
253         for (const_iterator it = begin(); it < end(); ++it) {
254                 // check this position in the cell first
255                 f.visit(x, y);
256                 f.nextPos();
257
258                 // check inset
259                 MathInset const * p = it->nucleus();
260                 p->findPos(f);
261
262                 // move on
263                 MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it);
264                 if (q) {
265                         x += q->width(p);
266                         f.nextPos();
267                         ++it;
268                 } else {
269                         x += p->width();
270                 }
271         }
272 }
273 */
274
275 void MathXArray::center(int & x, int & y) const
276 {
277         x = xo_ + width_ / 2;
278         y = yo_ + (descent_ - ascent_) / 2;
279 }
280
281
282 void MathXArray::towards(int & x, int & y) const
283 {
284         int cx = 0;
285         int cy = 0;
286         center(cx, cy);
287
288         double r = 1.0;
289         //int dist = (x - cx) * (x - cx) + (y - cy) * (y - cy);
290
291         x = cx + int(r * (x - cx));
292         y = cy + int(r * (y - cy));
293 }