mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-26 03:11:59 +00:00
Fix ticket #9224: text overflows through adjacent insets
The logic of Row::shortenIfNeeded is completely changed to look at the row from the start and not the end. This leads to clearer code.
This commit is contained in:
parent
7bb472d685
commit
ac018bd8db
73
src/Row.cpp
73
src/Row.cpp
@ -362,37 +362,50 @@ void Row::shortenIfNeeded(pos_type const keep, int const w)
|
||||
if (empty() || width() <= w)
|
||||
return;
|
||||
|
||||
/** First, we try to remove elements one by one from the end
|
||||
* until a separator is found. cit points to the first element
|
||||
* we want to remove from the row.
|
||||
*/
|
||||
Elements::iterator const beg = elements_.begin();
|
||||
Elements::iterator const end = elements_.end();
|
||||
Elements::iterator cit = end;
|
||||
Elements::iterator first_below = end;
|
||||
int new_end = end_;
|
||||
int new_wid = dim_.wid;
|
||||
// if the row ends with a separator, skip it.
|
||||
if (cit != beg && boost::prior(cit)->type == SEPARATOR && new_end > keep) {
|
||||
--cit;
|
||||
new_end = cit->pos;
|
||||
new_wid -= cit->dim.wid;
|
||||
Elements::iterator last_sep = elements_.end();
|
||||
double last_width = 0;
|
||||
double wid = x;
|
||||
|
||||
Elements::iterator cit = beg;
|
||||
for ( ; cit != end ; ++cit) {
|
||||
if (cit->type == SEPARATOR && cit->pos >= keep) {
|
||||
last_sep = cit;
|
||||
last_width = wid;
|
||||
}
|
||||
if (wid + cit->width() > w)
|
||||
break;
|
||||
wid += cit->width();
|
||||
}
|
||||
|
||||
// Search for a separator where the row can be broken.
|
||||
while (cit != beg && boost::prior(cit)->type != SEPARATOR && new_end > keep) {
|
||||
if (last_sep != end) {
|
||||
// We have found a suitable separator. This is the
|
||||
// common case.
|
||||
end_ = last_sep->endpos;
|
||||
dim_.wid = last_width;
|
||||
elements_.erase(last_sep, end);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cit == end) {
|
||||
// This should not happen since the row is too long.
|
||||
LYXERR0("Something is wrong cannot shorten row: " << *this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cit != beg && cit->type == VIRTUAL) {
|
||||
// It is not possible to separate a virtual element from the
|
||||
// previous one.
|
||||
--cit;
|
||||
new_end = cit->pos;
|
||||
new_wid -= cit->dim.wid;
|
||||
if (new_wid < w && first_below == end)
|
||||
first_below = cit;
|
||||
wid -= cit->width();
|
||||
}
|
||||
|
||||
if (cit != beg) {
|
||||
// We have found a suitable separator. This is the
|
||||
// common case.
|
||||
end_ = new_end;
|
||||
dim_.wid = new_wid;
|
||||
// There is no separator, but several elements (probably
|
||||
// insets) have been added. We can cut at this place.
|
||||
end_ = cit->pos;
|
||||
dim_.wid = wid;
|
||||
elements_.erase(cit, end);
|
||||
return;
|
||||
}
|
||||
@ -402,17 +415,11 @@ void Row::shortenIfNeeded(pos_type const keep, int const w)
|
||||
* something: when we have one big string, maybe with some
|
||||
* other things after it.
|
||||
*/
|
||||
double max_w = w - x;
|
||||
if (first_below->breakAt(max_w)) {
|
||||
end_ = first_below->endpos;
|
||||
dim_.wid = int(x + first_below->width());
|
||||
if (cit->breakAt(w - x)) {
|
||||
end_ = cit->endpos;
|
||||
dim_.wid = int(x + cit->width());
|
||||
// If there are other elements, they should be removed.
|
||||
elements_.erase(boost::next(first_below), end);
|
||||
} else if (first_below->pos > pos_) {
|
||||
end_ = first_below->pos;
|
||||
dim_.wid = new_wid;
|
||||
// Remove all elements from first_below.
|
||||
elements_.erase(first_below, end);
|
||||
elements_.erase(boost::next(cit), end);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -802,7 +802,9 @@ void TextMetrics::breakRow(Row & row, int const right_margin, pit_type const pit
|
||||
int const width = max_width_ - right_margin;
|
||||
pos_type const body_pos = par.beginOfBody();
|
||||
row.clear();
|
||||
row.dimension().wid = leftMargin(max_width_, pit, pos);
|
||||
// This make get changed in computeRowMetrics depending on RTL
|
||||
row.x = leftMargin(max_width_, pit, pos);
|
||||
row.dimension().wid = row.x;
|
||||
row.right_margin = right_margin;
|
||||
|
||||
if (pos >= end || row.width() > width) {
|
||||
|
Loading…
Reference in New Issue
Block a user