]> git.lyx.org Git - lyx.git/blob - src/lyxrow.C
rename commandtags.h to lfuns.h and renumber/cleanup. Rebuild the tree !
[lyx.git] / src / lyxrow.C
1 /**
2  * \file lyxrow.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author unknown
7  *
8  * Full author contact details are available in file CREDITS
9  *
10  * Metrics for an on-screen text row.
11  */
12
13 #include <config.h>
14
15 #include "lyxrow.h"
16 #include "paragraph.h"
17 #include "layout.h"
18 #include "lyxlayout.h"
19
20 using lyx::pos_type;
21
22 using std::max;
23 using std::min;
24
25 Row::Row()
26         : par_(0), pos_(0), fill_(0), height_(0), width_(0),
27           ascent_of_text_(0), baseline_(0), next_(0), previous_(0)
28 {}
29
30
31 void Row::par(Paragraph * p)
32 {
33         par_ = p;
34 }
35
36
37 void Row::pos(pos_type p)
38 {
39         pos_ = p;
40 }
41
42
43 pos_type Row::pos() const
44 {
45         return pos_;
46 }
47
48
49 void Row::fill(int f)
50 {
51         fill_ = f;
52 }
53
54
55 int Row::fill() const
56 {
57         return fill_;
58 }
59
60
61 void Row::height(unsigned short h)
62 {
63         height_ = h;
64 }
65
66
67 void Row::width(unsigned int w)
68 {
69         width_ = w;
70 }
71
72
73 unsigned int Row::width() const
74 {
75         return width_;
76 }
77
78
79 void Row::ascent_of_text(unsigned short a)
80 {
81         ascent_of_text_ = a;
82 }
83
84
85 unsigned short Row::ascent_of_text() const
86 {
87         return ascent_of_text_;
88 }
89
90
91 void Row::top_of_text(unsigned int top)
92 {
93         top_of_text_ = top;
94 }
95
96
97 unsigned int Row::top_of_text() const
98 {
99         return top_of_text_;
100 }
101
102
103 void Row::baseline(unsigned int b)
104 {
105         baseline_ = b;
106 }
107
108
109 unsigned int Row::baseline() const
110 {
111         return baseline_;
112 }
113
114
115 void Row::next(Row * r)
116 {
117         next_ = r;
118 }
119
120
121 void Row::previous(Row * r)
122 {
123         previous_ = r;
124 }
125
126
127 Row * Row::previous() const
128 {
129         return previous_;
130 }
131
132
133 bool Row::isParStart() const
134 {
135         return !pos();
136 }
137
138
139 bool Row::isParEnd() const
140 {
141         return !next() || next()->par() != par();
142 }
143
144
145 pos_type Row::lastPos() const
146 {
147         if (!par()->size())
148                 return 0;
149
150         if (isParEnd()) {
151                 return par()->size() - 1;
152         } else {
153                 return next()->pos() - 1;
154         }
155 }
156
157
158 namespace {
159
160 bool nextRowIsAllInset(Row const & row, pos_type last)
161 {
162         if (last + 1 >= row.par()->size())
163                 return false;
164
165         if (!row.par()->isInset(last + 1))
166                 return false;
167
168         Inset * i = row.par()->getInset(last + 1);
169         return i->needFullRow() || i->display();
170 }
171
172 };
173
174
175 pos_type Row::lastPrintablePos() const
176 {
177         pos_type const last = lastPos();
178
179         // if this row is an end of par, just act like lastPos()
180         if (isParEnd())
181                 return last;
182
183         bool const nextrownotinset = !nextRowIsAllInset(*this, last);
184
185         if (nextrownotinset && par()->isSeparator(last))
186                 return last - 1;
187
188         return last;
189 }
190
191
192 int Row::numberOfSeparators() const
193 {
194         pos_type const last = lastPrintablePos();
195         pos_type p = max(pos(), par()->beginningOfBody());
196
197         int n = 0;
198         for (; p < last; ++p) {
199                 if (par()->isSeparator(p)) {
200                         ++n;
201                 }
202         }
203         return n;
204 }
205
206
207 int Row::numberOfHfills() const
208 {
209         pos_type const last = lastPos();
210         pos_type first = pos();
211
212         // hfill *DO* count at the beginning of paragraphs!
213         if (first) {
214                 while (first < last && par()->isHfill(first)) {
215                         ++first;
216                 }
217         }
218
219         first = max(first, par()->beginningOfBody());
220
221         int n = 0;
222
223         // last, because the end is ignored!
224         for (pos_type p = first; p < last; ++p) {
225                 if (par()->isHfill(p))
226                         ++n;
227         }
228         return n;
229 }
230
231
232 int Row::numberOfLabelHfills() const
233 {
234         pos_type last = lastPos();
235         pos_type first = pos();
236
237         // hfill *DO* count at the beginning of paragraphs!
238         if (first) {
239                 while (first < last && par()->isHfill(first))
240                         ++first;
241         }
242
243         last = min(last, par()->beginningOfBody());
244         int n = 0;
245
246         // last, because the end is ignored!
247         for (pos_type p = first; p < last; ++p) {
248                 if (par()->isHfill(p))
249                         ++n;
250         }
251         return n;
252 }
253
254
255 bool Row::hfillExpansion(pos_type pos) const
256 {
257         if (!par()->isHfill(pos))
258                 return false;
259
260         // at the end of a row it does not count
261         // unless another hfill exists on the line
262         if (pos >= lastPos()) {
263                 pos_type i = this->pos();
264                 while (i < pos && !par()->isHfill(i)) {
265                         ++i;
266                 }
267                 if (i == pos) {
268                         return false;
269                 }
270         }
271
272         // at the beginning of a row it does not count, if it is not
273         // the first row of a paragaph
274         if (isParStart())
275                 return true;
276
277         // in some labels it does not count
278         if (par()->layout()->margintype != MARGIN_MANUAL
279             && pos < par()->beginningOfBody())
280                 return false;
281
282         // if there is anything between the first char of the row and
283         // the specified position that is not a newline and not a hfill,
284         // the hfill will count, otherwise not
285         pos_type i = this->pos();
286         while (i < pos && (par()->isNewline(i) || par()->isHfill(i)))
287                 ++i;
288
289         return i != pos;
290 }