Allow breaking a row element at a leading/trailing space

When an inset is separated from the adjacent string by a space, it is
reasonable to be able to break the string after the space.
Unfortunately, QTextLayout does not do that.

This patch reverts the workaround inserted in 71378268 and replaces it
with a different trick: the string is enlosed between a pair of
zero-width non breaking space characters, so that the leading/trailing
spaces are now normal spaces, where QTextLayout will agree to break
the string.

    Fixes bug #9921 for good.
This commit is contained in:
Jean-Marc Lasgouttes 2016-01-19 12:02:43 +01:00
parent af966e1ee3
commit 31471496fd
2 changed files with 12 additions and 13 deletions

View File

@ -129,17 +129,6 @@ bool Row::Element::breakAt(int w, bool force)
return true;
}
// Qt will not break at a leading space, and we need that sometimes, see
// http://www.lyx.org/trac/ticket/9921.
// It would be nice to fix this properly, but for now do it by hand.
// FIXME: figure out what to do for RtL text.
if (!isRTL() && !str.empty() && str[0] == ' ') {
dim.wid = 0;
str = ' ';
endpos = pos + 1;
return true;
}
return false;
}

View File

@ -219,7 +219,16 @@ bool GuiFontMetrics::breakAt(docstring & s, int & x, bool const rtl, bool const
if (s.empty())
return false;
QTextLayout tl;
tl.setText(toqstr(s));
/* Qt will not break at a leading or trailing space, and we need
* that sometimes, see http://www.lyx.org/trac/ticket/9921.
*
* To work around the problem, we enclose the string between
* zero-width characters so that the QTextLayout algorithm will
* agree to break the text at these extremal spaces.
*/
// Unicode character ZERO WIDTH NO-BREAK SPACE
QChar const zerow_nbsp(0xfeff);
tl.setText(zerow_nbsp + toqstr(s) + zerow_nbsp);
tl.setFont(font_);
// Note that both setFlags and the enums are undocumented
tl.setFlags(rtl ? Qt::TextForceRightToLeft : Qt::TextForceLeftToRight);
@ -234,7 +243,8 @@ bool GuiFontMetrics::breakAt(docstring & s, int & x, bool const rtl, bool const
if (int(line.naturalTextWidth()) > x)
return false;
x = int(line.naturalTextWidth());
s = s.substr(0, line.textLength());
// The -1 is here to account for the leading zerow_nbsp.
s = s.substr(0, line.textLength() - 1);
return true;
}