From 7d19265ba02aa0f7dcd14b34bb3f04add8584ad8 Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Wed, 22 Jul 2015 11:05:02 +0200 Subject: [PATCH] Do not break row at inset boundary if possible The first change is to concentrate on the last ro elements that contain separators and try to break it a a width that is shorter than both - its current width (we want to break it, after all) - the amount of space available. This simple heuristic seems to give good results. --- src/Row.cpp | 49 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/src/Row.cpp b/src/Row.cpp index 0974265328..a619874b93 100644 --- a/src/Row.cpp +++ b/src/Row.cpp @@ -382,13 +382,44 @@ void Row::shortenIfNeeded(pos_type const keep, int const w) Elements::iterator const end = elements_.end(); int wid = left_margin; + // The last breakable element that has been found and its x position. + Elements::iterator last_brk = elements_.end(); + int last_wid = 0; + Elements::iterator cit = beg; for ( ; cit != end ; ++cit) { - if (cit->endpos >= keep && wid + cit->dim.wid > w) + if (cit->countSeparators() && cit->pos >= keep) { + last_brk = cit; + last_wid = wid; + } + if (wid + cit->dim.wid > w) break; wid += cit->dim.wid; } + /* We have found a suitable separable element. This is the common case. + * Try to break it cleanly (at word boundary) at a length that is both + * - less than the available space on the row + * - shorter than the natural width of the element, in order to enforce + * break-up. + */ + if (last_brk != end + && last_brk->breakAt(min(w - last_wid, last_brk->dim.wid - 2), false)) { + end_ = last_brk->endpos; + /* after breakAt, there may be spaces at the end of the + * string, but they are not counted in the string length + * (QTextLayout feature, actually). We remove them, but do not + * change the endo of the row, since the spaces at row break + * are invisible. + */ + last_brk->str = rtrim(last_brk->str); + last_brk->endpos = last_brk->pos + last_brk->str.length(); + dim_.wid = last_wid + last_brk->dim.wid; + // If there are other elements, they should be removed. + elements_.erase(next(last_brk, 1), end); + return; + } + if (cit == end) { // This should not happen since the row is too long. LYXERR0("Something is wrong cannot shorten row: " << *this); @@ -402,22 +433,6 @@ void Row::shortenIfNeeded(pos_type const keep, int const w) wid -= cit->dim.wid; } - // Try to break this row cleanly (at word boundary) - if (cit->breakAt(w - wid, false)) { - end_ = cit->endpos; - // after breakAt, there may be spaces at the end of the - // string, but they are not counted in the string length - // (qtextlayout feature, actually). We remove them, but do not - // change the endo of the row, since the spaces at row break - // are invisible. - cit->str = rtrim(cit->str); - cit->endpos = cit->pos + cit->str.length(); - dim_.wid = wid + cit->dim.wid; - // If there are other elements, they should be removed. - elements_.erase(next(cit, 1), end); - return; - } - if (cit != beg) { // There is no separator, but several elements have been // added. We can cut right here. -- 2.39.2