]> git.lyx.org Git - lyx.git/blob - src/mathed/math_xdata.C
disable some of the speedup thingies until I found aproper solution for the
[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 "Painter.h"
10 #include "debug.h"
11
12
13 using std::max;
14 using std::min;
15
16
17 extern MathScriptInset const * asScript(MathArray::const_iterator it);
18
19
20 MathXArray::MathXArray()
21         : width_(0), ascent_(0), descent_(0), xo_(0), yo_(0), size_(),
22           clean_(false), drawn_(false)
23 {}
24
25
26 void MathXArray::touch() const
27 {       
28         clean_  = false;
29         drawn_  = false;
30 }
31
32
33 void MathXArray::metrics(MathMetricsInfo const & mi) const
34 {
35         //if (clean_)
36         //      return;
37
38         size_   = mi;
39         clean_  = true;
40         drawn_  = false;
41
42         if (data_.empty()) {
43                 mathed_char_dim(LM_TC_VAR, mi, 'I', ascent_, descent_, width_);
44                 return;
45         }
46
47         ascent_  = 0;
48         descent_ = 0;
49         width_   = 0;
50
51         for (const_iterator it = begin(); it != end(); ++it) {
52                 MathInset const * p = it->nucleus();
53                 MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it);
54                 if (q) {
55                         q->metrics(p, mi);
56                         ascent_  = max(ascent_,  q->ascent2(p));
57                         descent_ = max(descent_, q->descent2(p));
58                         width_  += q->width2(p);        
59                         ++it;
60                 } else {
61                         p->metrics(mi);
62                         ascent_  = max(ascent_,  p->ascent());
63                         descent_ = max(descent_, p->descent());
64                         width_  += p->width();  
65                 }
66         }
67         //lyxerr << "MathXArray::metrics(): '" << ascent_ << " " 
68         //      << descent_ << " " << width_ << "'\n";
69 }
70
71
72 void MathXArray::draw(Painter & pain, int x, int y) const
73 {
74         //if (drawn_ && x == xo_ && y == yo_)
75         //      return;
76
77         //lyxerr << "x: " << x << " y: " << y << " " << pain.workAreaHeight() << endl;
78
79         xo_    = x;
80         yo_    = y;
81         drawn_ = true;
82
83         if (y + descent_ <= 0)                   // don't draw above the workarea
84                 return;
85         if (y - ascent_ >= pain.paperHeight())   // don't draw below the workarea
86                 return;
87         if (x + width_ <= 0)                     // don't draw left of workarea
88                 return;
89         if (x >= pain.paperWidth())              // don't draw right of workarea
90                 return;
91
92         const_iterator it = begin(), et = end();
93
94         if (it == et) {
95                 pain.rectangle(x, y - ascent_, width_, height(), LColor::mathline);
96                 return;
97         }
98
99         for (; it != et; ++it) {
100                 MathInset const * p = it->nucleus();
101                 MathScriptInset const * q = (it + 1 == et) ? 0 : asScript(it);
102                 if (q) {
103                         q->draw(p, pain, x, y);
104                         x += q->width2(p);
105                         ++it;
106                 } else {
107                         p->draw(pain, x, y);
108                         x += p->width();
109                 }
110         }
111 }
112
113
114 int MathXArray::pos2x(size_type targetpos) const
115 {
116         int x = 0;
117         const_iterator target = min(begin() + targetpos, end());
118         for (const_iterator it = begin(); it < target; ++it) {
119                 MathInset const * p = it->nucleus();
120                 MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it);
121                 if (q) {
122                         ++it;
123                         if (it < target)
124                                 x += q->width2(p);
125                         else  // "half" position
126                                 x += q->dxx(p) + q->nwid(p);
127                 } else
128                         x += p->width();
129         }
130         return x;
131 }
132
133
134 MathArray::size_type MathXArray::x2pos(int targetx) const
135 {
136         const_iterator it = begin();
137         int lastx = 0;
138         int currx = 0;
139         for (; currx < targetx && it < end(); ++it) {
140                 lastx = currx;
141
142                 int wid = 0;
143                 MathInset const * p = it->nucleus();
144                 MathScriptInset const * q = 0;
145                 if (it + 1 != end())
146                         q = asScript(it);
147                 if (q) {
148                         wid = q->width2(p);
149                         ++it;
150                 } else
151                         wid = p->width();
152
153                 currx += wid;
154         }
155         if (abs(lastx - targetx) < abs(currx - targetx) && it != begin())
156                 --it;
157         return it - begin();
158 }
159
160
161 int MathXArray::dist(int x, int y) const
162 {
163         int xx = 0;
164         int yy = 0;
165
166         if (x < xo_)
167                 xx = xo_ - x;
168         else if (x > xo_ + width_)
169                 xx = x - xo_ - width_;
170
171         if (y < yo_ - ascent_)
172                 yy = yo_ - ascent_ - y;
173         else if (y > yo_ + descent_)
174                 yy = y - yo_ - descent_;
175
176         return xx + yy; 
177 }
178
179
180 void MathXArray::boundingBox(int & x1, int & x2, int & y1, int & y2)
181 {
182         x1 = xo_;
183         x2 = xo_ + width_;
184         y1 = yo_ - ascent_;
185         y2 = yo_ + descent_;
186 }
187
188 /*
189 void MathXArray::findPos(MathPosFinder & f) const
190 {
191         double x = xo_;
192         double y = yo_; 
193         for (const_iterator it = begin(); it < end(); ++it) {
194                 // check this position in the cell first
195                 f.visit(x, y);
196                 f.nextPos();
197
198                 // check inset
199                 MathInset const * p = it->nucleus();
200                 p->findPos(f);
201
202                 // move on
203                 MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it);
204                 if (q) {
205                         x += q->width(p);
206                         f.nextPos();
207                         ++it;
208                 } else {
209                         x += p->width();
210                 }
211         }
212 }
213 */
214
215 void MathXArray::center(int & x, int & y) const
216 {
217         x = xo_ + width_ / 2;
218         y = yo_ + (descent_ - ascent_) / 2;
219 }
220
221
222 void MathXArray::towards(int & x, int & y) const
223 {
224         int cx = 0;
225         int cy = 0;
226         center(cx, cy);
227
228         double r = 1.0;
229         //int dist = (x - cx) * (x - cx) + (y - cy) * (y - cy);
230
231         x = cx + int(r * (x - cx));
232         y = cy + int(r * (y - cy));
233 }