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