]> git.lyx.org Git - lyx.git/blob - src/mathed/xarray.C
split super/subscript handling in new base class MathUpDownInset and
[lyx.git] / src / mathed / xarray.C
1
2 #include <config.h>
3
4 #ifdef __GNUG__
5 #pragma implementation
6 #endif
7
8 #include "xarray.h"
9 #include "math_inset.h"
10 #include "mathed/support.h"
11 #include "math_defs.h"
12 #include "Painter.h"
13
14 using std::max;
15 using std::min;
16
17
18 MathXArray::MathXArray()
19         : width_(0), ascent_(0), descent_(0), xo_(0), yo_(0), style_(LM_ST_TEXT)
20 {}
21
22
23 void MathXArray::Metrics(MathStyles st, int, int)
24 {
25         if (data_.empty()) {
26                 mathed_char_dim(LM_TC_VAR, st, 'I', ascent_, descent_, width_); 
27                 return;
28         }
29         
30         ascent_  = 0;
31         descent_ = 0;
32         width_   = 0;
33         style_    = st;
34
35         // keep last values for scriptInset's need to look back
36         int asc = 0;
37         int des = 0;
38         int wid = 0;
39         mathed_char_height(LM_TC_VAR, st, 'I', asc, des);
40
41         for (int pos = 0; pos < data_.size(); data_.next(pos)) {
42                 MathInset * p = data_.nextInset(pos);
43                 if (p) {
44                         // only MathUpDownInsets will use the asc/des information...
45                         p->Metrics(st, asc, des);
46                         asc = p->ascent();
47                         des = p->descent();
48                         wid = p->width();
49                 } else {
50                         char cx = data_.GetChar(pos); 
51                         MathTextCodes fc = data_.GetCode(pos); 
52                         mathed_char_dim(fc, style_, cx, asc, des, wid);
53                 }
54                 ascent_  = max(ascent_, asc);
55                 descent_ = max(descent_, des);
56                 width_   += wid;
57         }
58 }
59
60
61 void MathXArray::draw(Painter & pain, int x, int y)
62 {
63         xo_ = x;
64         yo_ = y;
65
66         if (data_.empty()) {
67                 pain.rectangle(x, y - ascent_, width_, height(), LColor::mathline);
68                 return;
69         }
70
71         for (int pos = 0; pos < data_.size(); data_.next(pos)) {
72                 MathInset * p = data_.nextInset(pos);
73                 if (p) {
74                         p->draw(pain, x, y);
75                         x += p->width();
76                 } else {
77                         char cx = data_.GetChar(pos);
78                         MathTextCodes fc = data_.GetCode(pos);
79                         string s;
80                         s += cx;
81                         drawStr(pain, fc, style_, x, y, s);
82                         x += mathed_char_width(fc, style_, cx);
83                 }
84         }
85 }
86
87
88 int MathXArray::pos2x(int targetpos) const
89 {
90         int x = 0;
91         targetpos = min(targetpos, data_.size());
92         for (int pos = 0; pos < targetpos; data_.next(pos)) 
93                 x += width(pos);
94         return x;
95 }
96
97
98 int MathXArray::x2pos(int targetx) const
99 {
100         int pos = 0;
101         for (int x = 0; x < targetx && pos < data_.size(); data_.next(pos))
102                 x += width(pos);
103         return pos;
104 }
105
106 int MathXArray::width(int pos) const
107 {
108         if (pos >= data_.size())
109                 return 0;
110
111         if (data_.isInset(pos)) 
112                 return data_.nextInset(pos)->width();
113         else 
114                 return mathed_char_width(data_.GetCode(pos), style_, data_.GetChar(pos));
115 }
116
117 std::ostream & operator<<(std::ostream & os, MathXArray const & ar)
118 {
119         os << ar.data_;
120         return os;
121 }
122