From bd3c82f8db4391fc1d6d3338827356143fd598dd Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 24 Feb 2020 11:07:29 +0100 Subject: Fix non-trivial soft-hyphen line breaks The effect of the soft-hyphen needs to be updated once the final the break point has been found. This change cleans the logic by using two variables keeping track of soft-hyphen at current evaluated position and at last confirmed break point. Also adds tests for supression of soft-hyphens in the tight WrapAnywhere case. Fixes: QTBUG-35940 Fixes: QTBUG-44257 Change-Id: I7a89a8ef991b87691879bb7ce40cec4a3605fdd5 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qtextlayout.cpp | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'src/gui/text/qtextlayout.cpp') diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index a3e194f835..aaca1061b7 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1667,7 +1667,8 @@ namespace { QFontEngine *previousGlyphFontEngine; QFixed minw; - QFixed softHyphenWidth; + QFixed currentSoftHyphenWidth; + QFixed commitedSoftHyphenWidth; QFixed rightBearing; QFixed minimumRightBearing; @@ -1681,7 +1682,7 @@ namespace { QFixed calculateNewWidth(const QScriptLine &line) const { return line.textWidth + tmpData.textWidth + spaceData.textWidth - + softHyphenWidth + negativeRightBearing(); + + (line.textWidth > 0 ? currentSoftHyphenWidth : QFixed()) + negativeRightBearing(); } inline glyph_t currentGlyph() const @@ -1755,6 +1756,7 @@ inline bool LineBreakHelper::checkFullOtherwiseExtend(QScriptLine &line) if (line.length && !manualWrap && (newWidth > line.width || glyphCount > maxGlyphs)) return true; + const QFixed oldTextWidth = line.textWidth; minw = qMax(minw, tmpData.textWidth); line += tmpData; line.textWidth += spaceData.textWidth; @@ -1765,6 +1767,11 @@ inline bool LineBreakHelper::checkFullOtherwiseExtend(QScriptLine &line) spaceData.textWidth = 0; spaceData.length = 0; + if (oldTextWidth != line.textWidth || currentSoftHyphenWidth > 0) { + commitedSoftHyphenWidth = currentSoftHyphenWidth; + currentSoftHyphenWidth = 0; + } + return false; } @@ -1837,7 +1844,6 @@ void QTextLine::layout_helper(int maxGlyphs) while (newItem < eng->layoutData->items.size()) { lbh.resetRightBearing(); - lbh.softHyphenWidth = 0; if (newItem != item) { item = newItem; const QScriptItem ¤t = eng->layoutData->items.at(item); @@ -1975,9 +1981,9 @@ void QTextLine::layout_helper(int maxGlyphs) } while (lbh.currentPosition < end); lbh.minw = qMax(lbh.tmpData.textWidth, lbh.minw); - if (lbh.currentPosition > 0 && lbh.currentPosition < end - && attributes[lbh.currentPosition].lineBreak - && eng->layoutData->string.at(lbh.currentPosition - 1).unicode() == QChar::SoftHyphen) { + if (lbh.currentPosition > 0 && lbh.currentPosition <= end + && (lbh.currentPosition == end || attributes[lbh.currentPosition].lineBreak) + && eng->layoutData->string.at(lbh.currentPosition - 1) == QChar::SoftHyphen) { // if we are splitting up a word because of // a soft hyphen then we ... // @@ -1994,10 +2000,7 @@ void QTextLine::layout_helper(int maxGlyphs) // want the soft-hyphen to slip into the next line // and thus become invisible again. // - if (line.length) - lbh.softHyphenWidth = lbh.glyphs.advances[lbh.logClusters[lbh.currentPosition - 1]]; - else if (breakany) - lbh.tmpData.textWidth += lbh.glyphs.advances[lbh.logClusters[lbh.currentPosition - 1]]; + lbh.currentSoftHyphenWidth = lbh.glyphs.advances[lbh.logClusters[lbh.currentPosition - 1]]; } if (sb_or_ws|breakany) { @@ -2023,6 +2026,7 @@ void QTextLine::layout_helper(int maxGlyphs) lbh.calculateRightBearing(); if (lbh.checkFullOtherwiseExtend(line)) { + // We are too wide to accept the next glyph with its bearing, so we restore the // right bearing to that of the previous glyph (the one that was already accepted), // so that the bearing can be be applied to the final width of the text below. @@ -2031,9 +2035,7 @@ void QTextLine::layout_helper(int maxGlyphs) else lbh.calculateRightBearingForPreviousGlyph(); - if (!breakany) { - line.textWidth += lbh.softHyphenWidth; - } + line.textWidth += lbh.commitedSoftHyphenWidth; goto found; } @@ -2045,6 +2047,7 @@ void QTextLine::layout_helper(int maxGlyphs) } LB_DEBUG("reached end of line"); lbh.checkFullOtherwiseExtend(line); + line.textWidth += lbh.commitedSoftHyphenWidth; found: line.textAdvance = line.textWidth; -- cgit v1.2.3