]> git.lyx.org Git - lyx.git/blob - src/lyxrow_funcs.C
* lyxrow.[Ch]: add end_ member
[lyx.git] / src / lyxrow_funcs.C
1 #include <config.h>
2
3 #include "lyxrow_funcs.h"
4 #include "lyxtext.h"
5 #include "paragraph.h"
6 #include "lyxlayout.h"
7 #include "debug.h"
8
9 #include "support/LAssert.h"
10
11 #include <boost/next_prior.hpp>
12 #include <algorithm>
13
14 using lyx::pos_type;
15 using lyx::support::Assert;
16
17 using std::max;
18 using std::min;
19 using std::endl;
20
21
22 bool isParEnd(Paragraph const & par, RowList::iterator rit)
23 {
24 #if 0
25         if ((boost::next(rit) == par.rows.end()) != (rit->end() >= par.size())) {
26                 lyxerr << endl;
27                 lyxerr << "broken row 1: end: " << rit->end() << " next: "
28                         << boost::next(rit)->pos() << endl;
29                 lyxerr << endl;
30                 Assert(false);
31         }
32 #endif
33         return boost::next(rit) == par.rows.end();
34 }
35
36
37 pos_type lastPos(Paragraph const & par, RowList::iterator rit)
38 {
39         if (par.empty())
40                 return 0;
41
42         if (isParEnd(par, rit))
43                 return par.size() - 1;
44
45         if (1 && boost::next(rit)->pos() != rit->end()) {
46                 lyxerr << endl;
47                 lyxerr << "broken row 2: end: " << rit->end() << " next: "
48                         << boost::next(rit)->pos() << endl;
49                 lyxerr << endl;
50                 Assert(false);
51         }
52         return boost::next(rit)->pos() - 1;
53 }
54
55
56 namespace {
57
58 bool nextRowIsAllInset(Paragraph const & par, pos_type last)
59 {
60         if (last + 1 >= par.size())
61                 return false;
62
63         if (!par.isInset(last + 1))
64                 return false;
65
66         InsetOld const * i = par.getInset(last + 1);
67         return i->needFullRow() || i->display();
68 }
69
70 } // anon namespace
71
72
73 pos_type lastPrintablePos(Paragraph const & par, RowList::iterator rit)
74 {
75         pos_type const last = lastPos(par, rit);
76
77         // if this row is an end of par, just act like lastPos()
78         if (isParEnd(par, rit))
79                 return last;
80
81         if (!nextRowIsAllInset(par, last) && par.isSeparator(last))
82                 return last - 1;
83
84         return last;
85 }
86
87
88 int numberOfSeparators(Paragraph const & par, RowList::iterator rit)
89 {
90         pos_type const last = lastPrintablePos(par, rit);
91         int n = 0;
92         pos_type p = max(rit->pos(), par.beginningOfBody());
93         for ( ; p < last; ++p)
94                 if (par.isSeparator(p))
95                         ++n;
96         return n;
97 }
98
99
100 // This is called _once_ from LyXText and should at least be moved into
101 // an anonymous namespace there. (Lgb)
102 int numberOfHfills(Paragraph const & par, RowList::iterator rit)
103 {
104         pos_type const last = lastPos(par, rit);
105         pos_type first = rit->pos();
106
107         // hfill *DO* count at the beginning of paragraphs!
108         if (first) {
109                 while (first < last && par.isHfill(first))
110                         ++first;
111         }
112
113         first = max(first, par.beginningOfBody());
114
115         int n = 0;
116
117         // last, because the end is ignored!
118         for (pos_type p = first; p < last; ++p)
119                 if (par.isHfill(p))
120                         ++n;
121
122         return n;
123 }
124
125
126 // This is called _once_ from LyXText and should at least be moved into
127 // an anonymous namespace there. (Lgb)
128 int numberOfLabelHfills(Paragraph const & par, RowList::iterator rit)
129 {
130         pos_type last = lastPos(par, rit);
131         pos_type first = rit->pos();
132
133         // hfill *DO* count at the beginning of paragraphs!
134         if (first) {
135                 while (first < last && par.isHfill(first))
136                         ++first;
137         }
138
139         last = min(last, par.beginningOfBody());
140         int n = 0;
141
142         // last, because the end is ignored!
143         for (pos_type p = first; p < last; ++p) {
144                 if (par.isHfill(p))
145                         ++n;
146         }
147         return n;
148 }
149
150
151 bool hfillExpansion(Paragraph const & par, RowList::iterator rit, pos_type pos)
152 {
153         if (!par.isHfill(pos))
154                 return false;
155
156         // at the end of a row it does not count
157         // unless another hfill exists on the line
158         if (pos >= lastPos(par, rit))
159                 for (pos_type i = rit->pos(); i < pos && !par.isHfill(i); ++i)
160                         return false;
161
162         // at the beginning of a row it does not count, if it is not
163         // the first row of a paragaph
164         if (rit->isParStart())
165                 return true;
166
167         // in some labels it does not count
168         if (par.layout()->margintype != MARGIN_MANUAL
169             && pos < par.beginningOfBody())
170                 return false;
171
172         // if there is anything between the first char of the row and
173         // the specified position that is not a newline and not a hfill,
174         // the hfill will count, otherwise not
175         pos_type i = rit->pos();
176         while (i < pos && (par.isNewline(i) || par.isHfill(i)))
177                 ++i;
178
179         return i != pos;
180 }