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