]> git.lyx.org Git - lyx.git/blob - src/mathed/math_textinset.C
more trivial tweaks to mathed bindings
[lyx.git] / src / mathed / math_textinset.C
1
2 #ifdef __GNUG__
3 #pragma implementation 
4 #endif
5
6 #include "math_textinset.h"
7 #include "math_metricsinfo.h"
8 #include "debug.h"
9
10
11 MathTextInset::MathTextInset()
12         : MathNestInset(1)
13 {}
14
15
16 MathInset * MathTextInset::clone() const
17 {
18         return new MathTextInset(*this);
19 }
20
21
22 MathInset::idx_type MathTextInset::pos2row(pos_type pos) const
23 {
24         for (pos_type r = 0, n = cache_.nargs(); r < n; ++r) 
25                 if (pos >= cache_.cellinfo_[r].begin_ && pos <= cache_.cellinfo_[r].end_)
26                         return r;
27         lyxerr << "illegal row for pos " << pos << "\n";
28         return 0;
29 }
30
31
32 void MathTextInset::getPos(idx_type, pos_type pos, int & x, int & y) const
33 {
34         idx_type const i = pos2row(pos);
35         pos_type const p = pos - cache_.cellinfo_[i].begin_; 
36         cache_.getPos(i, p, x, y);
37 }
38
39
40 bool MathTextInset::idxUpDown(idx_type &, pos_type & pos, bool up,
41         int /*targetx*/) const
42 {
43         // try to move only one screen row up or down if possible
44         idx_type i = pos2row(pos);
45         MathGridInset::CellInfo const & cell1 = cache_.cellinfo_[i];
46         int const x = cells_[0].pos2x(cell1.begin_, pos, cell1.glue_);
47         if (up) {
48                 if (i == 0)
49                         return false;
50                 --i;
51         } else {
52                 ++i;
53                 if (i == cache_.nargs())
54                         return false;
55         }
56         MathGridInset::CellInfo const & cell2 = cache_.cellinfo_[i];
57         pos = cell(0).x2pos(cell2.begin_, x, cell2.glue_);
58         return true;
59 }
60
61
62 void MathTextInset::metrics(MathMetricsInfo & mi) const
63 {
64         cell(0).metrics(mi);
65
66         // we do our own metrics fiddling
67         // delete old cache
68         cache_ = MathGridInset(1, 0);
69
70         int spaces  = 0;
71         int safe    = 0;
72         int curr    = 0;
73         int begin   = 0;
74         int safepos = 0;
75         for (size_type i = 0, n = cell(0).size(); i < n; ++i) {
76                 //lyxerr << "at pos: " << i << " of " << n << " safepos: " << safepos
77                 //      << " curr: " << curr << " safe: " << safe
78                 //      << " spaces: " << spaces << endl;
79
80                 //   0      1      2      3       4      5      6
81                 // <char> <char> <char> <space> <char> <char> <char>
82                 // ................... <safe>
83                 //                      ..........................<curr>
84                 // ....................<safepos>
85
86                 // Special handling of spaces. We reached a safe position for breaking.
87                 char const c = cell(0)[i]->getChar();
88                 if (c == ' ') {
89                         //lyxerr << "reached safe pos\n";
90                         // we don't count the space into the safe pos
91                         safe += curr;
92                         // we reset to this safepos if the next chunk does not fit
93                         safepos = i;
94                         ++spaces;
95                         // restart chunk with size of the space
96                         curr = cell(0)[i]->width();
97                         continue;
98                 }
99
100                 if (c != '\n') {
101                         // This is a regular char. Go on if we either don't care for
102                         // the width limit or have not reached that limit.
103                         curr += cell(0)[i]->width();
104                         if (!mi.base.restrictwidth || curr + safe <= mi.base.textwidth) 
105                                 continue;
106                 }
107
108                 // We passed the limit. Create a row entry.
109                 //lyxerr << "passed limit\n";
110                 cache_.appendRow();
111                 MathArray & ar = cache_.cell(cache_.nargs() - 1);
112                 MathGridInset::CellInfo & row = cache_.cellinfo_.back();
113                 if (c == '\n') {
114                         // we are here because we hit a hard newline
115                         row.begin_ = begin;
116                         row.end_   = i + 1;
117                         begin      = i + 1;    // next chunk starts after the newline
118                         spaces     = 0;
119                 } else if (spaces) {
120                         // but we had a space break before this position.
121                         // so retreat to this position
122                         //lyxerr << "... but had safe pos.\n";
123                         row.begin_ = begin;
124                         row.end_   = safepos;  // this is position of the safe space
125                         i          = safepos;  // i gets incremented at end of loop
126                         begin      = i + 1;    // next chunk starts after the space
127                         spaces     = 0;
128                 } else {
129                         // This item is too large and it is the only one.
130                         // We have no choice but to produce an overfull box.
131                         lyxerr << "... without safe pos\n";
132                         row.begin_ = begin;
133                         row.end_   = i + 1;
134                         begin      = i + 1;
135                 }
136                 ar = MathArray(cell(0).begin() + row.begin_, cell(0).begin() + row.end_);
137                 //lyxerr << "line: " << ar << "\n";
138                 // in any case, start the new row with empty boxes
139                 curr = 0;
140                 safe = 0;
141         }
142         // last row: put in everything else
143         cache_.appendRow();
144         MathArray & ar = cache_.cell(cache_.nargs() - 1);
145         MathGridInset::CellInfo & row = cache_.cellinfo_.back();
146         row.begin_ = begin;
147         row.end_   = cell(0).size();
148         ar = MathArray(cell(0).begin() + row.begin_, cell(0).begin() + row.end_);
149         //lyxerr << "last line: " << ar.data() << "\n";
150
151         // what to report?
152         cache_.metrics(mi);
153         dim_ = cache_.dimensions();
154         //lyxerr << "outer dim: " << dim_ << endl;
155 }
156
157
158 void MathTextInset::draw(MathPainterInfo & pi, int x, int y) const
159 {
160         cache_.draw(pi, x + 1, y);
161 }
162
163
164 void MathTextInset::drawSelection(MathPainterInfo & pi,
165                 idx_type idx1, pos_type pos1, idx_type idx2, pos_type pos2) const
166 {
167         cache_.drawSelection(pi, idx1, pos1, idx2, pos2);       
168 }