[LyX/master] Avoid row breaking at inconvenient places.

Jean-Marc Lasgouttes lasgouttes at lyx.org
Fri Mar 3 15:23:43 UTC 2023


commit f7de345f85b4a34346fc52b60a9e754b466d24f0
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date:   Mon Feb 20 15:04:31 2023 +0100

    Avoid row breaking at inconvenient places.
    
    The test that was used to avoid breaking a string that was followed
    by a too long element was not correct (especially the part that
    compared with total row width).
    
    Typical example here is:
    - a word with a part that has a font change like /un/breakable;
    - a longish sentence after it.
    
    Use a new test that is good enough for this particular case, although
    with sortcomings. I do not want to overcomplicate and prefer to wait
    for other complaints (this code is already more complicated that I
    would like).
    
    Document known shortcoming.
    
    Fix ticket #12660.
---
 src/Row.cpp |   27 +++++++++++++++++++++++----
 1 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/src/Row.cpp b/src/Row.cpp
index 102b1ea..8c86c77 100644
--- a/src/Row.cpp
+++ b/src/Row.cpp
@@ -601,12 +601,31 @@ Row::Elements Row::shortenIfNeeded(int const w, int const next_width)
 		 */
 		if (brk.splitAt(min(w - wid_brk, brk.dim.wid - 2), next_width, false, tail)) {
 			/* if this element originally did not cause a row overflow
-			 * in itself, and the remainder of the row would still be
-			 * too large after breaking, then we will have issues in
-			 * next row. Thus breaking does not help.
+			 * in itself, and the next item is not breakable and would
+			 * still be too large after breaking, then we will have
+			 * issues in next row. Thus breaking does not help.
+			 *
+			 * FIXME: this is not perfect, since it is difficult to
+			 * know whether next element in tail is too large:
+			 *
+			 * - next element could be a very long word, which is
+			 *   theoretically breakable, but not in practice
+			 *   (difficult to solve).
+			 *
+			 * - next element could be short enough, but linked to
+			 *   another one with a NoBreak bond.
+			 *
+			 * Basically, it is difficult to solve that in a purely
+			 * left-to-right algorithm; implementing the TeX badness
+			 * algorithm is more difficult and more costly, so we do
+			 * our best in our restricted setting.
 			 */
+			auto const cit_next = cit_brk + 1;
+			int const tail_wid = !tail.empty() ? tail.front().dim.wid : 0;
 			if (wid_brk + cit_brk->dim.wid < w
-			    && dim_.wid - (wid_brk + brk.dim.wid) >= next_width) {
+			    && cit_next != elements_.end()
+			    && tail_wid + cit_next->dim.wid > next_width
+			    && !(cit_next->row_flags & CanBreakInside)) {
 				tail.clear();
 				break;
 			}


More information about the lyx-cvs mailing list