+ // Iterate backwards over breakable elements and try to break them
+ Elements::iterator cit_brk = cit;
+ int wid_brk = wid + cit_brk->dim.wid;
+ ++cit_brk;
+ Elements tail;
+ while (cit_brk != beg) {
+ --cit_brk;
+ // make a copy of the element to work on it.
+ Element brk = *cit_brk;
+ /* If the current element allows breaking row after itself,
+ * and if the row is already short enough after this element,
+ * then cut right after it.
+ */
+ if (wid_brk <= max_width && brk.row_flags & CanBreakAfter) {
+ end_ = brk.endpos;
+ dim_.wid = wid_brk;
+ moveElements(elements_, cit_brk + 1, tail);
+ return tail;
+ }
+ // assume now that the current element is not there
+ wid_brk -= brk.dim.wid;
+ /* If the current element allows breaking row before itself,
+ * and if the row is already short enough before this element,
+ * then cut right before it.
+ */
+ if (wid_brk <= max_width && brk.row_flags & CanBreakBefore && cit_brk != beg) {
+ end_ = (cit_brk -1)->endpos;
+ dim_.wid = wid_brk;
+ moveElements(elements_, cit_brk, tail);
+ return tail;
+ }
+ /* We have found a suitable separable element. This is the common case.
+ * Try to break it cleanly 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.
+ */
+ int const split_width = min(max_width - wid_brk, brk.dim.wid - 2);
+ if (brk.splitAt(split_width, next_width, BEST_EFFORT, 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 here does not help.
+ */
+ if (wid_brk + cit_brk->dim.wid < max_width
+ && min_row_wid - (wid_brk + brk.dim.wid) >= next_width) {
+ tail.clear();
+ break;
+ }
+ /* if we did not manage to fit a part of the element into
+ * the split_width limit, at least remember that we can
+ * shorten the row if needed.
+ */
+ if (brk.dim.wid > split_width) {
+ min_row_wid = wid_brk + brk.dim.wid;
+ tail.clear();
+ continue;
+ }
+ // We have found a proper place where to break this string element.
+ end_ = brk.endpos;
+ *cit_brk = brk;
+ dim_.wid = wid_brk + brk.dim.wid;
+ // If there are other elements, they should be removed.
+ moveElements(elements_, cit_brk + 1, tail);
+ return tail;
+ }
+ LATTEST(tail.empty());