]> git.lyx.org Git - features.git/commitdiff
Avoid row breaking at inconvenient places.
authorJean-Marc Lasgouttes <lasgouttes@lyx.org>
Mon, 20 Feb 2023 14:04:31 +0000 (15:04 +0100)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Fri, 3 Mar 2023 16:24:06 +0000 (17:24 +0100)
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

index 102b1ea4ae9df206947a3d8fea66037cd7879c65..8c86c7731ce89809b8b2a381a1c91db9c7275698 100644 (file)
@@ -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;
                        }