From f7de345f85b4a34346fc52b60a9e754b466d24f0 Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Mon, 20 Feb 2023 15:04:31 +0100 Subject: [PATCH] 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 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/Row.cpp b/src/Row.cpp index 102b1ea4ae..8c86c7731c 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; } -- 2.39.5