]> git.lyx.org Git - lyx.git/blob - src/mathed/math_textinset.C
revert Buffer LyxText->InsetText commit
[lyx.git] / src / mathed / math_textinset.C
1 /**
2  * \file math_textinset.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author André Pönitz
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "math_textinset.h"
14 #include "math_data.h"
15
16 #include "cursor_slice.h"
17 #include "debug.h"
18 #include "metricsinfo.h"
19
20 using std::auto_ptr;
21 using std::endl;
22
23
24 MathTextInset::MathTextInset()
25         : MathNestInset(1)
26 {}
27
28
29 auto_ptr<InsetBase> MathTextInset::clone() const
30 {
31         return auto_ptr<InsetBase>(new MathTextInset(*this));
32 }
33
34
35 MathInset::idx_type MathTextInset::pos2row(pos_type pos) const
36 {
37         for (pos_type r = 0, n = cache_.nargs(); r < n; ++r)
38                 if (pos >= cache_.cellinfo_[r].begin_ && pos <= cache_.cellinfo_[r].end_)
39                         return r;
40         lyxerr << "illegal row for pos " << pos << endl;
41         return 0;
42 }
43
44
45 void MathTextInset::getCursorPos(CursorSlice const & cur, int & x, int & y) const
46 {
47         CursorSlice c = cur;
48         c.idx() = pos2row(cur.pos());
49         c.pos() -= cache_.cellinfo_[c.idx()].begin_;
50         cache_.getCursorPos(c, x, y);
51         y = cache_.cell(c.idx()).yo();
52 }
53
54
55 #if 0
56 bool MathTextInset::idxUpDown2(LCursor & pos, bool up) const
57 {
58         // try to move only one screen row up or down if possible
59         idx_type i = pos2row(pos);
60         //lyxerr << "\nMathTextInset::idxUpDown()  i: " << i << endl;
61         MathGridInset::CellInfo const & cell1 = cache_.cellinfo_[i];
62         int const x = cache_.cell(i).pos2x(pos - cell1.begin_, cell1.glue_);
63         if (up) {
64                 if (i == 0)
65                         return false;
66                 --i;
67         } else {
68                 ++i;
69                 if (i == cache_.nargs())
70                         return false;
71         }
72         MathGridInset::CellInfo const & cell2 = cache_.cellinfo_[i];
73         pos = cell2.begin_ + cache_.cell(i).x2pos(x, cell2.glue_);
74         return true;
75 }
76 #endif
77
78
79 void MathTextInset::metrics(MetricsInfo & mi, Dimension & dim) const
80 {
81         cell(0).metrics(mi);
82
83         // we do our own metrics fiddling
84         // save old positional information
85         int const old_xo = cache_.cell(0).xo();
86         int const old_yo = cache_.cell(0).yo();
87
88         // delete old cache
89         cache_ = MathGridInset(1, 0);
90
91         int spaces  = 0;
92         int safe    = 0;
93         int curr    = 0;
94         int begin   = 0;
95         int safepos = 0;
96         for (size_type i = 0, n = cell(0).size(); i < n; ++i) {
97                 //lyxerr << "at pos: " << i << " of " << n << " safepos: " << safepos
98                 //      << " curr: " << curr << " safe: " << safe
99                 //      << " spaces: " << spaces << endl;
100
101                 //   0      1      2      3       4      5      6
102                 // <char> <char> <char> <space> <char> <char> <char>
103                 // ................... <safe>
104                 //                      ..........................<curr>
105                 // ....................<safepos>
106
107                 // Special handling of spaces. We reached a safe position for breaking.
108                 char const c = cell(0)[i]->getChar();
109                 if (c == ' ') {
110                         //lyxerr << "reached safe pos" << endl;
111                         // we don't count the space into the safe pos
112                         safe += curr;
113                         // we reset to this safepos if the next chunk does not fit
114                         safepos = i;
115                         ++spaces;
116                         // restart chunk with size of the space
117                         curr = cell(0)[i]->width();
118                         continue;
119                 }
120
121                 if (c != '\n') {
122                         // This is a regular char. Go on if we either don't care for
123                         // the width limit or have not reached that limit.
124                         curr += cell(0)[i]->width();
125                         if (curr + safe <= mi.base.textwidth)
126                                 continue;
127                 }
128
129                 // We passed the limit. Create a row entry.
130                 //lyxerr << "passed limit" << endl;
131                 cache_.appendRow();
132                 MathArray & ar = cache_.cell(cache_.nargs() - 1);
133                 MathGridInset::CellInfo & row = cache_.cellinfo_.back();
134                 if (c == '\n') {
135                         // we are here because we hit a hard newline
136                         row.begin_ = begin;
137                         row.end_   = i + 1;
138                         begin      = i + 1;    // next chunk starts after the newline
139                         spaces     = 0;
140                 } else if (spaces) {
141                         // but we had a space break before this position.
142                         // so retreat to this position
143                         //lyxerr << "... but had safe pos." << endl;
144                         row.begin_ = begin;
145                         row.end_   = safepos;  // this is position of the safe space
146                         i          = safepos;  // i gets incremented at end of loop
147                         begin      = i + 1;    // next chunk starts after the space
148                         spaces     = 0;
149                 } else {
150                         // This item is too large and it is the only one.
151                         // We have no choice but to produce an overfull box.
152                         lyxerr << "... without safe pos" << endl;
153                         row.begin_ = begin;
154                         row.end_   = i + 1;
155                         begin      = i + 1;
156                 }
157                 ar = MathArray(cell(0).begin() + row.begin_, cell(0).begin() + row.end_);
158                 //lyxerr << "line: " << ar << endl;
159                 // in any case, start the new row with empty boxes
160                 curr = 0;
161                 safe = 0;
162         }
163         // last row: put in everything else
164         cache_.appendRow();
165         MathArray & ar = cache_.cell(cache_.nargs() - 1);
166         MathGridInset::CellInfo & row = cache_.cellinfo_.back();
167         row.begin_ = begin;
168         row.end_   = cell(0).size();
169         ar = MathArray(cell(0).begin() + row.begin_, cell(0).begin() + row.end_);
170         //lyxerr << "last line: " << ar.data() << endl;
171
172         // what to report?
173         cache_.metrics(mi, dim_);
174         //lyxerr << "outer dim: " << dim_ << endl;
175
176         // reset position cache
177         for (idx_type i = 0; i < cache_.nargs(); ++i)
178                 cache_.cell(i).setXY(old_xo, old_yo);
179
180         dim = dim_;
181 }
182
183
184 void MathTextInset::draw(PainterInfo & pi, int x, int y) const
185 {
186         cache_.draw(pi, x + 1, y);
187 }
188
189
190 /*
191 void MathTextInset::drawSelection(PainterInfo & pi,
192                 idx_type idx1, pos_type pos1, idx_type idx2, pos_type pos2) const
193 {
194         cache_.drawSelection(pi, idx1, pos1, idx2, pos2);
195 }
196 */