]> git.lyx.org Git - lyx.git/blob - src/mathed/math_parboxinset.C
Compilation fix.
[lyx.git] / src / mathed / math_parboxinset.C
1
2 #include "math_parboxinset.h"
3 #include "math_mathmlstream.h"
4 #include "math_streamstr.h"
5 #include "lyxlength.h"
6 #include "debug.h"
7
8 using std::vector;
9
10 MathParboxInset::MathParboxInset()
11         : MathNestInset(1), lyx_width_(0), tex_width_("0mm"),
12           position_('c')
13 {
14         lyxerr << "constructing MathParboxInset\n";
15 }
16
17
18 MathInset * MathParboxInset::clone() const
19 {
20         return new MathParboxInset(*this);
21 }
22
23
24 void MathParboxInset::setPosition(string const & p)
25 {
26         position_ = p.size() > 0 ? p[0] : 'c';
27 }
28
29
30 void MathParboxInset::setWidth(string const & w)
31 {
32         tex_width_ = w;
33         lyx_width_ = LyXLength(w).inBP();
34         lyxerr << "setting " << w << " to " << lyx_width_ << " pixel\n";
35 }
36
37
38 int MathParboxInset::pos2row(pos_type pos) const
39 {
40         for (int r = 0, n = rows_.size(); r < n; ++r) 
41                 if (pos >= rows_[r].begin && pos < rows_[r].end)
42                         return r;
43         lyxerr << "illegal row for pos " << pos << "\n";
44         return 0;
45 }
46
47
48 void MathParboxInset::getPos(idx_type idx, pos_type pos, int & x, int & y) const
49 {
50         int const r = pos2row(pos);
51         //lyxerr << "found cursor at pos " << pos << " in row " << r << "\n";
52         x = cells_[0].xo() + cells_[0].pos2x(rows_[r].begin, pos, rows_[r].glue);
53         y = cells_[0].yo() + rows_[r].yo;
54         // move cursor visually into empty cells ("blue rectangles");
55         if (cell(0).empty())
56                 x += 2;
57 }
58
59
60 void MathParboxInset::metrics(MathMetricsInfo & mi) const
61 {
62         MathFontSetChanger dummy(mi.base, "textnormal");
63
64         // we do our own metrics fiddling
65         // delete old cache
66         rows_.clear();
67
68 #if 0
69
70         dim_ = xcell(0).metrics(mi);
71
72 #else
73
74         vector<Dimension> dims; 
75         xcell(0).metricsExternal(mi, dims);
76
77         int spaces = 0;
78         Dimension safe;
79         Dimension curr;
80         safe.clear(mi.base.font);
81         curr.clear(mi.base.font);
82         int begin = 0;
83         int safepos = 0;
84         int yo = 0;
85         for (size_type i = 0, n = cell(0).size(); i < n; ++i) {
86                 //lyxerr << "at pos: " << i << " of " << n << " safepos: " << safepos
87                 //      << " curr: " << curr << " safe: " << safe
88                 //      << " spaces: " << spaces << endl;
89
90
91                 //   0      1      2      3       4      5      6
92                 // <char> <char> <char> <space> <char> <char> <char>
93                 // ................... <safe>
94                 //                      ..........................<curr>
95                 // ....................<safepos>
96
97                 // Special handling of spaces. We reached a safe position for breaking.
98                 if (cell(0)[i]->getChar() == ' ') {
99                         //lyxerr << "reached safe pos\n";
100                         // we don't count the space into the safe pos
101                         safe += curr;
102                         // we reset to this safepos if the next chunk does not fit
103                         safepos = i;
104                         ++spaces;
105                         // restart chunk with size of the space
106                         curr.clear(mi.base.font);
107                         curr += dims[i];
108                         continue;
109                 }
110
111                 // This is a regular char. Go on if we either don't care for
112                 // the width limit or have not reached that limit.
113                 curr += dims[i];
114                 if (curr.w + safe.w <= lyx_width_) 
115                         continue;
116
117                 // We passed the limit. Create a row entry.
118                 //lyxerr << "passed limit\n";
119                 MathXArray::Row row;
120                 if (spaces) {
121                         // but we had a space break before this position.
122                         // so retreat to this position
123                         row.dim   = safe;
124                         row.glue  = (lyx_width_ - safe.w) / spaces;
125                         row.begin = begin;
126                         row.end   = safepos;  // this is position of the safe space
127                         i         = safepos;  // i gets incremented at end of loop
128                         begin     = i + 1;    // next chunk starts after the space
129                         //lyxerr << "... but had safe pos. glue: " << row.glue << "\n";
130                         spaces   = 0;
131                 } else {
132                         lyxerr << "... without safe pos\n";
133                         // This item is too large and it is the only one.
134                         // We have no choice but to produce an overfull box.
135                         row.dim   = curr;   // safe should be 0.
136                         row.glue  = 0;      // does not matter
137                         row.begin = begin;
138                         row.end   = i + 1;
139                         begin     = i + 1;
140                 }
141                 row.yo   = yo;
142                 yo      += row.dim.height();
143                 rows_.push_back(row);
144                 // in any case, start the new row with empty boxes
145                 curr.clear(mi.base.font);
146                 safe.clear(mi.base.font);
147         }
148         // last row: put in everything else
149         MathXArray::Row row;
150         row.dim   = safe;
151         row.dim  += curr;
152         row.begin = begin;
153         row.end   = cell(0).size();
154         row.glue  = 0; // last line is left aligned
155         row.yo    = yo;
156         rows_.push_back(row);
157
158         // what to report?
159         dim_.w = lyx_width_;
160         dim_.a = rows_.front().dim.a;
161         dim_.d = rows_.back().dim.d + yo;
162         metricsMarkers();
163 #endif
164 }
165
166
167 void MathParboxInset::draw(MathPainterInfo & pi, int x, int y) const
168 {
169         MathFontSetChanger dummy(pi.base, "textnormal");
170 #if 0
171         xcell(0).draw(pi, x + 1, y);
172 #else
173         xcell(0).drawExternal(pi, x + 1, y, rows_);
174 #endif
175         drawMarkers(pi, x, y);
176 }
177
178
179 void MathParboxInset::write(WriteStream & os) const
180 {
181         os << "\\parbox";
182         if (position_ != 'c')
183                 os << '[' << position_ << ']';
184         os << '{' << tex_width_ << "}{" << cell(0) << '}';
185 }
186
187
188 void MathParboxInset::infoize(std::ostream & os) const
189 {
190         os << "Box: Parbox " << tex_width_;
191 }
192