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